- 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 <nl> 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
This commit is contained in:
koennecke
2011-09-23 07:55:49 +00:00
parent 2dd46f0968
commit ce565b4d50
29 changed files with 676 additions and 145 deletions

View File

@ -895,7 +895,9 @@ int InterpWrite(SicsInterp * pSics, char *buffer)
assert(pSics); assert(pSics);
pTcl = (Tcl_Interp *) pSics->pTcl; pTcl = (Tcl_Interp *) pSics->pTcl;
if(Tcl_GetStringResult(pTcl) != buffer){
Tcl_SetResult(pTcl, buffer, TCL_VOLATILE); Tcl_SetResult(pTcl, buffer, TCL_VOLATILE);
}
return 1; return 1;
} }

View File

@ -21,6 +21,9 @@ int decodeSICSPriv(char *privText)
int code = 0; int code = 0;
strtolower(privText); strtolower(privText);
if(strcmp(privText,"manager") == 0){
return 1;
}
while (aCode[code] != NULL) { while (aCode[code] != NULL) {
if (strcmp(aCode[code], privText) == 0) { if (strcmp(aCode[code], privText) == 0) {
return code; return code;

View File

@ -327,7 +327,7 @@ static void DevReset(DevSer * devser)
devser->current->kill(devser->current->data); devser->current->kill(devser->current->data);
} }
devser->killCurrent = 0; devser->killCurrent = 0;
free(devser->current); /* free(devser->current); */
} }
} }

View File

@ -322,11 +322,22 @@ static int DiffScanTask(void *pData)
countValue = (float) data->lCount; countValue = (float) data->lCount;
rawCount = data->lCount; rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor - 1]; 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 { } else {
if (data->Monitors[self->scaleMonitor - 1] - if (data->Monitors[self->scaleMonitor - 1] -
self->last.Monitors[self->scaleMonitor - 1] < 5) { self->last.Monitors[self->scaleMonitor - 1] < 5) {
SCWrite(self->scanObject->pCon, "WARNING: low count rate", eLog); 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; rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor - 1]; rawMon = data->Monitors[self->scaleMonitor - 1];
@ -344,6 +355,8 @@ static int DiffScanTask(void *pData)
fPos, countValue, rawCount, rawMon); fPos, countValue, rawCount, rawMon);
SCWrite(self->scanObject->pCon, pBueffel, eLog); SCWrite(self->scanObject->pCon, pBueffel, eLog);
InvokeCallBack(self->scanObject->pCall, SCANPOINT, self->scanObject); 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 check for interrupt

View File

@ -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 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 histogram memory; then the histogram memory data is written. Or it can be
a sicsdata object, the value of which will then be written. a sicsdata object, the value of which will then be written.
<dt>nxscript putslab16 alias startlist sizelist obj
<dd>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.
</dl> </dl>
</p> </p>
<H1>Automatic Updating of NeXus Files</H1> <H1>Automatic Updating of NeXus Files</H1>

12
emon.c
View File

@ -6,6 +6,8 @@
Mark Koennecke, Juli 1997 Mark Koennecke, Juli 1997
Reduced polling frequency to any 20 seconds, Mark Koennecke, August 2011
Copyright: Copyright:
Labor fuer Neutronenstreuung Labor fuer Neutronenstreuung
@ -39,6 +41,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <time.h>
#include <tcl.h> /* for DString */ #include <tcl.h> /* for DString */
#include "fortify.h" #include "fortify.h"
#include "lld.h" #include "lld.h"
@ -46,6 +49,11 @@
#include "emon.i" #include "emon.i"
#include "emon.h" #include "emon.h"
#include "event.h" #include "event.h"
/*
* any how many seconds we check
*/
#define SCANINTERVALL 20
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
pEnvMon CreateEnvMon(void) pEnvMon CreateEnvMon(void)
{ {
@ -68,6 +76,7 @@ pEnvMon CreateEnvMon(void)
free(pNew); free(pNew);
return NULL; return NULL;
} }
pNew->nextRun = time(NULL)+SCANINTERVALL;
AddCommand(pServ->pSics, "emon", EVWrapper, DeleteEnvMon, pNew); AddCommand(pServ->pSics, "emon", EVWrapper, DeleteEnvMon, pNew);
return pNew; return pNew;
} }
@ -340,7 +349,10 @@ int EnvMonTask(void *pData)
return 0; return 0;
} }
if(time(NULL) > self->nextRun){
EVMonitorControllers(self); EVMonitorControllers(self);
self->nextRun = time(NULL) + SCANINTERVALL;
}
return 1; return 1;
} }

6
emon.h
View File

