- 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
|
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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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}
|
||||||
|
@ -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
|
||||||
@}
|
@}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
2
drive.c
2
drive.c
@ -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);
|
||||||
|
@ -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();
|
||||||
|
278
optimise.c
278
optimise.c
@ -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)
|
||||||
{
|
{
|
||||||
|
1
scan.tex
1
scan.tex
@ -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
1
scan.w
@ -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.
|
||||||
|
@ -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){
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
Reference in New Issue
Block a user