- 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:
@ -895,7 +895,9 @@ int InterpWrite(SicsInterp * pSics, char *buffer)
|
||||
|
||||
assert(pSics);
|
||||
pTcl = (Tcl_Interp *) pSics->pTcl;
|
||||
if(Tcl_GetStringResult(pTcl) != buffer){
|
||||
Tcl_SetResult(pTcl, buffer, TCL_VOLATILE);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
3
access.c
3
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;
|
||||
|
2
devser.c
2
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); */
|
||||
}
|
||||
}
|
||||
|
||||
|
15
diffscan.c
15
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
|
||||
|
@ -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.
|
||||
<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>
|
||||
</p>
|
||||
<H1>Automatic Updating of NeXus Files</H1>
|
||||
|
12
emon.c
12
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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <tcl.h> /* 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;
|
||||
}
|
||||
|
||||
if(time(NULL) > self->nextRun){
|
||||
EVMonitorControllers(self);
|
||||
self->nextRun = time(NULL) + SCANINTERVALL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
30
emon.h
30
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 EVWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
pEnvMon FindEMON(SicsInterp * pSics);
|
||||
pEnvMon FindEMON(SicsInterp *pSics);
|
||||
|
||||
int EnvMonTask(void *pEv);
|
||||
void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);
|
||||
int EnvMonTask(void *pEv);
|
||||
void EnvMonSignal(void *pEndv, int iSignal, void *pSigData);
|
||||
|
||||
#line 164 "emonitor.w"
|
||||
#line 165 "emonitor.w"
|
||||
|
||||
#endif
|
||||
|
1
emon.i
1
emon.i
@ -10,6 +10,7 @@
|
||||
pObjectDescriptor pDes;
|
||||
int iList;
|
||||
int iEnd;
|
||||
time_t nextRun;
|
||||
} EnvMon;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
|
@ -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]
|
||||
|
@ -63,6 +63,7 @@ The environment monitor uses the following datastructures:
|
||||
pObjectDescriptor pDes;
|
||||
int iList;
|
||||
int iEnd;
|
||||
time_t nextRun;
|
||||
} EnvMon;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
|
14
exebuf.c
14
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);
|
||||
}
|
||||
|
1
exeman.c
1
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;
|
||||
|
204
fourmess.c
204
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,
|
||||
|
55
hdbtable.c
55
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)
|
||||
{
|
||||
@ -413,6 +460,14 @@ pSICSOBJ MakeHdbTable(char *name, char *hdbclass)
|
||||
SetHdbProperty(cmd,"priv","user");
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
43
hmcontrol.c
43
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 <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <tcl.h>
|
||||
#include <unistd.h>
|
||||
#include "fortify.h"
|
||||
#include "hmcontrol.h"
|
||||
#include "HistMem.h"
|
||||
@ -66,7 +74,7 @@ static int HMCStart(void *pData, SConnection * pCon)
|
||||
return HWFault;
|
||||
}
|
||||
|
||||
for (i = 0; i < self->nSlaves; i++) {
|
||||
for (i = 1; i < self->nSlaves; i++) {
|
||||
ReleaseCountLock(self->slaves[i]);
|
||||
status = self->slaves[i]->StartCount(self->slaveData[i], pCon);
|
||||
if (status != OKOK) {
|
||||
@ -74,6 +82,19 @@ static int HMCStart(void *pData, SConnection * pCon)
|
||||
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.
|
||||
*/
|
||||
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,13 +360,18 @@ 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
|
||||
*/
|
||||
@ -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;
|
||||
|
@ -33,6 +33,7 @@ typedef struct {
|
||||
CounterMode eMode;
|
||||
pICallBack pCall;
|
||||
int checkSlaves;
|
||||
int stopSlaves;
|
||||
} HMcontrol, *pHMcontrol;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -169,7 +169,6 @@ static float MOLIGetValue(void *data, SConnection * pCon)
|
||||
pIDrivable makeMotListInterface()
|
||||
{
|
||||
pIDrivable pDriv = NULL;
|
||||
|
||||
pDriv = CreateDrivableInterface();
|
||||
if (pDriv == NULL) {
|
||||
return NULL;
|
||||
|
26
nserver.c
26
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;
|
||||
|
115
nxscript.c
115
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] );
|
||||
}
|
||||
|
@ -1174,19 +1174,20 @@ 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){
|
||||
traceIO(st->controller->node->name, "transreply:%s", lastReply);
|
||||
} else {
|
||||
traceIO("sctunknown", "transreply:%s", 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;
|
||||
}
|
||||
*/
|
||||
}
|
||||
if (st->reply != NULL) {
|
||||
SCWrite(con,st->reply,eValue);
|
||||
|
@ -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);
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
63
tasdrive.c
63
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 <assert.h>
|
||||
#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,7 +256,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
|
||||
float val, fixed;
|
||||
int status = OKOK;
|
||||
char buffer[132];
|
||||
pIDrivable pDriv = NULL;
|
||||
pDummy dum = NULL;
|
||||
|
||||
dum = (pDummy)mot;
|
||||
if(strcmp(dum->pDescriptor->name,"Motor") == 0){
|
||||
val = getMotorValue(mot, pCon);
|
||||
MotorGetPar(mot, "fixed", &fixed);
|
||||
if (ABS(fixed - 1.0) < .1) {
|
||||
@ -258,9 +268,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *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;
|
||||
}
|
||||
|
15
tasscanub.c
15
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 <stdio.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",
|
||||
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);
|
||||
|
81
tasub.c
81
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 <assert.h>
|
||||
#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;
|
||||
|
@ -1,3 +1,3 @@
|
||||
324
|
||||
332
|
||||
NEVER, EVER modify or delete this file
|
||||
You'll risk eternal damnation and a reincarnation as a cockroach!
|
||||
|
Reference in New Issue
Block a user