@ -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 E N V I R O N M E N T M O N I T O R
@ -17,7 +17,7 @@
typedef struct __EnvMon *pEnvMon; typedef struct __EnvMon *pEnvMon;
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
#line 85 "emonitor.w" #line 86 "emonitor.w"
pEnvMon CreateEnvMon(void); pEnvMon CreateEnvMon(void);
@ -39,6 +39,6 @@ pEnvMon FindEMON(SicsInterp * pSics);
int EnvMonTask(void *pEv); int EnvMonTask(void *pEv);
void EnvMonSignal(void *pEndv, int iSignal, void *pSigData); void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);
#line 164 "emonitor.w" #line 165 "emonitor.w"
#endif #endif

1
emon.i
View File

@ -10,6 +10,7 @@
pObjectDescriptor pDes; pObjectDescriptor pDes;
int iList; int iList;
int iEnd; int iEnd;
time_t nextRun;
} EnvMon; } EnvMon;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
typedef struct { typedef struct {

View File

@ -68,6 +68,7 @@ $\langle$emondat {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ pObjectDescriptor pDes;@\\ \mbox{}\verb@ pObjectDescriptor pDes;@\\
\mbox{}\verb@ int iList;@\\ \mbox{}\verb@ int iList;@\\
\mbox{}\verb@ int iEnd;@\\ \mbox{}\verb@ int iEnd;@\\
\mbox{}\verb@ time_t nextRun;@\\
\mbox{}\verb@ } EnvMon;@\\ \mbox{}\verb@ } EnvMon;@\\
\mbox{}\verb@/*---------------------------------------------------------------------------*/@\\ \mbox{}\verb@/*---------------------------------------------------------------------------*/@\\
\mbox{}\verb@ typedef struct {@\\ \mbox{}\verb@ typedef struct {@\\
@ -77,7 +78,7 @@ $\langle$emondat {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ } EVEntry, *pEVEntry; @\\ \mbox{}\verb@ } EVEntry, *pEVEntry; @\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@\\ \mbox{}\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
@ -120,7 +121,7 @@ $\langle$emonint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ @\\ \mbox{}\verb@ @\\
\mbox{}\verb@ int EnvMonTask(void *pEv);@\\ \mbox{}\verb@ int EnvMonTask(void *pEv);@\\
\mbox{}\verb@ void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);@\\ \mbox{}\verb@ void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-1ex} \vspace{-1ex}
\footnotesize\addtolength{\baselineskip}{-1ex} \footnotesize\addtolength{\baselineskip}{-1ex}
@ -193,7 +194,7 @@ controllers configured into SICS.
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\ \mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$emonint {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@$\langle$emonint {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@#endif@\\ \mbox{}\verb@#endif@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]
@ -211,7 +212,7 @@ controllers configured into SICS.
\mbox{}\verb@ Mark Koennecke, Juli 1997@\\ \mbox{}\verb@ Mark Koennecke, Juli 1997@\\
\mbox{}\verb@---------------------------------------------------------------------------*/@\\ \mbox{}\verb@---------------------------------------------------------------------------*/@\\
\mbox{}\verb@@$\langle$emondat {\footnotesize ?}$\rangle$\verb@@\\ \mbox{}\verb@@$\langle$emondat {\footnotesize ?}$\rangle$\verb@@\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\Diamond$
\end{list} \end{list}
\vspace{-2ex} \vspace{-2ex}
\end{minipage}\\[4ex] \end{minipage}\\[4ex]

View File

@ -63,6 +63,7 @@ The environment monitor uses the following datastructures:
pObjectDescriptor pDes; pObjectDescriptor pDes;
int iList; int iList;
int iEnd; int iEnd;
time_t nextRun;
} EnvMon; } EnvMon;
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
typedef struct { typedef struct {

View File

@ -95,9 +95,9 @@ static char *locateName(char *filename)
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
int exeBufLoad(pExeBuf self, char *filename) int exeBufLoad(pExeBuf self, char *filename)
{ {
char line[256]; char line[256], *pPtr;
FILE *fd = NULL; FILE *fd = NULL;
int status; int status, idx;
assert(self); assert(self);
fd = fopen(filename, "r"); fd = fopen(filename, "r");
@ -114,6 +114,16 @@ int exeBufLoad(pExeBuf self, char *filename)
} }
} }
fclose(fd); 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) { if (self->name != NULL) {
free(self->name); free(self->name);
} }

View File

@ -721,6 +721,7 @@ static int appendLine(pExeMan self, SConnection * pCon,
SCWrite(pCon, "ERROR: no upload in operation", eError); SCWrite(pCon, "ERROR: no upload in operation", eError);
return 0; return 0;
} }
memset(pLine,0,sizeof(pLine));
Arg2Text(argc - 2, &argv[2], pLine, 1023); Arg2Text(argc - 2, &argv[2], pLine, 1023);
exeBufAppend(self->uploadBuffer, pLine); exeBufAppend(self->uploadBuffer, pLine);
return 1; return 1;

View File

