diff --git a/SCinter.c b/SCinter.c index 1867618f..acd616f3 100644 --- a/SCinter.c +++ b/SCinter.c @@ -895,7 +895,9 @@ int InterpWrite(SicsInterp * pSics, char *buffer) assert(pSics); pTcl = (Tcl_Interp *) pSics->pTcl; - Tcl_SetResult(pTcl, buffer, TCL_VOLATILE); + if(Tcl_GetStringResult(pTcl) != buffer){ + Tcl_SetResult(pTcl, buffer, TCL_VOLATILE); + } return 1; } diff --git a/access.c b/access.c index 51e62db0..2b77d4b7 100644 --- a/access.c +++ b/access.c @@ -21,6 +21,9 @@ int decodeSICSPriv(char *privText) int code = 0; strtolower(privText); + if(strcmp(privText,"manager") == 0){ + return 1; + } while (aCode[code] != NULL) { if (strcmp(aCode[code], privText) == 0) { return code; diff --git a/devser.c b/devser.c index c192d38a..73fa4372 100644 --- a/devser.c +++ b/devser.c @@ -327,7 +327,7 @@ static void DevReset(DevSer * devser) devser->current->kill(devser->current->data); } devser->killCurrent = 0; - free(devser->current); + /* free(devser->current); */ } } diff --git a/diffscan.c b/diffscan.c index 4fe97de2..0dd9e54d 100644 --- a/diffscan.c +++ b/diffscan.c @@ -322,11 +322,22 @@ static int DiffScanTask(void *pData) countValue = (float) data->lCount; rawCount = data->lCount; rawMon = data->Monitors[self->scaleMonitor - 1]; - self->normalizationScale = data->Monitors[self->scaleMonitor - 1]; + if(rawMon > 100){ + self->normalizationScale = rawMon; + traceSys("diffscan","START:normalizing on %d, scale monitor is %d", + self->normalizationScale, self->scaleMonitor); + } else { + traceSys("diffscan","START:normalization count %d, on scale monitor is %d and is to low", + rawMon, self->scaleMonitor); + SCWrite(self->scanObject->pCon,"WARNING: Skipping first point because of low count rate", eWarning); + return finish; + } } else { if (data->Monitors[self->scaleMonitor - 1] - self->last.Monitors[self->scaleMonitor - 1] < 5) { SCWrite(self->scanObject->pCon, "WARNING: low count rate", eLog); + traceSys("diffscan","RUN:low monitor difference from %d to %d",data->Monitors[self->scaleMonitor-1], + self->last.Monitors[self->scaleMonitor -1]); } rawCount = data->lCount; rawMon = data->Monitors[self->scaleMonitor - 1]; @@ -344,6 +355,8 @@ static int DiffScanTask(void *pData) fPos, countValue, rawCount, rawMon); SCWrite(self->scanObject->pCon, pBueffel, eLog); InvokeCallBack(self->scanObject->pCall, SCANPOINT, self->scanObject); + traceSys("diffscan","RUN: pos, count, rawcount, rawmon: %f, %d, %d, %d", + fPos, countValue, rawCount, rawMon); /* check for interrupt diff --git a/doc/manager/nxscript.htm b/doc/manager/nxscript.htm index fc8635f4..6c27eff5 100644 --- a/doc/manager/nxscript.htm +++ b/doc/manager/nxscript.htm @@ -163,6 +163,10 @@ designated by targetAlias. to write as a Tcl list and obj is the SICS object to write. Obj can be a histogram memory; then the histogram memory data is written. Or it can be a sicsdata object, the value of which will then be written. +
nxscript putslab16 alias startlist sizelist obj +
Writes a slab of data as above. Parameters are as setailed above. + The difference is that this converts the data to a6 bit int before writing. + And SICSData objects are not supported.

Automatic Updating of NeXus Files

diff --git a/emon.c b/emon.c index 814360e6..7cbcc702 100644 --- a/emon.c +++ b/emon.c @@ -6,6 +6,8 @@ Mark Koennecke, Juli 1997 + Reduced polling frequency to any 20 seconds, Mark Koennecke, August 2011 + Copyright: Labor fuer Neutronenstreuung @@ -39,6 +41,7 @@ #include #include #include +#include #include /* for DString */ #include "fortify.h" #include "lld.h" @@ -46,6 +49,11 @@ #include "emon.i" #include "emon.h" #include "event.h" + +/* + * any how many seconds we check + */ +#define SCANINTERVALL 20 /*--------------------------------------------------------------------------*/ pEnvMon CreateEnvMon(void) { @@ -68,6 +76,7 @@ pEnvMon CreateEnvMon(void) free(pNew); return NULL; } + pNew->nextRun = time(NULL)+SCANINTERVALL; AddCommand(pServ->pSics, "emon", EVWrapper, DeleteEnvMon, pNew); return pNew; } @@ -340,7 +349,10 @@ int EnvMonTask(void *pData) return 0; } - EVMonitorControllers(self); + if(time(NULL) > self->nextRun){ + EVMonitorControllers(self); + self->nextRun = time(NULL) + SCANINTERVALL; + } return 1; } diff --git a/emon.h b/emon.h index 3a01e7b4..d1a747d0 100644 --- a/emon.h +++ b/emon.h @@ -1,5 +1,5 @@ -#line 148 "emonitor.w" +#line 149 "emonitor.w" /*-------------------------------------------------------------------------- E N V I R O N M E N T M O N I T O R @@ -14,31 +14,31 @@ ----------------------------------------------------------------------------*/ #ifndef SICSEMON #define SICSEMON -typedef struct __EnvMon *pEnvMon; + typedef struct __EnvMon *pEnvMon; /*-------------------------------------------------------------------------*/ -#line 85 "emonitor.w" +#line 86 "emonitor.w" -pEnvMon CreateEnvMon(void); -void DeleteEnvMon(void *pData); + pEnvMon CreateEnvMon(void); + void DeleteEnvMon(void *pData); -int EVRegisterController(pEnvMon self, char *pName, void *pData, - SConnection * pCon); -int EVUnregister(pEnvMon self, char *name); + int EVRegisterController(pEnvMon self, char *pName, void *pData, + SConnection *pCon); + int EVUnregister(pEnvMon self, char *name); + + int EVMonitorControllers(pEnvMon self); -int EVMonitorControllers(pEnvMon self); + int EVList(pEnvMon self, SConnection *pCon); -int EVList(pEnvMon self, SConnection * pCon); + int EVWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); -int EVWrapper(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); + pEnvMon FindEMON(SicsInterp *pSics); + + int EnvMonTask(void *pEv); + void EnvMonSignal(void *pEndv, int iSignal, void *pSigData); -pEnvMon FindEMON(SicsInterp * pSics); - -int EnvMonTask(void *pEv); -void EnvMonSignal(void *pEndv, int iSignal, void *pSigData); - -#line 164 "emonitor.w" +#line 165 "emonitor.w" #endif diff --git a/emon.i b/emon.i index 1ff51a27..f1754e46 100644 --- a/emon.i +++ b/emon.i @@ -10,6 +10,7 @@ pObjectDescriptor pDes; int iList; int iEnd; + time_t nextRun; } EnvMon; /*---------------------------------------------------------------------------*/ typedef struct { diff --git a/emonitor.tex b/emonitor.tex index 5e2447e2..91803789 100644 --- a/emonitor.tex +++ b/emonitor.tex @@ -68,6 +68,7 @@ $\langle$emondat {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ pObjectDescriptor pDes;@\\ \mbox{}\verb@ int iList;@\\ \mbox{}\verb@ int iEnd;@\\ +\mbox{}\verb@ time_t nextRun;@\\ \mbox{}\verb@ } EnvMon;@\\ \mbox{}\verb@/*---------------------------------------------------------------------------*/@\\ \mbox{}\verb@ typedef struct {@\\ @@ -77,7 +78,7 @@ $\langle$emondat {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ } EVEntry, *pEVEntry; @\\ \mbox{}\verb@@\\ \mbox{}\verb@@\\ -\mbox{}\verb@@$\diamond$ +\mbox{}\verb@@$\Diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} @@ -120,7 +121,7 @@ $\langle$emonint {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ @\\ \mbox{}\verb@ int EnvMonTask(void *pEv);@\\ \mbox{}\verb@ void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);@\\ -\mbox{}\verb@@$\diamond$ +\mbox{}\verb@@$\Diamond$ \end{list} \vspace{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex} @@ -193,7 +194,7 @@ controllers configured into SICS. \mbox{}\verb@/*-------------------------------------------------------------------------*/@\\ \mbox{}\verb@@$\langle$emonint {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@#endif@\\ -\mbox{}\verb@@$\diamond$ +\mbox{}\verb@@$\Diamond$ \end{list} \vspace{-2ex} \end{minipage}\\[4ex] @@ -211,7 +212,7 @@ controllers configured into SICS. \mbox{}\verb@ Mark Koennecke, Juli 1997@\\ \mbox{}\verb@---------------------------------------------------------------------------*/@\\ \mbox{}\verb@@$\langle$emondat {\footnotesize ?}$\rangle$\verb@@\\ -\mbox{}\verb@@$\diamond$ +\mbox{}\verb@@$\Diamond$ \end{list} \vspace{-2ex} \end{minipage}\\[4ex] diff --git a/emonitor.w b/emonitor.w index ef294610..db5f5b10 100644 --- a/emonitor.w +++ b/emonitor.w @@ -63,6 +63,7 @@ The environment monitor uses the following datastructures: pObjectDescriptor pDes; int iList; int iEnd; + time_t nextRun; } EnvMon; /*---------------------------------------------------------------------------*/ typedef struct { diff --git a/exebuf.c b/exebuf.c index 1ab096e5..e5ae6c56 100644 --- a/exebuf.c +++ b/exebuf.c @@ -95,9 +95,9 @@ static char *locateName(char *filename) /*-----------------------------------------------------------------------*/ int exeBufLoad(pExeBuf self, char *filename) { - char line[256]; + char line[256], *pPtr; FILE *fd = NULL; - int status; + int status, idx; assert(self); fd = fopen(filename, "r"); @@ -114,6 +114,16 @@ int exeBufLoad(pExeBuf self, char *filename) } } fclose(fd); + + /** + * make sure that there is a \n at the end + */ + idx = GetDynStringLength(self->bufferContent); + pPtr = GetCharArray(self->bufferContent); + if(pPtr[idx-1] != '\n'){ + DynStringConcat(self->bufferContent,"\n"); + } + if (self->name != NULL) { free(self->name); } diff --git a/exeman.c b/exeman.c index 38d85c47..d470a98c 100644 --- a/exeman.c +++ b/exeman.c @@ -721,6 +721,7 @@ static int appendLine(pExeMan self, SConnection * pCon, SCWrite(pCon, "ERROR: no upload in operation", eError); return 0; } + memset(pLine,0,sizeof(pLine)); Arg2Text(argc - 2, &argv[2], pLine, 1023); exeBufAppend(self->uploadBuffer, pLine); return 1; diff --git a/fourmess.c b/fourmess.c index f9e7eae5..bf09019c 100644 --- a/fourmess.c +++ b/fourmess.c @@ -34,6 +34,9 @@ #include "scanvar.h" #include "scan.i" #include "sdynar.h" +#include "lld.h" + +extern char *trim(char *); extern void SNXFormatTime(char *pBueffel, int iLen); @@ -797,12 +800,15 @@ static int hklCompare(const void *h1, const void *h2) } } -/*----------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------- + * This sorts on two theta only. + -----------------------------------------------------------------------------*/ static int SortRef(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { double *sortlist, d, lambda, om, hkl[4], ang[4]; const double *cell; + double *hklc; int nRefl, i, j; MATRIX B, H, Z1; lattice direct; @@ -860,7 +866,195 @@ static int SortRef(pSICSOBJ self, SConnection * pCon, pHdb commandNode, SCSendOK(pCon); return 1; } +/*---------------------------------------------------------------------------- + * Sorting reflection is actually a variant of the traveling salesman + * problem. Optimal solutions for this are computationally expensive. + * Optimise for the shortest path between reflections. Not all motors + * are equal though. Om and phi move quick whereas stt and chi go slow. + * As a compromise, what I try here is sorting by a weighted addition of + * stt and chi. + ----------------------------------------------------------------------------*/ +static int SortRefNew(pSICSOBJ self, SConnection * pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + double *sortlist, d, lambda, om, hkl[4], ang[4]; + const double *cell; + double *hklc; + int nRefl, i, j, status, count; + SingleXModes mode; + pFourMess priv = self->pPrivate; + pSingleDiff diffi = NULL; + diffi = SXGetDiffractometer(); + mode = SXGetMode(); + if(diffi == NULL){ + SCWrite(pCon,"ERROR: not initialized, no diffractometer", eError); + return 0; + } + + nRefl = ReflectionListCount(priv->messList); + sortlist = malloc(nRefl * 4 * sizeof(double)); + if (sortlist == NULL) { + SCWrite(pCon, "ERROR: out of memory in SortRef", eError); + return 0; + } + + /* + * I am using hkl[3] for storing the sort value to sort for! */ + for (i = 0, count = 0; i < nRefl; i++) { + GetRefIndex(priv->messList, i, hkl); + status = diffi->calculateSettings(diffi,hkl,ang); + if(status == 1){ + if(mode == Bisecting){ + hkl[3] = ang[0] + 0.5* ang[2]; + if(ang[2] < 0){ + SCWrite(pCon,"WARNING: chi < 0!", eWarning); + } + } else if(mode == NB){ + /* + * sort for nu in the first place. In order to cope with negativity, add + * 10. + */ + hkl[3] = ang[2]+10 + 0.1 * ang[0]; + } else { + hkl[3] = ang[0]; + } + memcpy(sortlist + count * 4, hkl, 4 * sizeof(double)); + count++; + } + } + + qsort(sortlist, count, 4 * sizeof(double), hklCompare); + + ClearReflectionList(priv->messList); + for (i = 0; i < count; i++) { + hklc = sortlist+i*4; + hklc[3] = .0; /* otherwise this will be interpreted as psi! */ + status = diffi->calculateSettings(diffi,hklc,ang); + AddRefIdxAng(priv->messList, sortlist+i*4,ang); + /* AddRefIdx(priv->messList, sortlist + i * 4); */ + } + free(sortlist); + SCSendOK(pCon); + return 1; +} +/*---------------------------------------------------------------------------- + * Write a reflection list in the TSPLIB format for running a traveling + * salesman algorithm against it. +----------------------------------------------------------------------------- */ +static int WriteTSP(pSICSOBJ self, SConnection * pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + double hkl[4], ang[4]; + int nRefl, i, j, status, count; + SingleXModes mode; + pFourMess priv = self->pPrivate; + pSingleDiff diffi = NULL; + FILE *fd = NULL; + + if(nPar < 1) { + SCWrite(pCon,"ERROR: need a filename parameter", eError); + return 0; + } + fd = fopen(trim(par[0]->value.v.text),"w"); + if(fd == NULL){ + SCPrintf(pCon,eError,"ERROR: failed to open %s for writing", par[0]->value.v.text); + return 0; + } + + diffi = SXGetDiffractometer(); + mode = SXGetMode(); + if(diffi == NULL){ + SCWrite(pCon,"ERROR: not initialized, no diffractometer", eError); + return 0; + } + + nRefl = ReflectionListCount(priv->messList); + /* + * smear header... + */ + fprintf(fd,"NAME : %s\n", par[0]->value.v.text); + fprintf(fd,"TYPE : TSP\n"); + fprintf(fd,"DIMENSION : %d\n", nRefl); + fprintf(fd,"EDGE_WEIGHT_TYPE : EUC_3D\n"); + fprintf(fd,"NODE_COORD_SECTION\n"); + + + for (i = 0, count = 0; i < nRefl; i++) { + GetRefIndex(priv->messList, i, hkl); + status = diffi->calculateSettings(diffi,hkl,ang); + if(status == 1){ + if(mode == Bisecting){ + fprintf(fd,"%d %e %e %e\n",i+1,ang[0]*3*100,ang[2]*2*100,ang[3]*100); + } else if(mode == NB){ + fprintf(fd,"%d %e %e %e\n",i,ang[2]*4*100,ang[0]*3*100,ang[1]*100); + } else { + fprintf(fd,"%d %e %e %e\n",i,ang[0]*3*100,ang[2]*2*100,ang[3]*2*100); + } + } + } + fclose(fd); + + SCSendOK(pCon); + return 1; +} +/*---------------------------------------------------------------------------- + * read a tour file as generated by LKH or other TSP solvers and + * reorder the reflection list accordingly. + -----------------------------------------------------------------------------*/ +static int ReadTour(pSICSOBJ self, SConnection * pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + FILE *fd = NULL; + char buffer[132]; + double hkl[4], ang[4]; + int idx, tour; + pFourMess priv = self->pPrivate; + pSingleDiff diffi = NULL; + + + if(nPar < 1) { + SCWrite(pCon,"ERROR: need name of a tour file to read", eError); + return 0; + } + fd = fopen(par[0]->value.v.text,"r"); + if(fd == NULL){ + SCPrintf(pCon,eError,"ERROR: failed to open tour file %s for reading", + par[0]->value.v.text); + return 0; + } + tour = LLDcreate(sizeof(hkl)); + diffi = SXGetDiffractometer(); + assert(diffi != NULL); + + /* skip header */ + while(fgets(buffer,sizeof(buffer),fd) != NULL){ + if(strstr(buffer,"TOUR_SECTION") != NULL){ + break; + } + } + while(fscanf(fd,"%d",&idx) == 1){ + if(idx < 0){ + break; + } + GetRefIndex(priv->messList,idx-1,hkl); + LLDnodeAppendFrom(tour,hkl); + } + fclose(fd); + + idx = LLDnodePtr2First(tour); + ClearReflectionList(priv->messList); + while(idx == 1){ + LLDnodeDataTo(tour,hkl); + hkl[3] = 0; + diffi->calculateSettings(diffi,hkl,ang); + AddRefIdxAng(priv->messList, hkl,ang); + idx = LLDnodePtr2Next(tour); + } + LLDdelete(tour); + SCSendOK(pCon); + return 1; +} /*----------------------------------------------------------------------------*/ static int FourMessSave(void *data, char *name, FILE * fd) { @@ -982,7 +1176,15 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics) cmd = AddSICSHdbPar(pNew->objectNode, "indsort", usUser, MakeSICSFunc(SortRef)); + cmd = + AddSICSHdbPar(pNew->objectNode, "writetsp", usUser, + MakeSICSFunc(WriteTSP)); + AddSICSHdbPar(cmd, "filename", usUser, MakeHdbText("Unknown")); + cmd = + AddSICSHdbPar(pNew->objectNode, "readtour", usUser, + MakeSICSFunc(ReadTour)); + AddSICSHdbPar(cmd, "filename", usUser, MakeHdbText("Unknown")); cmd = AddSICSHdbPar(pNew->objectNode, "template", usMugger, diff --git a/hdbtable.c b/hdbtable.c index 95cd4a4b..abdc7efc 100644 --- a/hdbtable.c +++ b/hdbtable.c @@ -295,6 +295,53 @@ static int GetRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, return 1; } /*----------------------------------------------------------------------*/ +static int GetRowNoCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + pHdb row = NULL, child, data; + int i, nodeNo; + char path[132]; + pDynString result, val; + + if(nPar < 1){ + SCWrite(pCon,"ERROR: need index of row to read",eError); + return 0; + } + nodeNo = par[0]->value.v.intValue; + + data = GetHipadabaNode(self->objectNode,"data"); + assert(data != NULL); + row = data->child; + for(i = 0; i < nodeNo; i++){ + row = row->next; + if(row == NULL){ + SCPrintf(pCon,eError,"ERROR: row %d not found", nodeNo); + return 0; + } + } + + result = CreateDynString(128,128); + if(result == NULL){ + SCWrite(pCon,"ERROR: out of memory in GetRowCmd", eError); + return 0; + } + child = row->child; + while(child != NULL){ + val = formatValue(child->value, child); + if(val != NULL){ + DynStringConcat(result,GetCharArray(val)); + if(child->next != NULL){ + DynStringConcatChar(result,','); + } + DeleteDynString(val); + } + child = child->next; + } + SCWrite(pCon,GetCharArray(result),eValue); + DeleteDynString(result); + return 1; +} +/*----------------------------------------------------------------------*/ static int ListTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, pHdb par[], int nPar) { @@ -414,7 +461,15 @@ pSICSOBJ MakeHdbTable(char *name, char *hdbclass) node = MakeHipadabaNode("id",HIPTEXT,1); SetHdbProperty(node,"priv","user"); AddHipadabaChild(cmd,node, NULL); - + + cmd = AddSICSHdbPar(result->objectNode, "getno", usUser, + MakeSICSFunc(GetRowNoCmd)); + SetHdbProperty(cmd,"type","command"); + SetHdbProperty(cmd,"priv","user"); + node = MakeHipadabaNode("id",HIPINT,1); + SetHdbProperty(node,"priv","user"); + AddHipadabaChild(cmd,node, NULL); + return result; } /*---------------------------------------------------------------------------*/ diff --git a/hipadaba.c b/hipadaba.c index 58437c0b..220a243e 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -354,6 +354,7 @@ hdbValue MakeHdbInt(int initValue) result.dataType = HIPINT; result.arrayLength = 1; result.v.intValue = initValue; + result.doNotFree = 0; return result; } @@ -365,6 +366,7 @@ hdbValue MakeHdbFloat(double initValue) result.dataType = HIPFLOAT; result.arrayLength = 1; result.v.doubleValue = initValue; + result.doNotFree = 0; return result; } @@ -376,6 +378,7 @@ hdbValue MakeHdbText(char *initText) result.dataType = HIPTEXT; result.v.text = initText; /* no strdup here ! */ result.arrayLength = strlen(initText); + result.doNotFree = 0; return result; } @@ -387,6 +390,7 @@ hdbValue MakeHdbIntArray(int length, int *data) result.dataType = HIPINTAR; result.arrayLength = length; result.v.intArray = data; + result.doNotFree = 0; return result; } @@ -398,6 +402,7 @@ hdbValue MakeHdbFloatArray(int length, double *data) result.dataType = HIPFLOATAR; result.arrayLength = length; result.v.floatArray = data; + result.doNotFree = 0; return result; } @@ -408,6 +413,7 @@ hdbValue MakeHdbFunc(voidFunc * func) result.dataType = HIPFUNC; result.v.func = func; + result.doNotFree = 0; return result; } @@ -418,6 +424,7 @@ hdbValue MakeHdbObj(void *obj) result.dataType = HIPOBJ; result.v.obj = obj; + result.doNotFree = 0; return result; } diff --git a/hmcontrol.c b/hmcontrol.c index e0a65263..21036ecb 100644 --- a/hmcontrol.c +++ b/hmcontrol.c @@ -9,11 +9,19 @@ copyright: see copyright.h Mark Koennecke, June 2001 + + Added a flag which does not call halt after the counter + finished. This feauture is necessary to allow normal + counting on CCD camera. When they get interrupted, the + image is invalid. This is not what is wanted. + + Mark Koennecke, July 2011 -------------------------------------------------------------------------*/ #include #include #include +#include #include "fortify.h" #include "hmcontrol.h" #include "HistMem.h" @@ -66,14 +74,27 @@ static int HMCStart(void *pData, SConnection * pCon) return HWFault; } - for (i = 0; i < self->nSlaves; i++) { - ReleaseCountLock(self->slaves[i]); - status = self->slaves[i]->StartCount(self->slaveData[i], pCon); - if (status != OKOK) { - HMCHalt(self); - return status; - } + for (i = 1; i < self->nSlaves; i++) { + ReleaseCountLock(self->slaves[i]); + status = self->slaves[i]->StartCount(self->slaveData[i], pCon); + if (status != OKOK) { + HMCHalt(self); + return status; + } } + /* + * This starts the counter: always 0, last.This should be the + * right thing as the HM do not start counting in earnest before + * the busy line from the counter box is set. + */ + ReleaseCountLock(self->slaves[0]); + status = self->slaves[0]->StartCount(self->slaveData[0], pCon); + if (status != OKOK) { + HMCHalt(self); + return status; + } + + /* Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories. If this assumption does not hold, change this code to check if this @@ -114,7 +135,10 @@ static int HMCStatus(void *pData, SConnection * pCon) stop counting on slaves when finished or when an error occurred. */ - HMCHalt(self); + if(self->stopSlaves){ + HMCHalt(self); + } + ReleaseCountLock(self->pCount); self->checkSlaves = 1; status = HWBusy; } @@ -301,6 +325,7 @@ int MakeHMControl(SConnection * pCon, SicsInterp * pSics, pNew->slaves[pNew->nSlaves] = pCount; pNew->slaveData[pNew->nSlaves] = pCom->pData; pNew->nSlaves++; + pNew->stopSlaves = 1; } /* @@ -335,14 +360,19 @@ int HMControlAction(SConnection * pCon, SicsInterp * pSics, */ self = (pHMcontrol) pData; assert(self); - if (argc < 4) { + if (argc < 2) { snprintf(pBueffel, 131, "ERROR: Usage %s start preset mode", argv[0]); SCWrite(pCon, pBueffel, eError); return 0; } strtolower(argv[1]); if (strcmp(argv[1], "start") == 0) { - /* + if (argc < 4) { + snprintf(pBueffel, 131, "ERROR: Usage %s start preset mode", argv[0]); + SCWrite(pCon, pBueffel, eError); + return 0; + } + /* interpret count parameters */ status = Tcl_GetDouble(pSics->pTcl, argv[2], &dPreset); @@ -374,6 +404,15 @@ int HMControlAction(SConnection * pCon, SicsInterp * pSics, } InvokeCallBack(self->pCall, COUNTSTART, pCon); SCSendOK(pCon); + }else if(strcmp(argv[1],"stopslaves") == 0){ + if(argc < 3){ + SCPrintf(pCon,eValue,"hm.stopslaves = %d", self->stopSlaves); + return 1; + } else { + self->stopSlaves = atoi(argv[2]); + SCPrintf(pCon,eValue,"hm.stopslaves = %d", self->stopSlaves); + return 1; + } } else { SCWrite(pCon, "ERROR: subcommand not recognized", eError); return 0; diff --git a/hmcontrol.h b/hmcontrol.h index f2bf5ce5..92500bf0 100644 --- a/hmcontrol.h +++ b/hmcontrol.h @@ -33,6 +33,7 @@ typedef struct { CounterMode eMode; pICallBack pCall; int checkSlaves; + int stopSlaves; } HMcontrol, *pHMcontrol; diff --git a/interface.c b/interface.c index 9e72eec6..c0f8ebf2 100644 --- a/interface.c +++ b/interface.c @@ -162,7 +162,7 @@ int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos) return MotorGetSoftPosition(pMot, pCon, fPos); } value = pDriv->GetValue(pObject, pCon); - if (value < 9999.99) { + if (value < -9999.99) { return 0; } *fPos = value; diff --git a/motorlist.c b/motorlist.c index ba745e37..ebfeeb87 100644 --- a/motorlist.c +++ b/motorlist.c @@ -169,7 +169,6 @@ static float MOLIGetValue(void *data, SConnection * pCon) pIDrivable makeMotListInterface() { pIDrivable pDriv = NULL; - pDriv = CreateDrivableInterface(); if (pDriv == NULL) { return NULL; diff --git a/nserver.c b/nserver.c index 167339c7..99b76c3f 100644 --- a/nserver.c +++ b/nserver.c @@ -478,31 +478,7 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData, return 1; } } - -/*------------------------------------------------------------------------*/ -int SicsWaitOld(long lTime) -{ - WaitStruct sWait; - pTaskMan pTasker = NULL; - long lID; - - if (pServ->simMode) { - return 1; - } - - pTasker = GetTasker(); - sWait.dFinish = DoubleTime() + lTime; - sWait.iEnd = 0; - lID = TaskRegister(pTasker, WaitTask, WaitSignal, NULL, &sWait, 1); - TaskWait(pTasker, lID); - return 1; -} - -/*------------------------------------------------------------------------ - The new SicsWait is still on probation. It prevents commands to be - executed on the same task on which the Sicswait is acting. - M.K. December 2005 - -------------------------------------------------------------------------*/ +/*--------------------------------------------------------------------------*/ int SicsWait(long lTime) { pTaskMan pTasker = NULL; diff --git a/nxscript.c b/nxscript.c index cdf4c575..ae899bbb 100644 --- a/nxscript.c +++ b/nxscript.c @@ -971,7 +971,7 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self, memsec = (pCounter) FindCommandData(pSics, argv[5], "HistMemSec"); if(memsec != NULL){ node = GetHipadabaNode(memsec->pDes->parNode,"data"); - if(data != NULL){ + if(node == NULL){ SCWrite(pCon,"ERROR: ?? data node to second gen HM not found", eError); return; } @@ -1001,6 +1001,116 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self, eLogError); } } +/*----------------------------------------------------------------------*/ +static short *HistInt2Short(HistInt *data, int length) +{ + int i; + + int16_t *shdata = NULL; + shdata = malloc(length*sizeof(int16_t)); + if(shdata == NULL){ + return NULL; + } + memset(shdata,0,length*sizeof(int16_t)); + for(i = 0; i < length; i++){ + shdata[i] = (short)data[i]; + } + return shdata; +} +/*----------------------------------------------------------------------*/ +static void putSlab16(SConnection * pCon, SicsInterp * pSics, pNXScript self, + int argc, char *argv[]) +{ + int start[NX_MAXRANK], size[NX_MAXRANK], dim[MAXDIM]; + int status, written = 0, rank, i; + pHistMem mem = NULL; + HistInt *histData = NULL; + int16_t *shortData = NULL; + pHdb node = NULL; + unsigned int length; + pCounter memsec = NULL; + + if (argc < 6) { + SCWrite(pCon, "ERROR: insufficient number of arguments to putslab", + eLogError); + return; + } + + status = NXDopenalias(self->fileHandle, self->dictHandle, argv[2]); + if (status != NX_OK) { + SCPrintf(pCon, eLogError, "ERROR: failed to open alias %s", argv[2]); + return; + } + + status = listToArray(pSics, argv[3], start); + if (status != TCL_OK) { + SCWrite(pCon, "ERROR: failed to convert start value list", eLogError); + return; + } + + status = listToArray(pSics, argv[4], size); + if (status != TCL_OK) { + SCWrite(pCon, "ERROR: failed to convert size value list", eLogError); + return; + } + + + /* + * try to write HM data + */ + mem = (pHistMem) FindCommandData(pSics, argv[5], "HistMem"); + if (mem != NULL) { + histData = GetHistogramPointer(mem, pCon); + if (histData) { + GetHistDim(mem, dim,&rank); + for(i = 0, length = 1; i < rank; i++){ + length *= dim[i]; + } + shortData = HistInt2Short(histData,length); + if(shortData != NULL){ + status = NXputslab(self->fileHandle, shortData, start, size); + free(shortData); + } + if (status == NX_OK) { + written = 1; + } + } + } + + /* + * try to write second gen histogram data + */ + memsec = (pCounter) FindCommandData(pSics, argv[5], "HistMemSec"); + if(memsec != NULL){ + node = GetHipadabaNode(memsec->pDes->parNode,"data"); + if(node == NULL){ + SCWrite(pCon,"ERROR: ?? data node to second gen HM not found", eError); + return; + } + GetHistDim((pHistMem)memsec, dim,&rank); + for(i = 0, length = 1; i < rank; i++){ + length *= dim[i]; + } + shortData = HistInt2Short(node->value.v.intArray,length); + if(shortData != NULL){ + status = NXputslab(self->fileHandle, shortData, start, size); + free(shortData); + } + if (status == NX_OK) { + written = 1; + } + } + + /* + * drop out of hierarchy + */ + NXopenpath(self->fileHandle, "/"); + + if (written == 0) { + SCWrite(pCon, "ERROR: failed to write data, data not recognised", + eLogError); + } +} /*-------------------------------------------------------------------*/ static void putTimeBinning(SConnection * pCon, SicsInterp * pSics, @@ -1397,6 +1507,9 @@ static int handlePut(SConnection * pCon, SicsInterp * pSics, } else if (strcmp(argv[1], "putslab") == 0) { /*===============*/ putSlab(pCon, pSics, self, argc, argv); + } else if (strcmp(argv[1], "putslab16") == 0) { + /*===============*/ + putSlab16(pCon, pSics, self, argc, argv); } else { SCPrintf(pCon, eLogError, "ERROR: put command %s not recognised", argv[1] ); } diff --git a/scriptcontext.c b/scriptcontext.c index e471dc76..f2751521 100644 --- a/scriptcontext.c +++ b/scriptcontext.c @@ -1174,20 +1174,21 @@ static char *TransactionHandler(void *actionData, char *lastReply, return st->command; } else { st->sent = 2; + /* if (st->controller->verbose) { SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply); } if (st->controller->fd != NULL) { fprintf(st->controller->fd,"%6.3f reply : %s\n", secondsOfMinute(), lastReply); } + */ /* printf("Transact: %s got %s\n", st->command, lastReply); */ - if(st->controller != NULL){ + if(st->controller != NULL){ traceIO(st->controller->node->name, "transreply:%s", lastReply); } else { traceIO("sctunknown", "transreply:%s", lastReply); } - - st->reply = strdup(lastReply); + st->reply = strdup(lastReply); return NULL; } } @@ -1218,14 +1219,24 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con, st->con = SCCopyConnection(con); st->command = strdup(par[0]->value.v.text); st->controller = c; + st->sent = 0; DevQueue(c->devser, st, WritePRIO, TransactionHandler, SctTransactMatch, NULL, NULL); while (st->sent != 2) { TaskYield(pServ->pTasker); + /* + * This is definitly shit: it will free the st pointer, + * which makes memory corruption when the queued task finally + * runs. I have commented it out for now. See if this test + * is needed at all. Other options include: + * - dequeuing the transaction from the DevQueue + * - writing an error message and return. This causes a little + * memory leak but as interrupts are not frequent this may be OK if (SCGetInterrupt(con) != eContinue) { - break; + break; } + */ } if (st->reply != NULL) { SCWrite(con,st->reply,eValue); diff --git a/sicshipadaba.c b/sicshipadaba.c index 93ff1a79..90f6aee7 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -2324,12 +2324,9 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, pHdb targetNode = NULL; hdbValue newValue; pDynString parData = NULL; - char error[512]; - int i, status; + char error[512], value[132]; + int i, status, priv; - if (!SCMatchRights(pCon, usUser)) { - return 0; - } if (argc < 3) { SCWrite(pCon, "ERROR: insufficient number of arguments to SetHdbNode", @@ -2342,6 +2339,17 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData, if (targetNode == NULL) { return 0; } + status = GetHdbProperty(targetNode,"priv",value,sizeof(value)); + if(status == 1){ + priv = decodeSICSPriv(value); + } else { + priv = usUser; + } + if (!SCMatchRights(pCon, priv)) { + return 0; + } + + if (!cloneHdbValue(&targetNode->value, &newValue)) { SCWrite(pCon, "ERROR: out of memory cloning node", eError); return 0; @@ -2439,6 +2447,9 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics, char error[512], oriPath[512]; int status; hdbValue newValue; + pDynString parData = NULL, result= NULL; + Protocol protocol = normal_protocol; + OutCode outCode; if (argc < 2) { SCWrite(pCon, "ERROR: need path to node", eError); @@ -2452,7 +2463,26 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics, } memset(&newValue, 0, sizeof(hdbValue)); GetHipadabaPar(targetNode, &newValue, pCon); - status = sendZippedNodeData(targetNode, newValue, pCon); + if(newValue.dataType == HIPTEXT){ + parData = formatValue(newValue, targetNode); + if (parData == NULL) { + SCWrite(pCon, "ERROR: out of memory formatting data", eError); + return 0; + } + if ((protocol = isJSON(pCon)) == 1) + outCode = eHdbEvent; + else + outCode = eValue; + + result = CreateDynString(128, 128); + formatNameValue(protocol, oriPath, GetCharArray(parData), result, + newValue.dataType); + SCWrite(pCon, GetCharArray(result), outCode); + DeleteDynString(parData); + DeleteDynString(result); + } else { + status = sendZippedNodeData(targetNode, newValue, pCon); + } ReleaseHdbValue(&newValue); return status; } diff --git a/sicsutil.c b/sicsutil.c index 74579732..53f89034 100644 --- a/sicsutil.c +++ b/sicsutil.c @@ -30,6 +30,9 @@ int decodeSICSPriv(char *privText) int code = 0; strtolower(privText); + if(strcmp(privText,"manager") == 0){ + return 1; + } while (aCode[code] != NULL) { if (strcmp(aCode[code], privText) == 0) { return code; diff --git a/splitter.c b/splitter.c index 5253ada3..562cdda3 100644 --- a/splitter.c +++ b/splitter.c @@ -1,10 +1,14 @@ /*--------------------------------------------------------------------------- Splitter: a module to break a line in a list of words, - therby determinig type and storing results in a List. + thereby determining type and storing results in a List. Mark Koennecke October 1996 + Fixed a line overrun in SplitText + + Mark Koennecke, July 2011 + Free for non commercial use, no warranties of any kind taken. ---------------------------------------------------------------------------*/ #include "fortify.h" @@ -153,7 +157,7 @@ TokenList *SplitText(char *pLine) i++; } pBueffel[i] = '\0'; - pChar++; +/* pChar++; */ eWhat = eeText; } else { i = 0; diff --git a/tasdrive.c b/tasdrive.c index c2e12494..b338fea8 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -7,6 +7,10 @@ In the long run it might be useful to switch all this to the more general motor list driving code. + + Modified to rather use drivables then motors + + Mark Koennecke, September 2011 --------------------------------------------------------------------*/ #include #include "sics.h" @@ -57,12 +61,12 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon, /* Monochromator */ - status = MotorGetSoftPosition(self->motors[A1], pCon, &val); + status = GetDrivablePosition(self->motors[A1], pCon, &val); if (status == 0) { return status; } theta = val; - status = MotorGetSoftPosition(self->motors[A2], pCon, &val); + status = GetDrivablePosition(self->motors[A2], pCon, &val); if (status == 0) { return status; } @@ -76,12 +80,12 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon, Analyzer */ if (self->tasMode != ELASTIC) { - status = MotorGetSoftPosition(self->motors[A5], pCon, &val); + status = GetDrivablePosition(self->motors[A5], pCon, &val); if (status == 0) { return status; } theta = val; - status = MotorGetSoftPosition(self->motors[A6], pCon, &val); + status = GetDrivablePosition(self->motors[A6], pCon, &val); if (status == 0) { return status; } @@ -97,22 +101,22 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon, /* crystal */ - status = MotorGetSoftPosition(self->motors[A3], pCon, &val); + status = GetDrivablePosition(self->motors[A3], pCon, &val); if (status == 0) { return status; } ang->a3 = val; - status = MotorGetSoftPosition(self->motors[A4], pCon, &val); + status = GetDrivablePosition(self->motors[A4], pCon, &val); if (status == 0) { return status; } ang->sample_two_theta = val; - status = MotorGetSoftPosition(self->motors[SGU], pCon, &val); + status = GetDrivablePosition(self->motors[SGU], pCon, &val); if (status == 0) { return status; } ang->sgu = val; - status = MotorGetSoftPosition(self->motors[SGL], pCon, &val); + status = GetDrivablePosition(self->motors[SGL], pCon, &val); if (status == 0) { return status; } @@ -205,6 +209,7 @@ static int TASHalt(void *pData) { ptasMot self = (ptasMot) pData; int i, length = 12; + pIDrivable pDriv = NULL; assert(self); /** @@ -215,7 +220,8 @@ static int TASHalt(void *pData) } for (i = 0; i < length; i++) { if (self->math->motors[i] != NULL) { - self->math->motors[i]->pDrivInt->Halt(self->math->motors[i]); + pDriv = GetDrivableInterface(self->math->motors[i]); + pDriv->Halt(self->math->motors[i]); } } return 1; @@ -239,7 +245,7 @@ static float getMotorValue(pMotor mot, SConnection * pCon) { float val; - MotorGetSoftPosition(mot, pCon, &val); + GetDrivablePosition(mot, pCon, &val); return val; } @@ -250,17 +256,23 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name, float val, fixed; int status = OKOK; char buffer[132]; + pIDrivable pDriv = NULL; + pDummy dum = NULL; - 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, eWarning); - return OKOK; + dum = (pDummy)mot; + 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, eWarning); + return OKOK; + } } mot->stopped = 0; if (ABS(val - target) > MOTPREC) { - status = mot->pDrivInt->SetValue(mot, pCon, (float) target); + pDriv = GetDrivableInterface(mot); + status = pDriv->SetValue(mot, pCon, (float) target); if (status != OKOK) { return status; } @@ -390,14 +402,13 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon, char error[131]; char pBueffel[256]; float val; + pIDrivable pDrivInt = NULL; MotorGetPar(self->math->motors[A3], "fixed", &val); if ((int) val != 1) { - status = - self->math->motors[A3]->pDrivInt->CheckLimits(self->math-> - motors[A3], - angles.a3, error, - 131); + pDrivInt = GetDrivableInterface(self->math->motors[A3]); + status = pDrivInt->CheckLimits(self->math->motors[A3], + angles.a3, error,131); if (status != 1) { retVal = 0; snprintf(pBueffel, 256, "ERROR: limit violation an a3: %s", error); @@ -405,8 +416,8 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon, } } - status = - self->math->motors[A4]->pDrivInt->CheckLimits(self->math->motors[A4], + pDrivInt = GetDrivableInterface(self->math->motors[A4]); + status = pDrivInt->CheckLimits(self->math->motors[A4], angles. sample_two_theta, error, 131); @@ -417,9 +428,8 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon, } if (driveTilt == 1) { - status = - self->math->motors[SGU]->pDrivInt->CheckLimits(self->math-> - motors[SGU], + pDrivInt = GetDrivableInterface(self->math->motors[SGU]); + status = pDrivInt->CheckLimits(self->math->motors[SGU], angles.sgu, error, 131); if (status != 1) { @@ -428,9 +438,8 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon, SCWrite(pCon, pBueffel, eError); } - status = - self->math->motors[SGL]->pDrivInt->CheckLimits(self->math-> - motors[SGL], + pDrivInt = GetDrivableInterface(self->math->motors[SGL]); + status = pDrivInt->CheckLimits(self->math->motors[SGL], angles.sgl, error, 131); if (status != 1) { @@ -516,6 +525,7 @@ static int checkMotors(ptasMot self, SConnection * pCon) { int i, status, length = 12; int mask[12]; + pIDrivable pDrivInt = NULL; self->math->mustRecalculate = 1; if (self->math->tasMode == ELASTIC) { @@ -532,9 +542,8 @@ static int checkMotors(ptasMot self, SConnection * pCon) for (i = 0; i < 12; i++) { if (self->math->motors[i] != NULL && mask[i] != 0) { - status = - self->math->motors[i]->pDrivInt->CheckStatus(self->math-> - motors[i], pCon); + pDrivInt = GetDrivableInterface(self->math->motors[i]); + status = pDrivInt->CheckStatus(self->math->motors[i], pCon); if (status != HWIdle && status != OKOK) { return status; } diff --git a/tasscanub.c b/tasscanub.c index cc1b189f..9bfa31e6 100644 --- a/tasscanub.c +++ b/tasscanub.c @@ -4,6 +4,10 @@ Mark Koennecke, May 2005, using code from an earlier TASAMAD emulation core. + + Modified to write UV matrix. + + Mark Koennecke, July 2011 ---------------------------------------------------------------------------*/ #include #include @@ -317,6 +321,17 @@ static int TASUBHeader(pScanData self) fprintf(self->fd, "PARAM: AA=%8.4f, BB=%8.4f, CC=%8.4f\n", pTAS->ub->cell.alpha, pTAS->ub->cell.beta, pTAS->ub->cell.gamma); + fprintf(self->fd, "PARAM: UB11=%8.4f, UB12=%8.4f, UB13=%8.4f\n", + pTAS->ub->machine.UB[0][0], pTAS->ub->machine.UB[0][1], pTAS->ub->machine.UB[0][2]); + fprintf(self->fd, "PARAM: UB21=%8.4f, UB22=%8.4f, UB23=%8.4f\n", + pTAS->ub->machine.UB[1][0], pTAS->ub->machine.UB[1][1], pTAS->ub->machine.UB[1][2]); + fprintf(self->fd, "PARAM: UB31=%8.4f, UB32=%8.4f, UB33=%8.4f\n", + pTAS->ub->machine.UB[2][0], pTAS->ub->machine.UB[2][1], pTAS->ub->machine.UB[2][2]); + + fprintf(self->fd, "PARAM: PN1=%8.4f, PN2=%8.4f, PN3=%8.4f\n", + pTAS->ub->machine.planeNormal[0][0], pTAS->ub->machine.planeNormal[1][0], pTAS->ub->machine.planeNormal[2][0]); + + r = pTAS->ub->r1; fprintf(self->fd, "PARAM: AX=%8.4f, AY=%8.4f, AZ=%8.4f\n", r.qe.qh, r.qe.qk, r.qe.ql); diff --git a/tasub.c b/tasub.c index 9948e276..618972eb 100644 --- a/tasub.c +++ b/tasub.c @@ -9,10 +9,15 @@ Reworked to support an updater script for Integration into Hipadaba Mark Koennecke, July 2009 + + Modified to use drivables rather then motors + + Mark Koennecke, September 2011 ----------------------------------------------------------------------*/ #include #include "sics.h" #include "lld.h" +#include "SCinter.h" #include "trigd.h" #include "tasub.h" #include "tasdrive.h" @@ -203,7 +208,7 @@ static int readTASAngles(ptasUB self, SConnection * pCon, ptasAngles ang) /* Monochromator */ - status = MotorGetSoftPosition(self->motors[A2], pCon, &val); + status = GetDrivablePosition(self->motors[A2], pCon, &val); if (status == 0) { return status; } @@ -213,7 +218,7 @@ static int readTASAngles(ptasUB self, SConnection * pCon, ptasAngles ang) Analyzer */ if (self->tasMode != ELASTIC) { - status = MotorGetSoftPosition(self->motors[A6], pCon, &val); + status = GetDrivablePosition(self->motors[A6], pCon, &val); if (status == 0) { return status; } @@ -225,22 +230,22 @@ static int readTASAngles(ptasUB self, SConnection * pCon, ptasAngles ang) /* crystal */ - status = MotorGetSoftPosition(self->motors[A3], pCon, &val); + status = GetDrivablePosition(self->motors[A3], pCon, &val); if (status == 0) { return status; } ang->a3 = val; - status = MotorGetSoftPosition(self->motors[A4], pCon, &val); + status = GetDrivablePosition(self->motors[A4], pCon, &val); if (status == 0) { return status; } ang->sample_two_theta = val; - status = MotorGetSoftPosition(self->motors[SGU], pCon, &val); + status = GetDrivablePosition(self->motors[SGU], pCon, &val); if (status == 0) { return status; } ang->sgu = val; - status = MotorGetSoftPosition(self->motors[SGL], pCon, &val); + status = GetDrivablePosition(self->motors[SGL], pCon, &val); if (status == 0) { return status; } @@ -270,7 +275,21 @@ static void updateTargets(ptasUB pNew, SConnection * pCon) readTASAngles(pNew, pCon, &ang); calcTasQEPosition(&pNew->machine, ang, &pNew->target); } +/*--------------------------------------------------------------------*/ +static pMotor TasFindMotor(SicsInterp *pSics, char *name) +{ + pMotor mot = NULL; + CommandList *pCom = NULL; + mot = FindMotor(pSics,name); + if(mot == NULL){ + pCom = FindCommand(pSics,name); + if(pCom != NULL && GetDrivableInterface(pCom->pData) != NULL){ + mot = (pMotor)pCom->pData; + } + } + return mot; +} /*--------------------------------------------------------------------*/ int TasUBFactory(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -306,34 +325,34 @@ int TasUBFactory(SConnection * pCon, SicsInterp * pSics, void *pData, /* * default names and assignement */ - pNew->motors[0] = FindMotor(pSics, "a1"); - pNew->motors[1] = FindMotor(pSics, "a2"); - pNew->motors[2] = FindMotor(pSics, "mcv"); - pNew->motors[3] = FindMotor(pSics, "mch"); - pNew->motors[4] = FindMotor(pSics, "a3"); - pNew->motors[5] = FindMotor(pSics, "a4"); - pNew->motors[6] = FindMotor(pSics, "sgu"); - pNew->motors[7] = FindMotor(pSics, "sgl"); - pNew->motors[8] = FindMotor(pSics, "a5"); - pNew->motors[9] = FindMotor(pSics, "a6"); - pNew->motors[10] = FindMotor(pSics, "acv"); - pNew->motors[11] = FindMotor(pSics, "ach"); + pNew->motors[0] = TasFindMotor(pSics, "a1"); + pNew->motors[1] = TasFindMotor(pSics, "a2"); + pNew->motors[2] = TasFindMotor(pSics, "mcv"); + pNew->motors[3] = TasFindMotor(pSics, "mch"); + pNew->motors[4] = TasFindMotor(pSics, "a3"); + pNew->motors[5] = TasFindMotor(pSics, "a4"); + pNew->motors[6] = TasFindMotor(pSics, "sgu"); + pNew->motors[7] = TasFindMotor(pSics, "sgl"); + pNew->motors[8] = TasFindMotor(pSics, "a5"); + pNew->motors[9] = TasFindMotor(pSics, "a6"); + pNew->motors[10] = TasFindMotor(pSics, "acv"); + pNew->motors[11] = TasFindMotor(pSics, "ach"); } else { /* * user defined names */ - pNew->motors[0] = FindMotor(pSics, argv[2]); - pNew->motors[1] = FindMotor(pSics, argv[3]); - pNew->motors[2] = FindMotor(pSics, argv[4]); - pNew->motors[3] = FindMotor(pSics, argv[5]); - pNew->motors[4] = FindMotor(pSics, argv[6]); - pNew->motors[5] = FindMotor(pSics, argv[7]); - pNew->motors[6] = FindMotor(pSics, argv[8]); - pNew->motors[7] = FindMotor(pSics, argv[9]); - pNew->motors[8] = FindMotor(pSics, argv[10]); - pNew->motors[9] = FindMotor(pSics, argv[11]); - pNew->motors[10] = FindMotor(pSics, argv[12]); - pNew->motors[11] = FindMotor(pSics, argv[13]); + pNew->motors[0] = TasFindMotor(pSics, argv[2]); + pNew->motors[1] = TasFindMotor(pSics, argv[3]); + pNew->motors[2] = TasFindMotor(pSics, argv[4]); + pNew->motors[3] = TasFindMotor(pSics, argv[5]); + pNew->motors[4] = TasFindMotor(pSics, argv[6]); + pNew->motors[5] = TasFindMotor(pSics, argv[7]); + pNew->motors[6] = TasFindMotor(pSics, argv[8]); + pNew->motors[7] = TasFindMotor(pSics, argv[9]); + pNew->motors[8] = TasFindMotor(pSics, argv[10]); + pNew->motors[9] = TasFindMotor(pSics, argv[11]); + pNew->motors[10] = TasFindMotor(pSics, argv[12]); + pNew->motors[11] = TasFindMotor(pSics, argv[13]); } /* curvature motors may be missing, anything else is a serious problem @@ -1047,7 +1066,7 @@ static int addAuxReflection(ptasUB self, SConnection * pCon, if (status != 1) { r2.qe.kf = self->current.kf; r2.qe.ki = self->current.ki; - MotorGetSoftPosition(self->motors[A3], pCon, &value); + GetDrivablePosition(self->motors[A3], pCon, &value); r2.angles.a3 = value + 180.; r2.angles.sgu = .0; r2.angles.sgl = .0; diff --git a/test/DataNumber b/test/DataNumber index 85ca8a81..1d6489e6 100644 --- a/test/DataNumber +++ b/test/DataNumber @@ -1,3 +1,3 @@ - 324 + 332 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach!