- Reworked the connection object and the IO system

- Reworked the support for TRICS
- Added a second generation motor
This commit is contained in:
koennecke
2009-02-03 08:05:39 +00:00
parent f6d595665e
commit 361ee9ebea
119 changed files with 16455 additions and 3674 deletions

300
cone.c
View File

@ -5,6 +5,10 @@
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, March 2006
Reworked for new four circle infrastructure.
Mark Koennecke, August 2008
------------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
@ -12,11 +16,15 @@
#include "hkl.i"
#include "vector.h"
#include "fourlib.h"
#include "singlex.h"
#include "sicsobj.h"
#include "sicshipadaba.h"
/*=================== Object Descriptor Interface ===================================================*/
static void *ConeGetInterface(void *pData, int iID){
pConeData self = NULL;
pSICSOBJ obj = (pSICSOBJ)pData;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
if(self == NULL){
return NULL;
}
@ -25,28 +33,15 @@ static void *ConeGetInterface(void *pData, int iID){
}
return NULL;
}
/*---------------------------------------------------------------------------------------------------*/
static void ConeSaveStatus(void *data, char *name, FILE *fd){
pConeData self = (pConeData)data;
if(self == NULL){
return;
}
fprintf(fd,"%s center %d\n", name,self->center);
fprintf(fd,"%s target %f %f %f\n", name, self->target.h,
self->target.k, self->target.l);
fprintf(fd,"%s qscale %f \n", name, self->qScale);
}
/*=================== Drivable Interface ============================================================*/
static int ConeHalt(void *pData){
pSICSOBJ obj = pData;
pConeData self = NULL;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
stopHKLMotors(self->pHkl);
return 1;
}
/*-----------------------------------------------------------------------------------------------------*/
@ -62,7 +57,7 @@ static int ConeCheckLimits(void *self, float fVal, char *error, int errLen){
static MATRIX makeCsToPsiMatrix(reflection center, double lambda){
MATRIX psiToCs = NULL, csToPsi = NULL, t1, t2;
double z1[3], u;
psiToCs = makeInstToConeVectorMatrix(center,lambda);
if(psiToCs == NULL){
return NULL;
@ -88,37 +83,71 @@ static MATRIX makeCsToPsiMatrix(reflection center, double lambda){
* me a lot of trouble keeping track of parameter changes in UBCALC etc.
* ---------------------------------------------------------------------------*/
static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
pSICSOBJ obj = pData, refList;
pConeData self = NULL;
float fSet[4];
double fSet[4];
float ffSet[4];
double openingAngle, length;
MATRIX csToPsi = NULL, B = NULL, newScat = NULL;
int status;
reflection center;
int status, i;
reflection center, target;
char buffer[131];
const double *cell;
double hkl[3], ang[4];
lattice direct;
hdbValue v;
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
/*
* calculate opening angle
*/
B = mat_creat(3,3,UNIT_MATRIX);
status = calculateBMatrix(self->ubi->direct,B);
cell = SXGetCell();
direct.a = cell[0];
direct.b = cell[1];
direct.c = cell[2];
direct.alpha = cell[3];
direct.beta = cell[4];
direct.gamma = cell[5];
status = calculateBMatrix(direct,B);
if(status < 0){
SCWrite(pCon,"ERROR: cell has no volume",eError);
return 0;
}
center = getReflection(self->ubi,self->center);
openingAngle = angleBetweenReflections(B,center,self->target);
/*
* get center from the main reflection list
*/
refList = SXGetReflectionList();
SICSHdbGetPar(obj,pCon,"center", &v);
if(!GetRefIndexID(refList,v.v.text,hkl)){
SCPrintf(pCon,eError,"ERROR: cannot find reflection with ID: %s", v.v.text);
return 0;
}
center.h = hkl[0];
center.k = hkl[1];
center.l = hkl[2];
GetRefAnglesID(refList,v.v.text,ang);
center.s2t = ang[0];
center.om = ang[1];
center.chi = ang[2];
center.phi = ang[3];
SICSHdbGetPar(obj,pCon,"target",&v);
target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2];
openingAngle = angleBetweenReflections(B,center,target);
/*
* calculate conversion matrix from cone system to PSI system
*/
csToPsi = makeCsToPsiMatrix(center,self->ubi->hkl->fLambda);
csToPsi = makeCsToPsiMatrix(center,SXGetLambda());
if(csToPsi == NULL){
SCWrite(pCon,"ERROR: bad parameters: failed to generate conversion matrix",
eError);
@ -129,7 +158,16 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
* calculate scattering vector on cone and make its length
* match the length of the apropriate scattering vector
*/
length = scatteringVectorLength(B,self->target) * self->qScale;
SICSHdbGetPar(obj,pCon,"target",&v);
target.h = v.v.floatArray[0];
target.k = v.v.floatArray[1];
target.l = v.v.floatArray[2];
SICSHdbGetPar(obj,pCon,"qscale",&v);
/*
* calculate scattering vector on cone and make its length
* match the length of the apropriate scattering vector
*/
length = scatteringVectorLength(B,target) * v.v.doubleValue;
newScat = calcConeVector(openingAngle, fVal, length, csToPsi);
if(newScat == NULL){
SCWrite(pCon,"ERROR: fails to calculate cone vector",eError);
@ -139,7 +177,7 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
/*
* try to find setting angles for this vector
*/
status = findAllowedBisecting(self->pHkl->fLambda,newScat, fSet,
status = findAllowedBisecting(SXGetLambda(),newScat, fSet,
hklInRange, self->pHkl);
/*
* clean up matrices
@ -157,201 +195,119 @@ static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
/*
* start motors
*/
return startHKLMotors(self->pHkl, pCon,fSet);
for(i = 0; i < 4; i++){
ffSet[i] = fSet[i];
}
return startHKLMotors(self->pHkl, pCon,ffSet);
}
/*---------------------------------------------------------------------------------------------------*/
static int checkMotors(pConeData self, SConnection *pCon){
int status;
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
if(status != HWIdle && status != OKOK){
return status;
int status, i;
pMotor pMot = NULL;
MotorFunction mots[] = {TwoTheta, Omega, Chi, Phi};
for(i = 0; i < 4; i++){
pMot = SXGetMotor(mots[i]);
if(pMot != NULL){
status = pMot->pDrivInt->CheckStatus(pMot, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
}
}
return HWIdle;
}
/*-----------------------------------------------------------------------------------------------------*/
static int ConeCheckStatus(void *pData, SConnection *pCon){
pSICSOBJ obj = pData;
pConeData self = NULL;
int status;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
return checkMotors(self,pCon);
}
/*-----------------------------------------------------------------------------------------------------*/
static float ConeGetValue(void *pData, SConnection *pCon){
pSICSOBJ obj = pData;
pConeData self = NULL;
float fVal[3];
int status;
self = (pConeData)pData;
self = (pConeData)obj->pPrivate;
assert(self != NULL);
return self->lastConeAngle;
}
/*=============================== Live and Death ====================================*/
static pConeData MakeConeMot(pUBCALC u){
static pConeData MakeConeMot(){
pConeData self = NULL;
assert(u != NULL);
self = (pConeData)malloc(sizeof(coneData));
if(self == NULL){
return NULL;
}
memset(self,0,sizeof(coneData));
self->pDes = CreateDescriptor("Cone");
self->pDriv = CreateDrivableInterface();
if(self->pDes == NULL || self->pDriv == NULL){
if(self->pDriv == NULL){
free(self);
return NULL;
}
self->pDes->GetInterface = ConeGetInterface;
self->pDriv->Halt = ConeHalt;
self->pDriv->CheckLimits = ConeCheckLimits;
self->pDriv->SetValue = ConeSetValue;
self->pDriv->CheckStatus = ConeCheckStatus;
self->pDriv->GetValue = ConeGetValue;
self->ubi = u;
self->pHkl = u->hkl;
self->qScale = 1.0;
return self;
}
/*----------------------------------------------------------------------------------*/
static void KillConeMot(void *pData){
pConeData self = NULL;
self = (pConeData)pData;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->pDriv){
free(self->pDriv);
}
free(self);
}
/*=============================== Interpreter Interface ============================*/
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pConeData self = NULL;
float value;
int id;
char pBuffer[132];
self = (pConeData)pData;
assert(self != NULL);
if(argc > 1) {
strtolower(argv[1]);
if(strcmp(argv[1],"center") == 0){
if(argc > 2){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
id = atoi(argv[2]);
if(id < 0 || id > 2 ){
SCWrite(pCon,"ERROR: id must be between 0 - 3",eError);
return 0;
}
self->center = id;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.center = %d", argv[0], self->center);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if(strcmp(argv[1],"qscale") == 0){
if(argc > 2){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->qScale = atof(argv[2]);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.qscale = %f", argv[0], self->qScale);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if (strcmp(argv[1],"target") == 0){
if(argc >= 5){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->target.h = atof(argv[2]);
self->target.k = atof(argv[3]);
self->target.l = atof(argv[4]);
self->qScale = 1.;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.target = %f %f %f", argv[0],
self->target.h, self->target.k, self->target.l);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else {
SCWrite(pCon,"ERROR: subcommand to cone not known",eError);
return 0;
}
}
/*
* default: print value
*/
value = self->pDriv->GetValue(self,pCon);
if(value < -9000.){
snprintf(pBuffer,131,"ERROR: failed to read %s",argv[0]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
snprintf(pBuffer,131,"%s = %f", argv[0], value);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
/*------------------------------------------------------------------------------------------*/
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pUBCALC ubi = NULL;
pSICSOBJ pNew = NULL;
pConeData pMot = NULL;
char pBuffer[131];
char pBuffer[131], pName[80];
int status;
pHdb cmd;
if(argc > 1){
strcpy(pName,argv[1]);
} else {
strcpy(pName,"cone");
}
if(argc < 3){
SCWrite(pCon,"ERROR: insuffient number of arguments to MakeCone",eError);
return 0;
}
ubi = FindCommandData(pSics,argv[2],"UBcalc");
if(ubi == NULL){
snprintf(pBuffer,131,"ERROR: %s is no UBcalc object" , argv[2]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
pMot = MakeConeMot(ubi);
if(pMot == NULL){
pNew = MakeSICSOBJ(pName,"Cone");
pMot = MakeConeMot();
if(pNew == NULL || pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating cone virtual motor",eError);
return 0;
}
status = AddCommand(pSics,argv[1],ConeAction,KillConeMot,pMot);
pNew->pDes->GetInterface = ConeGetInterface;
pNew->pPrivate = pMot;
pNew->KillPrivate = DefaultFree;
cmd = AddSICSHdbPar(pNew->objectNode,"target", usUser, makeHdbValue(HIPFLOATAR,3));
SetHdbProperty(cmd,"__save", "true");
cmd = AddSICSHdbPar(pNew->objectNode,"qscale", usUser, MakeHdbFloat(1.));
SetHdbProperty(cmd,"__save", "true");
cmd = AddSICSHdbPar(pNew->objectNode,"center", usUser, MakeHdbText("unknown"));
SetHdbProperty(cmd,"__save", "true");
if(argc > 2){
pMot->pHkl = FindCommandData(pSics,argv[2],"4-Circle-Calculus");
} else {
pMot->pHkl = FindCommandData(pSics,"hkl","4-Circle-Calculus");
}
if(pMot->pHkl == NULL){
snprintf(pBuffer,131,"ERROR: %s is no hkl object" , argv[2]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
status = AddCommand(pSics,pName,InterInvokeSICSOBJ,KillSICSOBJ,pNew);
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate cone motor",eError);
}
return status;
}