@ -34,6 +34,9 @@
#include "scanvar.h" #include "scanvar.h"
#include "scan.i" #include "scan.i"
#include "sdynar.h" #include "sdynar.h"
#include "lld.h"
extern char *trim(char *);
extern void SNXFormatTime(char *pBueffel, int iLen); 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, static int SortRef(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar) pHdb par[], int nPar)
{ {
double *sortlist, d, lambda, om, hkl[4], ang[4]; double *sortlist, d, lambda, om, hkl[4], ang[4];
const double *cell; const double *cell;
double *hklc;
int nRefl, i, j; int nRefl, i, j;
MATRIX B, H, Z1; MATRIX B, H, Z1;
lattice direct; lattice direct;
@ -860,7 +866,195 @@ static int SortRef(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
SCSendOK(pCon); SCSendOK(pCon);
return 1; 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) static int FourMessSave(void *data, char *name, FILE * fd)
{ {
@ -982,7 +1176,15 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics)
cmd = cmd =
AddSICSHdbPar(pNew->objectNode, "indsort", usUser, AddSICSHdbPar(pNew->objectNode, "indsort", usUser,
MakeSICSFunc(SortRef)); 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 = cmd =
AddSICSHdbPar(pNew->objectNode, "template", usMugger, AddSICSHdbPar(pNew->objectNode, "template", usMugger,

View File

@ -295,6 +295,53 @@ static int GetRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
return 1; 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, static int ListTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
pHdb par[], int nPar) pHdb par[], int nPar)
{ {
@ -413,6 +460,14 @@ pSICSOBJ MakeHdbTable(char *name, char *hdbclass)
SetHdbProperty(cmd,"priv","user"); SetHdbProperty(cmd,"priv","user");
node = MakeHipadabaNode("id",HIPTEXT,1); node = MakeHipadabaNode("id",HIPTEXT,1);
SetHdbProperty(node,"priv","user"); 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); AddHipadabaChild(cmd,node, NULL);
return result; return result;

View File

@ -354,6 +354,7 @@ hdbValue MakeHdbInt(int initValue)
result.dataType = HIPINT; result.dataType = HIPINT;
result.arrayLength = 1; result.arrayLength = 1;
result.v.intValue = initValue; result.v.intValue = initValue;
result.doNotFree = 0;
return result; return result;
} }
@ -365,6 +366,7 @@ hdbValue MakeHdbFloat(double initValue)
result.dataType = HIPFLOAT; result.dataType = HIPFLOAT;
result.arrayLength = 1; result.arrayLength = 1;
result.v.doubleValue = initValue; result.v.doubleValue = initValue;
result.doNotFree = 0;
return result; return result;
} }
@ -376,6 +378,7 @@ hdbValue MakeHdbText(char *initText)
result.dataType = HIPTEXT; result.dataType = HIPTEXT;
result.v.text = initText; /* no strdup here ! */ result.v.text = initText; /* no strdup here ! */
result.arrayLength = strlen(initText); result.arrayLength = strlen(initText);
result.doNotFree = 0;
return result; return result;
} }
@ -387,6 +390,7 @@ hdbValue MakeHdbIntArray(int length, int *data)
result.dataType = HIPINTAR; result.dataType = HIPINTAR;
result.arrayLength = length; result.arrayLength = length;
result.v.intArray = data; result.v.intArray = data;
result.doNotFree = 0;
return result; return result;
} }
@ -398,6 +402,7 @@ hdbValue MakeHdbFloatArray(int length, double *data)
result.dataType = HIPFLOATAR; result.dataType = HIPFLOATAR;
result.arrayLength = length; result.arrayLength = length;
result.v.floatArray = data; result.v.floatArray = data;
result.doNotFree = 0;
return result; return result;
} }
@ -408,6 +413,7 @@ hdbValue MakeHdbFunc(voidFunc * func)
result.dataType = HIPFUNC; result.dataType = HIPFUNC;
result.v.func = func; result.v.func = func;
result.doNotFree = 0;
return result; return result;
} }
@ -418,6 +424,7 @@ hdbValue MakeHdbObj(void *obj)
result.dataType = HIPOBJ; result.dataType = HIPOBJ;
result.v.obj = obj; result.v.obj = obj;
result.doNotFree = 0;
return result; return result;
} }

View File

