- Fixed sign problems with om in tasub

- Mended tasdrive to drive energy even if Q is askew
- Fixed QM values
- Fixed problems in mesure: om2th, wrong theta selection
- Fixed core dump when driving h,kl, failed
This commit is contained in:
koennecke
2005-06-09 12:04:38 +00:00
parent f33ca7b0d7
commit 3a0b4f293c
16 changed files with 1899 additions and 116 deletions

View File

@ -652,7 +652,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
SICSLogWrite(buffer,iOut);
/* write to commandlog if user or manager privilege */
if(SCGetRights(self) <= usUser)
if(SCGetRights(self) <= usUser && self->iMacro != 1)
{
sprintf(pBueffel,"To sock %d :",iRet);
WriteToCommandLog(pBueffel,buffer);

View File

@ -419,7 +419,10 @@
case HWFault: /* real HW error: burning, no net etc.. */
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
pDev = NULL;
LLDnodeDataTo(self->iList,&pDev);
LLDnodeDelete(self->iList);
iRet = LLDnodePtr2Prev(self->iList);
self->iStatus = DEVERROR;
if(pDrivInt)
{

View File

@ -129,7 +129,7 @@ static pDynString findBlockEnd(pExeBuf self){
return NULL;
}
buffer = GetCharArray(self->bufferContent);
if(self->end != 0){
if(self->end != -1){
self->start = self->end + 1;
}
for(i = self->start; i < strlen(buffer); i++){
@ -162,7 +162,7 @@ int exeBufProcess(pExeBuf self, SicsInterp *pSics,
assert(pSics);
self->start = 0;
self->end = 0;
self->end = -1;
self->lineno = 0;
pTcl = InterpGetTcl(pSics);

View File

@ -629,7 +629,7 @@
if(isInTOFMode(self->pDriv->data))
{
iDim[*nDim] = getNoOfTimebins(self->pDriv->data);
*nDim ++;
*nDim = *nDim + 1;
}
return 1;
}

33
hkl.c
View File

@ -887,6 +887,30 @@ 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 RunHKL(pHKL self, float fHKL[3],
float fPsi, int iHamil, SConnection *pCon)
@ -911,7 +935,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start two theta motor",eError);
StopExe(pServ->pExecutor,"all");
stopHKLMotors(self);
return 0;
}
@ -921,7 +945,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start omega motor",eError);
StopExe(pServ->pExecutor,"all");
stopHKLMotors(self);
return 0;
}
@ -933,7 +957,6 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
pDum->pDescriptor, pDum, pCon,fSet[2]);
if(!iRet)
{
StopExe(pServ->pExecutor,"all");
SCWrite(pCon,"ERROR: cannot start nu motor",eError);
return 0;
}
@ -953,7 +976,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start chi motor",eError);
StopExe(pServ->pExecutor,"all");
stopHKLMotors(self);
return 0;
}
pDum = (pDummy)self->pPhi;
@ -962,7 +985,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self,
if(!iRet)
{
SCWrite(pCon,"ERROR: cannot start phi",eError);
StopExe(pServ->pExecutor,"all");
stopHKLMotors(self);
return 0;
}
for(i = 0; i < 3; i++)

View File

