- Removed SCStart/EndBuffering as far as possible and fixed an issue with

the capture command in that it not put resluts into the Tcl interpreter.
  This broke scriptcontext scripts in complicated situations.
- Resolved some issues with the TAS calculation and negative scattering sense.
- Fixed a bug which did not reset the state to idle after checking
  reachability in confvirtualmot.c


SKIPPED:
	psi/autowin.c
	psi/eigera2.c
	psi/jvlprot.c
	psi/makefile_linux
	psi/sinqhttpopt.c
	psi/tasscan.c
This commit is contained in:
koennecke
2012-10-29 12:56:29 +00:00
parent d798373fdf
commit 4f560552c4
27 changed files with 599 additions and 129 deletions

View File

@ -206,10 +206,13 @@ void WriteToCommandLogId(char *prompt, int id, char *text)
setCircular(pTail, strdup(stamp1));
nextCircular(pTail);
}
setCircular(pTail, pCopy);
setCircular(pTail, strdup(pCopy));
nextCircular(pTail);
}
lastId = id;
if(pCopy != NULL){
free(pCopy);
}
}
/*------------------------------------------------------------------------*/

View File

@ -246,6 +246,11 @@ static int ConfCheckLimits(void *pData, float fVal, char *error,
}
}
if(self->state != NULL){
free(self->state);
}
self->state = strdup("idle");
iRet = LLDnodePtr2First(self->motorList);
while (iRet != 0) {
LLDnodeDataTo(self->motorList, &tuktuk);
@ -652,6 +657,9 @@ int ConfigurableVirtualMotorAction(SConnection * pCon, SicsInterp * pSics,
if (argc > 2) {
/* set case */
Arg2Text(argc - 2, &argv[2], pBueffel, 510);
if(self->state != NULL){
free(self->state);
}
self->state = strdup(pBueffel);
SCSendOK(pCon);
return 1;

View File

@ -902,6 +902,7 @@ static int SCBufferWrite(SConnection * self, char *buffer, int iOut)
if (strchr(buffer, '\n') == NULL) {
DynStringConcat(self->data, "\n");
}
testAndStoreInTcl(self, buffer, iOut);
return 1;
}
@ -1154,7 +1155,7 @@ int SCWriteZipped(SConnection * self, char *pName, void *pData,
compStream.zfree = (free_func) NULL;
compStream.opaque = (voidpf) NULL;
/* iRet = deflateInit(&compStream, Z_DEFAULT_COMPRESSION); */
iRet = deflateInit(&compStream, 2);
iRet = deflateInit(&compStream, 1);
if (iRet != Z_OK) {
sprintf(outBuf, "ERROR: zlib error: %d", iRet);
SCWrite(self, outBuf, eError);

View File

@ -274,6 +274,7 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
double dTarget;
char pBueffel[512];
Status eOld;
char *error = NULL;
assert(pCon);
assert(pSics);
@ -318,8 +319,13 @@ int DriveWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
}
iRet = Start2Run(pCon, pSics, argv[i], RUNDRIVE, dTarget);
if (!iRet) {
snprintf(pBueffel, 511,"ERROR: cannot run %s to %s", argv[i],
error = Tcl_GetStringResult(tcl_interp);
if(error != NULL) {
snprintf(pBueffel, 511,"%s", error);
} else {
snprintf(pBueffel, 511,"ERROR: cannot run %s to %s", argv[i],
argv[i + 1]);
}
SCWrite(pCon, pBueffel, eError);
StopExe(GetExecutor(), "ALL");
SetStatus(eOld);

View File

@ -153,6 +153,12 @@ int DynStringConcat(pDynString self, char *pText)
self->iTextLen = iRequested;
return 1;
}
/*--------------------------------------------------------------------------*/
int DynStringConcatLine(pDynString self, char *pText)
{
DynStringConcat(self,pText);
return DynStringConcatChar(self,'\n');
}
/*--------------------------------------------------------------------------*/
int DynStringConcatChar(pDynString self, char c)

View File

@ -49,6 +49,11 @@ int DynStringConcat(pDynString self, char *pText);
Concatenates the string in DynString with the one supplied
in string.
*/
int DynStringConcatLine(pDynString self, char *pText);
/*
Concatenates the string in DynString with the one supplied
in string. And add a newline.
*/
int DynStringConcatChar(pDynString self, char c);
/*

View File

@ -1168,13 +1168,18 @@ static int printBuffer(pExeMan self, SConnection * pCon,
return 0;
}
DeleteDynString(filePath);
SCStartBuffering(pCon);
filePath = CreateDynString(256,256);
if(filePath == NULL){
SCWrite(pCon,"ERROR: out of memory printing buffer",eError);
return 0;
}
while (fgets(pLine, 511, fd) != NULL) {
SCWrite(pCon, pLine, eValue);
DynStringConcat(filePath, pLine);
DynStringConcatChar(filePath,'\n');
}
fclose(fd);
filePath = SCEndBuffering(pCon);
SCWrite(pCon, GetCharArray(filePath), eValue);
DeleteDynString(filePath);
return 1;
}

View File

@ -486,17 +486,23 @@ int FitWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
}
/* print results */
SCStartBuffering(pCon);
snprintf(pBueffel,sizeof(pBueffel)-1, "Estimated Peak Center: %f, StdDev: %f \n",
self->fCenter, self->fStddev);
SCWrite(pCon, pBueffel, eValue);
snprintf(pBueffel,sizeof(pBueffel)-1, "Maximum peak height: %ld\n", self->lPeak);
SCWrite(pCon, pBueffel, eValue);
snprintf(pBueffel,sizeof(pBueffel)-1, "Approximate FWHM: %f\n", self->FWHM);
SCWrite(pCon, pBueffel, eValue);
buf = SCEndBuffering(pCon);
if (buf != NULL) {
buf = CreateDynString(256,256);
if(buf != NULL){
snprintf(pBueffel,sizeof(pBueffel)-1, "Estimated Peak Center: %f, StdDev: %f \n",
self->fCenter, self->fStddev);
DynStringConcat(buf,pBueffel);
DynStringConcatChar(buf,'\n');
snprintf(pBueffel,sizeof(pBueffel)-1, "Maximum peak height: %ld\n", self->lPeak);
DynStringConcat(buf,pBueffel);
DynStringConcatChar(buf,'\n');
snprintf(pBueffel,sizeof(pBueffel)-1, "Approximate FWHM: %f\n", self->FWHM);
DynStringConcat(buf,pBueffel);
DynStringConcatChar(buf,'\n');
SCWrite(pCon, GetCharArray(buf), eValue);
DeleteDynString(buf);
} else {
SCWrite(pCon,"ERROR: out of memory printing fitcenter results",eError);
return 0;
}
return 1;
@ -549,14 +555,9 @@ int EdgeWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
}
/* print results */
SCStartBuffering(pCon);
snprintf(pBueffel,sizeof(pBueffel)-1, "Estimated Edge Center: %f\n",
self->fCenter);
SCWrite(pCon, pBueffel, eValue);
buf = SCEndBuffering(pCon);
if (buf != NULL) {
SCWrite(pCon, GetCharArray(buf), eValue);
}
return 1;
}

View File

@ -484,12 +484,18 @@ static unsigned short fletcher16( char *data, size_t len)
return result ;
}
/*------------------------------------------------------------------------*/
#define MAXLEN 65536
unsigned short getHdbCheckSum(hdbValue *val)
{
char *data;
size_t len;
len = getHdbValueLength(*val);
/*
if(len > MAXLEN){
len = MAXLEN;
}
*/
switch (val->dataType) {
case HIPNONE:
return 0;

View File

@ -982,17 +982,21 @@ void HMListOption(pHistMem self, SConnection * pCon)
memset(pValue, 0, sizeof(pValue));
memset(name, 0, sizeof(name));
SCStartBuffering(pCon);
buf = CreateDynString(256,256);
if(buf == NULL){
SCWrite(pCon,"ERROR: out of memory listing HM Options",eError);
return;
}
iRet = StringDictGet(self->pDriv->pOption, "name", name, 19);
if (0 == iRet) {
strcpy(name, "*");
}
iRet =
StringDictGet(self->pDriv->pOption, "driver", pValue,
sizeof(pValue) - 1);
StringDictGet(self->pDriv->pOption, "driver", pValue,
sizeof(pValue) - 1);
if (0 < iRet) {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.driver = %s", name, pValue);
SCWrite(pCon, pBuffer, eValue);
DynStringConcatLine(buf,pBuffer);
}
iRet = StringDictGetAsNumber(self->pDriv->pOption, "update", &fVal);
@ -1001,13 +1005,13 @@ void HMListOption(pHistMem self, SConnection * pCon)
} else {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.update = 0 (no buffering)", name);
}
SCWrite(pCon, pBuffer, eValue);
DynStringConcatLine(buf,pBuffer);
iRet = StringDictGetAsNumber(self->pDriv->pOption, "rank", &fVal);
if (0 < iRet) {
iRank = (int) rint(fVal);
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.rank = %d", name, iRank);
SCWrite(pCon, pBuffer, eValue);
DynStringConcatLine(buf,pBuffer);
} else {
iRank = 0;
}
@ -1016,12 +1020,12 @@ void HMListOption(pHistMem self, SConnection * pCon)
iRet = StringDictGetAsNumber(self->pDriv->pOption, pValue, &fVal);
if (0 < iRet) {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.dim%1.1d = %d", name, i, (int) rint(fVal));
SCWrite(pCon, pBuffer, eValue);
DynStringConcatLine(buf,pBuffer);
}
}
pKey =
StringDictGetNext(self->pDriv->pOption, pValue, sizeof(pValue) - 1);
StringDictGetNext(self->pDriv->pOption, pValue, sizeof(pValue) - 1);
while (pKey != NULL) {
iDiscard = 0;
if (0 == strcmp("name", pKey))
@ -1036,20 +1040,21 @@ void HMListOption(pHistMem self, SConnection * pCon)
iDiscard = 1;
if (0 == iDiscard) {
snprintf(pBuffer, 511, "%s.%s = %s", name, pKey, pValue);
SCWrite(pCon, pBuffer, eValue);
DynStringConcatLine(buf,pBuffer);
}
pKey =
StringDictGetNext(self->pDriv->pOption, pValue,
sizeof(pValue) - 1);
StringDictGetNext(self->pDriv->pOption, pValue,
sizeof(pValue) - 1);
}
/* Display Count Mode */
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.CountMode = %s", name, pMode[self->pDriv->eCount]);
DynStringConcatLine(buf,pBuffer);
SCWrite(pCon, pBuffer, eValue);
/* Display Preset */
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.preset = %f", name, self->pDriv->fCountPreset);
SCWrite(pCon, pBuffer, eValue);
DynStringConcatLine(buf,pBuffer);
if (self->pDriv->data->nTimeChan > 2) {
tofMode = 1;
@ -1057,11 +1062,9 @@ void HMListOption(pHistMem self, SConnection * pCon)
tofMode = 0;
}
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.tofMode = %d", name, tofMode);
SCWrite(pCon, pBuffer, eValue);
buf = SCEndBuffering(pCon);
if (buf != NULL) {
SCWrite(pCon, GetCharArray(buf), eValue);
}
DynStringConcatLine(buf,pBuffer);
SCWrite(pCon, GetCharArray(buf), eValue);
DeleteDynString(buf);
}
/*--------------------------------------------------------------------------*/

View File

@ -791,6 +791,7 @@ pMotor MotorInit(char *drivername, char *name, MotorDriver * pDriv)
if (!pM) {
return NULL;
}
memset(pM,0,sizeof(Motor));
/* create and initialize parameters */

View File

@ -127,7 +127,7 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
case HWPosFault:
/**
* It is questionable if one should not set a flag here
* and keep p;olling: it is not clear if this error is a
* and keep polling: it is not clear if this error is a
* communication problem or that the motor really
* has stopped.
*/

View File

@ -233,6 +233,9 @@ static int checkPosition(pMotor self, SConnection * pCon)
SCPrintf(pCon, eLogError,
"ERROR: Aborting %s after %d retries, off position by %f",
self->name, (int) maxretry, target - hard);
node = GetHipadabaNode(self->pDescriptor->parNode, "status");
assert(node != NULL);
UpdateHipadabaPar(node, MakeHdbText("error"), pCon);
return HWFault;
}
self->retryCount++;

