diff --git a/conman.c b/conman.c index d5ba423a..9ff958c5 100644 --- a/conman.c +++ b/conman.c @@ -387,7 +387,7 @@ void SCDeleteConnection(void *pData) } /* remove possible buffers */ - if (pVictim->data != NULL) { + if (pVictim->data != NULL && pVictim->dataOwner == 1) { DeleteDynString(pVictim->data); } @@ -427,6 +427,7 @@ SConnection *SCCopyConnection(SConnection * pCon) result->contextStack = -1; result->iList = -1; result->runLevel = pCon->runLevel; + result->data = pCon->data; return result; } @@ -869,7 +870,7 @@ int SCStartBuffering(SConnection * pCon) if (!VerifyConnection(pCon)) { return 0; } - if (pCon->data != NULL) { + if (pCon->data != NULL && pCon->dataOwner == 1) { DeleteDynString(pCon->data); } pCon->data = CreateDynString(128, 128); @@ -878,6 +879,7 @@ int SCStartBuffering(SConnection * pCon) } pCon->oldWriteFunc = pCon->write; pCon->write = SCBufferWrite; + pCon->dataOwner = 1; return 1; } diff --git a/conman.h b/conman.h index b0f7b49b..b2c96bd2 100644 --- a/conman.h +++ b/conman.h @@ -47,6 +47,7 @@ typedef struct __SConnection { writeFunc write; /* function doing writing */ int sicsError; /* Tcl interpreter requirement */ pDynString data; /* for I/O buffering */ + int dataOwner; /* marking a connection owning an I/O buffer */ writeFunc oldWriteFunc; /* saved write function used in I/O buffering */ long iCmdCtr; /* sycamore protocol used */ int conEventType; /* sycamore protocol support */ diff --git a/counter.h b/counter.h index 6c2aee8c..0b320c7c 100644 --- a/counter.h +++ b/counter.h @@ -43,6 +43,7 @@ typedef struct __Counter{ /*----------------------------- birth & death -----------------------------*/ +pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length); pCounter CreateCounter(char *name, pCounterDriver pDriv); void DeleteCounter(void *self); int MakeCounter(SConnection * pCon, SicsInterp * pSics, void *pData, diff --git a/countersec.c b/countersec.c index 8967e91b..a8e08d7b 100644 --- a/countersec.c +++ b/countersec.c @@ -27,7 +27,7 @@ typedef struct { char *pName; } MonEvent, *pMonEvent; /*---------------------------------------------------------------------------*/ -static int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code) +int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code) { pHdb node = NULL; hdbValue v; @@ -149,7 +149,7 @@ static int SecCtrCheckStatus(void *pData, SConnection *pCon) * check for overrun timers */ if(self->getMode(self) == eTimer && - time(NULL) > self->tStart + self->getPreset(self) && self->haltFixFlag == 0){ + time(NULL) > (self->tStart + (int)self->getPreset(self)) && self->haltFixFlag == 0){ SecCtrHalt(self); self->haltFixFlag = 1; } @@ -397,27 +397,18 @@ static int ContinueCmd(pSICSOBJ ccmd, SConnection * con, return self->pCountInt->Continue(self,con); } /*--------------------------------------------------------------------------*/ -int MakeSecCter(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]) +pCounter CreateSecCounter(SConnection *pCon, char *type, char *name, int length) { pCounter pRes = NULL; - int status, length; - pHdb node, child; - - if(argc < 3) { - SCWrite(pCon,"ERROR: need at least a name and length to create a counter", - eError); - return 0; - } - length = atoi(argv[2]); + pHdb node = NULL, child = NULL; pRes = (pCounter) malloc(sizeof(Counter)); if (!pRes) { SCWrite(pCon,"ERROR: out of memory in MakeSecCter", eError); - return 0; + return NULL; } memset(pRes,0,sizeof(Counter)); - pRes->pDes = CreateDescriptor("SingleCounter"); + pRes->pDes = CreateDescriptor(type); if (!pRes->pDes) { SCWrite(pCon,"ERROR: out of memory in MakeSecCter", eError); return 0; @@ -456,49 +447,48 @@ int MakeSecCter(SConnection * pCon, SicsInterp * pSics, void *pData, pRes->isUpToDate = 1; pRes->iExponent = 0; - pRes->name = strdup(argv[1]); - + pRes->name = strdup(name); - node = MakeHipadabaNode(argv[1],HIPNONE, 0); + node = MakeHipadabaNode(name,HIPNONE, 0); pRes->pDes->parNode = node; pRes->objectNode = node; child = MakeSICSHdbPar("time", usInternal, MakeHdbFloat(.0)); if (child == NULL) { - return 0; + return NULL; } AddHipadabaChild(node, child, NULL); child = MakeSICSHdbPar("preset", usUser, MakeHdbFloat(.0)); if (child == NULL) { - return 0; + return NULL; } SetHdbProperty(child, "__save", "true"); AddHipadabaChild(node, child, NULL); child = MakeSICSHdbPar("mode", usUser, MakeHdbText("monitor")); if (child == NULL) { - return 0; + return NULL; } SetHdbProperty(child, "__save", "true"); AddHipadabaChild(node, child, NULL); child = MakeSICSHdbPar("status", usInternal, MakeHdbText("idle")); if (child == NULL) { - return 0; + return NULL; } AddHipadabaChild(node, child, NULL); child = MakeSICSHdbPar("control", usUser, MakeHdbFloat(.0)); if (child == NULL) { - return 0; + return NULL; } AddHipadabaChild(node, child, NULL); child = MakeSICSHdbPar("values", usInternal, makeHdbValue(HIPINTAR, length)); if (child == NULL) { - return 0; + return NULL; } AddHipadabaChild(node, child, NULL); @@ -511,6 +501,28 @@ int MakeSecCter(SConnection * pCon, SicsInterp * pSics, void *pData, child = AddSICSHdbPar(node,"stop", usUser, MakeSICSFunc(StopCmd)); child = AddSICSHdbPar(node,"pause", usUser, MakeSICSFunc(PauseCmd)); child = AddSICSHdbPar(node,"continue", usUser, MakeSICSFunc(ContinueCmd)); + + return pRes; +} +/*--------------------------------------------------------------------------*/ +int MakeSecCter(SConnection * pCon, SicsInterp * pSics, void *pData, + int argc, char *argv[]) +{ + pCounter pRes = NULL; + int status, length; + pHdb node, child; + + if(argc < 3) { + SCWrite(pCon,"ERROR: need at least a name and length to create a counter", + eError); + return 0; + } + length = atoi(argv[2]); + + pRes = CreateSecCounter(pCon,"SingleCounter", argv[1], length); + if(pRes == NULL){ + return 0; + } status = AddCommand(pSics, argv[1], InterInvokeSICSOBJ, DeleteCounter, diff --git a/devexec.c b/devexec.c index eef71286..23a41f06 100644 --- a/devexec.c +++ b/devexec.c @@ -1087,9 +1087,9 @@ int Success(SConnection * pCon, SicsInterp * pSics, void *pData, if (iRet == DEVINT) { if (SCGetInterrupt(pCon) == eAbortOperation) { SCSetInterrupt(pCon, eContinue); - iRet = 0; - } else { iRet = 1; + } else { + iRet = 0; } } else if (iRet == DEVDONE) { SCWrite(pCon, "All done", eValue); diff --git a/diffscan.c b/diffscan.c index b9b24f8b..4fe97de2 100644 --- a/diffscan.c +++ b/diffscan.c @@ -303,6 +303,7 @@ static int DiffScanTask(void *pData) status = GetDrivablePosition(pVar->pObject, self->scanObject->pCon, &fPos); if (status == 0) { + ReleaseCountLock(pCount->pCountInt); return finish; } AppendScanVar(pVar, fPos); @@ -354,6 +355,10 @@ static int DiffScanTask(void *pData) finish = 0; } + if(finish == 0) { + ReleaseCountLock(pCount->pCountInt); + } + return finish; } diff --git a/fourmess.c b/fourmess.c index 68d13076..778a7cfb 100644 --- a/fourmess.c +++ b/fourmess.c @@ -167,7 +167,7 @@ static int FourMessStart(pSICSOBJ self, SConnection * pCon, /* open the reflection file */ sprintf(pBueffel, "Writing to %s.ccl, .rfl", pRoot); - SCWrite(pCon, pBueffel, eValue); + SCWrite(pCon, pBueffel, eLog); strcpy(pFilename, pRoot); strcat(pFilename, "ccl"); priv->profFile = fopen(pFilename, "w"); @@ -230,6 +230,41 @@ static int FourMessStart(pSICSOBJ self, SConnection * pCon, priv->count = 0; return 1; } +/*-----------------------------------------------------------------------------*/ +static int FourMessReopen(pSICSOBJ self, SConnection * pCon, + pHdb commandNode, pHdb par[], int nPar) +{ + pFourMess priv = NULL; + char pFilename[1024]; + + priv = self->pPrivate; + if(priv->hklFile != NULL){ + return 1; /* still open! */ + } + + if(priv->currentFileRoot == NULL){ + SCWrite(pCon,"ERROR: nothing to append too", eLogError); + return 0; + } + + strcpy(pFilename, priv->currentFileRoot); + strcat(pFilename, "ccl"); + priv->profFile = fopen(pFilename, "a"); + if(priv->profFile == NULL){ + SCPrintf(pCon,eLogError,"ERROR: failed to reopen %s", pFilename); + return 0; + } + strcpy(pFilename, priv->currentFileRoot); + strcat(pFilename, "rfl"); + priv->hklFile = fopen(pFilename, "a"); + if(priv->hklFile == NULL){ + SCPrintf(pCon,eLogError,"ERROR: failed to reopen %s", pFilename); + return 0; + } + SCPrintf(pCon,eValue,"Reopened %s.ccl,.rfl", priv->currentFileRoot); + + return 1; +} /*----------------------------------------------------------------------------*/ static int FourMessScanPar(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) @@ -351,7 +386,7 @@ static double getProtonAverage(pFourMess self) /*---------------------------------------------------------------------------*/ static int FourMessStoreIntern(pSICSOBJ self, SConnection * pCon, - double fHkl[3], double fPosition[4]) + double fHkl[3], double fPosition[4], char *extra) { pFourMess priv = self->pPrivate; float fSum, fSigma, fTemp, fStep, fPreset; @@ -453,8 +488,13 @@ static int FourMessStoreIntern(pSICSOBJ self, SConnection * pCon, GetScanVarStep(priv->pScanner, 0, &fStep); fPreset = GetScanPreset(priv->pScanner); prot = getProtonAverage(priv); - fprintf(priv->profFile, "%3d %7.4f %9.0f %7.3f %12f %s\n", iNP, fStep, - fPreset, fTemp, prot, pBueffel); + if(extra == NULL){ + fprintf(priv->profFile, "%3d %7.4f %9.0f %7.3f %12f %s\n", iNP, fStep, + fPreset, fTemp, prot, pBueffel); + } else { + fprintf(priv->profFile, "%3d %7.4f %9.0f %7.3f %12f %s %s\n", iNP, fStep, + fPreset, fTemp, prot, extra, pBueffel); + } for (i = 0; i < iNP; i++) { for (ii = 0; ii < 10 && i < iNP; ii++) { fprintf(priv->profFile, " %7ld", lCounts[i]); @@ -518,7 +558,32 @@ static int FourMessStore(pSICSOBJ self, SConnection * pCon, fPosition[i] = par[i + 3]->value.v.doubleValue; } - return FourMessStoreIntern(self, pCon, fHkl, fPosition); + return FourMessStoreIntern(self, pCon, fHkl, fPosition, NULL); +} + +/*----------------------------------------------------------------------------*/ +static int FourMessStoreExtra(pSICSOBJ self, SConnection * pCon, + pHdb commandNode, pHdb par[], int nPar) +{ + double fHkl[3], fPosition[4]; + int i; + + if (nPar < 8) { + SCWrite(pCon, "ERROR: not enough arguments for storeextra", eError); + return 0; + } + + /* load hkl */ + for (i = 0; i < 3; i++) { + fHkl[i] = par[i]->value.v.doubleValue; + } + + /* load positions */ + for (i = 0; i < 4; i++) { + fPosition[i] = par[i + 3]->value.v.doubleValue; + } + + return FourMessStoreIntern(self, pCon, fHkl, fPosition, par[7]->value.v.text); } /*------------------------------------------------------------------*/ @@ -619,18 +684,21 @@ static int GenIndex(pSICSOBJ self, SConnection * pCon, pHdb commandNode, H = mat_creat(3, 1, ZERO_MATRIX); - for (h = hkllim.v.intArray[0]; h < hkllim.v.intArray[3]; h++) { - for (k = hkllim.v.intArray[1]; k < hkllim.v.intArray[4]; k++) { - for (l = hkllim.v.intArray[2]; l < hkllim.v.intArray[5]; l++) { + for (h = hkllim.v.intArray[0]; h <= hkllim.v.intArray[3]; h++) { + for (k = hkllim.v.intArray[1]; k <= hkllim.v.intArray[4]; k++) { + for (l = hkllim.v.intArray[2]; l <= hkllim.v.intArray[5]; l++) { + /* SCPrintf(pCon,eLog, "Testing %d, %d, %d", h,k,l); */ /* first test: extinct */ if (IsSysAbsent_hkl(sginfo, h, k, l, NULL) != 0) { + /* SCPrintf(pCon,eLog, "%d, %d, %d rejected for sys absent", h, k, l); */ continue; - } + } /* second test: a symmetrically equivalent already seen */ if ((suppress != 0) && IsSuppressed_hkl(sginfo, minh, mink, minl, hkllim.v.intArray[1], hkllim.v.intArray[2], h, k, l) != 0) { + /* SCPrintf(pCon,eLog, "%d, %d, %d rejected for symmetrical eqiv", h, k, l); */ continue; } /* third test: within stt limits */ @@ -647,7 +715,7 @@ static int GenIndex(pSICSOBJ self, SConnection * pCon, pHdb commandNode, hkl[2] = (double) l; AddRefIdx(priv->messList, hkl); count++; - } + } } } } @@ -827,6 +895,9 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics) cmd = AddSICSHdbPar(pNew->objectNode, "close", usUser, MakeSICSFunc(FourMessClose)); + cmd = + AddSICSHdbPar(pNew->objectNode, "reopen", usUser, + MakeSICSFunc(FourMessReopen)); cmd = AddSICSHdbPar(pNew->objectNode, "prepare", usUser, @@ -847,6 +918,19 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics) AddSICSHdbPar(cmd, "om", usUser, MakeHdbFloat(.0)); AddSICSHdbPar(cmd, "chi", usUser, MakeHdbFloat(.0)); AddSICSHdbPar(cmd, "phi", usUser, MakeHdbFloat(.0)); + + cmd = + AddSICSHdbPar(pNew->objectNode, "storeextra", usUser, + MakeSICSFunc(FourMessStoreExtra)); + AddSICSHdbPar(cmd, "h", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "k", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "l", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "stt", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "om", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "chi", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "phi", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "extra", usUser, MakeHdbText("")); + cmd = AddSICSHdbPar(pNew->objectNode, "weak", usUser, MakeSICSFunc(FourMessWeak)); diff --git a/hdbtable.c b/hdbtable.c index bd33bfc5..fb04c84e 100644 --- a/hdbtable.c +++ b/hdbtable.c @@ -31,6 +31,7 @@ int SaveHdbTable(void *data, char *name, FILE * fd) datanode = GetHipadabaNode(self->objectNode,"data"); assert(datanode != NULL); row = datanode->child; + fprintf(fd,"%s clear\n", name); while(row != NULL){ fprintf(fd,"%s addrow ", name); child = row->child; diff --git a/hipadaba.h b/hipadaba.h index 9db6792e..d7047576 100644 --- a/hipadaba.h +++ b/hipadaba.h @@ -367,7 +367,7 @@ int InvokeCallbackChain(pHdb node, pHdbMessage message); void DeleteCallbackChain(pHdb node); /** * apply message to the node and all its children - * @param node Th node where to start recursing + * @param node The node where to start recursing * @param message The message to send */ void RecurseCallbackChains(pHdb node, pHdbMessage message); diff --git a/histmem.c b/histmem.c index b2a6a628..ed715f9e 100644 --- a/histmem.c +++ b/histmem.c @@ -175,7 +175,7 @@ static int HistStartCount(void *pData, SConnection * pCon) } if (!self->iInit) { - SCWrite(pCon, "ERROR: histogram memory not initialised", eError); + SCWrite(pCon, "ERROR: histogram memory not initialised", eLogError); return 0; } @@ -190,11 +190,11 @@ static int HistStartCount(void *pData, SConnection * pCon) } else { iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79); sprintf(pBueffel, "WARNING: %s ", pError); - SCWrite(pCon, pBueffel, eError); + SCWrite(pCon, pBueffel, eLogError); iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr); if (iRet == COTERM) { SCWrite(pCon, "ERROR: failed to fix histogram memory problem", - eError); + eLogError); SCSetInterrupt(pCon, eAbortBatch); ReleaseCountLock(self->pCountInt); return HWFault; diff --git a/histmemsec.c b/histmemsec.c new file mode 100644 index 00000000..d76f5bff --- /dev/null +++ b/histmemsec.c @@ -0,0 +1,235 @@ +/** + * This is a second generation histogram memory object. In contrast + * to counters and motors no attempt is made to provide backwards + * compatability with the old SICS way of doing things. This + * histogram memory object quite sensibly is derived from + * the counter object. It adds a rank, dimensions and variable + * data and a configuration method. For TOF, methods and variables + * for generating and maintaining time binnings are provided too. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, May 2009 + */ +#include +#include +#include + +#define CONFIG 1005 + +/* from countersec.c. */ +int SecCtrInvokeFunction(pCounter self, SConnection *pCon, int code); + +/*-------------------------------------------------------------------------*/ +static int initArray(pCounter self, int value) +{ + pHdb rank = NULL, dim = NULL, data = NULL, datalength; + int i, length; + hdbValue v; + + rank = GetHipadabaNode(self->pDes->parNode,"rank"); + assert(rank != NULL); + dim = GetHipadabaNode(self->pDes->parNode,"dim"); + assert(dim != NULL); + data = GetHipadabaNode(self->pDes->parNode,"data"); + assert(data != NULL); + datalength = GetHipadabaNode(self->pDes->parNode,"datalength"); + assert(datalength != NULL); + + length = dim->value.v.intArray[0]; + for(i = 1; i < rank->value.v.intValue; i++){ + length *= dim->value.v.intArray[i]; + } + v = MakeHdbInt(length); + UpdateHipadabaPar(datalength, v, NULL); + + v = makeHdbValue(HIPINTVARAR, length); + if(v.v.intArray == NULL){ + return 0; + } + for(i = 0; i < length; i++){ + v.v.intArray[i] = value; + } + UpdateHipadabaPar(data,v,NULL); + ReleaseHdbValue(&v); + return 1; +} +/*-------------------------------------------------------------------------*/ +static hdbCallbackReturn HMDimCallback(pHdb currentNode, void *data, + pHdbMessage message) +{ + pHdbDataMessage update = NULL; + + if((update = GetHdbUpdateMessage(message)) != NULL){ + copyHdbValue(update->v, ¤tNode->value); + initArray((pCounter)data, 0); + } + return hdbContinue; +} +/*--------------------------------------------------------------------------*/ +static int ResetCmd(pSICSOBJ ccmd, SConnection * pCon, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + if(nPar < 1){ + SCWrite(pCon, "ERROR: need a parameter to set", eError); + return 0; + } + + if(!initArray((pCounter) ccmd, par[0]->value.v.intValue )){ + SCWrite(pCon,"ERROR: out of memory initializing HM", eError); + return 0; + } + return 1; +} +/*--------------------------------------------------------------------------*/ +static int GenbinCmd(pSICSOBJ ccmd, SConnection * pCon, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + double start, step; + int np, i; + pHdb tof = NULL, dim = NULL; + hdbValue v; + + if(nPar < 3){ + SCWrite(pCon, "ERROR: need start step n parameters to gengin", + eError); + return 0; + } + + start = par[0]->value.v.doubleValue; + step = par[1]->value.v.doubleValue; + np = par[2]->value.v.intValue; + + tof = GetHipadabaNode(ccmd->pDes->parNode,"time_binning"); + assert(tof != NULL); + + dim = GetHipadabaNode(ccmd->pDes->parNode,"dim"); + assert(dim != NULL); + + v = makeHdbValue(HIPFLOATVARAR,np ); + if(v.v.floatArray == NULL){ + SCWrite(pCon,"ERROR: out of memory in genbin", eError); + return 0; + } + for(i = 0; i < np; i++){ + v.v.floatArray[i] = start + i*step; + } + UpdateHipadabaPar(tof,v,pCon); + ReleaseHdbValue(&v); + + GetHipadabaPar(dim,&v, pCon); + v.v.intArray[v.arrayLength-1] = np; + UpdateHipadabaPar(dim,v,pCon); + + return 1; +} +/*--------------------------------------------------------------------------*/ +static int InitCmd(pSICSOBJ ccmd, SConnection * con, + Hdb * cmdNode, Hdb * par[], int nPar) +{ + return SecCtrInvokeFunction((pCounter)ccmd,con,CONFIG); +} +/*--------------------------------------------------------------------------*/ +static int HMCtrTransferData(void *pData, SConnection *pCon) +{ + pCounter self = (pCounter)pData; + assert(self != NULL); + pHdb node = NULL; + hdbValue v; + int status; + + node = GetHipadabaNode(self->pDes->parNode,"data"); + assert(node != NULL); + self->isUpToDate = 1; + status = GetHipadabaPar(node,&v,pCon); + ReleaseHdbValue(&v); + return status; +} +/*-------------------------------------------------------------------------- + * Usage: + * MakeSecHM name rank (tof) + * -------------------------------------------------------------------------*/ +int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData, + int argc, char *argv[]) +{ + pCounter pRes = NULL; + int rank, status; + pHdb node = NULL, child = NULL; + + if(argc < 3) { + SCWrite(pCon,"ERROR: need at least a name and rank to create a HM", + eError); + return 0; + } + + rank = atoi(argv[2]); + + pRes = CreateSecCounter(pCon,"HistMem", argv[1], 2); + if(pRes == NULL){ + return 0; + } + pRes->pCountInt->TransferData = HMCtrTransferData; + + node = pRes->objectNode; + child = GetHipadabaNode(node,"values"); + if(child!= NULL){ + DeleteHipadabaNode(child,pCon); + } + + child = MakeSICSHdbPar("rank", usInternal, MakeHdbInt(rank)); + if (child == NULL) { + return 0; + } + AddHipadabaChild(node, child, NULL); + + child = MakeSICSHdbPar("dim", usMugger, makeHdbValue(HIPINTAR,rank)); + if (child == NULL) { + return 0; + } + AppendHipadabaCallback(child, + MakeHipadabaCallback(HMDimCallback, pRes, NULL)); + AddHipadabaChild(node, child, NULL); + + child = MakeSICSHdbPar("datalength", usInternal, MakeHdbInt(100)); + if (child == NULL) { + return 0; + } + AddHipadabaChild(node, child, NULL); + + child = MakeSICSHdbPar("data", usMugger, makeHdbValue(HIPINTVARAR,100)); + if (child == NULL) { + return 0; + } + AddHipadabaChild(node, child, NULL); + + child = AddSICSHdbPar(node,"set", usMugger, MakeSICSFunc(ResetCmd)); + AddSICSHdbPar(child, "value", usUser, MakeHdbInt(0)); + + child = AddSICSHdbPar(node,"init", usMugger, MakeSICSFunc(InitCmd)); + + /* + * test TOF option + */ + if(argc > 3){ + if(strcmp(argv[3],"tof") == 0){ + child = MakeSICSHdbPar("time_binning", usMugger, makeHdbValue(HIPFLOATVARAR,100)); + if (child == NULL) { + return 0; + } + AddHipadabaChild(node, child, NULL); + child = AddSICSHdbPar(node,"genbin", usMugger, MakeSICSFunc(GenbinCmd)); + AddSICSHdbPar(child, "start", usMugger, MakeHdbFloat(10.)); + AddSICSHdbPar(child, "step", usMugger, MakeHdbFloat(10.)); + AddSICSHdbPar(child, "np", usMugger, MakeHdbInt(10)); + } + } + + status = + AddCommand(pSics, argv[1], InterInvokeSICSOBJ, DeleteCounter, + (void *) pRes); + if (status != 1) { + SCPrintf(pCon,eError, "ERROR: duplicate command %s not created", argv[1]); + return 0; + } + return 1; +} diff --git a/histmemsec.h b/histmemsec.h new file mode 100644 index 00000000..b0b244fe --- /dev/null +++ b/histmemsec.h @@ -0,0 +1,20 @@ +/** + * This is a second generation histogram memory object. In contrast + * to counters and motors no attempt is made to provide backwards + * compatability with the old SICS way of doing things. This + * histogram memory object quite sensibly is derived from + * the counter object. It adds a rank, dimensions and variable + * data and a configuration method. For TOF, methods and variables + * for generating and maintaining time binnings are provided too. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, May 2009 + */ +#ifndef HISTMEMSEC_H_ +#define HISTMEMSEC_H_ +#include +int MakeSecHM(SConnection * pCon, SicsInterp * pSics, void *pData, + int argc, char *argv[]); + +#endif /*HISTMEMSEC_H_*/ diff --git a/hkl.c b/hkl.c index 594e4ead..e5ccb46e 100644 --- a/hkl.c +++ b/hkl.c @@ -61,7 +61,77 @@ static int HKLSave(void *pData, char *name, FILE * fd) fprintf(fd, "%s scantolerance %f\n", name, self->scanTolerance); return 1; } +/*---------------------------------------------------------------------------*/ +static void *HKLInterface(void *pData, int iID) +{ + pHKL self = (pHKL)pData; + assert(self != NULL); + + if(iID == DRIVEID){ + return self->pMotDriv; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int HKLHalt(void *pData) +{ + pHKL self = (pHKL)pData; + pSingleDiff single = NULL; + assert(self != NULL); + single = SXGetDiffractometer(); + assert(single != NULL); + + return self->pMotList->Halt(&single->motList); +} +/*---------------------------------------------------------------------------*/ +static int HKLLimits(void *pData, float val, char *error, int errLen) +{ + pHKL self = (pHKL)pData; + pSingleDiff single = NULL; + assert(self != NULL); + + single = SXGetDiffractometer(); + assert(single != NULL); + + return self->pMotList->CheckLimits(&single->motList, val, error, errLen); +} +/*---------------------------------------------------------------------------*/ +static long HKLSet(void *pData, SConnection *pCon, float val) +{ + pHKL self = (pHKL)pData; + pSingleDiff single = NULL; + assert(self != NULL); + + single = SXGetDiffractometer(); + assert(single != NULL); + + return self->pMotList->SetValue(&single->motList, pCon,val); +} +/*---------------------------------------------------------------------------*/ +static int HKLCheck(void *pData, SConnection *pCon) +{ + pHKL self = (pHKL)pData; + pSingleDiff single = NULL; + assert(self != NULL); + + single = SXGetDiffractometer(); + assert(single != NULL); + + return self->pMotList->CheckStatus(&single->motList, pCon); +} +/*---------------------------------------------------------------------------*/ +static float HKLGet(void *pData, SConnection *pCon) +{ + pHKL self = (pHKL)pData; + pSingleDiff single = NULL; + assert(self != NULL); + + single = SXGetDiffractometer(); + assert(single != NULL); + + return self->pMotList->GetValue(&single->motList, pCon); +} /*---------------------------------------------------------------------------*/ pHKL CreateHKL() { @@ -76,13 +146,21 @@ pHKL CreateHKL() /* create object descriptor */ pNew->pDes = CreateDescriptor("4-Circle-Calculus"); - pNew->pMotDriv = makeMotListInterface(); - if (!pNew->pDes || pNew->pMotDriv == NULL) { + pNew->pMotList = makeMotListInterface(); + pNew->pMotDriv = CreateDrivableInterface(); + if (!pNew->pDes || pNew->pMotDriv == NULL || pNew->pMotDriv == NULL) { free(pNew); return NULL; } pNew->pDes->SaveStatus = HKLSave; - + pNew->pDes->GetInterface = HKLInterface; + + pNew->pMotDriv->Halt = HKLHalt; + pNew->pMotDriv->CheckLimits = HKLLimits; + pNew->pMotDriv->CheckStatus = HKLCheck; + pNew->pMotDriv->SetValue = HKLSet; + pNew->pMotDriv->GetValue = HKLGet; + pNew->iQuad = 1; pNew->iHM = 0; pNew->UBinv = NULL; @@ -364,7 +442,7 @@ void stopHKLMotors(pHKL self) single = SXGetDiffractometer(); assert(single != NULL); - self->pMotDriv->Halt(&single->motList); + self->pMotList->Halt(&single->motList); } /*------------------------------------------------------------------------*/ @@ -383,7 +461,8 @@ int startHKLMotors(pHKL self, SConnection * pCon, float fSet[4]) } single->settingsToList(single, dSet); - status = self->pMotDriv->SetValue(&single->motList, pCon, .1); +/* status = self->pMotDriv->SetValue(&single->motList, pCon, .1); */ + status = StartDevice(pServ->pExecutor, "HKL", self->pDes, self, pCon,RUNDRIVE, .1); return status; } @@ -679,7 +758,44 @@ static int HKLCalculateTheta(pHKL self, float fHKL[3], double *stt) *stt = 2. * theta; return status; } - +/*--------------------------------------------------------------------------*/ +static int HandleBiToNB(SConnection *pCon, int argc, char *argv[]) +{ + double stt, om, chi, phi, gamma, omnb, nu; + int status; + + if(argc < 6){ + SCWrite(pCon,"ERROR: missing arguments, usage: hkl bitonb stt om chi phi", eError); + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pServ->pSics),argv[2], &stt); + if(status != 0){ + SCPrintf(pCon,eError,"ERROR: failed to convert %s to double", argv[2]); + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pServ->pSics),argv[3], &om); + if(status != 0){ + SCPrintf(pCon,eError,"ERROR: failed to convert %s to double", argv[3]); + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pServ->pSics),argv[4], &chi); + if(status != 0){ + SCPrintf(pCon,eError,"ERROR: failed to convert %s to double", argv[4]); + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pServ->pSics),argv[5], &phi); + if(status != 0){ + SCPrintf(pCon,eError,"ERROR: failed to convert %s to double", argv[5]); + return 0; + } + status = bisToNormalBeam(stt,om,chi,phi,&omnb, &gamma, &nu); + if(status != 1){ + SCWrite(pCon,"ERROR: not in range for normal beam", eError); + return 0; + } + SCPrintf(pCon,eValue, "NB = %f,%f,%f", gamma, omnb, nu); + return 1; +} /*--------------------------------------------------------------------------*/ int HKLAction(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -970,6 +1086,10 @@ int HKLAction(SConnection * pCon, SicsInterp * pSics, void *pData, SCSendOK(pCon); return 1; } + } + /*------------------ bitonb */ + else if (strcmp(argv[1], "bitonb") == 0) { + return HandleBiToNB(pCon, argc, argv); } else { sprintf(pBueffel, "ERROR: subcommand --> %s <-- not recognized", argv[1]); diff --git a/hkl.h b/hkl.h index 7014f0af..5f8374eb 100644 --- a/hkl.h +++ b/hkl.h @@ -17,36 +17,36 @@ #include "selector.h" #include "selvar.h" -typedef struct __HKL *pHKL; + typedef struct __HKL *pHKL; /*-------------------------------------------------------------------------*/ -pHKL CreateHKL(); -void DeleteHKL(void *pData); - -int HKLFactory(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); + pHKL CreateHKL(); + void DeleteHKL(void *pData); + + int HKLFactory(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); /*------------------------------------------------------------------------*/ -void SetHKLScanTolerance(pHKL self, float value); -int SetUB(pHKL self, float fUB[9]); -int GetUB(pHKL self, float fUB[9]); -int SetNOR(pHKL self, int iNOB); -int GetLambda(pHKL self, float *fVal); -int GetCurrentHKL(pHKL self, float fVal[3]); -int GetCurrentPosition(pHKL self, SConnection * pCon, float fPosition[4]); -int GetHKLFromAngles(pHKL self, SConnection * pCon, float fVal[3]); + void SetHKLScanTolerance(pHKL self, float value); + int SetUB(pHKL self, float fUB[9]); + int GetUB(pHKL self, float fUB[9]); + int SetNOR(pHKL self, int iNOB); + int GetLambda(pHKL self, float *fVal); + int GetCurrentHKL(pHKL self, float fVal[3]); + int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]); + int GetHKLFromAngles(pHKL self, SConnection *pCon, float fVal[3]); -int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil, - float fSet[4], SConnection * pCon); -int RunHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, SConnection - * pCon); -int DriveHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, - SConnection * pCon); + int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil, + float fSet[4],SConnection *pCon); + int RunHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, SConnection + *pCon); + int DriveHKL(pHKL self, float fHKL[3], float fPsi, int iHamil, + SConnection *pCon); -int DriveSettings(pHKL self, float fSet[4], SConnection * pCon); + int DriveSettings(pHKL self, float fSet[4],SConnection *pCon); -int HKLAction(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); -int hklInRange(void *data, double fSet[4], int mask[4]); -int startHKLMotors(pHKL self, SConnection * pCon, float fSet[4]); -void stopHKLMotors(pHKL self); + int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); + int hklInRange(void *data, double fSet[4], int mask[4]); + int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]); + void stopHKLMotors(pHKL self); -#endif +#endif diff --git a/hkl.i b/hkl.i index d7f15383..5f499997 100644 --- a/hkl.i +++ b/hkl.i @@ -20,6 +20,7 @@ float targetHKL[3]; int targetDirty; pIDrivable pMotDriv; + pIDrivable pMotList; } HKL; diff --git a/hkl.tex b/hkl.tex index 20b3f38b..d05d14ea 100644 --- a/hkl.tex +++ b/hkl.tex @@ -31,6 +31,7 @@ $\langle$hkldat {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ float targetHKL[3];@\\ \mbox{}\verb@ int targetDirty;@\\ \mbox{}\verb@ pIDrivable pMotDriv;@\\ +\mbox{}\verb@ pIDrivable pMotList;@\\ \mbox{}\verb@ } HKL;@\\ \mbox{}\verb@@$\Diamond$ \end{list} @@ -103,7 +104,7 @@ $\langle$hklint {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@@\\ \mbox{}\verb@ int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\ \mbox{}\verb@ int argc, char *argv[]); @\\ -\mbox{}\verb@ int hklInRange(void *data, float fSet[4], int mask[4]);@\\ +\mbox{}\verb@ int hklInRange(void *data, double fSet[4], int mask[4]);@\\ \mbox{}\verb@ int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);@\\ \mbox{}\verb@ void stopHKLMotors(pHKL self);@\\ \mbox{}\verb@@$\Diamond$ diff --git a/hkl.w b/hkl.w index ae676544..98d3834b 100644 --- a/hkl.w +++ b/hkl.w @@ -26,6 +26,7 @@ The object uses the following object data structure: float targetHKL[3]; int targetDirty; pIDrivable pMotDriv; + pIDrivable pMotList; } HKL; @} @@ -86,7 +87,7 @@ module: int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); - int hklInRange(void *data, float fSet[4], int mask[4]); + int hklInRange(void *data, double fSet[4], int mask[4]); int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]); void stopHKLMotors(pHKL self); @} diff --git a/hklmot.h b/hklmot.h index df4494ca..d3aae155 100644 --- a/hklmot.h +++ b/hklmot.h @@ -11,17 +11,17 @@ #define SICSHKLMOT /*====================== data structure ==============================================================*/ -typedef struct __HKLMOT { - pObjectDescriptor pDes; - pHKL pHkl; - pIDrivable pDriv; - int index; -} HKLMot, *pHKLMot; +typedef struct __HKLMOT { + pObjectDescriptor pDes; + pHKL pHkl; + pIDrivable pDriv; + int index; + }HKLMot, *pHKLMot; /*======================= interpreter interface ======================================================*/ -int HKLMotAction(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); -int HKLMotInstall(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); +int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); +int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); #endif + + diff --git a/macro.c b/macro.c index df512bb1..3172133e 100644 --- a/macro.c +++ b/macro.c @@ -1082,6 +1082,11 @@ int CaptureAction(SConnection *pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, "EROOR: out of memory in capture", eError); return 0; } + /* + * This line is required to support nested captures + */ + comCon->data = NULL; + memset(buffer, 0, sizeof(buffer)); command = Arg2Tcl(argc - 1, &argv[1], buffer, sizeof buffer); if (!command) { diff --git a/make_gen b/make_gen index 32d9377d..b7a2193f 100644 --- a/make_gen +++ b/make_gen @@ -40,7 +40,8 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \ - rwpuffer.o asynnet.o background.o countersec.o hdbtable.o + rwpuffer.o asynnet.o background.o countersec.o hdbtable.o velosec.o \ + histmemsec.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/maximize.c b/maximize.c index 9c857bb8..381d84d7 100644 --- a/maximize.c +++ b/maximize.c @@ -166,7 +166,7 @@ start: } /* search to the left until out of space or lCts < lMax/2. */ - SCWrite(pCon, "Searching for low angle boundary..", eWarning); + SCWrite(pCon, "Searching for low angle boundary..", eLog); for (i = self->maxpts / 2; i >= 0; i--) { /* drive motor */ fPos = fStart - (self->maxpts / 2 - i) * fStep; @@ -181,7 +181,7 @@ start: } /* print a message */ sprintf(pBueffel, "%5d %8.2f %ld", i, x[i], lCts); - SCWrite(pCon, pBueffel, eWarning); + SCWrite(pCon, pBueffel, eLog); /* store counts and some logic */ if (lCts < 1) { @@ -229,7 +229,7 @@ start: if (iSkip == 0) { lMin = 100000; lMax = -100000; - SCWrite(pCon, "Searching for high angle boundary..", eWarning); + SCWrite(pCon, "Searching for high angle boundary..", eLog); for (i = self->maxpts / 2; i < self->maxpts; i++) { /* drive motor */ fPos = fStart + (i - self->maxpts / 2) * fStep; @@ -244,7 +244,7 @@ start: } /* print a message */ sprintf(pBueffel, "%5d %8.2f %ld", i, x[i], lCts); - SCWrite(pCon, pBueffel, eWarning); + SCWrite(pCon, pBueffel, eLog); /* store counts and some logic */ if (lCts < 1) { diff --git a/ofac.c b/ofac.c index 1dab74b6..69456f3d 100644 --- a/ofac.c +++ b/ofac.c @@ -131,6 +131,8 @@ #include "singlex.h" #include "motorsec.h" #include "background.h" +#include "velosec.h" +#include "histmemsec.h" /*----------------------- Server options creation -------------------------*/ static int IFServerOption(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -339,6 +341,8 @@ static void InitIniCommands(SicsInterp * pInter, pTaskMan pTask) AddCommand(pInter, "MakeRefList", MakeReflectionList, NULL, NULL); AddCommand(pInter, "MakeSingleX", MakeSingleX, NULL, NULL); AddCommand(pInter, "MakeSecMotor", SecMotorFactory, NULL, NULL); + AddCommand(pInter, "MakeSecNVS", MakeSecNVS, NULL, NULL); + AddCommand(pInter, "MakeSecHM", MakeSecHM, NULL, NULL); /* install site specific commands @@ -419,6 +423,8 @@ static void KillIniCommands(SicsInterp * pSics) RemoveCommand(pSics, "MakeRefList"); RemoveCommand(pSics, "MakeSingleX"); RemoveCommand(pSics, "MakeSecMotor"); + RemoveCommand(pSics, "MakeSecNVS"); + RemoveCommand(pSics, "MakeSecHM"); /* remove site specific installation commands */ diff --git a/reflist.c b/reflist.c index c3030a68..e9a0e241 100644 --- a/reflist.c +++ b/reflist.c @@ -652,7 +652,7 @@ int GetRefAngles(pSICSOBJ refl, int idx, double ang[]) /* skip hkl */ for(i = 0; i < 3; i++, child = child->next){} /* do angles */ - for(i = 0; i < 4; i++, child = child->next){ + for(i = 0; i < 4 && child != NULL; i++, child = child->next){ ang[i] = child->value.v.doubleValue; } return 1; diff --git a/scan.c b/scan.c index b754912f..f7624ec3 100644 --- a/scan.c +++ b/scan.c @@ -99,6 +99,18 @@ static void ConfigureScanDict(pStringDict dict) StringDictAddPair(dict, "userdata", "unknown"); StringDictAddPair(dict, "finish", "stdscan finish"); } +/*------------------------------------------------------------------------*/ +static void ResetScanDict(pStringDict dict) +{ + StringDictUpdate(dict, "writeheader", "stdscan writeheader"); + StringDictUpdate(dict, "prepare", "stdscan prepare"); + StringDictUpdate(dict, "drive", "stdscan drive"); + StringDictUpdate(dict, "count", "stdscan count"); + StringDictUpdate(dict, "collect", "stdscan collect"); + StringDictUpdate(dict, "writepoint", "stdscan writepoint"); + StringDictUpdate(dict, "userdata", "unknown"); + StringDictUpdate(dict, "finish", "stdscan finish"); +} /*--------------------------------------------------------------------------*/ pScanData CreateScanObject(char *pRecover, char *pHeader, pCounter pCount, @@ -1921,6 +1933,7 @@ int ScanWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, return 1; } else if (strcmp(argv[2], "script") == 0) { ConfigureScript(self); + ResetScanDict(self->scanFunctions); SCSendOK(pCon); return 1; } else { diff --git a/scriptcontext.c b/scriptcontext.c index bee87d6e..2bcffc12 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -849,7 +849,7 @@ static int SctUnpollCmd(pSICSOBJ ccmd, SConnection * con, if (nPar < 1) { SCPrintf(con, eError, - "ERROR: should be: %s poll ()", + "ERROR: should be: %s unpoll ()", ccmd->objectNode->name); return 0; } diff --git a/sicsdata.c b/sicsdata.c index b24b1223..209100a4 100644 --- a/sicsdata.c +++ b/sicsdata.c @@ -20,6 +20,8 @@ #include "scan.h" #include "HistMem.h" #include "sicsdata.h" +#include "sicshipadaba.h" + #define ABS(x) (x < 0 ? -(x) : (x)) /*--------------------------------------------------------------------*/ static void KillSICSData(void *pData) @@ -770,7 +772,163 @@ static int copyData(pSICSData self, SicsInterp * pSics, return 1; } +/*--------------------------------------------------------------------*/ +static int copyNode(pSICSData self, int argc, char *argv[], + SConnection * pCon, SicsInterp * pSics) +{ + int status, pos, length, *iData, i; + pHdb node = NULL; + if (argc < 2) { + SCWrite(pCon, "ERROR: not enough arguments to SICSData copynode", + eError); + return 0; + } + status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos); + if (status != TCL_OK) { + SCWrite(pCon, + "ERROR: failed to convert copynode position to integer", eError); + return 0; + } + + node = FindHdbNode(NULL,argv[1], pCon); + if(node == NULL){ + SCPrintf(pCon,eError,"ERROR: node %s not found", argv[1]); + return 0; + } + + if(argc < 2){ + status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &length); + if (status != TCL_OK) { + SCWrite(pCon, + "ERROR: failed to convert copynode length to integer", eError); + return 0; + } else { + length = node->value.arrayLength; + } + } + if(length < 1) { + length = 1; + } + if(length > node->value.arrayLength){ + length = node->value.arrayLength; + } + + iData = getSICSDataPointer(self, pos, pos + length); + if (!iData) { + SCWrite(pCon, "ERROR: out of memory in SICSData copynode", eError); + return 0; + } + + switch(node->value.dataType){ + case HIPINT: + setSICSDataInt(self,pos,node->value.v.intValue); + break; + case HIPFLOAT: + setSICSDataFloat(self,pos,(float)node->value.v.doubleValue); + break; + case HIPINTAR: + case HIPINTVARAR: + memcpy(iData+pos, node->value.v.intArray, length*sizeof(int)); + assignType(self, pos, pos + length, INTTYPE); + break; + case HIPFLOATAR: + case HIPFLOATVARAR: + for(i = 0; i < length; i++){ + setSICSDataFloat(self,pos+i, (float)node->value.v.floatArray[i]); + } + break; + default: + SCWrite(pCon,"ERROR: cannot copy non numeric data into a SICSData", eError); + return 0; + } + + SCSendOK(pCon); + return 1; +} +/*--------------------------------------------------------------------*/ +static int copyToNode(pSICSData self, int argc, char *argv[], + SConnection * pCon, SicsInterp * pSics) +{ + int status, start, length,i, j, ival; + float fval; + pHdb node = NULL; + + if (argc < 3) { + SCWrite(pCon, "ERROR: not enough arguments to SICSData copytonode", + eError); + return 0; + } + status = Tcl_GetInt(InterpGetTcl(pSics), argv[1], &start); + if (status != TCL_OK) { + SCWrite(pCon, + "ERROR: failed to convert copytonode start to integer", eError); + return 0; + } + status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &length); + if (status != TCL_OK) { + SCWrite(pCon, + "ERROR: failed to convert copytonode length to integer", eError); + return 0; + } + + node = FindHdbNode(NULL,argv[0], pCon); + if(node == NULL){ + SCPrintf(pCon,eError,"ERROR: node %s not found", argv[1]); + return 0; + } + + switch(node->value.dataType){ + case HIPINT: + getSICSDataInt(self,start,&ival); + node->value.v.intValue = ival; + break; + case HIPFLOAT: + getSICSDataFloat(self,start,&fval); + node->value.v.doubleValue = (double) fval; + break; + case HIPINTAR: + case HIPINTVARAR: + if(node->value.arrayLength != length){ + if(node->value.v.intArray != NULL){ + free(node->value.v.intArray); + } + node->value.v.intArray = malloc(length*sizeof(int)); + if(node->value.v.intArray == NULL){ + SCWrite(pCon,"ERROR: out of memory in copytonode",eError); + return 0; + } + node->value.arrayLength = length; + } + memcpy(node->value.v.intArray, self->data, length*sizeof(int)); + break; + case HIPFLOATAR: + case HIPFLOATVARAR: + if(node->value.arrayLength != length){ + if(node->value.v.floatArray != NULL){ + free(node->value.v.floatArray); + } + node->value.v.floatArray = malloc(length*sizeof(double)); + if(node->value.v.floatArray == NULL){ + SCWrite(pCon,"ERROR: out of memory in copytonode",eError); + return 0; + } + node->value.arrayLength = length; + } + + for(i = start, j = 0; i < length; i++, j++){ + getSICSDataFloat(self,i,&fval); + node->value.v.floatArray[j] = (double)fval; + } + break; + default: + SCWrite(pCon,"ERROR: cannot copy non numeric data into a SICSData", eError); + return 0; + } + NotifyHipadabaPar(node,pCon); + SCSendOK(pCon); + return 1; +} /*---------------------------------------------------------------------- Look here in order to find out about commands understood ----------------------------------------------------------------------*/ @@ -860,7 +1018,13 @@ int SICSDataAction(SConnection * pCon, SicsInterp * pSics, void *pData, } else if (strcmp(argv[1], "copyhmbank") == 0) { /*--------- copyhmbank */ return copyHMBank(self, argc - 2, &argv[2], pCon, pSics); - } else if (strcmp(argv[1], "writezipped") == 0) { + } else if (strcmp(argv[1], "copynode") == 0) { + /*--------- copynode */ + return copyNode(self, argc - 2, &argv[2], pCon, pSics); + } else if (strcmp(argv[1], "copytonode") == 0) { + /*--------- copyTonode */ + return copyToNode(self, argc - 2, &argv[2], pCon, pSics); + } else if (strcmp(argv[1], "writezipped") == 0) { /*--------- writezipped */ if (argc < 3) { SCWrite(pCon, "ERROR: need a name for writezipped", eError); diff --git a/sicshdbfactory.c b/sicshdbfactory.c index cc721066..26708c9a 100644 --- a/sicshdbfactory.c +++ b/sicshdbfactory.c @@ -428,6 +428,8 @@ static int MakeAliasNode(pHdb parent, char *name, SConnection *pCon, { hdbValue v; pHdb targetNode = NULL, child = NULL; + char value[512]; + const char *key; if(argc < 4){ SCWrite(pCon,"ERROR: hdbfactory alias needs 4 arguments, not enough supplied", @@ -456,7 +458,14 @@ static int MakeAliasNode(pHdb parent, char *name, SConnection *pCon, AppendHipadabaCallback(targetNode, MakeHipadabaCallback(AliasTargetCallback, strdup(argv[1]),free)); - + /* + * copy properties + */ + InitHdbPropertySearch(targetNode); + while((key = GetNextHdbProperty(targetNode, value, 512)) != NULL){ + SetHdbProperty(child,(char *)key,value); + } + SCSendOK(pCon); return 1; } diff --git a/sicshipadaba.c b/sicshipadaba.c index b87429b2..c7c9598f 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -1924,6 +1924,12 @@ pDynString formatValue(hdbValue v, pHdb node) if (result == NULL) { return NULL; } + + if(v.arrayLength > 65536){ + DynStringCopy(result,"Data to big to format into text"); + return result; + } + switch (v.dataType) { case HIPNONE: break; diff --git a/sicsobj.c b/sicsobj.c index 5f5db105..ac560375 100644 --- a/sicsobj.c +++ b/sicsobj.c @@ -375,7 +375,7 @@ static int isNodePrintable(pHdb node) static void objFormatNode(pHdb node, char separator, char *prefix, pDynString data) { - char par[128]; + char par[128], buffer[256]; pDynString dyn = NULL; int i; pHdb child; @@ -385,7 +385,13 @@ static void objFormatNode(pHdb node, char separator, DynStringConcat(data, par); dyn = formatValue(node->value, node); if (dyn != NULL) { - DynStringConcat(data, GetCharArray(dyn)); + if(GetDynStringLength(dyn) < 256){ + DynStringConcat(data, GetCharArray(dyn)); + } else { + strncpy(buffer,GetCharArray(dyn),255); + DynStringConcat(data, buffer); + DynStringConcat(data,"......"); + } } else { dyn = CreateDynString(60, 63); } diff --git a/simidx.c b/simidx.c index 3a231db7..33de098a 100644 --- a/simidx.c +++ b/simidx.c @@ -479,6 +479,11 @@ static int findAngleMatch(MATRIX B, int idxr1, int r1, /*------------------------------------------------------------- * If the system is right handed the determinat of the * matrix having the indices as columns must be positive + * I now (05/2009) thgink that this test is wrong. The testing + * has to be done separatly, by checking if the determinant of the + * calculated UB is > 0. As I do not want this in this file, which + * ought to be diffractometer independent, this test may need to + * left to a the caller. -------------------------------------------------------------*/ static int testRightHandedness(int r1, int r1idx, int r2, int r2idx, int r3, int r3idx) @@ -747,12 +752,14 @@ int SimIdxRun() SimIdxPrint(10, "Choosen triplet: %d, %d, %d\n", triplet[0], triplet[1], triplet[2]); - status = findSolutionsForTriplet(triplet, 1); + status = findSolutionsForTriplet(triplet, 0); + /* if (nSolutions == 0) { SimIdxPrint(1, "WARNING: found no right handed solution set, trying to find lefthanded"); status = findSolutionsForTriplet(triplet, 0); } + */ if (nSolutions == 0) { SimIdxPrint(10, "Failed to find solution for triplet, trying duett"); status = secondForDuett(triplet); diff --git a/singlebi.c b/singlebi.c index 2ed0c732..a41cd412 100644 --- a/singlebi.c +++ b/singlebi.c @@ -215,23 +215,7 @@ static int hklInRange(void *data, double fSet[4], int mask[4]) mask[0] = checkTheta(self, &dTheta); fSet[0] = dTheta; - /* for omega check against the limits +- SCANBORDER in order to allow for - a omega scan. - */ - MotorGetPar(pOmega, "softlowerlim", &fLimit); - if ((float) fSet[1] < fLimit) { - mask[1] = 1; - } else { - mask[1] = 0; - MotorGetPar(pOmega, "softupperlim", &fLimit); - if ((float) fSet[1] > fLimit) { - mask[1] = 0; - } else { - mask[1] = 1; - } - } - - /* check chi and phi */ + mask[1] = MotorCheckBoundary(pOmega, fSet[1], &fHard, pError, 131); mask[2] = MotorCheckBoundary(pChi, fSet[2], &fHard, pError, 131); mask[3] = MotorCheckBoundary(pPhi, fSet[3], &fHard, pError, 131); for (i = 0, test = 0; i < 4; i++) { diff --git a/singlex.c b/singlex.c index e6f5bc79..03e0d391 100644 --- a/singlex.c +++ b/singlex.c @@ -26,6 +26,7 @@ #include "singlenb.h" #include "singletas.h" #include "lld.h" +#include "fourlib.h" extern void InitSimpleIndex(SConnection * pCon, SicsInterp * pSics); /* from simindex.c */ @@ -425,7 +426,35 @@ static int SymRefCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, SCWrite(pCon, "ERROR: no reachable symmetry equivalent found", eError); return 0; } - +/*-----------------------------------------------------------------------------*/ +static int SttUBCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + double hkl[3], theta, d; + MATRIX z1 = NULL; + + if (nPar < 3) { + SCWrite(pCon, "ERROR: need start h,k,l for sttUB", eError); + return 0; + } + hkl[0] = par[0]->value.v.doubleValue; + hkl[1] = par[1]->value.v.doubleValue; + hkl[2] = par[2]->value.v.doubleValue; + z1 = calculateScatteringVector(SXGetDiffractometer(), hkl); + if(z1 == NULL){ + SCWrite(pCon,"ERROR: cannot calculate scattering vector", eError); + return 0; + } + if(!calcTheta(SXGetLambda(), z1, &d, &theta )){ + mat_free(z1); + SCWrite(pCon,"ERROR: cannot calculate theta", eError); + return 0; + } + mat_free(z1); + SCPrintf(pCon,eValue,"%f", 2.*theta); + + return 1; +} /*-----------------------------------------------------------------------------*/ static int SingleXAction(SConnection * pCon, SicsInterp * pSics, void *data, int argc, char *argv[]) @@ -599,6 +628,13 @@ int MakeSingleX(SConnection * pCon, SicsInterp * pSics, AddSICSHdbPar(cmd, "k", usUser, MakeHdbInt(0)); AddSICSHdbPar(cmd, "l", usUser, MakeHdbInt(0)); + cmd = + AddSICSHdbPar(pNew->objectNode, "sttub", usUser, + MakeSICSFunc(SttUBCmd)); + AddSICSHdbPar(cmd, "h", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "k", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "l", usUser, MakeHdbFloat(.0)); + cmd = AddSICSHdbPar(pNew->objectNode, "peaksearch", usUser, makeHdbValue(HIPNONE, 1)); diff --git a/velosec.c b/velosec.c new file mode 100644 index 00000000..5c369afd --- /dev/null +++ b/velosec.c @@ -0,0 +1,157 @@ +/** + * This is the implementation file for a second generation velocity selector + * object. This is an extension to the drivable object. It mainly adds handling of + * the tilt motor to the system. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, April 2009 + */ +#include +#include +#include +#include +#include +#include +#include + +#define ABS(x) (x < 0 ? -(x) : (x)) +/* + * from sctdriveobj.c + */ +pSICSOBJ MakeSctDriveObj(pHdb node, char *class, SctController * c, + int doNotKillNode); +/*--------------------------------------------------------------------------*/ +static hdbCallbackReturn tiltCallback(pHdb node, void *userData, + pHdbMessage message) +{ + pHdbDataMessage get = NULL, set = NULL; + pMotor tilt = (pMotor)userData; + float val, rot; + char nvsName[80]; + SConnection *pCon, *mine; + void *pNVS = NULL; + int status; + + assert(tilt != NULL); + + if((get = GetHdbGetMessage(message)) != NULL){ + if(get->callData != NULL){ + val = tilt->pDrivInt->GetValue(tilt,(SConnection *)get->callData); + } else { + val = tilt->pDrivInt->GetValue(tilt,pServ->dummyCon); + } + node->value.v.doubleValue = val; + } + if((set = GetHdbGetMessage(message)) != NULL){ + if(set->callData != NULL){ + pCon = (SConnection *)set->callData; + } else { + pCon = pServ->dummyCon; + } + /* + * do we need to do anything? + */ + GetDrivablePosition(tilt,pCon,&val); + if(ABS(val - set->v->v.doubleValue) < .01 ){ + SCWrite(pCon,"tilt already at position", eValue); + return hdbContinue; + } + GetHdbProperty(node,"NVS", nvsName, 80); + + pNVS = FindCommandData(pServ->pSics,nvsName,"NVS"); + assert(pNVS != NULL); + GetDrivablePosition(pNVS, pCon, &rot); + + SCWrite(pCon,"Wait for NVS to stop...", eLog); + status = Drive(pCon, pServ->pSics, nvsName, .0); + if(status != 1){ + SCWrite(pCon,"ERROR: failed to stop NVS, driving tilt aborted", eError); + return hdbContinue; + } + + SCWrite(pCon,"Actually driving tilt...", eLog); + mine = SCCopyConnection(pCon); + SCSetRights(mine, usInternal); + status = Drive(pCon, pServ->pSics, tilt->name, (float)set->v->v.doubleValue); + if(status != 1){ + SCWrite(pCon,"ERROR: failed to drive tilt, NVS stopped", eError); + return hdbContinue; + } + SCDeleteConnection(mine); + GetDrivablePosition(tilt,pCon,&val); + UpdateHipadabaPar(node, MakeHdbFloat(val), pCon); + + SCWrite(pCon,"Wait even more for NVS to get to speed again...", eLog); + status = Drive(pCon, pServ->pSics, nvsName, rot); + if(status != 1){ + SCWrite(pCon,"ERROR: failed to run NVS to speed", eError); + return hdbContinue; + } + SCWrite(pCon,"Done", eValue); + } + return hdbContinue; +} +/*--------------------------------------------------------------------------*/ +int MakeSecNVS(SConnection * pCon, SicsInterp * pSics, + void *object, int argc, char *argv[]) +{ + pMotor tilt = NULL; + pSICSOBJ pNew = NULL; + SctController *sct = NULL; + pHdb node = NULL, tilli; + int status; + + if(argc < 4){ + SCWrite(pCon, + "ERROR: missing required parameters, Usage: MakeNVS name tiltmotorname sctcontroller", + eError); + return 0; + } + + tilt = (pMotor)FindCommandData(pSics,argv[2],"Motor"); + if(tilt == NULL){ + SCPrintf(pCon,eError, "ERROR: tilt motor %s not found", argv[2]); + return 0; + } + + sct = (SctController *)FindCommandData(pSics, argv[3],"ScriptContext"); + if(sct == NULL){ + SCPrintf(pCon,eError, "ERROR: scriptcontext %s not found", argv[3]); + return 0; + } + + node = MakeHipadabaNode(argv[1],HIPFLOAT,1); + SetHdbProperty(node,"sicsdev",argv[1]); + SetHdbProperty(node,"priv", "user"); + + pNew = MakeSctDriveObj(node, "NVS", sct, 0); + if(pNew == NULL || node == NULL){ + SCWrite(pCon,"ERROR: failed to create NVS, out of memory?", + eError); + return 0; + } + + + tilli = MakeSICSHdbPar("tilt", usMugger, MakeHdbFloat(.0)); + if(tilli == NULL){ + KillSICSOBJ(pNew); + SCWrite(pCon,"ERROR: failed to create tilt node, out-of-memory?", eError); + return 0; + } + /* + * In the set callback I need the name of the NVS because I need to stop and + * drive it up again. Rather then have another data structure I pass this name + * as a property to the tilt node. + */ + SetHdbProperty(tilli,"NVS", argv[1]); + + MotorSetPar(tilt,pCon,"accesscode", (float)usInternal); + AppendHipadabaCallback(tilli, MakeHipadabaCallback(tiltCallback, tilt,NULL)); + AddHipadabaChild(node, tilli, pCon); + + status = AddCommand(pSics, + argv[1], InterInvokeSICSOBJ, KillSICSOBJ, pNew); + + return status; +} diff --git a/velosec.h b/velosec.h new file mode 100644 index 00000000..d983567f --- /dev/null +++ b/velosec.h @@ -0,0 +1,19 @@ +/** + * This is the header file for a second generation velocity selector + * object. This is an extension to the drivable object. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, April 2009 + */ +#ifndef VELOSEC_H_ +#define VELOSEC_H_ + +/** + * Usual style factory function for creating a + * NVS object. + */ +int MakeSecNVS(SConnection * pCon, SicsInterp * pSics, + void *object, int argc, char *argv[]); + +#endif /*VELOSEC_H_*/