PSI sics-cvs-psi-2006

This commit is contained in:
2006-05-08 02:00:00 +00:00
committed by Douglas Clowes
parent ae77364de2
commit 6e926b813f
388 changed files with 445529 additions and 14109 deletions

460
hkl.c
View File

@@ -35,10 +35,7 @@
#include "hkl.h"
#include "hkl.i"
#include "splitter.h"
/*
the space we leave in omega in order to allow for a scan to be done
*/
#define SCANBORDER 3.
/*
the tolerance in chi we give before we allow to fix omega with phi
*/
@@ -62,6 +59,9 @@
self->fUB[0], self->fUB[1], self->fUB[2], self->fUB[3], self->fUB[4],
self->fUB[5], self->fUB[6], self->fUB[7], self->fUB[8]);
fprintf(fd,"%s hm %d\n",name, self->iHM);
fprintf(fd,"%s scantolerance %f\n", name,self->scanTolerance);
fprintf(fd,"%s nb %d\n", name, self->iNOR);
fprintf(fd,"%s phiom %d\n", name, self->iOMPHI);
return 1;
}
@@ -106,6 +106,7 @@
pNew->fUB[4] = 1.;
pNew->fUB[8] = 1.;
pNew->UBinv = NULL;
pNew->scanTolerance = 2.5;
return pNew;
}
@@ -204,7 +205,8 @@
#include "selvar.i"
/*---------------------------------------------------------------------------*/
static int HKLCallback(int iEvent, void *pEvent, void *pUser)
static int HKLCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
pHKL self = NULL;
pSelVar pVar = NULL;
@@ -235,6 +237,7 @@
pICallBack pCall = NULL, pCall2 = NULL;
pDummy pDum = NULL;
float fVal;
commandContext comCon;
assert(pCon);
assert(self);
@@ -263,7 +266,10 @@
}
/* install new callback */
comCon.transID = 0;
strncpy(comCon.deviceID,"internal",SCDEVIDLEN);
self->lID = RegisterCallback(pCall2,
comCon,
WLCHANGE,
HKLCallback,
self,
@@ -283,6 +289,12 @@
}
return 1;
}
/*-------------------------------------------------------------------------*/
void SetHKLScanTolerance(pHKL self, float fVal)
{
assert(self);
self->scanTolerance = fVal;
}
/*-------------------------------------------------------------------------*/
int SetWavelengthManual(pHKL self, float fVal)
{
@@ -433,12 +445,12 @@ static int checkBisecting(pHKL self,
a omega scan
*/
MotorGetPar(self->pOmega,"softlowerlim",&fLimit);
if((float)om < fLimit + SCANBORDER){
if((float)om < fLimit + self->scanTolerance){
iTest = 0;
} else {
iTest = 1;
MotorGetPar(self->pOmega,"softupperlim",&fLimit);
if((float)om > fLimit - SCANBORDER){
if((float)om > fLimit - self->scanTolerance){
iTest = 0;
} else {
iTest = 1;
@@ -462,15 +474,16 @@ static int checkNormalBeam(double om, double *gamma, double nu,
char pError[132];
float fHard;
fSet[0] = (float)*gamma;
fSet[1] = (float)om;
fSet[2] = (float)nu;
/* check omega, gamma and nu */
iTest = MotorCheckBoundary(self->pOmega,(float)om, &fHard,pError,131);
iTest += checkTheta(self,gamma);
iTest += MotorCheckBoundary(self->pNu,(float)nu, &fHard,pError,131);
if(iTest == 3) /* none of them burns */
{
fSet[0] = (float)*gamma;
fSet[1] = (float)om;
fSet[2] = (float)nu;
return 1;
}
return 0;
@@ -495,7 +508,7 @@ static int chiVertical(double chi){
static int tryOmegaTweak(pHKL self, MATRIX z1, double *stt, double *om,
double *chi, double *phi){
int status;
float fLower, fUpper, omTarget, omOffset;
float fLower, fUpper, omTarget, omOffset, phiSign;
double dumstt, offom, offchi, offphi;
@@ -512,11 +525,11 @@ static int tryOmegaTweak(pHKL self, MATRIX z1, double *stt, double *om,
omTarget = -9999;
MotorGetPar(self->pOmega,"softlowerlim",&fLower);
MotorGetPar(self->pOmega,"softupperlim",&fUpper);
if(*om < fLower + SCANBORDER) {
omTarget = fLower + SCANBORDER + .5;
if(*om < fLower + self->scanTolerance) {
omTarget = fLower + self->scanTolerance;
}
if(*om > fUpper - SCANBORDER){
omTarget = fUpper - SCANBORDER - .5;
if(*om > fUpper - self->scanTolerance){
omTarget = fUpper - self->scanTolerance;
}
if(omTarget < -7000){
return 0;
@@ -535,7 +548,8 @@ static int tryOmegaTweak(pHKL self, MATRIX z1, double *stt, double *om,
dumstt = *stt;
offom = omTarget;
offchi = *chi;
offphi = *phi - omOffset;
MotorGetPar(self->pPhi,"sign",&phiSign);
offphi = *phi - omOffset*phiSign;
if(checkBisecting(self,&dumstt,offom,offchi,offphi)){
*om = offom;
*chi = offchi;
@@ -583,7 +597,7 @@ static MATRIX calculateScatteringVector(pHKL self, float fHKL[3])
return z1;
}
/*---------------------------------------------------------------------*/
static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
static int calculateBisectingOld(MATRIX z1, pHKL self, SConnection *pCon,
float fSet[4], double myPsi, int iRetry)
{
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
@@ -620,7 +634,7 @@ static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
{
if(iRetry > 1)
{
psi = i*10.;
psi = i*.5;
}
else
{
@@ -660,12 +674,80 @@ static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
return 0;
}
/*----------------------------------------------------------------------*/
int hklInRange(void *data, float fSet[4], int mask[4])
{
pHKL self = (pHKL)data;
float fHard, fLimit;
char pError[132];
int i, test;
double dTheta;
/* check two theta */
dTheta = fSet[0];
mask[0] = checkTheta(self, &dTheta);
fSet[0] = dTheta;
/* for omega check against the limits +- SCANBORDER in order to allow for
a omega scan
*/
MotorGetPar(self->pOmega,"softlowerlim",&fLimit);
if((float)fSet[1] < fLimit + self->scanTolerance){
mask[1] = 0;
} else {
mask[1] = 1;
MotorGetPar(self->pOmega,"softupperlim",&fLimit);
if((float)fSet[1] > fLimit - self->scanTolerance){
mask[1] = 0;
} else {
mask[1] = 1;
}
}
/* check chi and phi*/
mask[2] = MotorCheckBoundary(self->pChi,fSet[2], &fHard,pError,131);
mask[3] = MotorCheckBoundary(self->pPhi,fSet[3], &fHard,pError,131);
for(i = 0, test = 0; i < 4; i++){
test += mask[i];
}
if(test != 4) {
return 0;
} else {
return 1;
}
}
/*---------------------------------------------------------------------*/
static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
float fSet[4], double myPsi, int iRetry)
{
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
int i, test;
/*
just the plain angle calculation
*/
if(!z1mToBisecting(self->fLambda,z1,&stt,&om,&chi,&phi))
{
return 0;
}
if(iRetry == 1) {
rotatePsi(om,chi,phi,psi,&ompsi,&chipsi,&phipsi);
fSet[1] = ompsi;
fSet[2] = circlify(chipsi);
fSet[3] = circlify(phipsi);
return 1;
} else {
return findAllowedBisecting(self->fLambda, z1, fSet, hklInRange,self);
}
}
/*-----------------------------------------------------------------------*/
static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
float fSet[4], double myPsi, int iRetry)
{
int i, iTest;
double stt, om, chi, phi, gamma, nu, psi;
int i, iTest, status;
double stt, om, chi, phi, gamma, nu, psi, omnb;
float currentPhi, currentChi;
double ompsi, chipsi, phipsi;
MATRIX chim, phim, z4, z3;
@@ -696,45 +778,19 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
mat_free(chim);
mat_free(z4);
/*
do the bisecting angles first
*/
if(!z1mToBisecting(self->fLambda,z3,&stt,&om,&chi,&phi))
{
return 0;
}
if(ABS(chi -90.) < .001 && ABS(phi-180.) < .001)
status = z1mToNormalBeam(self->fLambda, z3, &gamma, &omnb, &nu);
omnb += 180.;
mat_free(z3);
if(status != 1)
{
chi = .0;
phi = .0;
return 0;
}
/*
in order to cope with all those limitations: rotate through psi
*/
for(i = 0; i < iRetry; i++)
{
if(iRetry > 1)
{
psi = 10. *i;
}
else
{
psi = myPsi;
}
rotatePsi(om,chi,phi,psi,&ompsi,&chipsi,&phipsi);
if(bisToNormalBeam(stt,ompsi,chipsi,phipsi,
&om, &gamma, &nu))
{
if(checkNormalBeam(om, &gamma, nu,fSet,pCon,self))
{
if(checkNormalBeam(omnb, &gamma, nu,fSet,pCon,self)){
return 1;
}
}
}
return 0;
} else {
return 0;
}
}
/*---------------------------------------------------------------------*/
static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
@@ -827,7 +883,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
}
/* some people are stupid.......... */
myPsi = circlify(myPsi);
myPsi = circlify(fPsi);
/*
no retries if specific psi requested.
@@ -838,7 +894,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
}
else
{
iRetry = 35;
iRetry = 699;
}
@@ -847,6 +903,30 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
if(self->iNOR == 0)
{
status = calculateBisecting(z1,self,pCon,fSet, myPsi, iRetry);
/*
* Betrand mode: wrap phi rotation into omega
*/
if(self->iOMPHI > 0) {
if(ABS(fSet[2] - .0) < .1 || ABS(fSet[2] - 180.) < .1){
fSet[1] -= fSet[3];
/*
fSet[1] = 360. - fSet[3];
*/
fSet[3] = .0;
if(fSet[1] < 0.){
fSet[1] += 360.;
}
if(fSet[1] > 360.0){
fSet[1] -= 360.;
}
} else {
snprintf(pBueffel,511,
"ERROR: for omphi mode chi must be 0 or 180, is %f",
fSet[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
}
else if(self->iNOR == 1)
{
@@ -861,9 +941,19 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
if(!status)
{
sprintf(pBueffel,"ERROR: cannot calculate %4.1f %4.1f %4.1f",
if(iRetry == 1)
{
sprintf(pBueffel,
"ERROR: cannot calculate %4.1f %4.1f %4.1f, psi = %4.1f",
fHKL[0], fHKL[1], fHKL[2], fPsi);
SCWrite(pCon,pBueffel,eError);
}
else
{
sprintf(pBueffel,"ERROR: cannot calculate %4.1f %4.1f %4.1f",
fHKL[0], fHKL[1], fHKL[2]);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,pBueffel,eError);
}
}
mat_free(z1);
@@ -871,6 +961,92 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
return 0;
}
/*------------------------------------------------------------------------*/
static void stopHKLMotors(pHKL self)
{
if(self->pTheta != NULL)
{
self->pTheta->pDrivInt->Halt(self->pTheta);
}
if(self->pOmega != NULL)
{
self->pOmega->pDrivInt->Halt(self->pOmega);
}
if(self->pChi != NULL)
{
self->pChi->pDrivInt->Halt(self->pChi);
}
if(self->pPhi != NULL)
{
self->pPhi->pDrivInt->Halt(self->pPhi);
}
if(self->pNu != NULL)
{
self->pNu->pDrivInt->Halt(self->pNu);
}
}
/*------------------------------------------------------------------------*/
int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4])
{
char pBueffel[512];
pDummy pDum;
int iRet;
/* start all the motors */
pDum = (pDummy)self->pTheta;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[0]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start two theta motor",eError);
stopHKLMotors(self);
return 0;
}
pDum = (pDummy)self->pOmega;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[1]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start omega motor",eError);
stopHKLMotors(self);
return 0;
}
/* special case: normal beam */
if(self->iNOR)
{
pDum = (pDummy)self->pNu;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[2]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start nu motor",eError);
return 0;
}
return 1;
}
pDum = (pDummy)self->pChi;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[2]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start chi motor",eError);
stopHKLMotors(self);
return 0;
}
pDum = (pDummy)self->pPhi;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[3]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start phi",eError);
stopHKLMotors(self);
return 0;
}
return 1;
}
/*-------------------------------------------------------------------------*/
int RunHKL(pHKL self, float fHKL[3],
float fPsi, int iHamil, SConnection *pCon)
@@ -888,67 +1064,11 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
return 0;
}
/* start all the motors */
pDum = (pDummy)self->pTheta;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[0]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start two theta motor",eError);
StopExe(pServ->pExecutor,"all");
return 0;
}
pDum = (pDummy)self->pOmega;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[1]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start omega motor",eError);
StopExe(pServ->pExecutor,"all");
return 0;
}
/* special case: normal beam */
if(self->iNOR)
{
pDum = (pDummy)self->pNu;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[2]);
if(!iRet)
{
StopExe(pServ->pExecutor,"all");
SCWrite(pCon,"ERROR: cannot start nu motor",eError);
return 0;
}
else
{
for(i = 0; i < 3; i++)
{
self->fLastHKL[i] = fHKL[i];
}
return 1;
}
iRet = startHKLMotors(self,pCon,fSet);
if(iRet != 1){
return iRet;
}
pDum = (pDummy)self->pChi;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[2]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start chi motor",eError);
StopExe(pServ->pExecutor,"all");
return 0;
}
pDum = (pDummy)self->pPhi;
iRet = StartDevice(pServ->pExecutor, "HKL",
pDum->pDescriptor, pDum, pCon,fSet[3]);
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start phi",eError);
StopExe(pServ->pExecutor,"all");
return 0;
}
for(i = 0; i < 3; i++)
{
self->fLastHKL[i] = fHKL[i];
@@ -1082,8 +1202,17 @@ ente:
return 0;
break;
case DEVDONE:
sprintf(pBueffel,"Driving to %8.4f %8.4f %8.4f done",
fHKL[0], fHKL[1], fHKL[2]);
if(fPsi > .01)
{
snprintf(pBueffel,131,
"Driving to %8.4f %8.4f %8.4f, psi = %8.4f done",
fHKL[0], fHKL[1], fHKL[2],fPsi);
}
else
{
snprintf(pBueffel,131,"Driving to %8.4f %8.4f %8.4f done",
fHKL[0], fHKL[1], fHKL[2]);
}
SCWrite(pCon,pBueffel,eStatus);
break;
default:
@@ -1186,8 +1315,20 @@ ente:
return 1;
}
/*--------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
int GetHKLFromAngles(pHKL self, SConnection *pCon, float fHKL[3])
{
int status;
float fAng[4];
status = GetCurrentPosition(self,pCon,fAng);
if(status == 1)
{
angle2HKL(self,fAng[0], fAng[1], fAng[2], fAng[3],fHKL);
return 1;
}
return 0;
}
/*--------------------------------------------------------------------------*/
static int GetCommandData(int argc, char *argv[], float fHKL[3],
float *fPsi, int *iHamil, SConnection *pCon)
@@ -1273,8 +1414,9 @@ ente:
if(strcmp(argv[1],"list") == 0 )
{
sprintf(pBueffel,
"lambda = %f Normal Beam = %d Quadrant = %d HM = %d",
self->fLambda, self->iNOR, self->iQuad,self->iHM);
"lambda = %f Normal Beam = %d PHIOM = %d Quadrant = %d HM = %d",
self->fLambda, self->iNOR, self->iOMPHI,
self->iQuad,self->iHM);
SCWrite(pCon,pBueffel,eValue);
sprintf(pBueffel,"UB = { %f %f %f",
self->fUB[0], self->fUB[1],self->fUB[2]);
@@ -1289,6 +1431,9 @@ ente:
sprintf(pBueffel,"Last HKL: %f %f %f ",
self->fLastHKL[0], self->fLastHKL[1],self->fLastHKL[2]);
SCWrite(pCon,pBueffel,eValue);
snprintf(pBueffel,510,"%s.scantolerance = %f", argv[0],
self->scanTolerance);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*----------- current */
@@ -1350,8 +1495,9 @@ ente:
{
if(argc < 3)
{
SCWrite(pCon,"ERROR: Insufficient number of arguments to HKL lambda",eError);
return 0;
snprintf(pBueffel,132,"%s.lambda = %f", argv[0],self->fLambda);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
if(!SCMatchRights(pCon,usUser))
{
@@ -1373,6 +1519,16 @@ ente:
SCSendOK(pCon);
return 1;
}
/*------------- getub*/
else if(strcmp(argv[1],"getub") == 0)
{
snprintf(pBueffel,510,"%s.ub = %f %f %f %f %f %f %f %f %f",
argv[0], self->fUB[0], self->fUB[1], self->fUB[2],
self->fUB[3], self->fUB[4], self->fUB[5],
self->fUB[6], self->fUB[7], self->fUB[8]);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*------- lambdavar*/
else if(strcmp(argv[1],"lambdavar") == 0)
{
@@ -1473,8 +1629,9 @@ ente:
{
if(argc < 3)
{
SCWrite(pCon,"ERROR: Insufficient number of arguments to HKL nb",eError);
return 0;
snprintf(pBueffel,511,"%s.nb = %d",argv[0],self->iNOR);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
if(!SCMatchRights(pCon,usUser))
{
@@ -1497,6 +1654,29 @@ ente:
SCSendOK(pCon);
return 1;
}
/*------------- phi omega mode (to be removed) */
else if(strcmp(argv[1],"phiom") == 0)
{
if(argc < 3)
{
snprintf(pBueffel,511,"%s.phiom = %d",argv[0],self->iOMPHI);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
if(!SCMatchRights(pCon,usUser))
{
return 0;
}
if(!isNumeric(argv[2]))
{
sprintf(pBueffel,"ERROR: %s was not recognized as a number", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
self->iOMPHI = atoi(argv[2]);
SCSendOK(pCon);
return 1;
}
/*------------- quadrant */
else if(strcmp(argv[1],"quadrant") == 0)
{
@@ -1527,6 +1707,30 @@ ente:
SCSendOK(pCon);
return 1;
}
/*------------- scantolerance */
else if(strcmp(argv[1],"scantolerance") == 0)
{
if(argc < 3)
{
snprintf(pBueffel,510,"%s.scantolerance = %f",argv[0],
self->scanTolerance);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
if(!SCMatchRights(pCon,usUser))
{
return 0;
}
if(!isNumeric(argv[2]))
{
sprintf(pBueffel,"ERROR: %s was not recognized as a number", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
self->scanTolerance = atof(argv[2]);
SCSendOK(pCon);
return 1;
}
/*------------- calculate */
else if(strcmp(argv[1],"calc") == 0)
{