\subsection{Crystallographic Computations}
The HKL object performs standard four circle calculations. I.e., given a UB
matrix it calculates the four circle diffractometer setting angles required
for a reflection with index hkl. The UB must be determined from a set of
reflections found manually or automatically. This is done in an offline
program. The code in this module is a direct reimplementation of  fortran code
provided by Jean Allibon, ILL with the MAD four circle diffractometer
control program in  ANSI-C. For theory, see the contribution by 
W.C. Hamilton in the International Tables for Crystallography, 1974 edition.

There is a sister object to HKL which uses HKL to implement virtual motors for
H, K, and L. See below for the description

The object uses the following object data structure:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap1}
$\langle$hkldat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@   typedef struct __HKL {@\\
\mbox{}\verb@                         pObjectDescriptor pDes;@\\
\mbox{}\verb@                         double fUB[9];@\\
\mbox{}\verb@                         MATRIX UBinv;@\\
\mbox{}\verb@                         double fLambda;@\\
\mbox{}\verb@                         int iManual;@\\
\mbox{}\verb@                         double fLastHKL[5];@\\
\mbox{}\verb@                         int iNOR;@\\
\mbox{}\verb@                         int iQuad;@\\
\mbox{}\verb@                         int iHM;@\\
\mbox{}\verb@                         pMotor pTheta;@\\
\mbox{}\verb@                         pMotor pOmega;@\\
\mbox{}\verb@                         pMotor pChi;@\\
\mbox{}\verb@                         pMotor pPhi;@\\
\mbox{}\verb@                         pMotor pNu;@\\
\mbox{}\verb@                         pSelVar pMono;@\\
\mbox{}\verb@                         long lID;@\\
\mbox{}\verb@                         float scanTolerance;@\\
\mbox{}\verb@                         float targetHKL[3];@\\
\mbox{}\verb@                         int targetDirty;@\\
\mbox{}\verb@                         } HKL;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The fields are more or less self explaining:
\begin{description}
\item[pDes] The standard object descriptor.
\item[fUB] The UB matrix.
\item[iUB] is a flag which spcifies if a UB is specified.
\item[fLambda] The wavelength of the neutrons.
\item[iManual] A flag which defines if the wavelength has been set manually
or is updated automatically from a wavelength variable.
\item[fLastHKL] the HKL of the last reflection calculated.
\item[iNor] a flag for normal beam calculation mode.
\item[iHM] a flag for histogram memory mode. In this mode two theta
limits are checked  alos for detector 2 and 3.
\item[pTheta] The two theta motor. All motor are needed for boundary
checking.
\item[pOmega] The omega axis motor.
\item[pChi] The chi axis motor.
\item[pPhi] the phi axis motor.
\item[pNu] the nu axis motor for normal beam geometry. 
 This is detector tilt.
\item[pMono] The selector variable doing the wavelength.
\item[scanTolerance] The hkl module refuses to position a reflection if it is 
to close to omega limits for scanning. This is the tolerance to use.
\item[targetHKL] The target HKL values to support the H, K, L virtual motors
\item[targetDirty] A flag which is set when the virtual motors have to recalculate the
 settings and to drive. 
\end{description}

The wavelength is a bit tricky. As it would be to time consuming to read two
motors each time a calculation is performed, the lambda variable is updated
by registering a callback with the selector variable handling the
monochromator wavelength. As TriCS will be run with two monochromators on a
lift a means has to be provided to change the selector variable online. An
additonal feature is that the wavelength can be manipulated manually. This
adresses the issue that automatic wavelength may be inaccurate due to
lazy instrument scientists not   adjusting their instruments.

In terms of an interface the following functions will be provided by this
module:

