/** * This is a library of functions and data structures for performing * triple axis spectrometer angle calculations using the UB-matrix * formalism as described by Mark Lumsden. * * copyright: see file COPYRIGHT * * Mark Koennecke, April 2005 */ #ifndef TASUBLIB #define TASUBLIB #include "cell.h" #include "matrix/matrix.h" /*================= error codes =====================================*/ #define ENERGYTOBIG -700 #define BADSYNC -701 /* mono/analyzer out of sync: 2*theta != two_theta*/ #define UBNOMEMORY -702 #define TRIANGLENOTCLOSED -703 #define BADRMATRIX -704 /*================= Monochromator/Analyzer stuff =====================*/ /** * convert an energy in meV to Ki, Kf type values * @param input energy * @return Ki, or Kf */ double energyToK(double energy); /** * convert from Ki, Kf to energy in meV * @param input K value * @return output energy in meV */ double KtoEnergy(double k); /*----------------------------------------------------------------------*/ /** * data structure describing a monochromator or analyzer crystal */ typedef struct { double dd; /* lattice spacing */ int ss; /* scattering sense */ double HB1, HB2; /* horizontal curvature parameters */ double VB1, VB2; /* vertical curvature parameters */ } maCrystal, *pmaCrystal; /** * data structure for the angles of a mono/ana calculation */ typedef struct{ double theta; double two_theta; double horizontal_curvature; double vertical_curvature; }maAngles, *pmaAngles; /*-----------------------------------------------------------------------*/ /** * calculate the angles for the wavelength or K value k * @param data The crystals constants * @param angles output angles * @param k The wavelength or k value to calculate * @return 1 on success, a negative error code on failure. */ int maCalcAngles(maCrystal data, pmaAngles angles, double k); /** * calculate the value of the K vector from angles * @param data The crystals constants * @param angles The current angles * @param k The output K vector * @return 1 on success, a negative error code on failure. */ int maCalcK(maCrystal data, maAngles angles, double *k); /*======================= reciprocal space =============================*/ typedef struct { double h,k,l; double a3, two_theta, sgu, sgl; double ki, kf; }tasReflection, *ptasReflection; /** * calculate a UB from two reflections and the cell. * @param cell The lattice constant of the crystal * @param r1 The first reflection * @param r2 The second reflection * @param erroroCode An error code which gives more details * when an error occurs. * @return a UB matix on sucess, or NULL on failure. Then errorCode * can be inspected what caused the problem. */ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1, tasReflection r2, int *errorCode); /** * calcluate the normal to the plane describe by the two reflections r1, r2 * @param r1 first reflection * @param r2 second reflection * @return a plane normal on success, NULL else */ MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2); /** * calculate the angles for r. R's h, k, l, ki, kf must be set, the angles * will be updated. * @param UB The UB matrix to use * @param planeNormal The normal to the scattering plane to use * @param ss The scattering sense at the sample * @param r The input/output reflection * @return 1 on success, a negative error code when errors are encountered */ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, ptasReflection r); /** * calculate QH, QK, QL from the angles given * @param UB The UB matrix to use * @param r The reflection to proecess. The angles and ki, kf have to be set * to appropriate values before this can work properly. * @return 1 on success, a negative error code on failures. */ int calcTasQH(MATRIX UB, ptasReflection r); /*======================== pulling it together.. =======================*/ typedef struct { maCrystal monochromator, analyzer; MATRIX UB; MATRIX planeNormal; int ss_sample; /* scattering sense sample */ tasReflection r; }tasMachine, *ptasMachine; /*---------------------------------------------------------------------*/ typedef struct { maAngles monochromator; double a3; double sample_two_theta; double sgl; double sgu; maAngles analyzer; }tasAngles, *ptasAngles; /*-------------------------------------------------------------------*/ typedef struct { double ki, kf; double qh,qk,ql; }tasQEPosition, *ptasQEPosition; /** * calculate all the tas target angles for a position in Q-Energy space. * @param machine The machine description * @param qe Input QE position * @param angles output angles. * @return 1 on success, a negative error code in case of problems */ int calcAllTasAngles(ptasMachine machine, tasQEPosition qe, ptasAngles angles); /** * calculate the current position of the spectrometer in Q-E space from * angles. * @param machine The machine parameters * @param angles The input angles * @param qe The output Q-E position * @return 1 on success, a negative error code on errors. */ int calcTasQEPosition(ptasMachine machine, tasAngles angles, ptasQEPosition qe); #endif