View File

@ -372,18 +372,21 @@ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb node = NULL;
pDynString txt;
SCStartBuffering(pCon);
txt = CreateDynString(256,256);
if(txt == NULL){
SCWrite(pCon,"ERROR: out of memory listing names", eError);
return 0;
}
node = GetHipadabaNode(self->objectNode, "data");
node = node->child;
while (node != NULL) {
snprintf(buffer, 132, "%s", node->name);
SCWrite(pCon, buffer, eValue);
DynStringConcatLine(txt,buffer);
node = node->next;
}
txt = SCEndBuffering(pCon);
SCWrite(pCon, GetCharArray(txt), eValue);
DeleteDynString(txt);
return 1;
}
/*----------------------------------------------------------------------*/

24
scan.c
View File

@ -507,7 +507,8 @@ CountEntry CollectCounterData(pScanData self)
/*---------------------------------------------------------------------------*/
static int ScanLoop(pScanData self)
{
int i, iInt, iRet, iStatus;
int i, iInt, iRet, iStatus, iHeaderWritten = 0;
assert(self);
assert(self->pCon);
@ -548,6 +549,18 @@ static int ScanLoop(pScanData self)
continue;
}
if(iHeaderWritten == 0) {
iRet = self->WriteHeader(self);
iHeaderWritten++;
if (!iRet) {
SCWrite(self->pCon, "ERROR: cannot open data file, Scan aborted",
eError);
self->pCon = NULL;
self->pSics = NULL;
return 0;
}
}
/*-------------- count */
iRet = self->ScanCount(self, i);
/* finished, check for interrupts. Whatever happened, user
@ -648,15 +661,6 @@ int DoScan(pScanData self, int iNP, int iMode, float fPreset,
}
iRet = self->WriteHeader(self);
if (!iRet) {
SCWrite(self->pCon, "ERROR: cannot open data file, Scan aborted",
eError);
self->pCon = NULL;
self->pSics = NULL;
return 0;
}
self->iActive = 1;
iRet = ScanLoop(self);
ScriptScanFinish(self);

View File

@ -1429,7 +1429,9 @@ static char *TransactionHandler(void *actionData, char *lastReply,
} else {
traceIO("sctunknown", "transreply:%s", lastReply);
}
st->reply = strdup(lastReply);
if(lastReply != NULL){
st->reply = strdup(lastReply);
}
return NULL;
}
}

View File

@ -38,7 +38,7 @@ void DefaultFree(void *data)
}
/*---------------------------------------------------------------------------*/
static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
static void saveSICSNodeBroken(pHdb node, char *prefix, FILE * fd)
{
/*
nodes with the property __save are saved
@ -78,6 +78,38 @@ static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
}
ReleaseHdbValue(&v);
}
}
child = node->child;
while (child != NULL) {
snprintf(newprefix, 1024, "%s/%s", prefix, child->name);
saveSICSNodeBroken(child, newprefix, fd);
child = child->next;
}
}
/*---------------------------------------------------------------------------*/
static void saveSICSNode(pHdb node, char *prefix, FILE * fd)
{
char newprefix[1024], val[20];
char path[MAX_HDB_PATH];
pHdb child;
hdbValue v;
pDynString data = NULL;
char *cmd;
cmd = GetHdbProp(node, "creationCmd");
if (cmd != NULL) {
GetHdbPath(node, path, sizeof path);
fprintf(fd, cmd, prefix, path);
fprintf(fd, "\n");
}
if (GetHdbProperty(node, "__save", val, 20) == 1) {
GetHipadabaPar(node, &v, NULL);
data = formatValue(v, node);
if (data != NULL) {
fprintf(fd, "%s %s\n", prefix, GetCharArray(data));
DeleteDynString(data);
}
ReleaseHdbValue(&v);
child = node->child;
while (child != NULL) {
snprintf(newprefix, 1024, "%s/%s", prefix, child->name);
@ -96,6 +128,33 @@ int SaveSICSOBJ(void *data, char *name, FILE * fd)
pHdb node;
char *cmd;
if (self != NULL && self->objectNode != NULL) {
node = self->objectNode->child;
cmd = GetHdbProp(self->objectNode, "creationCmd");
if (cmd != NULL) {
GetHdbPath(self->objectNode, path, sizeof path);
fprintf(fd, cmd, name, path);
fprintf(fd, "\n");
}
while (node != NULL) {
snprintf(prefix, 1024, "%s %s", name, node->name);
saveSICSNode(node, prefix, fd);
node = node->next;
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
int SaveSICSOBJBroken(void *data, char *name, FILE * fd)
{
pSICSOBJ self = (pSICSOBJ) data;
char prefix[1024];
char path[MAX_HDB_PATH];
pHdb node;
char *cmd;
if (self != NULL && self->objectNode != NULL) {
/*
node = self->objectNode->child;

View File

@ -211,6 +211,7 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int status, iVal;
char buffer[512];
pDynString txt = NULL;
SConnection *dummy = NULL;
assert(self != NULL);
if (argc < 2) {
@ -320,11 +321,17 @@ int SICSPollWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1;
}
} else if (strcmp(argv[1], "list") == 0) {
SCStartBuffering(pCon);
printPollList(self, pCon);
txt = SCEndBuffering(pCon);
dummy = SCCreateDummyConnection(pSics);
if(dummy == NULL){
SCWrite(pCon,"ERROR: out of memory listing polling data",eError);
return 0;
}
SCStartBuffering(dummy);
printPollList(self, dummy);
txt = SCEndBuffering(dummy);
if (txt != NULL) {
SCWrite(pCon, GetCharArray(txt), eValue);
SCDeleteConnection(dummy);
}
return 1;
} else if (strcmp(argv[1], "poll") == 0) {

View File

@ -54,8 +54,8 @@ static int calculateTASSettings(pSingleDiff self,
} else {
status = 1;
}
settings[0] = angles.a3;
settings[1] = angles.sample_two_theta;
settings[0] = angles.sample_two_theta;
settings[1] = angles.a3;
settings[2] = angles.sgu;
settings[3] = angles.sgl;
if (!MotorCheckBoundary(SXGetMotor(Omega), (float) settings[0], &fHard,

View File

@ -199,17 +199,19 @@ static int listRestoreErr(pRestoreObj self, SConnection * pCon)
int status;
pDynString data = NULL;
SCStartBuffering(pCon);
data = CreateDynString(256,256);
if(data == NULL){
SCWrite(pCon,"ERROR: out of memory listing errors",eError);
return 0;
}
status = LLDnodePtr2First(self->errList);
while (status == 1) {
LLDstringData(self->errList, buffer);
SCWrite(pCon, buffer, eValue);
DynStringConcatLine(data,buffer);
status = LLDnodePtr2Next(self->errList);
}
data = SCEndBuffering(pCon);
if (data != NULL) {
SCWrite(pCon, GetCharArray(data), eValue);
}
SCWrite(pCon, GetCharArray(data), eValue);
DeleteDynString(data);
return 1;
}

View File

@ -262,9 +262,9 @@ void InvokeNewTarget(pExeList self, char *name, float target);
/*--------------------------------------------------------------------------*/
static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
double target, int silent)
double target, int silent, int stopFixed)
{
float val, fixed;
float val, fixed, precision = MOTPREC;
int status = OKOK;
char buffer[132];
pIDrivable pDriv = NULL;
@ -272,18 +272,21 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
pDynString mes = NULL;
dum = (pDummy)mot;
val = getMotorValue(mot, pCon);
if(strcmp(dum->pDescriptor->name,"Motor") == 0){
val = getMotorValue(mot, pCon);
MotorGetPar(mot, "fixed", &fixed);
if (ABS(fixed - 1.0) < .1) {
snprintf(buffer, 131, "WARNING: %s is FIXED", name);
SCWrite(pCon, buffer, eLog);
return OKOK;
}
MotorGetPar(mot,"precision",&precision);
MotorGetPar(mot, "fixed", &fixed);
if (ABS(fixed - 1.0) < .1) {
if(stopFixed == 0){
snprintf(buffer, 131, "WARNING: %s is FIXED", name);
SCWrite(pCon, buffer, eLog);
}
return OKOK;
}
}
mot->stopped = 0;
if (ABS(val - target) > MOTPREC) {
pDriv = GetDrivableInterface(mot);
if (ABS(val - target) > precision) {
pDriv = GetDrivableInterface(mot);
status = pDriv->SetValue(mot, pCon, (float) target);
if(status != OKOK){
SCPrintf(pCon,eLog,"ERROR: failed to drive %s to %f", name, target);
@ -302,20 +305,21 @@ static int startMotors(ptasMot self, tasAngles angles,
SConnection * pCon, int driveQ, int driveTilt)
{
double curve;
int status, silent;
int status, silent, stopFixed;
silent = self->math->silent;
stopFixed = self->math->stopFixed;
self->math->mustRecalculate = 1;
/*
monochromator
*/
status = startTASMotor(self->math->motors[A1], pCon, "a1",
angles.monochromator_two_theta / 2., silent);
angles.monochromator_two_theta / 2., silent, stopFixed);
if (status != OKOK) {
return status;
}
status = startTASMotor(self->math->motors[A2], pCon, "a2",
angles.monochromator_two_theta, silent);
angles.monochromator_two_theta, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -324,7 +328,7 @@ static int startMotors(ptasMot self, tasAngles angles,
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
angles.monochromator_two_theta);
status = startTASMotor(self->math->motors[MCV], pCon, "mcv",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
SCWrite(pCon,"WARNING: monochromator vertical curvature motor failed to start", eLog);
SCSetInterrupt(pCon,eContinue);
@ -335,7 +339,7 @@ static int startMotors(ptasMot self, tasAngles angles,
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
angles.monochromator_two_theta);
status = startTASMotor(self->math->motors[MCH], pCon, "mch",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
SCWrite(pCon,"WARNING: monochromator horizontal curvature motor failed to start", eLog);
SCSetInterrupt(pCon,eContinue);
@ -348,12 +352,12 @@ static int startMotors(ptasMot self, tasAngles angles,
*/
if (self->math->tasMode != ELASTIC) {
status = startTASMotor(self->math->motors[A5], pCon, "a5",
angles.analyzer_two_theta / 2.0, silent);
angles.analyzer_two_theta / 2.0, silent,stopFixed);
if (status != OKOK) {
return status;
}
status = startTASMotor(self->math->motors[A6], pCon, "a6",
angles.analyzer_two_theta, silent);
angles.analyzer_two_theta, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -362,7 +366,7 @@ static int startMotors(ptasMot self, tasAngles angles,
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
angles.analyzer_two_theta);
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
SCWrite(pCon,"WARNING: analyzer vertical curvature motor failed to start", eLog);
SCSetInterrupt(pCon,eContinue);
@ -372,7 +376,7 @@ static int startMotors(ptasMot self, tasAngles angles,
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
angles.analyzer_two_theta);
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
SCWrite(pCon,"WARNING: analyzer horizontal curvature motor failed to start", eLog);
SCSetInterrupt(pCon,eContinue);
@ -388,24 +392,24 @@ static int startMotors(ptasMot self, tasAngles angles,
crystal
*/
status = startTASMotor(self->math->motors[A3], pCon, "a3",
angles.a3, silent);
angles.a3, silent,stopFixed);
if (status != OKOK) {
return status;
}
status = startTASMotor(self->math->motors[A4], pCon, "a4",
angles.sample_two_theta, silent);
angles.sample_two_theta, silent,stopFixed);
if (status != OKOK) {
return status;
}
if (driveTilt == 1) {
status = startTASMotor(self->math->motors[SGL], pCon, "sgl",
angles.sgl, silent);
angles.sgl, silent,stopFixed);
if (status != OKOK) {
return status;
}
status = startTASMotor(self->math->motors[SGU], pCon, "sgu",
angles.sgu, silent);
angles.sgu, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -524,6 +528,7 @@ static int calculateAndDrive(ptasMot self, SConnection * pCon)
"WARNING: scattering vector is out of plane and you disallowed me to try to drive there",
eWarning);
}
mat_free(scatteringPlaneNormal);
}
driveTilt = 0;
}
@ -623,19 +628,20 @@ static int startQMMotors(ptasMot self, tasAngles angles,
{
float val;
double curve;
int status, silent;
int status, silent, stopFixed;
silent = self->math->silent;
stopFixed = self->math->stopFixed;
/*
monochromator
*/
status = startTASMotor(self->math->motors[A1], pCon, "a1",
angles.monochromator_two_theta / 2., silent);
angles.monochromator_two_theta / 2., silent,stopFixed);
if (status != OKOK) {
return status;
}
status = startTASMotor(self->math->motors[A2], pCon, "a2",
angles.monochromator_two_theta, silent);
angles.monochromator_two_theta, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -644,7 +650,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
angles.monochromator_two_theta);
status = startTASMotor(self->math->motors[MCV], pCon, "mcv",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -654,7 +660,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
angles.monochromator_two_theta);
status = startTASMotor(self->math->motors[MCH], pCon, "mch",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -665,12 +671,12 @@ static int startQMMotors(ptasMot self, tasAngles angles,
analyzer
*/
status = startTASMotor(self->math->motors[A5], pCon, "a5",
angles.analyzer_two_theta / 2.0, silent);
angles.analyzer_two_theta / 2.0, silent,stopFixed);
if (status != OKOK) {
return status;
}
status = startTASMotor(self->math->motors[A6], pCon, "a6",
angles.analyzer_two_theta, silent);
angles.analyzer_two_theta, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -679,7 +685,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
angles.analyzer_two_theta);
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -688,7 +694,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
angles.analyzer_two_theta);
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
curve, silent);
curve, silent,stopFixed);
if (status != OKOK) {
return status;
}
@ -698,7 +704,7 @@ static int startQMMotors(ptasMot self, tasAngles angles,
crystal
*/
status = startTASMotor(self->math->motors[A4], pCon, "a4",
angles.sample_two_theta, silent);
angles.sample_two_theta, silent,stopFixed);
if (status != OKOK) {
return status;
}

View File

@ -266,11 +266,12 @@ static int TASUBHeader(pScanData self)
fprintf(self->fd, "DATE_: %s\n", pWork);
fprintf(self->fd, "TITLE: %s\n", GetVarText("title"));
fprintf(self->fd, "COMND: %s\n", GetVarText("lastscancommand"));
tasUpdate(self->pCon,pTAS->ub);
fprintf(self->fd,
"POSQE: QH=%8.4f, QK=%8.4f, QL=%8.4f, EN=%8.4f, UN=MEV\n",
pTAS->ub->current.qh,
pTAS->ub->current.qk,
pTAS->ub->current.qk, getTasPar(pTAS->ub->current, EN));
pTAS->ub->current.ql, getTasPar(pTAS->ub->current, EN));
/*
build the steps line
*/
@ -662,6 +663,11 @@ static int TASUBScanDrive(pScanData self, int iPoint)
/*
loop through all the scan variables
*/
if(iPoint == 0 && pTAS->iFast != 1) {
pTAS->ub->stopFixed = 0;
} else {
pTAS->ub->stopFixed = 1;
}
for (i = 0; i < self->iScanVar; i++) {
DynarGet(self->pScanVar, i, &pPtr);
pVar = (pVarEntry) pPtr;
@ -675,6 +681,7 @@ static int TASUBScanDrive(pScanData self, int iPoint)
}
}
/*
now wait for our motors to arrive, thereby ignoring any error
returns. DO NOT WAIT if fast scan!
@ -684,6 +691,7 @@ static int TASUBScanDrive(pScanData self, int iPoint)
} else {
status = Wait4Success(GetExecutor());
pTAS->ub->silent = 0;
pTAS->ub->stopFixed = 0;
}
return 1;
}
@ -789,6 +797,7 @@ static int TASUBCollect(pScanData self, int iPoint)
/* loop over all scan variables */
status = 1;
memset(&sCount,0,sizeof(CountEntry));
pTAS->ub->silent = 0;
for (i = 0; i < self->iScanVar; i++) {

78
tasub.c
View File

@ -21,6 +21,7 @@
#include "trigd.h"
#include "tasub.h"
#include "tasdrive.h"
#include "vector.h"
/*------------------- motor indexes in motor data structure ---------*/
#define A1 0
#define A2 1
@ -154,6 +155,7 @@ static ptasUB MakeTasUB()
pNew->pDes = CreateDescriptor("TAS-UB");
pNew->machine.UB = mat_creat(3, 3, UNIT_MATRIX);
pNew->machine.planeNormal = mat_creat(3, 1, ZERO_MATRIX);
pNew->machine.planeNormal[2][0] = 1.;
pNew->reflectionList = LLDcreate(sizeof(tasReflection));
if (!pNew->pDes || !pNew->machine.UB || pNew->reflectionList < 0 ||
pNew->machine.planeNormal == NULL) {
@ -893,7 +895,13 @@ int findReflection(int list, int idx, ptasReflection r)
}
return 0;
}
/*-----------------------------------------------------------------*/
void setStopFixed(ptasUB self, int val)
{
if(val == 0 || val ==1) {
self->stopFixed = val;
}
}
/*------------------------------------------------------------------*/
static void listUB(ptasUB self, SConnection * pCon)
{
@ -1179,7 +1187,9 @@ static int calcAuxUB(ptasUB self, SConnection * pCon, SicsInterp * pSics,
mat_free(self->machine.planeNormal);
}
self->machine.UB = UB;
self->machine.planeNormal = calcPlaneNormal(r1, r2);
self->machine.planeNormal = makeVector();
self->machine.planeNormal[2][0] = 1.;
/* self->machine.planeNormal = calcPlaneNormal(r1, r2); */
self->ubValid = 1;
SCparChange(pCon);
SCSendOK(pCon);
@ -1260,7 +1270,9 @@ static int calcUB(ptasUB self, SConnection * pCon, SicsInterp * pSics,
mat_free(self->machine.planeNormal);
}
self->machine.UB = UB;
self->machine.planeNormal = calcPlaneNormal(r1, r2);
/* self->machine.planeNormal = calcPlaneNormalQ(UB,r1, r2);*/
self->machine.planeNormal = makeVector();
self->machine.planeNormal[2][0] = 1.;
self->r1 = r1;
self->r2 = r2;
self->ubValid = 1;
@ -1321,6 +1333,62 @@ static int calcUBFromCell(ptasUB self, SConnection * pCon)
mat_free(B);
return 1;
}
/*-----------------------------------------------------------------*/
static int calcTestUBWrap(ptasUB self, SConnection *pCon,
int argc, char *argv[])
{
MATRIX UB;
double om, sgu, sgl;
tasReflection r1, r2;
if(argc < 5) {
SCWrite(pCon,"ERROR: not enough arguments to test UB", eError);
return 0;
}
om = atof(argv[2]);
sgu = atof(argv[3]);
sgl = atof(argv[4]);
UB = calcTestUB(self->cell, om, sgu, sgl);
if(UB == NULL){
SCWrite(pCon,"ERROR: out of memory or invalid cell in test UB", eError);
return 0;
}
mat_free(self->machine.UB);
self->machine.UB = UB;
/*
r1.qe.qh = 1.0;
r1.qe.qk = .0;
r1.qe.ql = .0;
r2.qe.qh = .0;
r2.qe.qk = 1.0;
r2.qe.ql = .0;
self->machine.planeNormal = calcPlaneNormalQ(UB,r1,r2);
self->machine.planeNormal[0][0] = -Sind(sgl);
self->machine.planeNormal[1][0] = Cosd(sgl)*Sind(sgu);
self->machine.planeNormal[2][0] = Cosd(sgl)*Cosd(sgu);
SCPrintf(pCon,eValue,"Normal = %f,%f,%f\n", self->machine.planeNormal[0][0],
self->machine.planeNormal[1][0],
self->machine.planeNormal[2][0]);
self->machine.planeNormal = calcTestNormal(sgu,sgl);
SCPrintf(pCon,eValue,"Alternative normal = %f,%f,%f\n", self->machine.planeNormal[0][0],
self->machine.planeNormal[1][0],
self->machine.planeNormal[2][0]);
*/
self->machine.planeNormal[0][0] = .0;
self->machine.planeNormal[1][0] = .0;
self->machine.planeNormal[2][0] = 1.0;
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------*/
static int calcRefAngles(ptasUB self, SConnection * pCon,
@ -1409,7 +1477,7 @@ static int calcRefAngles(ptasUB self, SConnection * pCon,
snprintf(pBueffel, 255, " %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f",
angles.monochromator_two_theta,
angles.a3, angles.sample_two_theta,
angles.sgl, angles.sgu, angles.analyzer_two_theta);
angles.sgu, angles.sgl, angles.analyzer_two_theta);
} else {
snprintf(pBueffel, 255, " %8.2f %8.2f %8.2f %8.2f %8.2f",
angles.monochromator_two_theta,
@ -1941,6 +2009,8 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
return addAuxReflection(self, pCon, pSics, argc, argv);
} else if (strcmp(argv[1], "makeubfromcell") == 0) {
return calcUBFromCell(self, pCon);
} else if (strcmp(argv[1], "maketestub") == 0) {
return calcTestUBWrap(self, pCon, argc, argv);
} else if (strcmp(argv[1], "calcang") == 0) {
return calcRefAngles(self, pCon, pSics, argc, argv);
} else if (strcmp(argv[1], "calcqe") == 0) {

View File

@ -32,6 +32,7 @@
tasReflection r1, r2;
int ubValid;
int silent;
int stopFixed; /* flag to stop multiple fixed messages in scans*/
char *updater;
}tasUB, *ptasUB;
@ -54,4 +55,5 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
int findReflection(int list, int idx, ptasReflection r);
int tasUpdate(SConnection *pCon, ptasUB self);
void setStopFixed(ptasUB self, int val);
#endif

View File

@ -202,22 +202,45 @@ static MATRIX uFromAngles(double om, double sgu, double sgl)
if (u == NULL) {
return NULL;
}
vectorSet(u, 0, -Cosd(sgl) * Cosd(om));
vectorSet(u, 1, Cosd(sgu) * Sind(om) - Sind(sgu) * Sind(sgl) * Cosd(om));
vectorSet(u, 0, Cosd(om) * Cosd(sgl));
vectorSet(u, 1, -Sind(om) * Cosd(sgu) + Cosd(om)* Sind(sgl)*Sind(sgu));
vectorSet(u, 2,
-Sind(sgu) * Sind(om) - Cosd(sgu) * Sind(sgl) * Cosd(om));
Sind(om) * Sind(sgu) + Cosd(om) * Sind(sgl) * Cosd(sgu));
return u;
}
/*---------------------------------------------------------------*/
MATRIX calcTasUVectorFromAngles(tasReflection r)
MATRIX calcTasUVectorFromAngles(tasReflection rr)
{
double theta, om;
double theta, om, ss;
MATRIX m;
tasReflection r;
r = rr;
if(r.angles.sample_two_theta < .0){
ss = -1.;
} else {
ss = 1.;
}
r.angles.sample_two_theta = ABS(r.angles.sample_two_theta);
theta = calcTheta(r.qe.ki, r.qe.kf, r.angles.sample_two_theta);
om = r.angles.a3 - theta;
return uFromAngles(om, r.angles.sgu, r.angles.sgl);
om = r.angles.a3 - ss*theta;
/*
This here may have to do with scattering sense.....
if (om < -180.){
om += 180;
}
*/
m = uFromAngles(om, r.angles.sgu, ss*r.angles.sgl);
/*
printf("Q = %f, %f, %f inwards Uv = %f %f %f, om = %f\n", r.qe.qh, r.qe.qk, r.qe.ql,
m[0][0], m[1][0],m[2][0], om);
*/
return m ;
}
/*-----------------------------------------------------------------------------*/
@ -316,19 +339,179 @@ MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2)
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];
}
}
*/
mat_free(u1);
mat_free(u2);
normalizeVector(planeNormal);
normalizeVector(planeNormal);
return planeNormal;
} else {
return NULL;
}
}
/*-------------------------------------------------------------------*/
MATRIX calcPlaneNormalQOld(MATRIX UB, tasReflection r1, tasReflection r2)
{
MATRIX u1 = NULL, u2 = NULL, planeNormal = NULL;
int i;
u1 = tasReflectionToQC(r1.qe, UB);
u2 = tasReflectionToQC(r2.qe,UB);
if (u1 != NULL && u2 != NULL) {
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];
}
}
*/
mat_free(u1);
mat_free(u2);
normalizeVector(planeNormal);
return planeNormal;
} else {
return NULL;
}
}
/*-------------------------------------------------------------------*/
MATRIX calcPlaneNormalQ(MATRIX UB, tasReflection r1, tasReflection r2)
{
MATRIX q1 = NULL, q2 = NULL, q3 = NULL, planeNormal = NULL;
int i;
q1 = makeVector();
q2 = makeVector();
q1[0][0] = r1.qe.qh;
q1[1][0] = r1.qe.qk;
q1[2][0] = r1.qe.ql;
q2[0][0] = r2.qe.qh;
q2[1][0] = r2.qe.qk;
q2[2][0] = r2.qe.ql;
q3 = vectorCrossProduct(q1,q2);
planeNormal = mat_mul(UB,q3);
normalizeVector(planeNormal);
if (planeNormal[2][0] < .0) {
for (i = 0; i < 3; i++) {
planeNormal[i][0] = -1. * planeNormal[i][0];
}
}
mat_free(q1);
mat_free(q2);
mat_free(q3);
planeNormal[0][0] *= -1.;
planeNormal[1][0] *= -1.;
return planeNormal;
}
/*--------------------------------------------------------------------*/
MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl)
{
MATRIX B, M, N, OM, UB;
int status;
/*
* create matrices
*/
B = mat_creat(3, 3, ZERO_MATRIX);
status = calculateBMatrix(cell, B);
if (status < 0) {
return NULL;
}
M = mat_creat(3, 3, ZERO_MATRIX);
N = mat_creat(3, 3, ZERO_MATRIX);
OM = mat_creat(3, 3, ZERO_MATRIX);
if(M == NULL || N == NULL || OM == NULL){
mat_free(B);
return NULL;
}
N[0][0] = 1.;
N[1][1] = Cosd(sgu);
N[1][2] = -Sind(sgu);
N[2][1] = Sind(sgu);
N[2][2] = Cosd(sgu);
M[0][0] = Cosd(sgl);
M[0][2] = Sind(sgl);
M[1][1] = 1.;
M[2][0] = -Sind(sgl);
M[2][2] = Cosd(sgl);
OM[0][0] = Cosd(om);
OM[0][1] = -Sind(om);
OM[1][0] = Sind(om);
OM[1][1] = Cosd(om);
OM[2][2] = 1.;
/*
Multiply....
*/
UB = mat_mul(OM,M);
UB = mat_mul(UB,N);
UB = mat_mul(UB,B);
mat_free(OM);
mat_free(N);
mat_free(M);
mat_free(B);
return UB;
}
/*--------------------------------------------------------------------*/
MATRIX calcTestNormal(double sgu, double sgl)
{
MATRIX M, N, Z, NORM;
int status;
M = mat_creat(3, 3, ZERO_MATRIX);
N = mat_creat(3, 3, ZERO_MATRIX);
Z = mat_creat(3, 1, ZERO_MATRIX);
if(M == NULL || N == NULL || Z == NULL){
return NULL;
}
N[0][0] = 1.;
N[1][1] = Cosd(sgu);
N[1][2] = -Sind(sgu);
N[2][1] = Sind(sgu);
N[2][2] = Cosd(sgu);
M[0][0] = Cosd(sgl);
M[0][2] = Sind(sgl);
M[1][1] = 1.;
M[2][0] = -Sind(sgl);
M[2][2] = Cosd(sgl);
Z[2][0] = 1.;
NORM = mat_inv(N);
NORM = mat_mul(NORM,mat_inv(M));
NORM = mat_mul(NORM,Z);
mat_free(N);
mat_free(M);
mat_free(Z);
return NORM;
}
/*--------------------------------------------------------------------*/
MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
@ -345,11 +528,18 @@ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
calculate the B matrix and the HT matrix
*/
B = mat_creat(3, 3, ZERO_MATRIX);
status = calculateBMatrix(cell, B);
if (status < 0) {
*errorCode = status;
return NULL;
}
/*
printf("B-matrix\n");
mat_dump(B);
printf("\n");
*/
h1 = tasReflectionToHC(r1.qe, B);
h2 = tasReflectionToHC(r2.qe, B);
if (h1 == NULL || h2 == NULL) {
@ -469,6 +659,19 @@ static MATRIX buildTVMatrix(MATRIX U1V, MATRIX U2V)
T[i][1] = U2V[i][0];
T[i][2] = T3V[i][0];
}
/*
printf("\n");
printf("U1V\n");
mat_dump(U1V);
printf("U2V\n");
mat_dump(U2V);
printf("U3V\n");
mat_dump(T3V);
printf("TV-matrix\n");
mat_dump(T);
printf("\n");
*/
killVector(T3V);
return T;
}
@ -487,8 +690,12 @@ static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal,
return NULL;
}
normalizeVector(U1V);
/*
printf("Q = %f, %f, %f outwards Uv = %f %f %f\n", qe.qh, qe.qk, qe.ql,
U1V[0][0], U1V[1][0],U1V[2][0]);
*/
U2V = vectorCrossProduct(planeNormal, U1V);
U2V = vectorCrossProduct(planeNormal, U1V);
if (U2V == NULL) {
killVector(U1V);
*errorCode = UBNOMEMORY;
@ -514,6 +721,12 @@ static MATRIX buildRMatrix(MATRIX UB, MATRIX planeNormal,
*errorCode = BADUBORQ;
}
/*
printf("TV after inversion\n");
mat_dump(TVINV);
printf("\n");
*/
killVector(U1V);
killVector(U2V);
mat_free(TV);
@ -544,7 +757,7 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset,
tasQEPosition qe, ptasAngles angles)
{
MATRIX R, QC;
double om, q, theta, cos2t;
double om, q, theta, cos2t, cossgl;
int errorCode = 1;
R = buildRMatrix(UB, planeNormal, qe, &errorCode);
@ -552,8 +765,10 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset,
return errorCode;
}
/* mat_dump(R); */
angles->sgl = Asind(-R[2][0]);
cossgl = sqrt(R[0][0]*R[0][0]+R[1][0]*R[1][0]);
angles->sgl = ss*Atan2d(-R[2][0],cossgl);
if (ABS(angles->sgl - 90.) < .5) {
mat_free(R);
return BADUBORQ;
@ -573,14 +788,18 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset,
R-matrix definition.
*/
om = Atan2d(R[1][0], R[0][0]);
angles->sgu = Atan2d(R[2][1], R[2][2]);
om = Atan2d(R[1][0]/cossgl, R[0][0]/cossgl);
angles->sgu = Atan2d(R[2][1]/cossgl, R[2][2]/cossgl);
QC = tasReflectionToQC(qe, UB);
if (QC == NULL) {
mat_free(R);
return UBNOMEMORY;
}
/*
printf("Q = %f, %f, %f calculated om = %f\n", qe.qh, qe.qk, qe.ql, om);
*/
q = vectorLength(QC);
q = 2. * PI * vectorLength(QC);
@ -592,20 +811,23 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset,
killVector(QC);
return TRIANGLENOTCLOSED;
}
theta = calcTheta(qe.ki, qe.kf, Acosd(cos2t));
angles->sample_two_theta = ss * Acosd(cos2t);
theta = calcTheta(qe.ki, qe.kf, angles->sample_two_theta);
angles->a3 = om + theta + a3offset;
angles->a3 = om + ss*theta + a3offset;
/*
put a3 into -180, 180 properly. We can 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 - a3offset) {
angles->a3 += 360.;
}
*/
angles->a3 = fmod(angles->a3 + ss*180.,360.) - ss*180.;
killVector(QC);
mat_free(R);

