- Added log instrumentation to devexe

- Added a hill climbing option to optimise
- Added hrpt files


SKIPPED:
	psi/libpsi.a
	psi/sinqhmdriv.c
	psi/tabledrive.c
This commit is contained in:
koennecke
2006-07-13 07:24:44 +00:00
parent e6ad9da6ad
commit 47e38eba5a
15 changed files with 633 additions and 14 deletions

240
devexec.c
View File

@ -42,10 +42,12 @@
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS. MODIFICATIONS.
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include <sys/time.h>
#include "fortify.h" #include "fortify.h"
#include "sics.h" #include "sics.h"
#include "nserver.h" #include "nserver.h"
@ -56,11 +58,51 @@
#include "status.h" #include "status.h"
#include "lld.h" #include "lld.h"
#include "commandlog.h" #include "commandlog.h"
#include "ifile.h"
/* /*
#define DEBUG 1 #define DEBUG 1
*/ */
/*======================== Logging stuff ==================================*/
static FILE *devLog = NULL;
/*-------------------------------------------------------------------------*/
int openDevexecLog(){
char *fileName = NULL;
char fileBuffer[1024];
if(devLog == NULL){
fileName = IFindOption(pSICSOptions,"devexeclog");
if(fileName != NULL){
strcpy(fileBuffer,fileName);
} else {
fileBuffer[0] = '\0';
fileName = getenv("HOME");
if(fileName != NULL){
strcpy(fileBuffer,fileName);
}
strcat(fileBuffer,"/log/devexec.log");
}
devLog = fopen(fileBuffer,"a+");
}
if(devLog == NULL){
return 0;
} else {
return 1;
}
}
/*-------------------------------------------------------------------------*/
void DevexecLog(char *operation, char *device) {
struct timeval tv;
struct timezone tm;
if(devLog != NULL){
gettimeofday(&tv,&tm);
fprintf(devLog, "DEVEXEC:%s:%s:%ld:%ld\n",operation,device,
tv.tv_sec, tv.tv_usec);
fflush(devLog);
}
}
/*======================== internal data structures =======================*/
typedef struct _DevEntry { typedef struct _DevEntry {
void *pData; void *pData;
pObjectDescriptor pDescriptor; pObjectDescriptor pDescriptor;
@ -122,6 +164,7 @@ typedef struct {
int iLock; int iLock;
pICallBack pCall; pICallBack pCall;
time_t lastRun; time_t lastRun;
int paused;
} ExeList; } ExeList;
static pExeList pExecutor = NULL; static pExeList pExecutor = NULL;
@ -178,6 +221,10 @@ typedef struct {
free(self); free(self);
pServ->pExecutor = NULL; pServ->pExecutor = NULL;
if(devLog != NULL){
fclose(devLog);
devLog = NULL;
}
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void ExeInterest(pExeList self, pDevEntry pDev, char *text) { void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
@ -295,6 +342,7 @@ typedef struct {
self->iEnd = 0; self->iEnd = 0;
pCon->conStatus = HWBusy; pCon->conStatus = HWBusy;
} }
DevexecLog("START",pNew->name);
return 1; return 1;
} }
else else
@ -397,7 +445,7 @@ typedef struct {
pCon,pCter->pDriv->fPreset); pCon,pCter->pDriv->fPreset);
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int CheckExeList(pExeList self) int CheckExeListOld(pExeList self)
{ {
int iRet; int iRet;
pDevEntry pDev = NULL; pDevEntry pDev = NULL;
@ -568,6 +616,196 @@ typedef struct {
return 0; return 0;
} }
} }
/*-------------------------------------------------------------------------*/
static int checkInterrupt(pCheckContext pCheck, int targetStatus){
if(SCGetInterrupt(pCheck->self->pOwner) != eContinue) {
pCheck->self->iStatus = DEVINT;
SCPopContext(pCheck->self->pOwner);
SetStatus(eEager);
return -1;
} else {
return targetStatus;
}
}
/*--------------------------------------------------------------------------*/
static int initializeCheck(pCheckContext pCheck, pDevEntry pDev){
int eCode;
SCPushContext(pCheck->self->pOwner,
pDev->comCon.transID, pDev->comCon.deviceID);
pCheck->pDev = pDev;
pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCheck->pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCheck->pDrivInt != NULL){
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pCheck->self->pOwner);
} else if(pCheck->pCountInt != NULL) {
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pCheck->self->pOwner);
}
return eCode;
}
/*--------------------------------------------------------------------------*/
static int finishDevice(pCheckContext pCheck){
int status;
if(pCheck->pCountInt != NULL) {
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->self->pOwner);
} else if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount = 0;
}
ExeInterest(pCheck->self, pCheck->pDev, "finished");
DevexecLog("STOP",pCheck->pDev->name);
DeleteDevEntry(pCheck->pDev);
LLDnodeDelete(pCheck->self->iList);
status = LLDnodePtr2Prev(pCheck->self->iList);
SCWrite(pCheck->self->pOwner, "", eFinish);
pCheck->self->iStatus = DEVDONE;
return checkInterrupt(pCheck,status);
}
/*-------------------------------------------------------------------------*/
static int errorDevice(pCheckContext pCheck){
int status;
ExeInterest(pCheck->self, pCheck->pDev, "finished with problem");
DevexecLog("STOP",pCheck->pDev->name);
DeleteDevEntry(pCheck->pDev);
LLDnodeDelete(pCheck->self->iList);
status = LLDnodePtr2Prev(pCheck->self->iList);
SCWrite(pCheck->self->pOwner, "", eFinish);
pCheck->self->iStatus = DEVERROR;
if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount++;
}
return checkInterrupt(pCheck,status);
}
/*-------------------------------------------------------------------------*/
static int testFinish(pExeList self){
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
self->pOwner = NULL;
self->iRun = 0;
self->iEnd = 1;
self->iStop = 0;
self->lTask = -1;
return 1;
} else {
return 0;
}
}
/*--------------------------------------------------------------------------*/
int CheckExeList(pExeList self)
{
int iRet, status;
checkContext check;
pDevEntry pDev = NULL;
pICountable pCountInt = NULL;
pIDrivable pDrivInt = NULL;
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
/* Sometimes this gets called, though nothing is running. There are
cases where this is feasible for maintainance, but in some cases it
is pure rubbish, because nothing runs. This will be checked here.
*/
if(testFinish(self) == 1){
return 1;
}
/*
check the status of all registered devices. Remove when finished
*/
check.self = self;
status = LLDnodePtr2First(self->iList);
while(status != 0)
{
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
eCode = initializeCheck(&check,pDev);
if(eCode != HWNoBeam && eCode != HWPause && self->paused == 1){
DevexecLog("CONTINUE","ALL");
self->paused = 0;
}
switch(eCode)
{
case HWIdle:
case OKOK:
status = finishDevice(&check);
if(status < 0){
return status;
}
break;
case HWFault: /* real HW error: burning, no net etc.. */
status = errorDevice(&check);
if(status < 0){
return status;
}
break;
case HWNoBeam:
SetStatus(eOutOfBeam);
if(self->paused == 0){
self->paused = 1;
DevexecLog("NOBEAM","ALL");
}
status = checkInterrupt(&check,1);
if(status < 0){
return status;
}
break;
case HWPause:
SetStatus(ePaused);
if(self->paused == 0){
self->paused = 1;
DevexecLog("PAUSE","ALL");
}
status = checkInterrupt(&check,1);
if(status < 0){
/*
* continue in order to wait for devices to come to a stop
*/
ContinueExecution(self);
return status;
}
break;
case HWBusy:
if(check.pDrivInt != NULL)
{
isDriving = 1;
}
else if(check.pCountInt != NULL)
{
isCounting = 1;
}
self->iStatus = DEVBUSY;
break;
case HWPosFault: /* cannot get somewhere... */
status = errorDevice(&check);
if(status < 0){
return status;
}
break;
}
SCPopContext(self->pOwner);
}
status = LLDnodePtr2Next(self->iList);
}
if (isCounting) {
if (isDriving) {
SetStatus(eCountDrive);
} else {
SetStatus(eCounting);
}
} else if (isDriving) {
SetStatus(eDriving);
}
iRet = LLDnodePtr2First(self->iList);
return testFinish(self);
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int Wait4Success(pExeList self) int Wait4Success(pExeList self)
{ {

View File

@ -152,11 +152,7 @@
/* /*
continues execution continues execution
*/ */
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
* various commands
*/
/*--------------------------- Locking ---------------------------------*/ /*--------------------------- Locking ---------------------------------*/
#line 183 "devexec.w" #line 183 "devexec.w"
@ -171,5 +167,6 @@
pExeList GetExecutor(void); pExeList GetExecutor(void);
void SetExecutor(pExeList pExe); void SetExecutor(pExeList pExe);
/*----------------------- Logging -----------------------------------------*/
void DevexecLog(char *op, char *device);
#endif #endif

View File

@ -353,7 +353,8 @@ to the global SICS device executor.
\mbox{}\verb@ @\\ \mbox{}\verb@ @\\
\mbox{}\verb@ pExeList GetExecutor(void);@\\ \mbox{}\verb@ pExeList GetExecutor(void);@\\
\mbox{}\verb@ void SetExecutor(pExeList pExe);@\\ \mbox{}\verb@ void SetExecutor(pExeList pExe);@\\
\mbox{}\verb@ @\\ \mbox{}\verb@/*----------------------- Logging -----------------------------------------*/@\\
\mbox{}\verb@ void DevexecLog(char *op, char *device); @\\
\mbox{}\verb@#endif @\\ \mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$ \mbox{}\verb@@$\diamond$
\end{list} \end{list}

View File

@ -299,7 +299,8 @@ to the global SICS device executor.
pExeList GetExecutor(void); pExeList GetExecutor(void);
void SetExecutor(pExeList pExe); void SetExecutor(pExeList pExe);
/*----------------------- Logging -----------------------------------------*/
void DevexecLog(char *op, char *device);
#endif #endif
@} @}

