- 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

440
ubcalc.c
View File

@ -6,6 +6,10 @@
copyright: see file COPYRIGHT
Mark Koennecke, March 2005
Heavily reworked to fit into the new four circle system
Mark Koennecke, July 2008
-----------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
@ -17,6 +21,9 @@
#include "ubcalc.h"
#include "motor.h"
#include "hkl.h"
#include "singlex.h"
#include "reflist.h"
#include "singlediff.h"
/*----------------------------------------------------------------------*/
static void killUBCALC(void *pData){
pUBCALC self = (pUBCALC)pData;
@ -37,18 +44,6 @@ static int SaveUBCalc(void *data, char *name, FILE *fd){
if(self == NULL){
return 0;
}
fprintf(fd,"%s cell %f %f %f %f %f %f\n", name, self->direct.a,
self->direct.b, self->direct.c, self->direct.alpha,
self->direct.beta, self->direct.gamma);
fprintf(fd,"%s ref1 %f %f %f %f %f %f %f\n",name,
self->r1.h, self->r1.k, self->r1.l,
self->r1.s2t, self->r1.om, self->r1.chi, self->r1.phi);
fprintf(fd,"%s ref2 %f %f %f %f %f %f %f\n",name,
self->r2.h, self->r2.k, self->r2.l,
self->r2.s2t, self->r2.om, self->r2.chi, self->r2.phi);
fprintf(fd,"%s ref3 %f %f %f %f %f %f %f\n",name,
self->r3.h, self->r3.k, self->r3.l,
self->r3.s2t, self->r3.om, self->r3.chi, self->r3.phi);
fprintf(fd,"%s difftheta %f\n", name, self->allowedDeviation);
fprintf(fd, "%s maxindex %d\n", name, self->indexSearchLimit);
fprintf(fd ,"%s maxlist %d\n", name, self->maxSuggestions);
@ -76,190 +71,41 @@ static pUBCALC makeUBCALC(pHKL hkl){
return pNew;
}
/*----------------------------------------------------------------------*/
int CreateUBCalc(SConnection *pCon, SicsInterp *pSics, char *name,
char *hklname){
pUBCALC pNew = NULL;
int status;
pHKL hkl = NULL;
hkl = FindCommandData(pSics,hklname,"4-Circle-Calculus");
if(hkl == NULL){
SCWrite(pCon,"ERROR: HKL object not found or wrong type",eError);
return 0;
}
pNew = makeUBCALC(hkl);
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating UBCALC",eError);
return 0;
}
status = AddCommand(pSics,name,UBCalcWrapper,killUBCALC,pNew);
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate UBCALC module",eError);
}
return status;
}
/*----------------------------------------------------------------------*/
int MakeUBCalc(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pUBCALC pNew = NULL;
int status;
pHKL hkl = NULL;
if(argc < 3){
SCWrite(pCon,"ERROR: missing argument to MakeUBCalc: MakeUBCalc name hklobject",eError);
return 0;
}
hkl = FindCommandData(pSics,argv[2],"4-Circle-Calculus");
if(hkl == NULL){
SCWrite(pCon,"ERROR: HKL object not found or wrong type",eError);
return 0;
}
pNew = makeUBCALC(hkl);
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating UBCALC",eError);
return 0;
}
status = AddCommand(pSics,argv[1],UBCalcWrapper,killUBCALC,pNew);
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate UBCALC module",eError);
}
return status;
if(argc < 3){
SCWrite(pCon,"ERROR: missing argument to MakeUBCalc: MakeUBCalc name hklobject",eError);
return 0;
}
return CreateUBCalc(pCon,pSics,argv[1], argv[2]);
}
/*---------------------------------------------------------------------*/
static int readCell(SConnection *pCon, pUBCALC self, int argc, char *argv[]){
int status;
Tcl_Interp *pTcl = InterpGetTcl(pServ->pSics);
char pBueffel[256];
if(argc < 8){
SCWrite(pCon,"ERROR: insufficient number of arguments to ubcalc cell",
eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[2],&self->direct.a);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[3],&self->direct.b);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[4],&self->direct.c);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[4]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[5],&self->direct.alpha);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[5]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[6],&self->direct.beta);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[6]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[7],&self->direct.gamma);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[7]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int readRefMotors(SConnection *pCon, SicsInterp *pSics,
reflection *r){
pMotor pMot = NULL;
float val;
pMot = FindMotor(pSics,"stt");
if(pMot == NULL){
SCWrite(pCon,"ERROR: cannot find stt motor",eError);
return 0;
}
MotorGetSoftPosition(pMot,pCon,&val);
r->s2t = val;
pMot = FindMotor(pSics,"om");
if(pMot == NULL){
SCWrite(pCon,"ERROR: cannot find om motor",eError);
return 0;
}
MotorGetSoftPosition(pMot,pCon,&val);
r->om = val;
pMot = FindMotor(pSics,"chi");
if(pMot == NULL){
SCWrite(pCon,"ERROR: cannot find chi motor",eError);
return 0;
}
MotorGetSoftPosition(pMot,pCon,&val);
r->chi = val;
pMot = FindMotor(pSics,"phi");
if(pMot == NULL){
SCWrite(pCon,"ERROR: cannot find phi motor",eError);
return 0;
}
MotorGetSoftPosition(pMot,pCon,&val);
r->phi = val;
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
/*---------------------------------------------------------------------*/
static int readReflection(SConnection *pCon, SicsInterp *pSics, reflection *r,
int argc, char *argv[]){
char pBueffel[255];
int status;
Tcl_Interp *pTcl = InterpGetTcl(pSics);
if(argc < 5){
SCWrite(pCon,"ERROR: not enough arguments to ubcalc ref1,2",eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[2],&r->h);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[3],&r->k);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[4],&r->l);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[4]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(argc >= 9){
status = Tcl_GetDouble(pTcl,argv[5],&r->s2t);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[5]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[6],&r->om);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[6]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[7],&r->chi);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[7]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(pTcl,argv[8],&r->phi);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[8]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else {
return readRefMotors(pCon,pSics,r);
}
}
/*---------------------------------------------------------------------*/
static void listUB(SConnection *pCon, MATRIX UB){
Tcl_DString list;
char pBueffel[255];
@ -281,13 +127,90 @@ static void listUB(SConnection *pCon, MATRIX UB){
Tcl_DStringFree(&list);
}
/*---------------------------------------------------------------------*/
static int calcUB(pUBCALC self, SConnection *pCon){
static int updateUBCALC(pUBCALC self, SConnection *pCon,
char *id1, char *id2, char *id3){
const double *cell;
double hkl[3], angles[4];
pSICSOBJ refList;
cell = SXGetCell();
self->direct.a = cell[0];
self->direct.b = cell[1];
self->direct.c = cell[2];
self->direct.alpha = cell[3];
self->direct.beta = cell[4];
self->direct.gamma = cell[5];
refList = SXGetReflectionList();
if(id1 != NULL){
if(!GetRefIndexID(refList,id1,hkl)){
SCPrintf(pCon,eError,"ERROR: reflection with id %s not found",id1);
return 0;
} else {
self->r1.h = hkl[0];
self->r1.k = hkl[1];
self->r1.l = hkl[2];
GetRefAnglesID(refList,id1,angles);
self->r1.s2t = angles[0];
self->r1.om = angles[1];
self->r1.chi = angles[2];
self->r1.phi = angles[3];
}
}
if(id2 != NULL){
if(!GetRefIndexID(refList,id2,hkl)){
SCPrintf(pCon,eError,"ERROR: reflection with id %s not found",id2);
return 0;
} else {
self->r2.h = hkl[0];
self->r2.k = hkl[1];
self->r2.l = hkl[2];
GetRefAnglesID(refList,id2,angles);
self->r2.s2t = angles[0];
self->r2.om = angles[1];
self->r2.chi = angles[2];
self->r2.phi = angles[3];
}
}
if(id3 != NULL){
if(!GetRefIndexID(refList,id3,hkl)){
SCPrintf(pCon,eError,"ERROR: reflection with id %s not found",id3);
return 0;
} else {
self->r3.h = hkl[0];
self->r3.k = hkl[1];
self->r3.l = hkl[2];
GetRefAnglesID(refList,id3,angles);
self->r3.s2t = angles[0];
self->r3.om = angles[1];
self->r3.chi = angles[2];
self->r3.phi = angles[3];
}
}
return 1;
}
/*---------------------------------------------------------------------*/
static int calcUB(pUBCALC self, SConnection *pCon,
char *ref1, char *ref2){
MATRIX newUB = NULL;
int err = 1;
newUB = calcUBFromCellAndReflections(self->direct, self->r1, self->r2, &err);
pSingleDiff single = NULL;
if(!updateUBCALC(self,pCon,ref1,ref2,NULL)){
return 0;
}
single = SXGetDiffractometer();
assert(single != NULL);
newUB = single->calcUBFromTwo(single,ref1, ref2, &err);
if(newUB == NULL){
switch(err){
case REFERR:
SCWrite(pCon,"ERROR: one of reflections ID's is invalid",eError);
return 0;
break;
case UBNOMEMORY:
SCWrite(pCon,"ERROR: out of memory while calculating UB",eError);
return 0;
@ -310,25 +233,6 @@ static int calcUB(pUBCALC self, SConnection *pCon){
}
}
/*---------------------------------------------------------------------*/
static void listCell(SConnection *pCon, char *name, lattice direct){
char pBueffel[255];
snprintf(pBueffel,255,"%s.cell = %f %f %f %f %f %f",
name,direct.a, direct.b,direct.c,
direct.alpha,direct.beta,direct.gamma);
SCWrite(pCon,pBueffel,eValue);
}
/*---------------------------------------------------------------------*/
static void listReflection(SConnection *pCon, char *name,
char *refName, reflection r){
char pBueffel[255];
snprintf(pBueffel,255,"%s.%s = %f %f %f %f %f %f %f",
name,refName, r.h, r.k, r.l, r.s2t, r.om, r.chi, r.phi);
SCWrite(pCon,pBueffel,eValue);
}
/*---------------------------------------------------------------------*/
static int sendUBToHKL(SConnection *pCon, SicsInterp *pSics,
pHKL hkl, MATRIX UB){
float ub[9];
@ -346,7 +250,8 @@ static int sendUBToHKL(SConnection *pCon, SicsInterp *pSics,
return 1;
}
/*---------------------------------------------------------------------*/
static int setUBCalcParameters(pUBCALC self, SConnection *pCon, char *name, char *value){
static int setUBCalcParameters(pUBCALC self, SConnection *pCon,
char *name, char *value){
if(strcmp(name,"difftheta") == 0){
if(!SCMatchRights(pCon,usUser)){
@ -412,26 +317,27 @@ static void listPar(pUBCALC self, char *name, SConnection *pCon){
/*---------------------------------------------------------------------*/
static int findIndex(pUBCALC self, SConnection *pCon, SicsInterp *pSics,
int argc, char *argv[]){
float two_theta, lambda;
float two_theta;
pMotor pMot = NULL;
int status, numRef, i;
refIndex *index = NULL;
Tcl_DString list;
char pLine[255];
double lambda;
if(argc > 2){
two_theta = atof(argv[2]);
} else {
pMot = FindMotor(pSics,"stt");
pMot = SXGetMotor(TwoTheta);
if(pMot == NULL){
SCWrite(pCon,"ERROR: cannot find stt motor",eError);
return 0;
}
MotorGetSoftPosition(pMot,pCon,&two_theta);
}
GetLambda(self->hkl,&lambda);
lambda = SXGetLambda();
updateUBCALC(self,pCon,NULL,NULL,NULL);
numRef = self->maxSuggestions;
index = (refIndex *)malloc(numRef*sizeof(refIndex));
if(index == NULL){
@ -476,18 +382,29 @@ static int findIndex(pUBCALC self, SConnection *pCon, SicsInterp *pSics,
return 1;
}
/*---------------------------------------------------------------------*/
static int calcUB3Ref(pUBCALC self, SConnection *pCon){
float lambda;
static int calcUB3Ref(pUBCALC self, SConnection *pCon,
char *id1, char *id2, char *id3){
double lambda;
MATRIX newUB = NULL;
int errCode = 1;
char pBueffel[256];
GetLambda(self->hkl,&lambda);
pSingleDiff single = NULL;
newUB = calcUBFromThreeReflections(self->r1, self->r2, self->r3,
lambda, &errCode);
lambda = SXGetLambda();
if(!updateUBCALC(self, pCon, id1, id2, id3)){
return 0;
}
single = SXGetDiffractometer();
assert(single != NULL);
newUB = single->calcUBFromThree(single,id1, id2, id3, &errCode);
if(newUB == NULL){
switch(errCode){
case REFERR:
SCWrite(pCon,"ERROR: one of reflections ID's is invalid",eError);
return 0;
break;
case UBNOMEMORY:
SCWrite(pCon,"ERROR: out of memory calculating UB",eError);
break;
@ -517,8 +434,21 @@ static int cellFromUBWrapper(pUBCALC self, SConnection *pCon){
int status;
char pBueffel[256];
lattice direct;
status = cellFromUB(self->UB,&direct);
const double *ub;
MATRIX UB;
int i;
UB = mat_creat(3,3,UNIT_MATRIX);
ub = SXGetUB();
for(i = 0; i < 3; i++){
UB[0][i] = ub[i];
UB[1][i] = ub[i+3];
UB[2][i] = ub[i+6];
}
status = cellFromUB(UB,&direct);
mat_free(UB);
if(status < 0){
switch(status){
case CELLNOMEMORY:
@ -530,7 +460,7 @@ static int cellFromUBWrapper(pUBCALC self, SConnection *pCon){
}
return 0;
} else {
snprintf(pBueffel,255," %8.4f %8.4f %8.4f %6.2f %6.2f %6.2f",
snprintf(pBueffel,255,"%f %f %f %f %f %f",
direct.a, direct.b, direct.c,
direct.alpha, direct.beta, direct.gamma);
SCWrite(pCon,pBueffel,eValue);
@ -545,53 +475,29 @@ int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
assert(self);
if(argc < 2){
SCWrite(pCon,"Insuffcient number of arguments to ubcalc",eError);
return 0;
SCWrite(pCon,"Insuffcient number of arguments to ubcalc",eError);
return 0;
}
strtolower(argv[1]);
if(strcmp(argv[1],"cell") == 0){
if(argc > 3){
return readCell(pCon, self, argc, argv);
} else {
snprintf(pBuffer,511,"ubcalc cell = %f %f %f %f %f %f",
self->direct.a, self->direct.b, self->direct.c,
self->direct.alpha, self->direct.beta,self->direct.gamma);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if(strcmp(argv[1],"ref1") == 0){
return readReflection(pCon,pSics, &self->r1,argc,argv);
} else if(strcmp(argv[1],"ref2") ==0){
return readReflection(pCon,pSics, &self->r2,argc,argv);
} else if(strcmp(argv[1],"ref3") == 0){
return readReflection(pCon,pSics, &self->r3,argc,argv);
} else if(strcmp(argv[1],"listub") == 0){
if(strcmp(argv[1],"listub") == 0){
listUB(pCon,self->UB);
return 1;
} else if(strcmp(argv[1],"ub2ref") == 0){
return calcUB(self,pCon);
if(argc < 4){
SCWrite(pCon,"Insuffcient number of arguments to ubcalc ub2ref",eError);
return 0;
}
return calcUB(self,pCon, argv[2], argv[3]);
} else if(strcmp(argv[1],"ub3ref") == 0){
return calcUB3Ref(self,pCon);
if(argc < 5){
SCWrite(pCon,"Insuffcient number of arguments to ubcalc ub3ref",eError);
return 0;
}
return calcUB3Ref(self,pCon,argv[2],argv[3],argv[4]);
} else if(strcmp(argv[1],"cellub") == 0){
return cellFromUBWrapper(self,pCon);
} else if(strcmp(argv[1],"listcell") == 0){
listCell(pCon,argv[0],self->direct);
return 1;
} else if(strcmp(argv[1],"listref1") == 0){
listReflection(pCon,argv[0],"ref1",self->r1);
return 1;
} else if(strcmp(argv[1],"listref2") == 0){
listReflection(pCon,argv[0],"ref2",self->r2);
return 1;
} else if(strcmp(argv[1],"listref3") == 0){
listReflection(pCon,argv[0],"ref3",self->r3);
return 1;
} else if(strcmp(argv[1],"list") == 0){
listCell(pCon,argv[0],self->direct);
listReflection(pCon,argv[0],"ref1",self->r1);
listReflection(pCon,argv[0],"ref2",self->r2);
listReflection(pCon,argv[0],"ref3",self->r3);
}else if(strcmp(argv[1],"list") == 0){
listUB(pCon,self->UB);
listPar(self,argv[0],pCon);
return 1;