\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap2}
$\langle$hklint {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@   typedef struct __HKL *pHKL;@\\
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@   pHKL CreateHKL(pMotor pTheta, pMotor pOmega, @\\
\mbox{}\verb@                  pMotor pChi, pMotor  pPhi, pMotor pNu);@\\
\mbox{}\verb@   void DeleteHKL(void *pData);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@   int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@                  int argc, char *argv[]);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@  int SetWavelengthVariable(SConnection *pCon, pHKL self, pSelVar pVar);@\\
\mbox{}\verb@  int SetWavelengthManual(pHKL self, float fVal);@\\
\mbox{}\verb@  int SetUB(pHKL self, float fUB[9]);@\\
\mbox{}\verb@  int GetUB(pHKL self, float fUB[9]);@\\
\mbox{}\verb@  int SetNOR(pHKL self, int iNOB);@\\
\mbox{}\verb@  int GetLambda(pHKL self, float *fVal);@\\
\mbox{}\verb@  int GetCurrentHKL(pHKL self, float fVal[3]);@\\
\mbox{}\verb@  int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]);@\\
\mbox{}\verb@  int GetHKLFromAngles(pHKL self, SConnection *pCon, float fVal[3]);    @\\
\mbox{}\verb@@\\
\mbox{}\verb@  int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
\mbox{}\verb@                        float fSet[4],SConnection *pCon);@\\
\mbox{}\verb@  int RunHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, SConnection@\\
\mbox{}\verb@             *pCon);@\\
\mbox{}\verb@  int DriveHKL(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
\mbox{}\verb@               SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@  int DriveSettings(pHKL self, float fSet[4],SConnection *pCon);@\\
\mbox{}\verb@@\\
\mbox{}\verb@  int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@                int argc, char *argv[]);  @\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
All functions return 0 on failure, 1 on success if not stated otherwise.
Most functions take a pointer to a HKL data structure as first parameter.
 The function in more detail:
\begin{description}
\item[CreateHKL] creates a HKL object. The parameters are pointers to the
four four circle motors. Returns NULL on failure, a pointer to the new
object on success.
\item[DeleteHKL] properly removes an HKL object from the system.
\item[HKLFactory] The factory function which initialises an HKL object from
the initialisation script.
\item[SetWavelengthVariable] sets a new wavelength variable. Installs all
 necesarry callbacks for automatic update.
\item[SetWaveLengthManual] deinstall all callbacks and forces the wavelength
to the value specified a second parameter.
\item[SetUB] sets the UB matrix.
\item[SetNOR] sets the normal beam calculation flag to iNOR.
\item[CalculateSettings] is the heart of this all. As the name suggests
calculates the settings for a four circle diffractometer. The parameters
are:
\begin{description}
\item[self] A pointer to a HKL data structure.
\item[fHKL] The reflection indices to calculate the settings for.
\item[fPsi] The psi value for the reflection. For psi scans. Set to 0 if not
used.
\item[iHamil] The index of the hamilton position to calculate. Can be an
integer between 0 to 8. 0 denotes the normal case.
\item[fSet] contains the required settings if the function returns with
success. 0 = two theta, 1 = omega, 2 = chi, 3 = phi.
\end{description}
The function returns 1 on success, a negative value on failure. Possible
error returns are:
\begin{description}
\item[HKLIMPOSSIBLE] the calculation was impossible.
\item[HKLTHETALIMIT] a setting could be calculated but can not be accessed
due to a limit on two theta. 
\end{description}
\item[DriveHKL] calculates a setting and drives to the position. The
parameters are the same as with CalculateSettings. With the addition of a
pointer to the connection object doing the command for error messages and
everything.  The error returns are the same as with CalculateSettings
well. With the addition of HKJMOTFAIL, which means that a motor failed to
drive properly.  
\item[GetHKLFromAngles] calculates the current HKL from Angles.
\item[DriveSettings] drives to the the settings given in fSet.
\item[HKLAction] is the interpreter wrapper function for the HKL object.
\end{description}