@ -9,11 +9,19 @@
copyright: see copyright.h copyright: see copyright.h
Mark Koennecke, June 2001 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 <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <tcl.h> #include <tcl.h>
#include <unistd.h>
#include "fortify.h" #include "fortify.h"
#include "hmcontrol.h" #include "hmcontrol.h"
#include "HistMem.h" #include "HistMem.h"
@ -66,7 +74,7 @@ static int HMCStart(void *pData, SConnection * pCon)
return HWFault; return HWFault;
} }
for (i = 0; i < self->nSlaves; i++) { for (i = 1; i < self->nSlaves; i++) {
ReleaseCountLock(self->slaves[i]); ReleaseCountLock(self->slaves[i]);
status = self->slaves[i]->StartCount(self->slaveData[i], pCon); status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
if (status != OKOK) { if (status != OKOK) {
@ -74,6 +82,19 @@ static int HMCStart(void *pData, SConnection * pCon)
return status; 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. Warning: this assumes that slaves 1 - MAXSLAVE are histogram memories.
If this assumption does not hold, change this code to check if this 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 stop counting on slaves when finished or when an error
occurred. occurred.
*/ */
if(self->stopSlaves){
HMCHalt(self); HMCHalt(self);
}
ReleaseCountLock(self->pCount);
self->checkSlaves = 1; self->checkSlaves = 1;
status = HWBusy; status = HWBusy;
} }
@ -301,6 +325,7 @@ int MakeHMControl(SConnection * pCon, SicsInterp * pSics,
pNew->slaves[pNew->nSlaves] = pCount; pNew->slaves[pNew->nSlaves] = pCount;
pNew->slaveData[pNew->nSlaves] = pCom->pData; pNew->slaveData[pNew->nSlaves] = pCom->pData;
pNew->nSlaves++; pNew->nSlaves++;
pNew->stopSlaves = 1;
} }
/* /*
@ -335,13 +360,18 @@ int HMControlAction(SConnection * pCon, SicsInterp * pSics,
*/ */
self = (pHMcontrol) pData; self = (pHMcontrol) pData;
assert(self); assert(self);
if (argc < 4) { if (argc < 2) {
snprintf(pBueffel, 131, "ERROR: Usage %s start preset mode", argv[0]); snprintf(pBueffel, 131, "ERROR: Usage %s start preset mode", argv[0]);
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
return 0; return 0;
} }
strtolower(argv[1]); strtolower(argv[1]);
if (strcmp(argv[1], "start") == 0) { 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 interpret count parameters
*/ */
@ -374,6 +404,15 @@ int HMControlAction(SConnection * pCon, SicsInterp * pSics,
} }
InvokeCallBack(self->pCall, COUNTSTART, pCon); InvokeCallBack(self->pCall, COUNTSTART, pCon);
SCSendOK(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 { } else {
SCWrite(pCon, "ERROR: subcommand not recognized", eError); SCWrite(pCon, "ERROR: subcommand not recognized", eError);
return 0; return 0;

View File

@ -33,6 +33,7 @@ typedef struct {
CounterMode eMode; CounterMode eMode;
pICallBack pCall; pICallBack pCall;
int checkSlaves; int checkSlaves;
int stopSlaves;
} HMcontrol, *pHMcontrol; } HMcontrol, *pHMcontrol;

View File

@ -162,7 +162,7 @@ int GetDrivablePosition(void *pObject, SConnection * pCon, float *fPos)
return MotorGetSoftPosition(pMot, pCon, fPos); return MotorGetSoftPosition(pMot, pCon, fPos);
} }
value = pDriv->GetValue(pObject, pCon); value = pDriv->GetValue(pObject, pCon);
if (value < 9999.99) { if (value < -9999.99) {
return 0; return 0;
} }
*fPos = value; *fPos = value;

View File