@ -107,10 +107,10 @@ static int HKLCheckStatus(void *pData, SConnection *pCon){
assert(self != NULL);
if(self->pHkl->targetDirty == 1){
status = RunHKL(self->pHkl,self->pHkl->targetHKL,.0,0,pCon);
self->pHkl->targetDirty = 0;
if(status != 1){
return HWFault;
}
self->pHkl->targetDirty = 0;
return HWBusy;
} else {
return checkMotors(self,pCon);

View File

@ -633,6 +633,8 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
ClearScanVar(self->pScanner);
AddScanVar(self->pScanner, pServ->pSics,pCon,self->pCOmega,
fStart, stepWidth);
snprintf(pBueffel,131,"Scanning om from %f with step %f", fStart, stepWidth);
SCWrite(pCon,pBueffel,eValue);
/*
Oksana does not want o2t scans to be tightly coupled, this is why we
cannot use the normal o2t scan variable. Instead we calculate new limits and
@ -648,6 +650,8 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
fStart -= (np/2.)*stepWidth;
AddScanVar(self->pScanner, pServ->pSics,pCon,self->pC2Theta,
fStart, stepWidth);
snprintf(pBueffel,131,"Scanning 2theta from %f with step %f", fStart, stepWidth);
SCWrite(pCon,pBueffel,eValue);
}
/*
@ -665,10 +669,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
}
/* do the scan */
snprintf(pBueffel,131,"Scanning %s, step %f, np = %d",scanVar, stepWidth, np);
SCWrite(pCon,pBueffel,eWarning);
free(scanVar);
if(self->iCompact)
{
self->pScanner->CollectScanData = CompactScanData;

View File

@ -154,8 +154,8 @@ CreateSocketAdress(
i = sizeof(struct linger);
lili.l_onoff = 1;
lili.l_linger = 1;
/* setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
*/
setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
pRes->iType = PORT;
pRes->lMagic = NETMAGIC;
return pRes;

1443
nxxml.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@
#define ACH 11
/*============== Drivable Interface functions =====================*/
static int TASSetValue(void *pData, SConnection *pCon,
static long TASSetValue(void *pData, SConnection *pCon,
float value){
ptasMot self = (ptasMot)pData;
assert(self);
@ -142,7 +142,8 @@ static float TASQMGetValue(void *pData, SConnection *pCon){
if(status != 1){
return -999.99;
}
status = calcTasPowderPosition(&self->math->machine, angles, &self->math->current);
status = calcTasPowderPosition(&self->math->machine,
angles, &self->math->current);
if(status < 0){
SCWrite(pCon,"ERROR: out of memory calculating Q-E variables",eError);
return -999.99;
@ -176,7 +177,7 @@ static int TASHalt(void *pData){
}
/*---------------------------------------------------------------------------*/
static int startMotors(ptasMot self, tasAngles angles,
SConnection *pCon){
SConnection *pCon, int driveQ){
float val;
double curve;
int status;
@ -276,6 +277,9 @@ static int startMotors(ptasMot self, tasAngles angles,
}
}
}
if(driveQ == 0){
return OKOK;
}
/*
crystal
@ -319,39 +323,95 @@ static int startMotors(ptasMot self, tasAngles angles,
self->math->mustDrive = 0;
return OKOK;
}
/*---------------------------------------------------------------------------*/
static int checkQMotorLimits(ptasMot self, SConnection *pCon,
tasAngles angles){
int status, retVal = 1;
char error[131];
char pBueffel[256];
status = self->math->motors[A3]->pDrivInt->CheckLimits(self->math->motors[A3],
angles.a3,
error,
131);
if(status != 1) {
retVal = 0;
snprintf(pBueffel,256,"ERROR: limit violation an a3: %s", error);
SCWrite(pCon,pBueffel,eError);
}
status = self->math->motors[A4]->pDrivInt->CheckLimits(self->math->motors[A4],
angles.sample_two_theta,
error,
131);
if(status != 1) {
retVal = 0;
snprintf(pBueffel,256,"ERROR: limit violation an a4: %s", error);
SCWrite(pCon,pBueffel,eError);
}
status = self->math->motors[A3]->pDrivInt->CheckLimits(self->math->motors[SGU],
angles.sgu,
error,
131);
if(status != 1) {
retVal = 0;
snprintf(pBueffel,256,"ERROR: limit violation an SGU: %s", error);
SCWrite(pCon,pBueffel,eError);
}
status = self->math->motors[SGL]->pDrivInt->CheckLimits(self->math->motors[SGL],
angles.sgl,
error,
131);
if(status != 1) {
retVal = 0;
snprintf(pBueffel,256,"ERROR: limit violation an SGL: %s", error);
SCWrite(pCon,pBueffel,eError);
}
return retVal;
}
/*-----------------------------------------------------------------------------*/
static int calculateAndDrive(ptasMot self, SConnection *pCon){
tasAngles angles;
int status;
int status, driveQ = 1;
if(self->math->ubValid == 0){
SCWrite(pCon,"WARNING: UB matrix invalid",eWarning);
}
status = calcAllTasAngles(&self->math->machine, self->math->target,
&angles);
self->math->mustDrive = 0;
switch(status){
case ENERGYTOBIG:
SCWrite(pCon,"ERROR: desired energy to big",eError);
self->math->mustDrive = 0;
return HWFault;
break;
case UBNOMEMORY:
SCWrite(pCon,"ERROR: out of memory calculating angles",eError);
self->math->mustDrive = 0;
return HWFault;
driveQ = 0;
break;
case BADRMATRIX:
SCWrite(pCon,"ERROR: bad crystallographic parameters or bad UB",eError);
self->math->mustDrive = 0;
return HWFault;
driveQ = 0;
break;
case BADUBORQ:
SCWrite(pCon,"ERROR: bad UB matrix or bad Q-vector",eError);
driveQ = 0;
break;
case TRIANGLENOTCLOSED:
SCWrite(pCon,"ERROR: cannot close scattering triangle",eError);
self->math->mustDrive = 0;
return HWFault;
driveQ = 0;
break;
default:
return startMotors(self,angles,pCon);
}
return HWFault;
if(!checkQMotorLimits(self,pCon,angles)){
driveQ = 0;
}
if(driveQ == 0){
SCWrite(pCon,"WARNING: NOT driving Q-vector because of errors",eError);
}
return startMotors(self,angles,pCon, driveQ);
}
/*-----------------------------------------------------------------------------*/
static int checkMotors(ptasMot self, SConnection *pCon){

251
tasub.c
View File

@ -53,6 +53,7 @@ static void saveReflections(ptasUB self, char *name, FILE *fd){
/*-------------------------------------------------------------------*/
static int tasUBSave(void *pData, char *name, FILE *fd){
ptasUB self = (ptasUB)pData;
tasReflection r;
if(self == NULL){
return 0;
@ -83,8 +84,16 @@ static int tasUBSave(void *pData, char *name, FILE *fd){
name,
self->target.qh, self->target.qk, self->target.ql, self->target.qm,
self->target.ki, self->target.kf);
fprintf(fd,"%s setidx %d %d\n",
name, self->r1, self->r2);
r = self->r1;
fprintf(fd,"%s r1 %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n",
name, r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.angles.sample_two_theta,
r.angles.sgu, r.angles.sgl,
KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
r = self->r2;
fprintf(fd,"%s r2 %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n",
name, r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3, r.angles.sample_two_theta,
r.angles.sgu, r.angles.sgl,
KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
fprintf(fd,"%s update\n", name);
return 1;
}
@ -455,6 +464,8 @@ static int tasReadCell(SConnection *pCon, ptasUB self, int argc, char *argv[]){
SCWrite(pCon,pBueffel,eError);
return 0;
}
self->ubValid = 0;
SCWrite(pCon,"WARNING: UB is now invalid",eWarning);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
@ -477,8 +488,7 @@ static void clearReflections(ptasUB self){
LLDnodeDelete(self->reflectionList);
status = LLDnodePtr2Next(self->reflectionList);
}
self->r1 = -1;
self->r2 = -1;
self->ubValid = 0;
}
/*------------------------------------------------------------------*/
static void listReflections(ptasUB self, SConnection *pCon){
@ -621,6 +631,84 @@ static int addReflection(ptasUB self, SicsInterp *pSics,
SCparChange(pCon);
return 1;
}
/*------------------------------------------------------------------------------*/
static int readReflection(SConnection *pCon, SicsInterp *pSics,
ptasReflection res,
int argc, char *argv[]){
tasReflection r;
int status;
char pBueffel[256];
if(!SCMatchRights(pCon,usUser)){
return 0;
}
if(argc < 11){
SCWrite(pCon,"ERROR: not enough parameters to read reflection",eError);
return 0;
}
status = Tcl_GetDouble(InterpGetTcl(pSics),argv[2],&r.qe.qh);
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(InterpGetTcl(pSics),argv[3],&r.qe.qk);
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(InterpGetTcl(pSics),argv[4],&r.qe.ql);
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(InterpGetTcl(pSics),argv[5],&r.angles.a3);
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(InterpGetTcl(pSics),argv[6],&r.angles.sample_two_theta);
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(InterpGetTcl(pSics),argv[7],&r.angles.sgu);
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(InterpGetTcl(pSics),argv[8],&r.angles.sgl);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[8]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = Tcl_GetDouble(InterpGetTcl(pSics),argv[9],&r.qe.ki);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[9]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
r.qe.ki = energyToK(r.qe.ki);
status = Tcl_GetDouble(InterpGetTcl(pSics),argv[10],&r.qe.kf);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[10]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
r.qe.kf = energyToK(r.qe.kf);
if(ABS(r.qe.ki - r.qe.kf) > .01) {
SCWrite(pCon,"WARNING: KI != KF!",eWarning);
}
*res = r;
return 1;
}
/*-----------------------------------------------------------------*/
int findReflection(int list, int idx, ptasReflection r){
int count = 0;
@ -642,7 +730,7 @@ static void listUB(ptasUB self , SConnection *pCon){
Tcl_DString list;
char pBueffel[255];
int i;
tasReflection r;
Tcl_DStringInit(&list);
if(self->machine.UB == NULL){
@ -658,9 +746,32 @@ static void listUB(ptasUB self , SConnection *pCon){
Tcl_DStringAppend(&list,pBueffel,-1);
}
}
snprintf(pBueffel,255,"UB generated from reflections %d and %d in list\n",
self->r1, self->r2);
snprintf(pBueffel,255,"UB generated from reflections:\n");
Tcl_DStringAppend(&list,pBueffel,-1);
snprintf(pBueffel,255,
" QH QK QL A3 A4 SGU SGL EI EF\n");
Tcl_DStringAppend(&list,pBueffel,-1);
r = self->r1;
snprintf(pBueffel,255,
" %8.4f %8.4f %8.4f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3,
r.angles.sample_two_theta, r.angles.sgu, r.angles.sgl,
KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
Tcl_DStringAppend(&list,pBueffel,-1);
r = self->r2;
snprintf(pBueffel,255,
" %8.4f %8.4f %8.4f %7.2f %7.2f %6.2f %6.2f %6.2f %6.2f\n",
r.qe.qh, r.qe.qk, r.qe.ql, r.angles.a3,
r.angles.sample_two_theta, r.angles.sgu, r.angles.sgl,
KtoEnergy(r.qe.ki), KtoEnergy(r.qe.kf));
Tcl_DStringAppend(&list,pBueffel,-1);
snprintf(pBueffel,255,"Plane Normal: %8.4f %8.4f %8.4f\n",
self->machine.planeNormal[0][0], self->machine.planeNormal[1][0],
self->machine.planeNormal[2][0]);
Tcl_DStringAppend(&list,pBueffel,-1);
if(self->ubValid == 0){
Tcl_DStringAppend(&list,"WARNING: UB matrix is invalid\n",-1);
}
SCWrite(pCon,Tcl_DStringValue(&list),eValue);
Tcl_DStringFree(&list);
}
@ -723,7 +834,7 @@ static void listDiagnostik(ptasUB self, SConnection *pCon){
/*------------------------------------------------------------------*/
static int calcUB(ptasUB self, SConnection *pCon, SicsInterp *pSics,
int argc, char *argv[]){
int idx, status;
int idx1, idx2, status;
tasReflection r1, r2;
char pBueffel[256];
MATRIX UB = NULL;
@ -739,32 +850,32 @@ static int calcUB(ptasUB self, SConnection *pCon, SicsInterp *pSics,
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&idx);
status = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&idx1);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = findReflection(self->reflectionList, idx-1,&r1);
idx1--;
status = findReflection(self->reflectionList, idx1,&r1);
if(status != 1){
snprintf(pBueffel,255,"ERROR: cannot find reflection with index %d",idx);
snprintf(pBueffel,255,"ERROR: cannot find reflection with index %d",idx1+1);
SCWrite(pCon,pBueffel,eError);
return 0;
}
self->r1 = idx;
status = Tcl_GetInt(InterpGetTcl(pSics),argv[3],&idx);
status = Tcl_GetInt(InterpGetTcl(pSics),argv[3],&idx2);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = findReflection(self->reflectionList, idx-1,&r2);
idx2--;
status = findReflection(self->reflectionList, idx2,&r2);
if(status != 1){
snprintf(pBueffel,255,"ERROR: cannot find reflection with index %d",idx);
snprintf(pBueffel,255,"ERROR: cannot find reflection with index %d",idx2+1);
SCWrite(pCon,pBueffel,eError);
return 0;
}
self->r2 = idx;
UB = calcTasUBFromTwoReflections(self->cell,r1,r2,&status);
if(UB == NULL){
@ -778,6 +889,10 @@ static int calcUB(ptasUB self, SConnection *pCon, SicsInterp *pSics,
}
return 0;
}
if(mat_det(UB) < .000001){
SCWrite(pCon,"ERROR: invalid UB matrix, check reflections",eError);
return 0;
}
if(self->machine.UB != NULL){
mat_free(self->machine.UB);
}
@ -786,6 +901,9 @@ static int calcUB(ptasUB self, SConnection *pCon, SicsInterp *pSics,
}
self->machine.UB = UB;
self->machine.planeNormal = calcPlaneNormal(r1,r2);
self->r1 = r1;
self->r2 = r2;
self->ubValid = 1;
listUB(self,pCon);
listDiagnostik(self,pCon);
SCparChange(pCon);
@ -866,6 +984,74 @@ static int calcRefAngles(ptasUB self, SConnection *pCon,
return 1;
}
/*------------------------------------------------------------------*/
static int calcQFromAngles(ptasUB self, SConnection *pCon,
SicsInterp *pSics,
int argc, char *argv[]){
tasQEPosition q;
tasAngles angles;
char pBueffel[256];
int status;
if(argc < 8){
SCWrite(pCon,"ERROR: need a2, a3, a4, sgu, sgl, a6 for calculation",
eError);
return 0;
}
status = Tcl_GetDouble(InterpGetTcl(pSics),argv[2],
&angles.monochromator_two_theta);
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(InterpGetTcl(pSics),argv[3],&angles.a3);
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(InterpGetTcl(pSics),argv[4],&angles.sample_two_theta);
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(InterpGetTcl(pSics),argv[5],&angles.sgu);
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(InterpGetTcl(pSics),argv[6],&angles.sgl);
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(InterpGetTcl(pSics),argv[7],&angles.analyzer_two_theta);
if(status != TCL_OK){
snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[7]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = calcTasQEPosition(&self->machine,angles,&q);
switch(status){
case UBNOMEMORY:
SCWrite(pCon,"ERROR: Out of memory calculating angles",eError);
return 0;
break;
}
snprintf(pBueffel,255,"%8.4f %8.4f %8.4f %8.4f %8.4f",
q.qh,
q.qk,
q.ql,
KtoEnergy(q.ki),
KtoEnergy(q.kf));
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*------------------------------------------------------------------*/
static int setUB(SConnection *pCon, SicsInterp *pSics, ptasUB self,
int argc, char *argv[]){
double value;
@ -953,28 +1139,13 @@ static int setUB(SConnection *pCon, SicsInterp *pSics, ptasUB self,
return 0;
}
self->machine.UB[2][2] = value;
self->ubValid = 1;
SCSendOK(pCon);
SCparChange(pCon);
return 1;
}
/*------------------------------------------------------------------*/
static int setIDX(SConnection *pCon, SicsInterp *pSics, ptasUB self,
int argc, char *argv[]){
if(argc < 4) {
SCWrite(pCon,"ERROR: not enough arguments to setidx", eError);
return 0;
}
if(!SCMatchRights(pCon,usMugger)){
return 0;
}
self->r1 = atoi(argv[2]);
self->r2 = atoi(argv[3]);
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------*/
static int setNormal(SConnection *pCon, SicsInterp *pSics, ptasUB self,
int argc, char *argv[]){
double value;
@ -1114,11 +1285,6 @@ static int deleteReflection(SConnection *pCon, SicsInterp *pSics,
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(idx == self->r1 || idx == self->r2) {
SCWrite(pCon,"ERROR: I refuse to delete reflections used for current UB",
eError);
return 0;
}
idx--;
status = LLDnodePtr2First(self->reflectionList);
while(status == 1){
@ -1162,6 +1328,7 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
} else if(strcmp(argv[1],"clear") == 0){
clearReflections(self);
clearReflections(self);
SCWrite(pCon,"WARNING: UB is now invalid",eWarning);
SCSendOK(pCon);
return 1;
} else if(strcmp(argv[1],"listref") == 0){
@ -1174,20 +1341,24 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
return 1;
} else if(strcmp(argv[1],"makeub") == 0){
return calcUB(self,pCon,pSics,argc,argv);
} else if(strcmp(argv[1],"calcref") == 0){
} else if(strcmp(argv[1],"calcang") == 0){
return calcRefAngles(self,pCon,pSics,argc,argv);
} else if(strcmp(argv[1],"calcqe") == 0){
return calcQFromAngles(self,pCon,pSics,argc,argv);
} else if(strcmp(argv[1],"setub") == 0){
return setUB(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"setnormal") == 0){
return setNormal(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"setidx") == 0){
return setIDX(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"settarget") == 0){
return setTarget(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"update") == 0){
return tasUpdate(pCon,self);
} else if(strcmp(argv[1],"del") == 0){
return deleteReflection(pCon,pSics,self,argc,argv);
} else if(strcmp(argv[1],"r1") == 0){
return readReflection(pCon,pSics,&self->r1,argc,argv);
} else if(strcmp(argv[1],"r2") == 0){
return readReflection(pCon,pSics,&self->r2,argc,argv);
} else if(strcmp(argv[1],"const") == 0){
if(argc > 2){
strtolower(argv[2]);

View File

@ -27,7 +27,8 @@
int mustRecalculate;
int mustDrive;
pMotor motors[12];
int r1, r2;
tasReflection r1, r2;
int ubValid;
}tasUB, *ptasUB;

View File

@ -18,6 +18,8 @@
#define PI 3.141592653589793
#define ECONST 2.072
#define DEGREE_RAD (PI/180.0) /* Radians per degree */
#define VERT 0
#define HOR 1
/*============== monochromator/analyzer stuff =========================*/
double energyToK(double energy){
double K;
@ -33,8 +35,14 @@ double KtoEnergy(double k){
return energy;
}
/*-------------------------------------------------------------------*/
static double calcCurvature(double B1, double B2, double theta){
return B1 + B2/Sind(ABS(theta));
static double calcCurvature(double B1, double B2, double theta,
int ori){
assert(ori == VERT || ori == HOR);
if(ori == VERT){
return B1 + B2/Sind(ABS(theta));
} else {
return B1 + B2*Sind(ABS(theta));
}
}
/*--------------------------------------------------------------------*/
int maCalcTwoTheta(maCrystal data, double k, double *two_theta){
@ -51,11 +59,11 @@ int maCalcTwoTheta(maCrystal data, double k, double *two_theta){
}
/*--------------------------------------------------------------------*/
double maCalcVerticalCurvature(maCrystal data, double two_theta){
return calcCurvature(data.VB1,data.VB2, two_theta/2.);
return calcCurvature(data.VB1,data.VB2, two_theta/2.,VERT);
}
/*-------------------------------------------------------------------*/
double maCalcHorizontalCurvature(maCrystal data, double two_theta){
return calcCurvature(data.HB1,data.HB2, two_theta/2.);
return calcCurvature(data.HB1,data.HB2, two_theta/2.,HOR);
}
/*--------------------------------------------------------------------*/
double maCalcK(maCrystal data, double two_theta){
@ -155,11 +163,22 @@ static MATRIX calcTasUVectorFromAngles(tasReflection r){
/*-------------------------------------------------------------------*/
MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2){
MATRIX u1 = NULL, u2 = NULL, planeNormal = NULL;
int i;
u1 = calcTasUVectorFromAngles(r1);
u2 = calcTasUVectorFromAngles(r2);
if(u1 != NULL && u2 != NULL){
return vectorCrossProduct(u1,u2);
planeNormal = vectorCrossProduct(u1,u2);
/*
The plane normal has to point to the stars and not to the earth
core in order for the algorithm to work.
*/
if(planeNormal[2][0] < .0){
for(i = 0; i < 3; i++){
planeNormal[i][0] = -1.*planeNormal[i][0];
}
}
return planeNormal;
} else {
return NULL;
}
@ -187,11 +206,15 @@ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
h2 = tasReflectionToHC(r2.qe,B);
if(h1 == NULL || h2 == NULL){
*errorCode = UBNOMEMORY;
mat_free(B);
return NULL;
}
HT = matFromTwoVectors(h1,h2);
if(HT == NULL){
*errorCode = UBNOMEMORY;
mat_free(B);
mat_free(h1);
mat_free(h2);
return NULL;
}
@ -202,39 +225,59 @@ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
u2 = calcTasUVectorFromAngles(r2);
if(u1 == NULL || u2 == NULL){
*errorCode = UBNOMEMORY;
mat_free(B);
mat_free(h1);
mat_free(h2);
return NULL;
}
UT = matFromTwoVectors(u1,u2);
if(UT == NULL){
*errorCode = UBNOMEMORY;
mat_free(B);
mat_free(h1);
mat_free(h2);
mat_free(u1);
mat_free(u2);
mat_free(HT);
return NULL;
}
/*
debugging output
printf("B-matrix\n");
mat_dump(B);
printf("HT-matrix\n");
mat_dump(HT);
printf("UT-matrix\n");
mat_dump(UT);
*/
/*
UT = U * HT
*/
HTT = mat_tran(HT);
if(HTT == NULL){
*errorCode = UBNOMEMORY;
mat_free(B);
mat_free(h1);
mat_free(h2);
mat_free(u1);
mat_free(u2);
mat_free(HT);
return NULL;
}
U = mat_mul(UT,HTT);
if(U == NULL){
*errorCode = UBNOMEMORY;
mat_free(B);
mat_free(h1);
mat_free(h2);
mat_free(u1);
mat_free(u2);
mat_free(HT);
mat_free(HTT);
return NULL;
}
UB = mat_mul(U,B);
if(UB == NULL){
mat_free(B);
mat_free(h1);
mat_free(h2);
mat_free(u1);
mat_free(u2);
mat_free(HT);
mat_free(HTT);
mat_free(U);
*errorCode = UBNOMEMORY;
}
@ -296,12 +339,14 @@ static MATRIX tasReflectionToQC(tasQEPosition r, MATRIX UB){
}
/*----------------------------------------------------------------------------*/
static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal,
tasQEPosition qe){
tasQEPosition qe, int *errorCode){
MATRIX U1V, U2V, TV, TVINV, M;
*errorCode = 1;
U1V = tasReflectionToQC(qe,UB);
if(U1V == NULL){
*errorCode = UBNOMEMORY;
return NULL;
}
normalizeVector(U1V);
@ -309,6 +354,13 @@ static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal,
U2V = vectorCrossProduct(planeNormal,U1V);
if(U2V == NULL){
killVector(U1V);
*errorCode = UBNOMEMORY;
return NULL;
}
if(vectorLength(U2V) < .0001){
*errorCode = BADUBORQ;
killVector(U1V);
killVector(U2V);
return NULL;
}
@ -316,9 +368,14 @@ static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal,
if(TV == NULL){
killVector(U1V);
killVector(U2V);
*errorCode = UBNOMEMORY;
return NULL;
}
TVINV = mat_inv(TV);
if(TVINV == NULL){
*errorCode = BADUBORQ;
}
killVector(U1V);
killVector(U2V);
@ -329,30 +386,36 @@ static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal,
int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
ptasAngles angles){
MATRIX R, QC;
double om, q, theta, cos2t, tmp, sq;
double om, q, theta, cos2t;
int errorCode = 1;
R = buildRMatrix(UB, planeNormal, qe);
R = buildRMatrix(UB, planeNormal, qe, &errorCode);
if(R == NULL){
return UBNOMEMORY;
return errorCode;
}
sq = sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]);
if(ABS(sq) < .00001){
return BADRMATRIX;
angles->sgl = Asind(-R[2][0]);
if(ABS(angles->sgl -90.) < .5){
return BADUBORQ;
}
om = Acosd(R[0][0]/sq);
om -= 180.;
tmp = Asind(R[1][0]/sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]));
/*
Now, this is slightly different then in the publication by M. Lumsden.
The reason is that the atan2 helps to determine the sign of om
whereas the sin, cos formula given by M. Lumsden yield ambiguous signs
especially for om.
sgu = atan(R[2][1],R[2][2]) where:
R[2][1] = cos(sgl)sin(sgu)
R[2][2] = cos(sgu)cos(sgl)
om = atan(R[1][0],R[0][0]) where:
R[1][0] = sin(om)cos(sgl)
R[0][0] = cos(om)cos(sgl)
The definitions of th R components are taken from M. Lumsden
R-matrix definition.
*/
tmp = Acosd(sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]));
angles->sgl = Asind(-R[2][0]);
sq = sqrt(R[0][0]*R[0][0] + R[1][0]*R[1][0]);
if(ABS(sq) < .00001){
return BADRMATRIX;
}
angles->sgu = Asind(R[2][1]/sq);
tmp = Acosd(R[2][2]/sqrt(R[0][0]*R[0][0]+R[1][0]*R[1][0]));
om = Atan2d(R[1][0],R[0][0]);
angles->sgu = Atan2d(R[2][1],R[2][2]);
QC = tasReflectionToQC(qe,UB);
if(QC == NULL){
@ -370,6 +433,15 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
theta = calcTheta(qe.ki, qe.kf,angles->sample_two_theta);
angles->a3 = om + theta;
/*
put a3 into -180, 180 properly. We cal always turn by 180 because the
scattering geometry is symmetric in this respect. It is like looking at
the scattering plane from the other side
*/
angles->a3 -= 180.;
if(angles->a3 < -180.){
angles->a3 += 360.;
}
killVector(QC);
mat_free(R);
@ -395,9 +467,10 @@ int calcTasQH(MATRIX UB, tasAngles angles, ptasQEPosition qe){
Thereby take into account the physicists magic fudge
2PI factor
*/
q = sqrt(qe->ki*qe->ki + qe->kf*qe->kf - 2.*qe->ki*qe->kf*Cosd(angles.sample_two_theta));
q /= 2. * PI;
q = sqrt(qe->ki*qe->ki + qe->kf*qe->kf -
2.*qe->ki*qe->kf*Cosd(angles.sample_two_theta));
qe->qm = q;
q /= 2. * PI;
for(i = 0; i < 3; i++){
QV[i][0] *= q;
@ -431,14 +504,14 @@ int calcAllTasAngles(ptasMachine machine, tasQEPosition qe,
return status;
}
status = calcTasQAngles(machine->UB, machine->planeNormal,
machine->ss_sample, qe,angles);
status = maCalcTwoTheta(machine->analyzer,qe.kf,&
angles->analyzer_two_theta);
if(status != 1){
return status;
}
status = maCalcTwoTheta(machine->analyzer,qe.kf,&
angles->analyzer_two_theta);
status = calcTasQAngles(machine->UB, machine->planeNormal,
machine->ss_sample, qe,angles);
if(status != 1){
return status;
}
@ -498,7 +571,6 @@ int calcTasPowderPosition(ptasMachine machine, tasAngles angles,
qe->qm = sqrt(qe->ki*qe->ki + qe->kf*qe->kf -
2.*qe->ki*qe->kf*Cosd(angles.sample_two_theta));
return 1;
}
/*====================== Logic implementation =========================*/
@ -582,6 +654,3 @@ double getTasPar(tasQEPosition qe, int tasVar){
assert(0);
}
}

View File

@ -17,6 +17,7 @@
#define UBNOMEMORY -702
#define TRIANGLENOTCLOSED -703
#define BADRMATRIX -704
#define BADUBORQ -705
/*========================== defines for tasMode ====================*/
#define KICONST 1
#define KFCONST 2

10
trigd.c
View File

@ -53,6 +53,16 @@ extern double Atand (double x)
return (data);
}
/*******************************************************************************
* Atan of angle in degrees.
*******************************************************************************/
extern double Atan2d (double x, double y)
{
double data;
data = (atan2(x,y)/DEGREE_RAD);
return (data);
}
/*******************************************************************************
* Atan2 of angle in degrees.
*******************************************************************************/
extern double Atand2 (double x)

View File

@ -14,4 +14,5 @@
double Atand2 (double x);
double Acosd (double x);
double Asind (double x);
double Atan2d(double x, double y);
#endif