From ce565b4d50c16d6e81046739341c16df6807f3b9 Mon Sep 17 00:00:00 2001
From: koennecke
Date: Fri, 23 Sep 2011 07:55:49 +0000
Subject: [PATCH] - Fixed a normalisation problem in diffscan when the first
value did not have enough counts - Reduced polling frequency in emon -
Fixed a scriptcontext bug which would cause it to dump core in SctTransact
on interrupts - Fixed an issue with missing at the end of batch files -
Added a feature which does not call halt when counting stops in hmcontrol.c
This is necessary for the BOA CCD - Initalized doNotFree properly in
hipadaba.c - Added the travelling salesman reflection measurement algorithm -
Added another component to amorset - Removed old SicsWait from nserver.c -
Added a means to nxscript to write 16 bit data for BOA - Modified tasub to
accept a drivabel as a motor and not only a motor. This became necessary to
make EIGER work as A2 on EIGER is a virtual motor
SKIPPED:
psi/amorcomp.h
psi/amordrive.h
psi/amorset.c
psi/amorset.h
psi/amorset.tex
psi/amorset.w
psi/el734hp.c
psi/el737hpdriv.c
psi/make_gen
psi/pardef.c
psi/polterwrite.c
psi/psi.c
psi/sinqhttpopt.c
---
SCinter.c | 4 +-
access.c | 3 +
devser.c | 2 +-
diffscan.c | 15 ++-
doc/manager/nxscript.htm | 4 +
emon.c | 14 ++-
emon.h | 36 +++----
emon.i | 1 +
emonitor.tex | 9 +-
emonitor.w | 1 +
exebuf.c | 14 ++-
exeman.c | 1 +
fourmess.c | 204 ++++++++++++++++++++++++++++++++++++++-
hdbtable.c | 57 ++++++++++-
hipadaba.c | 7 ++
hmcontrol.c | 59 +++++++++--
hmcontrol.h | 1 +
interface.c | 2 +-
motorlist.c | 1 -
nserver.c | 26 +----
nxscript.c | 115 +++++++++++++++++++++-
scriptcontext.c | 19 +++-
sicshipadaba.c | 42 ++++++--
sicsutil.c | 3 +
splitter.c | 8 +-
tasdrive.c | 75 +++++++-------
tasscanub.c | 15 +++
tasub.c | 81 ++++++++++------
test/DataNumber | 2 +-
29 files changed, 676 insertions(+), 145 deletions(-)
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!