- 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:
240
devexec.c
240
devexec.c
@ -42,10 +42,12 @@
|
||||
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
||||
MODIFICATIONS.
|
||||
-----------------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "nserver.h"
|
||||
@ -56,11 +58,51 @@
|
||||
#include "status.h"
|
||||
#include "lld.h"
|
||||
#include "commandlog.h"
|
||||
#include "ifile.h"
|
||||
|
||||
/*
|
||||
#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 {
|
||||
void *pData;
|
||||
pObjectDescriptor pDescriptor;
|
||||
@ -122,6 +164,7 @@ typedef struct {
|
||||
int iLock;
|
||||
pICallBack pCall;
|
||||
time_t lastRun;
|
||||
int paused;
|
||||
} ExeList;
|
||||
|
||||
static pExeList pExecutor = NULL;
|
||||
@ -178,6 +221,10 @@ typedef struct {
|
||||
|
||||
free(self);
|
||||
pServ->pExecutor = NULL;
|
||||
if(devLog != NULL){
|
||||
fclose(devLog);
|
||||
devLog = NULL;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
|
||||
@ -295,6 +342,7 @@ typedef struct {
|
||||
self->iEnd = 0;
|
||||
pCon->conStatus = HWBusy;
|
||||
}
|
||||
DevexecLog("START",pNew->name);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -397,7 +445,7 @@ typedef struct {
|
||||
pCon,pCter->pDriv->fPreset);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int CheckExeList(pExeList self)
|
||||
int CheckExeListOld(pExeList self)
|
||||
{
|
||||
int iRet;
|
||||
pDevEntry pDev = NULL;
|
||||
@ -568,6 +616,196 @@ typedef struct {
|
||||
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)
|
||||
{
|
||||
|
@ -152,11 +152,7 @@
|
||||
/*
|
||||
continues execution
|
||||
*/
|
||||
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
/*
|
||||
* various commands
|
||||
*/
|
||||
|
||||
/*--------------------------- Locking ---------------------------------*/
|
||||
|
||||
#line 183 "devexec.w"
|
||||
@ -171,5 +167,6 @@
|
||||
|
||||
pExeList GetExecutor(void);
|
||||
void SetExecutor(pExeList pExe);
|
||||
|
||||
/*----------------------- Logging -----------------------------------------*/
|
||||
void DevexecLog(char *op, char *device);
|
||||
#endif
|
||||
|
@ -353,7 +353,8 @@ to the global SICS device executor.
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ pExeList GetExecutor(void);@\\
|
||||
\mbox{}\verb@ void SetExecutor(pExeList pExe);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@/*----------------------- Logging -----------------------------------------*/@\\
|
||||
\mbox{}\verb@ void DevexecLog(char *op, char *device); @\\
|
||||
\mbox{}\verb@#endif @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
|
@ -299,7 +299,8 @@ to the global SICS device executor.
|
||||
|
||||
pExeList GetExecutor(void);
|
||||
void SetExecutor(pExeList pExe);
|
||||
|
||||
/*----------------------- Logging -----------------------------------------*/
|
||||
void DevexecLog(char *op, char *device);
|
||||
#endif
|
||||
@}
|
||||
|
||||
|
@ -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
|
||||
definiton string belonging to aliasName does not need to contain a
|
||||
-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
|
||||
<dd>This writes an global attribute attName. Everything after attName
|
||||
is concatenated to a string which then respresents the value of the
|
||||
|
@ -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.
|
||||
<DT>opti run
|
||||
<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>
|
||||
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
|
||||
|
2
drive.c
2
drive.c
@ -387,7 +387,7 @@
|
||||
}
|
||||
else if(iRet == DEVINT)
|
||||
{
|
||||
sprintf(pBueffel,"Driving Interrupted!");
|
||||
sprintf(pBueffel,"ERROR: Driving Interrupted!");
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
ClearExecutor(GetExecutor());
|
||||
SetStatus(eOld);
|
||||
|
@ -43,6 +43,8 @@
|
||||
*/
|
||||
|
||||
extern void StopExit(void); /* in SICSmain.c */
|
||||
|
||||
extern int openDevexecLog(); /* in devexec.c */
|
||||
/* ========================= Less dreadful file statics =================== */
|
||||
|
||||
#define DEFAULTINIFILE "servo.tcl"
|
||||
@ -216,6 +218,8 @@
|
||||
assert(pCom);
|
||||
assert(pCom->pData);
|
||||
self->pExecutor = (pExeList)pCom->pData;
|
||||
openDevexecLog();
|
||||
DevexecLog("START","SICS");
|
||||
|
||||
|
||||
/* initialize Interrupt Port */
|
||||
@ -305,6 +309,7 @@
|
||||
|
||||
/* clear all pending bullshit */
|
||||
ClearExecutor(self->pExecutor);
|
||||
DevexecLog("STOP","SICS");
|
||||
|
||||
/* shut telnet down */
|
||||
KillTelnet();
|
||||
|
278
optimise.c
278
optimise.c
@ -22,6 +22,7 @@
|
||||
#include "scan.i"
|
||||
#include "fitcenter.h"
|
||||
#include "optimise.h"
|
||||
#include "stdscan.h"
|
||||
|
||||
#ifdef CYGNUS
|
||||
#define MAXFLOAT 9999999.99
|
||||
@ -83,7 +84,6 @@
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
pOptimise CreateOptimiser(pCounter pCount)
|
||||
@ -466,6 +466,197 @@
|
||||
|
||||
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)
|
||||
{
|
||||
@ -530,6 +721,45 @@
|
||||
}
|
||||
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 argc, char *argv[])
|
||||
@ -717,6 +947,52 @@
|
||||
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 */
|
||||
if(strcmp(argv[1],"countmode") == 0)
|
||||
{
|
||||
|
1
scan.tex
1
scan.tex
@ -531,6 +531,7 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ int CollectScanData(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@ * Script invocation for writing the scan header.@\\
|
||||
|
1
scan.w
1
scan.w
@ -477,6 +477,7 @@ documentation.
|
||||
*/
|
||||
int CollectScanData(pScanData self, int iPoint);
|
||||
int CollectScanDataJochen(pScanData self, int iPoint);
|
||||
int CollectSilent(pScanData self, int iPoint);
|
||||
/*===================================================================*/
|
||||
/**
|
||||
* Script invocation for writing the scan header.
|
||||
|
@ -566,6 +566,74 @@ void RemoveSICSPar(pHdb 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){
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define SICSCBPERM -608
|
||||
#define SICSCBRANGE -609
|
||||
#define SICSCBBADFIXED -610
|
||||
#define SICSNOPAR -611
|
||||
/*======================== data structure for automatic parameter update =======*/
|
||||
typedef struct {
|
||||
SConnection *pCon;
|
||||
@ -136,6 +137,29 @@ pHdb MakeSICSScriptPar(char *name, char *setScript, char *readScript, hdbValue v
|
||||
* @param node The node to delete
|
||||
*/
|
||||
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 ===================================*/
|
||||
/**
|
||||
* Install a SICS automatic notification callback on the node. This is
|
||||
|
@ -847,7 +847,7 @@ int prepareDataFile(pScanData self){
|
||||
return CollectScanDataIntern(self,iPoint,1);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static int CollectSilent(pScanData self, int iPoint)
|
||||
int CollectSilent(pScanData self, int iPoint)
|
||||
{
|
||||
pVarEntry pVar = NULL;
|
||||
void *pDings;
|
||||
|
@ -68,6 +68,7 @@
|
||||
*/
|
||||
int CollectScanData(pScanData self, int iPoint);
|
||||
int CollectScanDataJochen(pScanData self, int iPoint);
|
||||
int CollectSilent(pScanData self, int iPoint);
|
||||
/*===================================================================*/
|
||||
/**
|
||||
* Script invocation for writing the scan header.
|
||||
|
Reference in New Issue
Block a user