- 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:
267
ubcalc.c
267
ubcalc.c
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user