View File

@ -125,7 +125,10 @@ automatically appended to the definition string for the alias.
<dd>Writes the Tcl array arrayName to file using the aliasName. The <dd>Writes the Tcl array arrayName to file using the aliasName. The
definiton string belonging to aliasName does not need to contain a definiton string belonging to aliasName does not need to contain a
-dim argument as this is set by this routine. The parameter length is -dim argument as this is set by this routine. The parameter length is
the length of the array. Only rank 1 arrays are supported. the length of the array. Only rank 1 arrays are supported. The array is
considered a float array.
<dt>nxscript putintarray aliasName arrayName length
<dd>The same as above, but the data is considered integer.
<dt>nxsript putglobal attName bla bla bla <dt>nxsript putglobal attName bla bla bla
<dd>This writes an global attribute attName. Everything after attName <dd>This writes an global attribute attName. Everything after attName
is concatenated to a string which then respresents the value of the is concatenated to a string which then respresents the value of the

View File

@ -43,7 +43,10 @@ and number of steps parameters should cover the whole peak. However, the
Optimiser will extend the scan is the specified range is not sufficient. Optimiser will extend the scan is the specified range is not sufficient.
<DT>opti run <DT>opti run
<DD>Starts the optimiser. It will then optimise the peak. This may take some <DD>Starts the optimiser. It will then optimise the peak. This may take some
time. time as it uses a time consuming scan based algorithm.
<DT>opti climb
<DD>Starts the optimiser in hill climbing mode. Hill climbing is faster but may
not be as accurate as a scan based optimization.
</DL> </DL>
The behaviour of the optimiser can be configured by modifying some The behaviour of the optimiser can be configured by modifying some
parameters. The synatx is easy: <b>opti parameter</b> prints the value of the parameters. The synatx is easy: <b>opti parameter</b> prints the value of the

