\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. 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@ } 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. \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@@\\ \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[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}