From 4f560552c4ad1d19ca8d1acc4b9c34f55fa6da9b Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 29 Oct 2012 12:56:29 +0000 Subject: [PATCH] - 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 --- commandlog.c | 5 +- confvirtualmot.c | 8 ++ conman.c | 3 +- drive.c | 8 +- dynstring.c | 6 ++ dynstring.h | 5 + exeman.c | 11 ++- fitcenter.c | 31 +++--- hipadaba.c | 6 ++ histmem.c | 37 +++---- motor.c | 1 + motorlist.c | 2 +- motorsec.c | 3 + reflist.c | 11 ++- scan.c | 24 +++-- scriptcontext.c | 4 +- sicsobj.c | 61 +++++++++++- sicspoll.c | 13 ++- singletas.c | 4 +- statusfile.c | 14 +-- tasdrive.c | 74 +++++++------- tasscanub.c | 11 ++- tasub.c | 78 ++++++++++++++- tasub.h | 2 + tasublib.c | 252 ++++++++++++++++++++++++++++++++++++++++++++--- tasublib.h | 39 ++++++++ vector.c | 15 ++- 27 files changed, 599 insertions(+), 129 deletions(-) diff --git a/commandlog.c b/commandlog.c index 0f64f16d..e6439ec7 100644 --- a/commandlog.c +++ b/commandlog.c @@ -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); + } } /*------------------------------------------------------------------------*/ diff --git a/confvirtualmot.c b/confvirtualmot.c index c8216e12..c930f23f 100644 --- a/confvirtualmot.c +++ b/confvirtualmot.c @@ -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; diff --git a/conman.c b/conman.c index 5f81e203..99969576 100644 --- a/conman.c +++ b/conman.c @@ -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); diff --git a/drive.c b/drive.c index 27a575be..ef076664 100644 --- a/drive.c +++ b/drive.c @@ -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); diff --git a/dynstring.c b/dynstring.c index 456ad7fe..83977115 100644 --- a/dynstring.c +++ b/dynstring.c @@ -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) diff --git a/dynstring.h b/dynstring.h index dfed7425..be9d90be 100644 --- a/dynstring.h +++ b/dynstring.h @@ -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); /* diff --git a/exeman.c b/exeman.c index d470a98c..d5920ac2 100644 --- a/exeman.c +++ b/exeman.c @@ -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; } diff --git a/fitcenter.c b/fitcenter.c index d8c2ae3c..0e4aa9ae 100644 --- a/fitcenter.c +++ b/fitcenter.c @@ -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; } diff --git a/hipadaba.c b/hipadaba.c index ea862a6b..b0bf067d 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -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; diff --git a/histmem.c b/histmem.c index e026ecb1..aae6d9e3 100644 --- a/histmem.c +++ b/histmem.c @@ -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); } /*--------------------------------------------------------------------------*/ diff --git a/motor.c b/motor.c index 179af765..67ddd2af 100644 --- a/motor.c +++ b/motor.c @@ -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 */ diff --git a/motorlist.c b/motorlist.c index 6b13531e..f5433864 100644 --- a/motorlist.c +++ b/motorlist.c @@ -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. */ diff --git a/motorsec.c b/motorsec.c index b77643de..e0822c3b 100644 --- a/motorsec.c +++ b/motorsec.c @@ -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++; diff --git a/reflist.c b/reflist.c index 3a5426b1..dd2e81bd 100644 --- a/reflist.c +++ b/reflist.c @@ -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; } /*----------------------------------------------------------------------*/ diff --git a/scan.c b/scan.c index 0333aa48..07eb4a3a 100644 --- a/scan.c +++ b/scan.c @@ -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); diff --git a/scriptcontext.c b/scriptcontext.c index f3a7b62d..dc22c30d 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -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; } } diff --git a/sicsobj.c b/sicsobj.c index d2d300ed..07e3a24a 100644 --- a/sicsobj.c +++ b/sicsobj.c @@ -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; diff --git a/sicspoll.c b/sicspoll.c index 493fb405..462cf5e5 100644 --- a/sicspoll.c +++ b/sicspoll.c @@ -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) { diff --git a/singletas.c b/singletas.c index 7c20613c..b48ce0a4 100644 --- a/singletas.c +++ b/singletas.c @@ -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, diff --git a/statusfile.c b/statusfile.c index ddcc0884..1235a291 100644 --- a/statusfile.c +++ b/statusfile.c @@ -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; } diff --git a/tasdrive.c b/tasdrive.c index 87c14a53..0d5cdd54 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -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; } diff --git a/tasscanub.c b/tasscanub.c index ba2cfb40..5e6cb5de 100644 --- a/tasscanub.c +++ b/tasscanub.c @@ -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++) { diff --git a/tasub.c b/tasub.c index fae652d8..0d046f83 100644 --- a/tasub.c +++ b/tasub.c @@ -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) { diff --git a/tasub.h b/tasub.h index 0dead93c..a60af51f 100644 --- a/tasub.h +++ b/tasub.h @@ -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 diff --git a/tasublib.c b/tasublib.c index cd7f2cff..4b38bfee 100644 --- a/tasublib.c +++ b/tasublib.c @@ -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); diff --git a/tasublib.h b/tasublib.h index f94e6f2c..15ef992f 100644 --- a/tasublib.h +++ b/tasublib.h @@ -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. diff --git a/vector.c b/vector.c index a24e53bf..a508ff9e 100644 --- a/vector.c +++ b/vector.c @@ -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; }