- Initial commit of a UB calculation setup for four circle

diffractometers
This commit is contained in:
koennecke
2005-03-23 08:19:47 +00:00
parent 2b63ad06b2
commit beba0d4644
18 changed files with 1236 additions and 55 deletions

389
ubcalc.c Normal file
View File

@ -0,0 +1,389 @@
/*----------------------------------------------------------------------
UB calculation routines for four circle diffraction.
This is the interpreter interface to functionality implemented
in fourlib.c
copyright: see file COPYRIGHT
Mark Koennecke, March 2005
-----------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include "tcl.h"
#include "fortify.h"
#include "sics.h"
#include "ubfour.h"
#include "ubcalc.h"
#include "motor.h"
#include "hkl.h"
/*---------------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
lattice direct;
reflection r1, r2;
MATRIX UB;
} UBCALC, *pUBCALC;
/*----------------------------------------------------------------------*/
static void killUBCALC(void *pData){
pUBCALC self = (pUBCALC)pData;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->UB != NULL){
mat_free(self->UB);
}
free(self);
}
/*--------------------------------------------------------------------*/
static int SaveUBCalc(void *data, char *name, FILE *fd){
pUBCALC self = (pUBCALC)data;
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);
return 1;
}
/*---------------------------------------------------------------------*/
static pUBCALC makeUBCALC(){
pUBCALC pNew = NULL;
pNew = (pUBCALC)malloc(sizeof(UBCALC));
if(pNew == NULL){
return NULL;
}
memset(pNew,0,sizeof(UBCALC));
pNew->pDes = CreateDescriptor("UBcalc");
pNew->UB = mat_creat(3,3,UNIT_MATRIX);
if(pNew->pDes == NULL || pNew->UB == NULL){
return NULL;
}
pNew->pDes->SaveStatus = SaveUBCalc;
return pNew;
}
/*----------------------------------------------------------------------*/
int MakeUBCalc(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pUBCALC pNew = NULL;
int status;
pNew = makeUBCALC();
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating UBCALC",eError);
return 0;
}
if(argc > 1){
status = AddCommand(pSics,argv[1],UBCalcWrapper,killUBCALC,pNew);
} else {
status = AddCommand(pSics,"ubcalc",UBCalcWrapper,killUBCALC,pNew);
}
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate UBCALC module",eError);
}
return status;
}
/*---------------------------------------------------------------------*/
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];
int i;
Tcl_DStringInit(&list);
if(UB == NULL){
Tcl_DStringAppend(&list,"NO UB",-1);
} else {
Tcl_DStringAppend(&list,"UB = ", -1);
for(i = 0; i < 3; i++){
snprintf(pBueffel,255,"%f %f %f\n", UB[i][0],
UB[i][1],UB[i][2]);
Tcl_DStringAppend(&list,pBueffel,-1);
}
}
SCWrite(pCon,Tcl_DStringValue(&list),eValue);
Tcl_DStringFree(&list);
}
/*---------------------------------------------------------------------*/
static int calcUB(pUBCALC self, SConnection *pCon){
MATRIX newUB = NULL;
int err = 1;
newUB = calcUBFromCellAndReflections(self->direct, self->r1, self->r2, &err);
if(newUB == NULL){
switch(err){
case UBNOMEMORY:
SCWrite(pCon,"ERROR: out of memory while calculating UB",eError);
return 0;
break;
case REC_NO_VOLUME:
SCWrite(pCon,"ERROR: bad cell constants",eError);
return 0;
break;
default:
SCWrite(pCon,"ERROR: unknown error on UB matrix calculation",eError);
return 0;
}
} else {
if(self->UB != NULL){
mat_free(self->UB);
}
self->UB = newUB;
SCSendOK(pCon);
return 1;
}
}
/*---------------------------------------------------------------------*/
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,
char *name, MATRIX UB){
pHKL hkl = NULL;
char pBueffel[256];
float ub[9];
int i;
hkl = FindCommandData(pSics,name,"4-Circle-Calculus");
if(hkl == NULL){
snprintf(pBueffel,255,"ERROR: %s not found or of wrong type",name);
SCWrite(pCon,pBueffel,eError);
return 0;
}
for(i = 0; i < 3; i++){
ub[i] = UB[0][i];
ub[i+3] = UB[1][i];
ub[i+6] = UB[2][i];
}
SetUB(hkl,ub);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------*/
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pUBCALC self = (pUBCALC)pData;
assert(self);
if(argc < 2){
SCWrite(pCon,"Insuffcient number of arguments to ubcalc",eError);
return 0;
}
strtolower(argv[1]);
if(strcmp(argv[1],"cell") == 0){
return readCell(pCon, self, argc, argv);
} 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],"listub") == 0){
listUB(pCon,self->UB);
return 1;
} else if(strcmp(argv[1],"calcub") == 0){
return calcUB(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],"list") == 0){
listCell(pCon,argv[0],self->direct);
listReflection(pCon,argv[0],"ref1",self->r1);
listReflection(pCon,argv[0],"ref2",self->r2);
listUB(pCon,self->UB);
return 1;
} else if(strcmp(argv[1],"sendto") == 0){
if(argc < 3){
SCWrite(pCon,"ERROR: Nothing to send UB too",eError);
return 0;
}
return sendUBToHKL(pCon,pSics,argv[2],self->UB);
}
return 1;
}