\subsection{Triple Axis Spectrometer UB Matrix Calculations} This module handles the calculations typical for a triple axis spectrometer. This is the calculation in Q energy space. The algorithm useid is based on a UB matrix calculus as described by Mark Lumsden. This uses the goniometer tilt angles, sgu and sgl, to position the reflection. For more information, see the pdf file holding M. Lumsden's text. The actual calculation has been put into a library, tasublib.h and tasublib.c. This describes the interface to the SICS interpreter. This module caters for: \begin{itemize} \item UB matrix calculations \item Angle calculations \item The triple axis modes and logic \item Introduces the QE variables as virtual motors into SICS \end{itemize} A data structure: @d tasubdat @{ /*------------------- defines for tasMode -----------------------------------*/ typedef struct{ pObjectDescriptor pDes; tasMachine machine; int reflectionList; lattice cell; tasQEPosition target; tasQEPosition current; int tasMode; int outOfPlaneAllowed; double targetEn, actualEn; int mustRecalculate; int mustDrive; pMotor motors[12]; tasReflection r1, r2; int ubValid; int silent; char *updater; }tasUB, *ptasUB; @} \begin{description} \item[pDes] The traditional object descriptor \item[machine] The machine parameters: monochromator d spacing, scattering sense, UB and the like. \item[reflectionList] A list of reflections. \item[cell] The cell constants. \item[target] The Q energy target position \item[current] The actual Q energy position as calculated from angles. \item[tasMode] The mode: constant KI or constant KF \item[outOfPlaneAllowed] 0/1 determining if it is allowed to drive out of plane or not. \item[ptargetEn] The target energy transfer. \item[actualEn] The actual energy transfer as calcluated from angles. \item[mustRecalculate] A flag indicatin that the current Q energy psoition has to be recalculated. \item[mustDrive] A flag indicating that one of the values has changed and that we need to drive motors to get in sync again. \item[motors] The TAS motors: A1, A2, MCV (vertical curvature), MCH (horizontal curvature), A3, A4, SGU, SGL, A5, A6, ACV, ACH. The curvature motors may be NULL at runtime. \item[r1,r2] The indexs of the reflections used for calculating the orientation matrix. \item[ubValid] a flag denoting if the UB is valid. \item[silent] A flga which when 1 suppresses the printing of motor positions when driving. Usefule for scans. \item[updates] The optiona name of a script to call when tasu had been updated. This is to support Hipadaba tree integration without changing this complicated module too much. \end{description} For the virtual motors, there must be a data structure, too: @d tasubmotdat @{ /*--------------------- the tas virtual motor data structure ---------------------*/ typedef struct { pObjectDescriptor pDes; pIDrivable pDriv; ptasUB math; int code; }tasMot, *ptasMot; @} \begin{description} \item[pDes] The traditional SICS object descriptor. \item[pDriv] The drivable interface. \item[math] The tasUB module which does the hard work. \item[code] The type code: one of the defines from EI to QM given above. \end{description} In terms of an interface, there is only the interpreter interface, and of course the virtual motors within SICS: @d tasubint @{ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData, int argc, char *argv[]); int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData, int argc, char *argv[]); @} @o tasub.h @{ /*---------------------------------------------------------------------- SICS interface to the triple axis spectrometer calculation module. copyright: see file COPYRIGHT Mark Koennecke, April-May 2005 ----------------------------------------------------------------------*/ #ifndef TASUB #define TASUB #include #include "tasublib.h" #include "cell.h" #include "motor.h" @ @ /*--------------------------------------------------------------------*/ @ int findReflection(int list, int idx, ptasReflection r); int tasUpdate(SConnection *pCon, ptasUB self); #endif @} @o tasdrive.h @{ /*--------------------------------------------------------------------- SICS interface to the triple axis drivable motors. copyright: see file COPYRIGHT Mark Koennecke, May 2005 --------------------------------------------------------------------*/ #ifndef TASDRIV #define TASDRIV #include "tasub.h" int InstallTasMotor(SicsInterp *pSics, ptasUB self, int tasVar, char *name); int InstallTasQMMotor(SicsInterp *pSics, ptasUB self); int TasMot(SConnection *pCon,SicsInterp *pSics, void *pData, int argc, char *argv[]); #endif @}