- Reworked the connection object and the IO system

- Reworked the support for TRICS
- Added a second generation motor
This commit is contained in:
koennecke
2009-02-03 08:05:39 +00:00
parent f6d595665e
commit 361ee9ebea
119 changed files with 16455 additions and 3674 deletions

269
singletas.c Normal file
View File

@@ -0,0 +1,269 @@
/**
* This is an implementation of the polymorphic single crystal calculation module
* for the triple axis mode. In this mode the tilt angles of a standard sample
* cradle are used to orient the sample. The math behind this has been decribed by
* Mark Lumsden in his paper.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, November 2008
*/
#include <stdlib.h>
#include <assert.h>
#include <sics.h>
#include "singlediff.h"
#include "motor.h"
#include "singlex.h"
#include "motorlist.h"
#include "lld.h"
#include "tasublib.h"
#include "fourlib.h"
/*---------------------------------------------------------------------*/
static int calculateTASSettings(pSingleDiff self,
double *hkl, double *settings){
tasQEPosition qe;
tasAngles angles;
double e, *normal;
int status;
MATRIX mn;
char error[132];
float fHard;
e = 9.045/self->lambda;
e = e*e;
qe.ki = energyToK(e);
qe.kf = energyToK(e);
qe.qh = hkl[0];
qe.qk = hkl[1];
qe.ql = hkl[2];
normal = SXGetPlanenormal();
if(normal == NULL){
return 0;
}
mn = vectorToMatrix(normal);
if(mn == NULL){
return 0;
}
status = calcTasQAngles(self->UB, mn, 1, qe, &angles);
if(status < 0) {
status = 0;
} else {
status = 1;
}
settings[0] = angles.a3;
settings[1] = angles.sample_two_theta;
settings[2] = angles.sgu;
settings[3] = angles.sgl;
if(!MotorCheckBoundary(SXGetMotor(Omega), (float)settings[0],&fHard,
error, 132)){
status = 0;
}
if(!MotorCheckBoundary(SXGetMotor(TwoTheta), (float)settings[1],&fHard,
error, 132)){
status = 0;
}
if(!MotorCheckBoundary(SXGetMotor(Sgu), (float)settings[2],&fHard,
error, 132)){
status = 0;
}
if(!MotorCheckBoundary(SXGetMotor(Sgl), (float)settings[3],&fHard,
error, 132)){
status = 0;
}
free(normal);
mat_free(mn);
return status;
}
/*-------------------------------------------------------------------*/
static int settingsToTasList(struct __SingleDiff *self, double *settings){
setNewMotorTarget(self->motList, (char *)SXGetMotorName(Omega),
(float)settings[0]);
setNewMotorTarget(self->motList, (char *)SXGetMotorName(TwoTheta),
(float)settings[1]);
setNewMotorTarget(self->motList, (char *)SXGetMotorName(Sgu),
(float)settings[2]);
setNewMotorTarget(self->motList, (char *)SXGetMotorName(Sgl),
(float)settings[3]);
return 1;
}
/*--------------------------------------------------------------------*/
static int hklFromTasAngles(struct __SingleDiff *self, double *hkl){
pIDrivable pDriv;
double e, stt, om, sgu, sgl;
tasQEPosition qe;
tasAngles angles;
int status = 1;
e = 9.045/self->lambda;
e = e*e;
qe.ki = energyToK(e);
qe.kf = energyToK(e);
pDriv = makeMotListInterface();
pDriv->GetValue(&self->motList, pServ->dummyCon);
stt = getListMotorPosition(self->motList,
(char *)SXGetMotorName(TwoTheta));
om = getListMotorPosition(self->motList,
(char *)SXGetMotorName(Omega));
sgu = getListMotorPosition(self->motList,
(char *)SXGetMotorName(Sgu));
sgl = getListMotorPosition(self->motList,
(char *)SXGetMotorName(Sgl));
angles.a3 = om;
angles.sample_two_theta = stt;
angles.sgu = sgu;
angles.sgl = sgl;
status = calcTasQH(self->UB, angles, &qe);
if(status < 0){
status = 0;
}
hkl[0] = qe.qh;
hkl[1] = qe.qk;
hkl[2] = qe.ql;
return status;
}
/*-------------------------------------------------------------------------*/
static int hklFromTasAnglesGiven(struct __SingleDiff *self,
double *settings, double *hkl){
double e;
tasQEPosition qe;
tasAngles angles;
int status = 1;
e = 9.045/self->lambda;
e = e*e;
qe.ki = energyToK(e);
qe.kf = energyToK(e);
angles.a3 = settings[0];
angles.sample_two_theta = settings[1];
angles.sgu = settings[2];
angles.sgl = settings[3];
status = calcTasQH(self->UB, angles, &qe);
if(status < 0){
status = 0;
}
hkl[0] = qe.qh;
hkl[1] = qe.qk;
hkl[2] = qe.ql;
return status;
}
/*------------------------------------------------------------------*/
static int getTasReflection(char *id, tasReflection *r){
pSICSOBJ refList;
double hkl[3], angles[4];
double lambda, e;
lambda = SXGetLambda();
e = 9.045/lambda;
e = e*e;
refList = SXGetReflectionList();
if(!GetRefIndexID(refList,id,hkl)){
return 0;
} else {
r->qe.qh = hkl[0];
r->qe.qk = hkl[1];
r->qe.ql = hkl[2];
r->qe.ki = energyToK(e);
r->qe.kf = energyToK(e);
GetRefAnglesID(refList,id,angles);
r->angles.a3 = angles[0];
r->angles.sample_two_theta = angles[1];
r->angles.sgu = angles[2];
r->angles.sgl = angles[3];
}
return 1;
}
/*--------------------------------------------------------------------------*/
MATRIX calcTasUBFromTwo(pSingleDiff self,
char *refid1, char *refid2, int *err){
MATRIX ub = NULL, pl = NULL;
tasReflection r1, r2;
lattice direct;
double p[3];
direct.a = self->cell[0];
direct.b = self->cell[1];
direct.c = self->cell[2];
direct.alpha = self->cell[3];
direct.beta = self->cell[4];
direct.gamma = self->cell[5];
if(!getTasReflection(refid1,&r1)){
*err = REFERR;
return NULL;
}
if(!getTasReflection(refid2,&r2)){
*err = REFERR;
return NULL;
}
ub = calcTasUBFromTwoReflections(direct,r1,r2,err);
pl = calcPlaneNormal(r1,r2);
if(pl != NULL){
matrixToVector(pl,p);
SXSetPlanenormal(p);
mat_free(pl);
}
return ub;
}
/*--------------------------------------------------------------------------*/
MATRIX calcTasUBFromThree(pSingleDiff self,
char *refid1, char *refid2, char *refid3, int *err){
/*
* not implemented yet
* There is also a problem: if I have three reflections, which
* defines the plane normal? This also does not make much sense anyway:
* we usually will not have a reflection out of plane: thus the three
* will be coplanar and the results may not be useful at all!
*/
return NULL;
}
/*--------------------------------------------------------------------*/
static int calcTasZ1(pSingleDiff self, char *refid, double z1[3]){
tasReflection r1;
MATRIX u = NULL;
if(!getTasReflection(refid,&r1)){
return 0;
}
u = calcTasUVectorFromAngles(r1);
if(u == NULL){
return 0;
} else {
matrixToVector(u,z1);
mat_free(u);
}
return 1;
}
/*--------------------------------------------------------------------*/
void initializeSingleTas(pSingleDiff diff){
if(diff->motList >= 0){
LLDdelete(diff->motList);
}
diff->motList = LLDcreate(sizeof(MotControl));
addMotorToList(diff->motList, (char *)SXGetMotorName(TwoTheta), .0);
addMotorToList(diff->motList, (char *)SXGetMotorName(Omega), .0);
addMotorToList(diff->motList, (char *)SXGetMotorName(Sgu), .0);
addMotorToList(diff->motList, (char *)SXGetMotorName(Sgl), .0);
diff->calculateSettings = calculateTASSettings;
diff->settingsToList = settingsToTasList;
diff->hklFromAngles = hklFromTasAngles;
diff->hklFromAnglesGiven = hklFromTasAnglesGiven;
diff->calcUBFromTwo = calcTasUBFromTwo;
diff->calcUBFromThree = calcTasUBFromThree;
diff->calcZ1 = calcTasZ1;
}