- Added brute force indexing support to ubcalc

- Added calculation of UB from 3 reflections to ubcalc
- Added calculation of lattice constants from UB to ubcalc
- Some fixes in stdscan in order to make the scripted scan work
This commit is contained in:
koennecke
2005-04-01 13:48:25 +00:00
parent 152bc961ec
commit 5c30a7ea7b
10 changed files with 637 additions and 45 deletions

267
ubcalc.c
View File

@ -20,9 +20,13 @@
/*---------------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pHKL hkl;
lattice direct;
reflection r1, r2;
reflection r1, r2, r3;
MATRIX UB;
double allowedDeviation;
int indexSearchLimit;
int maxSuggestions;
} UBCALC, *pUBCALC;
/*----------------------------------------------------------------------*/
static void killUBCALC(void *pData){
@ -53,10 +57,16 @@ static int SaveUBCalc(void *data, char *name, FILE *fd){
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);
return 1;
}
/*---------------------------------------------------------------------*/
static pUBCALC makeUBCALC(){
static pUBCALC makeUBCALC(pHKL hkl){
pUBCALC pNew = NULL;
pNew = (pUBCALC)malloc(sizeof(UBCALC));
@ -70,6 +80,10 @@ static pUBCALC makeUBCALC(){
return NULL;
}
pNew->pDes->SaveStatus = SaveUBCalc;
pNew->hkl = hkl;
pNew->allowedDeviation = .3;
pNew->indexSearchLimit = 5;
pNew->maxSuggestions = 10;
return pNew;
}
/*----------------------------------------------------------------------*/
@ -77,17 +91,25 @@ int MakeUBCalc(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pUBCALC pNew = NULL;
int status;
pHKL hkl = NULL;
pNew = makeUBCALC();
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;
}
if(argc > 1){
status = AddCommand(pSics,argv[1],UBCalcWrapper,killUBCALC,pNew);
} else {
status = AddCommand(pSics,"ubcalc",UBCalcWrapper,killUBCALC,pNew);
}
status = AddCommand(pSics,argv[1],UBCalcWrapper,killUBCALC,pNew);
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate UBCALC module",eError);
}
@ -319,18 +341,12 @@ static void listReflection(SConnection *pCon, char *name,
}
/*---------------------------------------------------------------------*/
static int sendUBToHKL(SConnection *pCon, SicsInterp *pSics,
char *name, MATRIX UB){
pHKL hkl = NULL;
char pBueffel[256];
pHKL hkl, MATRIX UB){
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;
}
assert(hkl != NULL);
for(i = 0; i < 3; i++){
ub[i] = UB[0][i];
ub[i+3] = UB[1][i];
@ -340,6 +356,198 @@ static int sendUBToHKL(SConnection *pCon, SicsInterp *pSics,
SCSendOK(pCon);
return 1;
}
/*---------------------------------------------------------------------*/
static int setUBCalcParameters(pUBCALC self, SConnection *pCon, char *name, char *value){
if(strcmp(name,"difftheta") == 0){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->allowedDeviation = atof(value);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else if(strcmp(name,"maxindex") == 0){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->indexSearchLimit = atoi(value);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else if(strcmp(name,"maxlist") == 0){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->maxSuggestions = atoi(value);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
} else {
SCWrite(pCon,"ERROR: subcommand not recognized",eError);
return 0;
}
}
/*---------------------------------------------------------------------*/
static int getUBCalcParameters(pUBCALC self, SConnection *pCon, char *name){
char pBueffel[255];
int ret = 0;
if(strcmp(name,"difftheta") == 0){
snprintf(pBueffel,255,"ubcalc.difftheta = %f",self->allowedDeviation);
ret = 1;
} else if(strcmp(name,"maxindex") == 0){
snprintf(pBueffel,255,"ubcalc.maxindex = %d", self->indexSearchLimit);
ret = 1;
} else if(strcmp(name,"maxlist") == 0){
snprintf(pBueffel,255,"ubcalc.maxindex = %d", self->maxSuggestions);
ret = 1;
} else {
snprintf(pBueffel,255,"ERROR: subcommand not known");
}
SCWrite(pCon,pBueffel,eValue);
return ret;
}
/*---------------------------------------------------------------------*/
static void listPar(pUBCALC self, char *name, SConnection *pCon){
char pBueffel[255];
snprintf(pBueffel,255,"%s.difftheta = %f", name, self->allowedDeviation);
SCWrite(pCon,pBueffel,eValue);
snprintf(pBueffel,255,"%s.maxindex = %d", name, self->indexSearchLimit);
SCWrite(pCon,pBueffel,eValue);
snprintf(pBueffel,255,"%s.maxlist = %d", name, self->maxSuggestions);
SCWrite(pCon,pBueffel,eValue);
}
/*---------------------------------------------------------------------*/
static int findIndex(pUBCALC self, SConnection *pCon, SicsInterp *pSics,
int argc, char *argv[]){
float two_theta, lambda;
pMotor pMot = NULL;
int status, numRef, i;
refIndex *index = NULL;
Tcl_DString list;
char pLine[255];
if(argc > 2){
two_theta = atof(argv[2]);
} else {
pMot = FindMotor(pSics,"stt");
if(pMot == NULL){
SCWrite(pCon,"ERROR: cannot find stt motor",eError);
return 0;
}
MotorGetSoftPosition(pMot,pCon,&two_theta);
}
GetLambda(self->hkl,&lambda);
numRef = self->maxSuggestions;
index = (refIndex *)malloc(numRef*sizeof(refIndex));
if(index == NULL){
SCWrite(pCon,"ERROR: out of memory allocating index list",eError);
return 0;
}
memset(index,0,numRef*sizeof(refIndex));
status = searchIndex(self->direct,lambda, two_theta,self->allowedDeviation,
self->indexSearchLimit, index, numRef);
if(status < 0){
if(status == UBNOMEMORY){
SCWrite(pCon,"ERROR: out of memory searching indices",eError);
return 0;
} else if(status == REC_NO_VOLUME){
SCWrite(pCon,"ERROR: bad cell parameters",eError);
return 0;
} else {
SCWrite(pCon,"ERROR: unknown error code",eError);
return 0;
}
}
if(status < numRef) {
numRef = status;
}
Tcl_DStringInit(&list);
for(i = 0; i < numRef; i++){
snprintf(pLine,255," %3d %3d %3d %8.2f %8.2f %8.2f\r\n",
(int)index[i].h, (int)index[i].k, (int)index[i].l,
two_theta, index[i].t2calc,index[i].t2diff);
Tcl_DStringAppend(&list,pLine,-1);
}
if(numRef == 0){
Tcl_DStringAppend(&list,"No suitable reflections found",-1);
}
SCWrite(pCon,Tcl_DStringValue(&list),eValue);
Tcl_DStringFree(&list);
free(index);
return 1;
}
/*---------------------------------------------------------------------*/
static int calcUB3Ref(pUBCALC self, SConnection *pCon){
float lambda;
MATRIX newUB = NULL;
int errCode = 1;
char pBueffel[256];
GetLambda(self->hkl,&lambda);
newUB = calcUBFromThreeReflections(self->r1, self->r2, self->r3,
lambda, &errCode);
if(newUB == NULL){
switch(errCode){
case UBNOMEMORY:
SCWrite(pCon,"ERROR: out of memory calculating UB",eError);
break;
case INVALID_LAMBDA:
SCWrite(pCon,"ERROR: bad value for wavelength",eError);
break;
case NOTRIGHTHANDED:
SCWrite(pCon,"ERROR: reflections are coplanar or do not form a right handed system",
eError);
break;
default:
SCWrite(pCon,"ERROR: unknown error code from UB calculation",eError);
break;
}
return 0;
} else {
if(self->UB != NULL){
mat_free(self->UB);
}
self->UB = newUB;
SCSendOK(pCon);
}
return 1;
}
/*--------------------------------------------------------------------*/
static int cellFromUBWrapper(pUBCALC self, SConnection *pCon){
int status;
char pBueffel[256];
lattice direct;
status = cellFromUB(self->UB,&direct);
if(status < 0){
switch(status){
case CELLNOMEMORY:
SCWrite(pCon,"ERROR: out of memory while calculating cell",eError);
break;
default:
SCWrite(pCon,"ERROR: unknown error calculating cell",eError);
break;
}
return 0;
} else {
snprintf(pBueffel,255," %8.4f %8.4f %8.4f %6.2f %6.2f %6.2f",
direct.a, direct.b, direct.c,
direct.alpha, direct.beta, direct.gamma);
SCWrite(pCon,pBueffel,eValue);
}
return 1;
}
/*----------------------------------------------------------------------*/
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
@ -358,11 +566,17 @@ int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
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){
listUB(pCon,self->UB);
return 1;
} else if(strcmp(argv[1],"calcub") == 0){
return calcUB(self,pCon);
} else if(strcmp(argv[1],"calcub3ref") == 0){
return calcUB3Ref(self,pCon);
} else if(strcmp(argv[1],"cellfromub") == 0){
return cellFromUBWrapper(self,pCon);
} else if(strcmp(argv[1],"listcell") == 0){
listCell(pCon,argv[0],self->direct);
return 1;
@ -372,18 +586,27 @@ int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
} 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);
listUB(pCon,self->UB);
listPar(self,argv[0],pCon);
return 1;
} else if(strcmp(argv[1],"sendto") == 0){
if(argc < 3){
SCWrite(pCon,"ERROR: Nothing to send UB too",eError);
return 0;
} else if(strcmp(argv[1],"activate") == 0){
return sendUBToHKL(pCon,pSics,self->hkl,self->UB);
} else if(strcmp(argv[1],"index") == 0){
return findIndex(self,pCon,pSics,argc, argv);
} else {
if(argc > 2){
return setUBCalcParameters(self,pCon,argv[1],argv[2]);
} else {
return getUBCalcParameters(self,pCon,argv[1]);
}
return sendUBToHKL(pCon,pSics,argv[2],self->UB);
}
return 1;
}