View File

@ -387,7 +387,7 @@
} }
else if(iRet == DEVINT) else if(iRet == DEVINT)
{ {
sprintf(pBueffel,"Driving Interrupted!"); sprintf(pBueffel,"ERROR: Driving Interrupted!");
SCWrite(pCon,pBueffel,eError); SCWrite(pCon,pBueffel,eError);
ClearExecutor(GetExecutor()); ClearExecutor(GetExecutor());
SetStatus(eOld); SetStatus(eOld);

View File

@ -43,6 +43,8 @@
*/ */
extern void StopExit(void); /* in SICSmain.c */ extern void StopExit(void); /* in SICSmain.c */
extern int openDevexecLog(); /* in devexec.c */
/* ========================= Less dreadful file statics =================== */ /* ========================= Less dreadful file statics =================== */
#define DEFAULTINIFILE "servo.tcl" #define DEFAULTINIFILE "servo.tcl"
@ -216,6 +218,8 @@
assert(pCom); assert(pCom);
assert(pCom->pData); assert(pCom->pData);
self->pExecutor = (pExeList)pCom->pData; self->pExecutor = (pExeList)pCom->pData;
openDevexecLog();
DevexecLog("START","SICS");
/* initialize Interrupt Port */ /* initialize Interrupt Port */
@ -305,6 +309,7 @@
/* clear all pending bullshit */ /* clear all pending bullshit */
ClearExecutor(self->pExecutor); ClearExecutor(self->pExecutor);
DevexecLog("STOP","SICS");
/* shut telnet down */ /* shut telnet down */
KillTelnet(); KillTelnet();

View File

@ -22,6 +22,7 @@
#include "scan.i" #include "scan.i"
#include "fitcenter.h" #include "fitcenter.h"
#include "optimise.h" #include "optimise.h"
#include "stdscan.h"
#ifdef CYGNUS #ifdef CYGNUS
#define MAXFLOAT 9999999.99 #define MAXFLOAT 9999999.99
@ -83,7 +84,6 @@
{ {
return 1; return 1;
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
pOptimise CreateOptimiser(pCounter pCount) pOptimise CreateOptimiser(pCounter pCount)
@ -466,6 +466,197 @@
return iReturn; return iReturn;
} }
/*------------------------------------------------------------------------
* We use the scan object here for counting. The reason is that this
* handles well in the common case of a single counter but also has
* provisions for other counting methods through the scan modules
* scripting mechanism
* ------------------------------------------------------------------------*/
static long ClimbCount(pOptimise self, SConnection *pCon)
{
int status;
long data[1];
int (*CollectFunc)(pScanData self, int iPoint) = NULL;
SilentPrepare(self->pScanner);
status = self->pScanner->ScanCount(self->pScanner,0);
if(status != 1)
{
return status;
}
if(self->pScanner->CollectScanData == CollectScanData)
{
CollectFunc = self->pScanner->CollectScanData;
self->pScanner->CollectScanData = CollectSilent;
}
status = self->pScanner->CollectScanData(self->pScanner,0);
if(CollectFunc != NULL)
{
self->pScanner->CollectScanData = CollectFunc;
}
if(status != 1)
{
return status;
}
GetScanCounts(self->pScanner,data,1);
return data[0];
}
/*------------------------------------------------------------------------*/
static int ClimbDrive(SConnection *pCon,char *name, float value)
{
int status;
status = Start2Run(pCon,pServ->pSics,name,value);
if(status != 1)
{
return DRIVEERROR;
}
status = Wait4Success(GetExecutor());
if(status != DEVDONE)
{
return DRIVEERROR;
}
return 1;
}
/*-------------------------------------------------------------------------*/
static int ClimbVariable(pOptimise self, SConnection *pCon, int i)
{
pOVarEntry pOvar;
void *pData;
int status, direction = 1;
long oneCount, twoCount, lastCount, currentCount;
float varValue, startValue;
char buffer[256];
int (*CollectFunc)(pScanData self, int iPoint) = NULL;
assert(self);
assert( (i >= 0) && (i < self->iVar));
assert(pCon);
/* get variable data */
DynarGet(self->pVariables,i,&pData);
pOvar = (pOVarEntry)pData;
startValue = pOvar->fCenter;
/*
* prepare scan object
*/
self->pScanner->pCon = pCon;
self->pScanner->pSics = pServ->pSics;
self->pScanner->iNP = 1;
self->pScanner->iMode = self->eCount;
self->pScanner->fPreset = self->fPreset;
/*
* test for upwards direction
*/
varValue = pOvar->fCenter + pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
oneCount = ClimbCount(self,pCon);
if(oneCount < 0)
{
return SCANERROR;
}
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
varValue = pOvar->fCenter - pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
twoCount = ClimbCount(self,pCon);
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
if(twoCount < 0)
{
return SCANERROR;
}
if(oneCount > twoCount)
{
direction = 1;
lastCount = oneCount;
}
else
{
direction = -1;
lastCount = twoCount;
}
/*
* drive to the last best position
*/
varValue = pOvar->fCenter + direction*pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
currentCount = lastCount;
/*
* climb upwards as long as possible
*/
while(1)
{
pOvar->fCenter = varValue;
varValue = pOvar->fCenter + direction * pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
currentCount = ClimbCount(self,pCon);
if(currentCount < 0)
{
return SCANERROR;
}
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
snprintf(buffer,255,"Climbing %s, value = %f, count = %ld",
pOvar->pName, varValue, currentCount);
SCWrite(pCon,buffer,eWarning);
if(currentCount <= lastCount)
{
/*
* we are finished. Drive to previous position and
* break
*/
status = ClimbDrive(pCon,pOvar->pName,pOvar->fCenter);
if(!status)
{
return DRIVEERROR;
}
break;
}
else
{
/*
* go on, we are not over the top yet
*/
lastCount = currentCount;
}
}
pOvar->fShift = ABS(startValue - pOvar->fCenter);
return 1;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static int CheckSuccess(pOptimise self) static int CheckSuccess(pOptimise self)
{ {
@ -530,6 +721,45 @@
} }
return MAXCYCLE; return MAXCYCLE;
} }
/*---------------------------------------------------------------------------*/
int OptimiserClimb(pOptimise self, SConnection *pCon)
{
int i, iRet, iCycle, iRedoVar = 0;
char pBueffel[256];
assert(self);
if(self->iVar < 1)
{
SCWrite(pCon,"ERROR: Nothing to optimise",eError);
return 0;
}
iRet = OptimiserInit(self,pCon);
if(!iRet)
{
return iRet;
}
for(iCycle = 0; iCycle < self->iMaxCycles; iCycle++)
{
sprintf(pBueffel,"Optimiser cycle %d of %d started",iCycle, self->iMaxCycles);
SCWrite(pCon,pBueffel,eStatus);
for(i = iRedoVar; i < self->iVar; i++)
{
iRet = ClimbVariable(self,pCon,i);
if(iRet <= 0)
{
return iRet;
}
}
iRet = CheckSuccess(self);
if(iRet)
{
return 1;
}
}
return MAXCYCLE;
}
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
int MakeOptimiser(SConnection *pCon, SicsInterp *pSics, void *pData, int MakeOptimiser(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
@ -717,6 +947,52 @@
break; break;
} }
} }
/*-------- climb */
else if(strcmp(argv[1],"climb") == 0)
{
/* check rights */
if(!SCMatchRights(pCon,usUser))
{
SCWrite(pCon,"ERROR: You are not aurhorised to do this!",eError);
return 0;
}
iRet = OptimiserClimb(self,pCon);
switch(iRet)
{
case PEAKLOST:
SCWrite(pCon,"ERROR: lost the peak, sorry!",eError);
return 0;
break;
case MAXCYCLE:
sprintf(pBueffel,"ERROR: could not optimise peak in %d cycles",
self->iMaxCycles);
SCWrite(pCon,pBueffel,eError);
return 0;
break;
case SCANERROR:
SCWrite(pCon,"ERROR: failed to scan the peak",eError);
return 0;
break;
case SCANABORT:
SCWrite(pCon,"ERROR: Scan was aborted, Optimiser follows",eError);
return 0;
break;
case DRIVEERROR:
SCWrite(pCon,"ERROR: Failure to drive variable to new position",eError);
return 0;
break;
case 1:
SCWrite(pCon,"At long last, I finished optimising the peak",eValue);
return 1;
break;
default:
SCWrite(pCon,"ERROR: Unidentified error krept into Optimiser",eError);
return 0;
break;
}
SCWrite(pCon,"Optimiser climbed successfully",eValue);
return 1;
}
/* ------ count mode */ /* ------ count mode */
if(strcmp(argv[1],"countmode") == 0) if(strcmp(argv[1],"countmode") == 0)
{ {

View File

@ -531,6 +531,7 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ */@\\ \mbox{}\verb@ */@\\
\mbox{}\verb@ int CollectScanData(pScanData self, int iPoint);@\\ \mbox{}\verb@ int CollectScanData(pScanData self, int iPoint);@\\
\mbox{}\verb@ int CollectScanDataJochen(pScanData self, int iPoint);@\\ \mbox{}\verb@ int CollectScanDataJochen(pScanData self, int iPoint);@\\
\mbox{}\verb@ int CollectSilent(pScanData self, int iPoint);@\\
\mbox{}\verb@/*===================================================================*/@\\ \mbox{}\verb@/*===================================================================*/@\\
\mbox{}\verb@ /**@\\ \mbox{}\verb@ /**@\\
\mbox{}\verb@ * Script invocation for writing the scan header.@\\ \mbox{}\verb@ * Script invocation for writing the scan header.@\\

1
scan.w
View File

@ -477,6 +477,7 @@ documentation.
*/ */
int CollectScanData(pScanData self, int iPoint); int CollectScanData(pScanData self, int iPoint);
int CollectScanDataJochen(pScanData self, int iPoint); int CollectScanDataJochen(pScanData self, int iPoint);
int CollectSilent(pScanData self, int iPoint);
/*===================================================================*/ /*===================================================================*/
/** /**
* Script invocation for writing the scan header. * Script invocation for writing the scan header.

View File

@ -566,6 +566,74 @@ void RemoveSICSPar(pHdb node){
SICSDeleteNodeData(node); SICSDeleteNodeData(node);
} }
/*==================== access suport functions ==============================*/
int SICSHdbGetFloat(pHdb parent, SConnection *pCon,
char *path, float *value){
hdbValue v;
pHdb par = NULL;
int status;
char buffer[256];
par = GetHipadabaNode(parent,path);
if(par == NULL){
if(pCon != NULL){
snprintf(buffer,255,"ERROR: parameter %s not found", path);
SCWrite(pCon,buffer,eError);
}
return SICSNOPAR;
}
status = GetHipadabaPar(par,&v,pCon);
if(status < 0){
return status;
}
if(v.dataType == HIPFLOAT){
*value = (float)v.v.doubleValue;
} else if(v.dataType == HIPINT){
*value = (float)v.v.intValue;
} else {
/*
* it is an error to call this for array dada types
*/
assert(0);
}
return 1;
}
/*--------------------------------------------------------------------------*/
int SICSHdbSetFloat(pHdb parent, SConnection *pCon,
char *path, float value){
hdbValue v;
pHdb par = NULL;
int status;
char buffer[256];
par = GetHipadabaNode(parent,path);
if(par == NULL){
if(pCon != NULL){
snprintf(buffer,255,"ERROR: parameter %s not found", path);
SCWrite(pCon,buffer,eError);
}
return SICSNOPAR;
}
v.dataType = par->value.dataType;
if(v.dataType == HIPFLOAT){
v.v.doubleValue = (double)value;
} else if(v.dataType == HIPINT){
v.v.intValue = (long)value;
} else {
/*
* it is an error to call this for array dada types
*/
assert(0);
}
status = SetHipadabaPar(par,v,pCon);
if(status < 0){
return status;
}
return 1;
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
int InstallSICSNotify(pHdb node, SConnection *pCon, int id, int recurse){ int InstallSICSNotify(pHdb node, SConnection *pCon, int id, int recurse){

View File

@ -17,6 +17,7 @@
#define SICSCBPERM -608 #define SICSCBPERM -608
#define SICSCBRANGE -609 #define SICSCBRANGE -609
#define SICSCBBADFIXED -610 #define SICSCBBADFIXED -610
#define SICSNOPAR -611
/*======================== data structure for automatic parameter update =======*/ /*======================== data structure for automatic parameter update =======*/
typedef struct { typedef struct {
SConnection *pCon; SConnection *pCon;
@ -136,6 +137,29 @@ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript, hdbValue v
* @param node The node to delete * @param node The node to delete
*/ */
void RemoveSICSPar(pHdb node); void RemoveSICSPar(pHdb node);
/*============== access support functions =================================*/
/**
* SICSHdbGetFloat returns the float value of a parameter. Integers are
* automatically converted.
* @param parent The parent node where to start searching for the parameter
* @param pCon The optional connection object to use for reporting errors.
* @param path The path to the parameter.
* @param value The value of the parameter
* @return 1 on success, a negative error code else.
*/
int SICSHdbGetFloat(pHdb parent, SConnection *pCon,
char *path, float *value);
/**
* SICSHdbSetFloat sets the value of a parameter. Integers are
* automatically converted.
* @param parent The parent node where to start searching for the parameter
* @param pCon The optional connection object to use for reporting errors.
* @param path The path to the parameter.
* @param value The new value of the parameter
* @return 1 on success, a negative error code else.
*/
int SICSHdbSetFloat(pHdb parent, SConnection *pCon,
char *path, float value);
/*============= common SICS Interactions ===================================*/ /*============= common SICS Interactions ===================================*/
/** /**
* Install a SICS automatic notification callback on the node. This is * Install a SICS automatic notification callback on the node. This is

View File

@ -847,7 +847,7 @@ int prepareDataFile(pScanData self){
return CollectScanDataIntern(self,iPoint,1); return CollectScanDataIntern(self,iPoint,1);
} }
/*------------------------------------------------------------------------*/ /*------------------------------------------------------------------------*/
static int CollectSilent(pScanData self, int iPoint) int CollectSilent(pScanData self, int iPoint)
{ {
pVarEntry pVar = NULL; pVarEntry pVar = NULL;
void *pDings; void *pDings;

View File

@ -68,6 +68,7 @@
*/ */
int CollectScanData(pScanData self, int iPoint); int CollectScanData(pScanData self, int iPoint);
int CollectScanDataJochen(pScanData self, int iPoint); int CollectScanDataJochen(pScanData self, int iPoint);
int CollectSilent(pScanData self, int iPoint);
/*===================================================================*/ /*===================================================================*/
/** /**
* Script invocation for writing the scan header. * Script invocation for writing the scan header.