View File

@ -154,6 +154,17 @@ MATRIX calcTasUVectorFromAngles(tasReflection r);
* @return a negative error code on failure, 1 on success
*/
int calcTwoTheta(MATRIX B, tasQEPosition ref, int ss, double *twoTheta);
/**
* calculate a UB from the cell and values for the displacement of
* the crystal in om, sgu and sgl. This is for software testing.
* @param cell The lattice constant of the crystal
* @param om A theoretical omega
* @param sgu A theoreticl sgu
* @param sgl A theoretical sgl
* @return a UB matix on sucess, or NULL on failure. Failure means out of memory
* or an invalid cell.
*/
MATRIX calcTheoreticalTasUB(lattice cell, double om, double sgu, double sgl);
/**
* calculate a UB from two reflections and the cell.
* @param cell The lattice constant of the crystal
@ -166,6 +177,24 @@ int calcTwoTheta(MATRIX B, tasQEPosition ref, int ss, double *twoTheta);
*/
MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
tasReflection r2, int *errorCode);
/**
* calculate a test plane normal
* @param sgu A theoretical plane tilt on upper
* @param sgl A theoretical plane tilt on lower
* @return a normal on sucess, or NULL on failure. This can only happen
* when out of memory
*/
MATRIX calcTestNormal(double sgu, double sgl);
/**
* calculate a test UB
* @param cell The lattice constant of the crystal
* @param om A theoretical om for the crystal
* @param sgu A theoretical plane tilt on upper
* @param sgl A theoretical plane tilt on lower
* @return a UB matix on sucess, or NULL on failure. This can only happen
* when out of memory or with a bad cell
*/
MATRIX calcTestUB(lattice cell, double om, double sgu, double sgl);
/**
* calcluate the normal to the plane describe by the two reflections r1, r2
* @param r1 first reflection
@ -173,6 +202,16 @@ MATRIX calcTasUBFromTwoReflections(lattice cell, tasReflection r1,
* @return a plane normal on success, NULL else
*/
MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2);
/**
* calcluate the normal to the plane describe by the two reflections r1, r2
* This uses a different path in that it calculates the Qv from the UB and
* the Q values.
* @param UB The UB to use
* @param r1 first reflection
* @param r2 second reflection
* @return a plane normal on success, NULL else
*/
MATRIX calcPlaneNormalQ(MATRIX UB, tasReflection r1, tasReflection r2);
/**
* calculate the angles for r. R's h, k, l, ki, kf must be set, the angles
* will be updated.

View File

@ -123,17 +123,14 @@ MATRIX vectorCrossProduct(MATRIX v1, MATRIX v2)
return NULL;
}
vectorSet(result, 0,
vectorGet(v1, 1) * vectorGet(v2, 2) - vectorGet(v1,
2) *
vectorGet(v2, 1));
vectorGet(v1, 1) * vectorGet(v2, 2)
- vectorGet(v1,2) * vectorGet(v2, 1));
vectorSet(result, 1,
vectorGet(v1, 2) * vectorGet(v2, 0) - vectorGet(v1,
0) *
vectorGet(v2, 2));
vectorGet(v1, 2) * vectorGet(v2, 0)
- vectorGet(v1,0) * vectorGet(v2, 2));
vectorSet(result, 2,
vectorGet(v1, 0) * vectorGet(v2, 1) - vectorGet(v1,
1) *
vectorGet(v2, 0));
vectorGet(v1, 0) * vectorGet(v2, 1)
- vectorGet(v1, 1) * vectorGet(v2, 0));
return result;
}