@ -169,7 +169,6 @@ static float MOLIGetValue(void *data, SConnection * pCon)
pIDrivable makeMotListInterface() pIDrivable makeMotListInterface()
{ {
pIDrivable pDriv = NULL; pIDrivable pDriv = NULL;
pDriv = CreateDrivableInterface(); pDriv = CreateDrivableInterface();
if (pDriv == NULL) { if (pDriv == NULL) {
return NULL; return NULL;

View File

@ -478,31 +478,7 @@ int UserWait(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1; 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) int SicsWait(long lTime)
{ {
pTaskMan pTasker = NULL; pTaskMan pTasker = NULL;

View File

@ -971,7 +971,7 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self,
memsec = (pCounter) FindCommandData(pSics, argv[5], "HistMemSec"); memsec = (pCounter) FindCommandData(pSics, argv[5], "HistMemSec");
if(memsec != NULL){ if(memsec != NULL){
node = GetHipadabaNode(memsec->pDes->parNode,"data"); node = GetHipadabaNode(memsec->pDes->parNode,"data");
if(data != NULL){ if(node == NULL){
SCWrite(pCon,"ERROR: ?? data node to second gen HM not found", eError); SCWrite(pCon,"ERROR: ?? data node to second gen HM not found", eError);
return; return;
} }
@ -1001,6 +1001,116 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self,
eLogError); 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, 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) { } else if (strcmp(argv[1], "putslab") == 0) {
/*===============*/ /*===============*/
putSlab(pCon, pSics, self, argc, argv); putSlab(pCon, pSics, self, argc, argv);
} else if (strcmp(argv[1], "putslab16") == 0) {
/*===============*/
putSlab16(pCon, pSics, self, argc, argv);
} else { } else {
SCPrintf(pCon, eLogError, "ERROR: put command %s not recognised", argv[1] ); SCPrintf(pCon, eLogError, "ERROR: put command %s not recognised", argv[1] );
} }

View File

@ -1174,19 +1174,20 @@ static char *TransactionHandler(void *actionData, char *lastReply,
return st->command; return st->command;
} else { } else {
st->sent = 2; st->sent = 2;
/*
if (st->controller->verbose) { if (st->controller->verbose) {
SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply); SCPrintf(st->con, eLog, "%6.3f reply : %s", secondsOfMinute(), lastReply);
} }
if (st->controller->fd != NULL) { if (st->controller->fd != NULL) {
fprintf(st->controller->fd,"%6.3f reply : %s\n", secondsOfMinute(), lastReply); fprintf(st->controller->fd,"%6.3f reply : %s\n", secondsOfMinute(), lastReply);
} }
*/
/* printf("Transact: %s got %s\n", st->command, 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); traceIO(st->controller->node->name, "transreply:%s", lastReply);
} else { } else {
traceIO("sctunknown", "transreply:%s", lastReply); traceIO("sctunknown", "transreply:%s", lastReply);
} }
st->reply = strdup(lastReply); st->reply = strdup(lastReply);
return NULL; return NULL;
} }
@ -1218,14 +1219,24 @@ static int SctTransactCmd(pSICSOBJ ccmd, SConnection * con,
st->con = SCCopyConnection(con); st->con = SCCopyConnection(con);
st->command = strdup(par[0]->value.v.text); st->command = strdup(par[0]->value.v.text);
st->controller = c; st->controller = c;
st->sent = 0;
DevQueue(c->devser, st, WritePRIO, DevQueue(c->devser, st, WritePRIO,
TransactionHandler, SctTransactMatch, NULL, NULL); TransactionHandler, SctTransactMatch, NULL, NULL);
while (st->sent != 2) { while (st->sent != 2) {
TaskYield(pServ->pTasker); 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) { if (SCGetInterrupt(con) != eContinue) {
break; break;
} }
*/
} }
if (st->reply != NULL) { if (st->reply != NULL) {
SCWrite(con,st->reply,eValue); SCWrite(con,st->reply,eValue);

View File

@ -2324,12 +2324,9 @@ static int SetHdbNode(SConnection * pCon, SicsInterp * pSics, void *pData,
pHdb targetNode = NULL; pHdb targetNode = NULL;
hdbValue newValue; hdbValue newValue;
pDynString parData = NULL; pDynString parData = NULL;
char error[512]; char error[512], value[132];
int i, status; int i, status, priv;
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
if (argc < 3) { if (argc < 3) {
SCWrite(pCon, "ERROR: insufficient number of arguments to SetHdbNode", 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) { if (targetNode == NULL) {
return 0; 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)) { if (!cloneHdbValue(&targetNode->value, &newValue)) {
SCWrite(pCon, "ERROR: out of memory cloning node", eError); SCWrite(pCon, "ERROR: out of memory cloning node", eError);
return 0; return 0;
@ -2439,6 +2447,9 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics,
char error[512], oriPath[512]; char error[512], oriPath[512];
int status; int status;
hdbValue newValue; hdbValue newValue;
pDynString parData = NULL, result= NULL;
Protocol protocol = normal_protocol;
OutCode outCode;
if (argc < 2) { if (argc < 2) {
SCWrite(pCon, "ERROR: need path to node", eError); SCWrite(pCon, "ERROR: need path to node", eError);
@ -2452,7 +2463,26 @@ static int ZipGetHdbNode(SConnection * pCon, SicsInterp * pSics,
} }
memset(&newValue, 0, sizeof(hdbValue)); memset(&newValue, 0, sizeof(hdbValue));
GetHipadabaPar(targetNode, &newValue, pCon); GetHipadabaPar(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); status = sendZippedNodeData(targetNode, newValue, pCon);
}
ReleaseHdbValue(&newValue); ReleaseHdbValue(&newValue);
return status; return status;
} }

View File

@ -30,6 +30,9 @@ int decodeSICSPriv(char *privText)
int code = 0; int code = 0;
strtolower(privText); strtolower(privText);
if(strcmp(privText,"manager") == 0){
return 1;
}
while (aCode[code] != NULL) { while (aCode[code] != NULL) {
if (strcmp(aCode[code], privText) == 0) { if (strcmp(aCode[code], privText) == 0) {
return code; return code;

View File

@ -1,10 +1,14 @@
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
Splitter: a module to break a line in a list of words, 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 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. Free for non commercial use, no warranties of any kind taken.
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
#include "fortify.h" #include "fortify.h"
@ -153,7 +157,7 @@ TokenList *SplitText(char *pLine)
i++; i++;
} }
pBueffel[i] = '\0'; pBueffel[i] = '\0';
pChar++; /* pChar++; */
eWhat = eeText; eWhat = eeText;
} else { } else {
i = 0; i = 0;

View File

@ -7,6 +7,10 @@
In the long run it might be useful to switch all this to the more In the long run it might be useful to switch all this to the more
general motor list driving code. general motor list driving code.
Modified to rather use drivables then motors
Mark Koennecke, September 2011
--------------------------------------------------------------------*/ --------------------------------------------------------------------*/
#include <assert.h> #include <assert.h>
#include "sics.h" #include "sics.h"
@ -57,12 +61,12 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon,
/* /*
Monochromator Monochromator
*/ */
status = MotorGetSoftPosition(self->motors[A1], pCon, &val); status = GetDrivablePosition(self->motors[A1], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
theta = val; theta = val;
status = MotorGetSoftPosition(self->motors[A2], pCon, &val); status = GetDrivablePosition(self->motors[A2], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
@ -76,12 +80,12 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon,
Analyzer Analyzer
*/ */
if (self->tasMode != ELASTIC) { if (self->tasMode != ELASTIC) {
status = MotorGetSoftPosition(self->motors[A5], pCon, &val); status = GetDrivablePosition(self->motors[A5], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
theta = val; theta = val;
status = MotorGetSoftPosition(self->motors[A6], pCon, &val); status = GetDrivablePosition(self->motors[A6], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
@ -97,22 +101,22 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon,
/* /*
crystal crystal
*/ */
status = MotorGetSoftPosition(self->motors[A3], pCon, &val); status = GetDrivablePosition(self->motors[A3], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
ang->a3 = val; ang->a3 = val;
status = MotorGetSoftPosition(self->motors[A4], pCon, &val); status = GetDrivablePosition(self->motors[A4], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
ang->sample_two_theta = val; ang->sample_two_theta = val;
status = MotorGetSoftPosition(self->motors[SGU], pCon, &val); status = GetDrivablePosition(self->motors[SGU], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
ang->sgu = val; ang->sgu = val;
status = MotorGetSoftPosition(self->motors[SGL], pCon, &val); status = GetDrivablePosition(self->motors[SGL], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
@ -205,6 +209,7 @@ static int TASHalt(void *pData)
{ {
ptasMot self = (ptasMot) pData; ptasMot self = (ptasMot) pData;
int i, length = 12; int i, length = 12;
pIDrivable pDriv = NULL;
assert(self); assert(self);
/** /**
@ -215,7 +220,8 @@ static int TASHalt(void *pData)
} }
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if (self->math->motors[i] != NULL) { 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; return 1;
@ -239,7 +245,7 @@ static float getMotorValue(pMotor mot, SConnection * pCon)
{ {
float val; float val;
MotorGetSoftPosition(mot, pCon, &val); GetDrivablePosition(mot, pCon, &val);
return val; return val;
} }
@ -250,7 +256,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
float val, fixed; float val, fixed;
int status = OKOK; int status = OKOK;
char buffer[132]; char buffer[132];
pIDrivable pDriv = NULL;
pDummy dum = NULL;
dum = (pDummy)mot;
if(strcmp(dum->pDescriptor->name,"Motor") == 0){
val = getMotorValue(mot, pCon); val = getMotorValue(mot, pCon);
MotorGetPar(mot, "fixed", &fixed); MotorGetPar(mot, "fixed", &fixed);
if (ABS(fixed - 1.0) < .1) { if (ABS(fixed - 1.0) < .1) {
@ -258,9 +268,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
SCWrite(pCon, buffer, eWarning); SCWrite(pCon, buffer, eWarning);
return OKOK; return OKOK;
} }
}
mot->stopped = 0; mot->stopped = 0;
if (ABS(val - target) > MOTPREC) { 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) { if (status != OKOK) {
return status; return status;
} }
@ -390,14 +402,13 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon,
char error[131]; char error[131];
char pBueffel[256]; char pBueffel[256];
float val; float val;
pIDrivable pDrivInt = NULL;
MotorGetPar(self->math->motors[A3], "fixed", &val); MotorGetPar(self->math->motors[A3], "fixed", &val);
if ((int) val != 1) { if ((int) val != 1) {
status = pDrivInt = GetDrivableInterface(self->math->motors[A3]);
self->math->motors[A3]->pDrivInt->CheckLimits(self->math-> status = pDrivInt->CheckLimits(self->math->motors[A3],
motors[A3], angles.a3, error,131);
angles.a3, error,
131);
if (status != 1) { if (status != 1) {
retVal = 0; retVal = 0;
snprintf(pBueffel, 256, "ERROR: limit violation an a3: %s", error); snprintf(pBueffel, 256, "ERROR: limit violation an a3: %s", error);
@ -405,8 +416,8 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon,
} }
} }
status = pDrivInt = GetDrivableInterface(self->math->motors[A4]);
self->math->motors[A4]->pDrivInt->CheckLimits(self->math->motors[A4], status = pDrivInt->CheckLimits(self->math->motors[A4],
angles. angles.
sample_two_theta, sample_two_theta,
error, 131); error, 131);
@ -417,9 +428,8 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon,
} }
if (driveTilt == 1) { if (driveTilt == 1) {
status = pDrivInt = GetDrivableInterface(self->math->motors[SGU]);
self->math->motors[SGU]->pDrivInt->CheckLimits(self->math-> status = pDrivInt->CheckLimits(self->math->motors[SGU],
motors[SGU],
angles.sgu, error, angles.sgu, error,
131); 131);
if (status != 1) { if (status != 1) {
@ -428,9 +438,8 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon,
SCWrite(pCon, pBueffel, eError); SCWrite(pCon, pBueffel, eError);
} }
status = pDrivInt = GetDrivableInterface(self->math->motors[SGL]);
self->math->motors[SGL]->pDrivInt->CheckLimits(self->math-> status = pDrivInt->CheckLimits(self->math->motors[SGL],
motors[SGL],
angles.sgl, error, angles.sgl, error,
131); 131);
if (status != 1) { if (status != 1) {
@ -516,6 +525,7 @@ static int checkMotors(ptasMot self, SConnection * pCon)
{ {
int i, status, length = 12; int i, status, length = 12;
int mask[12]; int mask[12];
pIDrivable pDrivInt = NULL;
self->math->mustRecalculate = 1; self->math->mustRecalculate = 1;
if (self->math->tasMode == ELASTIC) { if (self->math->tasMode == ELASTIC) {
@ -532,9 +542,8 @@ static int checkMotors(ptasMot self, SConnection * pCon)
for (i = 0; i < 12; i++) { for (i = 0; i < 12; i++) {
if (self->math->motors[i] != NULL && mask[i] != 0) { if (self->math->motors[i] != NULL && mask[i] != 0) {
status = pDrivInt = GetDrivableInterface(self->math->motors[i]);
self->math->motors[i]->pDrivInt->CheckStatus(self->math-> status = pDrivInt->CheckStatus(self->math->motors[i], pCon);
motors[i], pCon);
if (status != HWIdle && status != OKOK) { if (status != HWIdle && status != OKOK) {
return status; return status;
} }

View File

@ -4,6 +4,10 @@
Mark Koennecke, May 2005, using code from an earlier TASAMAD emulation Mark Koennecke, May 2005, using code from an earlier TASAMAD emulation
core. core.
Modified to write UV matrix.
Mark Koennecke, July 2011
---------------------------------------------------------------------------*/ ---------------------------------------------------------------------------*/
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
@ -317,6 +321,17 @@ static int TASUBHeader(pScanData self)
fprintf(self->fd, "PARAM: AA=%8.4f, BB=%8.4f, CC=%8.4f\n", 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); 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; r = pTAS->ub->r1;
fprintf(self->fd, "PARAM: AX=%8.4f, AY=%8.4f, AZ=%8.4f\n", fprintf(self->fd, "PARAM: AX=%8.4f, AY=%8.4f, AZ=%8.4f\n",
r.qe.qh, r.qe.qk, r.qe.ql); r.qe.qh, r.qe.qk, r.qe.ql);

81
tasub.c
View File

@ -9,10 +9,15 @@
Reworked to support an updater script for Integration into Hipadaba Reworked to support an updater script for Integration into Hipadaba
Mark Koennecke, July 2009 Mark Koennecke, July 2009
Modified to use drivables rather then motors
Mark Koennecke, September 2011
----------------------------------------------------------------------*/ ----------------------------------------------------------------------*/
#include <assert.h> #include <assert.h>
#include "sics.h" #include "sics.h"
#include "lld.h" #include "lld.h"
#include "SCinter.h"
#include "trigd.h" #include "trigd.h"
#include "tasub.h" #include "tasub.h"
#include "tasdrive.h" #include "tasdrive.h"
@ -203,7 +208,7 @@ static int readTASAngles(ptasUB self, SConnection * pCon, ptasAngles ang)
/* /*
Monochromator Monochromator
*/ */
status = MotorGetSoftPosition(self->motors[A2], pCon, &val); status = GetDrivablePosition(self->motors[A2], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
@ -213,7 +218,7 @@ static int readTASAngles(ptasUB self, SConnection * pCon, ptasAngles ang)
Analyzer Analyzer
*/ */
if (self->tasMode != ELASTIC) { if (self->tasMode != ELASTIC) {
status = MotorGetSoftPosition(self->motors[A6], pCon, &val); status = GetDrivablePosition(self->motors[A6], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
@ -225,22 +230,22 @@ static int readTASAngles(ptasUB self, SConnection * pCon, ptasAngles ang)
/* /*
crystal crystal
*/ */
status = MotorGetSoftPosition(self->motors[A3], pCon, &val); status = GetDrivablePosition(self->motors[A3], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
ang->a3 = val; ang->a3 = val;
status = MotorGetSoftPosition(self->motors[A4], pCon, &val); status = GetDrivablePosition(self->motors[A4], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
ang->sample_two_theta = val; ang->sample_two_theta = val;
status = MotorGetSoftPosition(self->motors[SGU], pCon, &val); status = GetDrivablePosition(self->motors[SGU], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
ang->sgu = val; ang->sgu = val;
status = MotorGetSoftPosition(self->motors[SGL], pCon, &val); status = GetDrivablePosition(self->motors[SGL], pCon, &val);
if (status == 0) { if (status == 0) {
return status; return status;
} }
@ -270,7 +275,21 @@ static void updateTargets(ptasUB pNew, SConnection * pCon)
readTASAngles(pNew, pCon, &ang); readTASAngles(pNew, pCon, &ang);
calcTasQEPosition(&pNew->machine, ang, &pNew->target); 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 TasUBFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
@ -306,34 +325,34 @@ int TasUBFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
/* /*
* default names and assignement * default names and assignement
*/ */
pNew->motors[0] = FindMotor(pSics, "a1"); pNew->motors[0] = TasFindMotor(pSics, "a1");
pNew->motors[1] = FindMotor(pSics, "a2"); pNew->motors[1] = TasFindMotor(pSics, "a2");
pNew->motors[2] = FindMotor(pSics, "mcv"); pNew->motors[2] = TasFindMotor(pSics, "mcv");
pNew->motors[3] = FindMotor(pSics, "mch"); pNew->motors[3] = TasFindMotor(pSics, "mch");
pNew->motors[4] = FindMotor(pSics, "a3"); pNew->motors[4] = TasFindMotor(pSics, "a3");
pNew->motors[5] = FindMotor(pSics, "a4"); pNew->motors[5] = TasFindMotor(pSics, "a4");
pNew->motors[6] = FindMotor(pSics, "sgu"); pNew->motors[6] = TasFindMotor(pSics, "sgu");
pNew->motors[7] = FindMotor(pSics, "sgl"); pNew->motors[7] = TasFindMotor(pSics, "sgl");
pNew->motors[8] = FindMotor(pSics, "a5"); pNew->motors[8] = TasFindMotor(pSics, "a5");
pNew->motors[9] = FindMotor(pSics, "a6"); pNew->motors[9] = TasFindMotor(pSics, "a6");
pNew->motors[10] = FindMotor(pSics, "acv"); pNew->motors[10] = TasFindMotor(pSics, "acv");
pNew->motors[11] = FindMotor(pSics, "ach"); pNew->motors[11] = TasFindMotor(pSics, "ach");
} else { } else {
/* /*
* user defined names * user defined names
*/ */
pNew->motors[0] = FindMotor(pSics, argv[2]); pNew->motors[0] = TasFindMotor(pSics, argv[2]);
pNew->motors[1] = FindMotor(pSics, argv[3]); pNew->motors[1] = TasFindMotor(pSics, argv[3]);
pNew->motors[2] = FindMotor(pSics, argv[4]); pNew->motors[2] = TasFindMotor(pSics, argv[4]);
pNew->motors[3] = FindMotor(pSics, argv[5]); pNew->motors[3] = TasFindMotor(pSics, argv[5]);
pNew->motors[4] = FindMotor(pSics, argv[6]); pNew->motors[4] = TasFindMotor(pSics, argv[6]);
pNew->motors[5] = FindMotor(pSics, argv[7]); pNew->motors[5] = TasFindMotor(pSics, argv[7]);
pNew->motors[6] = FindMotor(pSics, argv[8]); pNew->motors[6] = TasFindMotor(pSics, argv[8]);
pNew->motors[7] = FindMotor(pSics, argv[9]); pNew->motors[7] = TasFindMotor(pSics, argv[9]);
pNew->motors[8] = FindMotor(pSics, argv[10]); pNew->motors[8] = TasFindMotor(pSics, argv[10]);
pNew->motors[9] = FindMotor(pSics, argv[11]); pNew->motors[9] = TasFindMotor(pSics, argv[11]);
pNew->motors[10] = FindMotor(pSics, argv[12]); pNew->motors[10] = TasFindMotor(pSics, argv[12]);
pNew->motors[11] = FindMotor(pSics, argv[13]); pNew->motors[11] = TasFindMotor(pSics, argv[13]);
} }
/* /*
curvature motors may be missing, anything else is a serious problem 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) { if (status != 1) {
r2.qe.kf = self->current.kf; r2.qe.kf = self->current.kf;
r2.qe.ki = self->current.ki; 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.a3 = value + 180.;
r2.angles.sgu = .0; r2.angles.sgu = .0;
r2.angles.sgl = .0; r2.angles.sgl = .0;

View File

@ -1,3 +1,3 @@
324 332
NEVER, EVER modify or delete this file NEVER, EVER modify or delete this file
You'll risk eternal damnation and a reincarnation as a cockroach! You'll risk eternal damnation and a reincarnation as a cockroach!