\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap3}
\verb@"hkl.i"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*-------------------------------------------------------------------------@\\
\mbox{}\verb@                                H K L@\\
\mbox{}\verb@@\\
\mbox{}\verb@  Internal data structure description. See hkl.h, c,w for more details.@\\
\mbox{}\verb@@\\
\mbox{}\verb@  Mark Koennecke, February 1998@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$hkldat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap4}
\verb@"hkl.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
\mbox{}\verb@                              H K L@\\
\mbox{}\verb@ This SICS object performs angle setting calculations for a four circle @\\
\mbox{}\verb@ diffractometer. The heart of this code is a C transcriptions of routines@\\
\mbox{}\verb@ written by Jean Allibon at ILL for the MAD program. Theory is explained in@\\
\mbox{}\verb@ the article by W. C. Hamilton in International Tables for Crystallography,@\\
\mbox{}\verb@ 1974 edition.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see copyright.h@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, February 1998@\\
\mbox{}\verb@@\\
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHKL@\\
\mbox{}\verb@#define SICSHKL@\\
\mbox{}\verb@#include "selector.h"@\\
\mbox{}\verb@#include "selvar.h"@\\
\mbox{}\verb@@$\langle$hklint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif  @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
\subsubsection{The Crystallographic Virtual Motor Object}
This module implements virtual motors H, K and L on top of the HKL object. It was choosen to implement this
in a separate module because the hkl module is already big and complex enough. The problem is how to
keep track of the necessary settings for HKL because the motors are interrelated. This is solved in the
following scheme:
\begin{itemize}
\item Starting any of the motors H, K or L results in new values to be set in the HKL internal data
 structure and a dirty flag to be set.
\item On a call to the drivable interfaces status function the dirty flag is checked and, if
 appropriate, the motor positions are recalculated and the motors started. 
\item H, K and L values are recalculated from motors on each read.
\end{itemize}
For each virtual motor an internal data structure is required:
\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap5}
$\langle$hklmotdat {\footnotesize ?}$\rangle\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@typedef         struct __HKLMOT {@\\
\mbox{}\verb@                        pObjectDescriptor pDes;@\\
\mbox{}\verb@                        pHKL pHkl;@\\
\mbox{}\verb@                        pIDrivable pDriv;@\\
\mbox{}\verb@                        int index;@\\
\mbox{}\verb@                        }HKLMot, *pHKLMot;@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex}
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
\item Macro referenced in scrap ?.
\end{list}
\end{minipage}\\[4ex]
\end{flushleft}
The fields are:\begin{description}
\item[pDes] The required object descriptor.
\item[pHkl] The HKL object to use for calculations.
\item[pDriv] The drivable interface.
\item[index] The index of the motors target in the targetHKL array in the HKL structure.  
\end{description}
The target HKL and the dirty flag is in the main HKL data structure. 

There is no external interface to this, all the functionality is hidden in the drivable interface
functions. The interpreter interface is minimal: only a value request is supported. There is
 however a factory function in order to install the HKL motors into the interpreter.

\begin{flushleft} \small
\begin{minipage}{\linewidth} \label{scrap6}
\verb@"hklmot.h"@ {\footnotesize ? }$\equiv$
\vspace{-1ex}
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@/*------------------------------------------------------------------------------------------------------@\\
\mbox{}\verb@ Virtual motor interface to reciprocal space coordinates H, K and L for a four circle diffractometer.@\\
\mbox{}\verb@ Requires a HKL object for calculations.@\\
\mbox{}\verb@@\\
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
\mbox{}\verb@@\\
\mbox{}\verb@ Mark Koennecke, February 2005@\\
\mbox{}\verb@--------------------------------------------------------------------------------------------------------*/@\\
\mbox{}\verb@#ifndef SICSHKLMOT@\\
\mbox{}\verb@#define SICSHKLMOT@\\
\mbox{}\verb@/*====================== data structure ==============================================================*/@\\
\mbox{}\verb@@$\langle$hklmotdat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@/*======================= interpreter interface ======================================================*/@\\
\mbox{}\verb@int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);@\\
\mbox{}\verb@int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@#endif@\\
\mbox{}\verb@@\\
\mbox{}\verb@        @\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-2ex}
\end{minipage}\\[4ex]
\end{flushleft}
