2434 lines
66 KiB
C
2434 lines
66 KiB
C
|
|
/*--------------------------------------------------------------------------
|
|
S C A N
|
|
|
|
Implementation file for the SICS scan command.
|
|
|
|
|
|
Mark Koennecke, October 1997, June 2001
|
|
|
|
Extracted scanvar.c, .h
|
|
Extended to allow for storing and retrieving of all scan data from scripts
|
|
Changed recover to work with ASCII files using the feautures implemented
|
|
above.
|
|
Extracted stdscan.h, stdscan.c
|
|
|
|
Mark Koennecke, November 2004
|
|
|
|
copyright: see copyright.h
|
|
----------------------------------------------------------------------------*/
|
|
#include "sics.h"
|
|
#include <stdio.h>
|
|
#include <arpa/inet.h>
|
|
#include <tcl.h>
|
|
#include <math.h>
|
|
#include "fortify.h"
|
|
#include "sdynar.h"
|
|
#include "dynstring.h"
|
|
#include "stringdict.h"
|
|
#include "status.h"
|
|
#include "sicsvar.h"
|
|
#include "counter.h"
|
|
#include "scan.h"
|
|
#include "scan.i"
|
|
#include "integrate.h"
|
|
#include "udpquieck.h"
|
|
#include "splitter.h"
|
|
#include "danu.h"
|
|
#include "userscan.h"
|
|
#include "motor.h"
|
|
#include "nxscript.h"
|
|
#include "site.h"
|
|
#include "lld.h"
|
|
#include "stdscan.h"
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static void DeleteCountEntry(void *pData)
|
|
{
|
|
free(pData);
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
void InitCountEntry(pCountEntry pCount)
|
|
{
|
|
int i;
|
|
|
|
pCount->lCount = -1L;
|
|
pCount->i = -1;
|
|
pCount->fTime = -1.0;
|
|
for(i = 0; i < 10; i++)
|
|
{
|
|
pCount->Monitors[i] = -1L;
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int DummyWrite(pScanData self)
|
|
{
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int DummyWrite2(pScanData self, int iPoint)
|
|
{
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static void *ScanInterface(void *pData, int iInter)
|
|
{
|
|
pScanData self = NULL;
|
|
|
|
self = (pScanData)pData;
|
|
assert(self);
|
|
|
|
if(iInter == CALLBACKINTERFACE)
|
|
{
|
|
return self->pCall;
|
|
}
|
|
return NULL;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static void ConfigureScanDict(pStringDict dict)
|
|
{
|
|
StringDictAddPair(dict,"writeheader","stdscan writeheader");
|
|
StringDictAddPair(dict,"prepare","stdscan prepare");
|
|
StringDictAddPair(dict,"drive","stdscan drive");
|
|
StringDictAddPair(dict,"count","stdscan count");
|
|
StringDictAddPair(dict,"collect","stdscan collect");
|
|
StringDictAddPair(dict,"writepoint","stdscan writepoint");
|
|
StringDictAddPair(dict,"userdata","unknown");
|
|
StringDictAddPair(dict,"finish","stdscan finish");
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
pScanData CreateScanObject(char *pRecover, char *pHeader,pCounter pCount,
|
|
char *objName)
|
|
{
|
|
pScanData pNew = NULL;
|
|
|
|
pNew = (pScanData)malloc(sizeof(ScanData));
|
|
if(!pNew)
|
|
{
|
|
return NULL;
|
|
}
|
|
memset(pNew,0,sizeof(ScanData));
|
|
|
|
/* create an ObjectDescriptor */
|
|
pNew->pDes = CreateDescriptor("ScanObject");
|
|
if(!pNew->pDes)
|
|
{
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
pNew->pDes->GetInterface = ScanInterface;
|
|
|
|
/* allocate the dynamic arrays */
|
|
pNew->pScanVar = CreateDynar(0,10,10,DeleteVarEntry);
|
|
pNew->pCounts = CreateDynar(0,10,10,DeleteCountEntry);
|
|
pNew->scanFunctions = CreateStringDict();
|
|
if( (!pNew->pScanVar) || (!pNew->pCounts) || (!pNew->scanFunctions) )
|
|
{
|
|
DeleteDescriptor(pNew->pDes);
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
|
|
/* make a callback interface */
|
|
pNew->pCall = CreateCallBackInterface();
|
|
if(!pNew->pCall)
|
|
{
|
|
DeleteScanObject(pNew);
|
|
return NULL;
|
|
}
|
|
|
|
/* assign various things */
|
|
if(pRecover)
|
|
{
|
|
strcpy(pNew->pRecover,pRecover);
|
|
}
|
|
if(pHeader)
|
|
{
|
|
strcpy(pNew->pHeaderFile,pHeader);
|
|
}
|
|
pNew->iMode = eTimer;
|
|
pNew->fPreset = 10.;
|
|
strcpy(pNew->pCounterName,pCount->name);
|
|
pNew->pCounterData = pCount;
|
|
pNew->PrepareScan = PrepareScan;
|
|
pNew->WriteHeader = WriteHeader;
|
|
pNew->WriteScanPoints = WriteScanPoints;
|
|
pNew->ScanDrive = ScanDrive;
|
|
pNew->ScanCount = ScanCount;
|
|
pNew->CollectScanData = CollectScanData;
|
|
pNew->iWindow = 6;
|
|
strncpy(pNew->objectName,objName, 131);
|
|
ConfigureScanDict(pNew->scanFunctions);
|
|
|
|
return pNew;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
void DeleteScanObject(void *pData)
|
|
{
|
|
pScanData self = NULL;
|
|
|
|
self = (pScanData)pData;
|
|
if(!self)
|
|
{
|
|
return;
|
|
}
|
|
if(self->pDes)
|
|
{
|
|
DeleteDescriptor(self->pDes);
|
|
}
|
|
if(self->pCall)
|
|
{
|
|
DeleteCallBackInterface(self->pCall);
|
|
}
|
|
if(self->pScanVar)
|
|
{
|
|
DeleteDynar(self->pScanVar);
|
|
}
|
|
if(self->pCounts)
|
|
{
|
|
DeleteDynar(self->pCounts);
|
|
}
|
|
if(self->pCommand)
|
|
{
|
|
free(self->pCommand);
|
|
}
|
|
if(self->scanFunctions)
|
|
{
|
|
DeleteStringDict(self->scanFunctions);
|
|
}
|
|
free(self);
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
int ResetScanFunctions(pScanData self)
|
|
{
|
|
assert(self);
|
|
|
|
self->PrepareScan = PrepareScan;
|
|
self->WriteHeader = WriteHeader;
|
|
self->WriteScanPoints = WriteScanPoints;
|
|
self->ScanDrive = ScanDrive;
|
|
self->ScanCount = ScanCount;
|
|
self->CollectScanData = CollectScanData;
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
|
char *name, float fStart, float fStep)
|
|
{
|
|
pVarEntry pVar = NULL;
|
|
|
|
if(self->iActive)
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot change parameters while scan is running",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
pVar = MakeScanVar(pSics,pCon,name,fStart,fStep);
|
|
if(pVar == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* put it away */
|
|
DynarPut(self->pScanVar,self->iScanVar,pVar);
|
|
self->iScanVar++;
|
|
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int AddLogVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
|
char *name)
|
|
{
|
|
pVarEntry pVar = NULL;
|
|
|
|
if(self->iActive)
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot change parameters while scan is running",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
pVar = MakeLogVar(pSics,pCon,name);
|
|
if(pVar == NULL)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* put it away */
|
|
DynarPut(self->pScanVar,self->iScanVar,pVar);
|
|
self->iScanVar++;
|
|
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int ClearScanVar(pScanData self)
|
|
{
|
|
if(self->iActive)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
self->iScanVar = 0;
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int WriteRecover(pScanData self)
|
|
{
|
|
FILE *fd;
|
|
pVarEntry pVar = NULL;
|
|
void *pData = NULL;
|
|
pCountEntry pCount = NULL;
|
|
int i, j, status;
|
|
|
|
fd = fopen(self->pRecover,"w");
|
|
if(!fd)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
fprintf(fd,"%s clear\n",self->objectName);
|
|
|
|
/* write scan vars */
|
|
for(i = 0; i < self->iScanVar; i++)
|
|
{
|
|
DynarGet(self->pScanVar,i,&pData);
|
|
pVar = (pVarEntry)pData;
|
|
if(pVar)
|
|
{
|
|
if(isLogVar(pVar))
|
|
{
|
|
fprintf(fd,"%s log %s\n", self->objectName, ScanVarName(pVar));
|
|
}
|
|
else
|
|
{
|
|
fprintf(fd,"%s add %s %f %f\n", self->objectName, ScanVarName(pVar),
|
|
ScanVarStart(pVar), ScanVarStep(pVar));
|
|
}
|
|
}
|
|
pData = NULL;
|
|
}
|
|
for(i = 0; i < self->iScanVar; i++)
|
|
{
|
|
DynarGet(self->pScanVar,i,&pData);
|
|
pVar = (pVarEntry)pData;
|
|
if(pVar)
|
|
{
|
|
status = LLDnodePtr2First(pVar->dataList);
|
|
while(status != 0) {
|
|
fprintf(fd,"%s appendvarpos %d %f\n",self->objectName,
|
|
i, LLDnodeFloat(pVar->dataList));
|
|
status = LLDnodePtr2Next(pVar->dataList);
|
|
}
|
|
}
|
|
pData = NULL;
|
|
}
|
|
|
|
/* write counts */
|
|
for(i = 0; i < self->iCounts; i++)
|
|
{
|
|
DynarGet(self->pCounts,i,&pData);
|
|
pCount = (pCountEntry)pData;
|
|
if(pCount != NULL)
|
|
{
|
|
fprintf(fd,"%s storecounts %ld %f %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n",
|
|
self->objectName,
|
|
pCount->lCount,
|
|
pCount->fTime,
|
|
pCount->Monitors[0],
|
|
pCount->Monitors[1],
|
|
pCount->Monitors[2],
|
|
pCount->Monitors[3],
|
|
pCount->Monitors[4],
|
|
pCount->Monitors[5],
|
|
pCount->Monitors[6],
|
|
pCount->Monitors[7],
|
|
pCount->Monitors[8],
|
|
pCount->Monitors[9]);
|
|
}
|
|
}
|
|
if(self->iMode == eTimer){
|
|
fprintf(fd,"%s continue %d timer %f\n",self->objectName,
|
|
self->iNP,self->fPreset);
|
|
}else {
|
|
fprintf(fd,"%s continue %d monitor %f\n",self->objectName,
|
|
self->iNP,self->fPreset);
|
|
}
|
|
fclose(fd);
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int AppendScanLine(pScanData self, char *line)
|
|
{
|
|
/* reopen file */
|
|
self->fd = fopen(self->pFile,"r+");
|
|
if(!self->fd)
|
|
{
|
|
SCWrite(self->pCon,
|
|
"ERROR: Failed to reopen scan file, aborting scan",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
/* jump to end of file */
|
|
fseek(self->fd,0,SEEK_END);
|
|
|
|
/* print */
|
|
fprintf(self->fd,"%s\n",line);
|
|
|
|
/* done */
|
|
fclose(self->fd);
|
|
self->fd = NULL;
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
extern char *stptok(const char *s, char *t, int len, char *brk);
|
|
extern char *trim(char *txt);
|
|
|
|
int StoreScanCounts(pScanData self, char *data)
|
|
{
|
|
CountEntry sCount;
|
|
char pNumber[30], *pPtr;
|
|
int iCount = 0;
|
|
char pBueffel[256];
|
|
|
|
if(data == NULL)
|
|
{
|
|
SCWrite(self->pCon,"WARNING: StoreScanCounts called without data",
|
|
eWarning);
|
|
return 1;
|
|
}
|
|
InitCountEntry(&sCount);
|
|
|
|
/* parse the data */
|
|
pPtr = trim(data);
|
|
pPtr = stptok(pPtr,pNumber,29," \t");
|
|
if(pPtr != NULL)
|
|
{
|
|
sCount.lCount = atoi(pNumber);
|
|
}
|
|
else
|
|
{
|
|
SCWrite(self->pCon,"WARNING: No data in StoreScanCounts",eWarning);
|
|
snprintf(pBueffel,255,"Received: %s", data);
|
|
SCWrite(self->pCon,pBueffel,eWarning);
|
|
return 1;
|
|
}
|
|
pPtr = stptok(pPtr,pNumber,29," \t");
|
|
if(pPtr != NULL)
|
|
{
|
|
sCount.fTime = atof(pNumber);
|
|
}
|
|
if(pPtr == NULL){
|
|
return 1;
|
|
}
|
|
|
|
while((pPtr = stptok(pPtr,pNumber,29," \t")) != NULL)
|
|
{
|
|
sCount.Monitors[iCount] = atoi(pNumber);
|
|
iCount++;
|
|
if(iCount >= 10)
|
|
{
|
|
SCWrite(self->pCon,
|
|
"ERROR: I have only space for 10 Monitors in count structure",
|
|
eError);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
sCount.i = self->iCounts;
|
|
DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry));
|
|
self->iCounts++;
|
|
if(self->iCounts > self->iNP){
|
|
self->iNP++;
|
|
}
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
CountEntry CollectCounterData(pScanData self)
|
|
{
|
|
int i, iRet;
|
|
CountEntry sCount;
|
|
char *pAns = NULL, *pPtr = NULL ;
|
|
Tcl_Interp *pTcl;
|
|
float fVal;
|
|
|
|
InitCountEntry(&sCount);
|
|
|
|
/* monitors */
|
|
for(i = 1; i < 10; i++)
|
|
{
|
|
sCount.Monitors[i-1] = GetMonitor((pCounter)self->pCounterData,i,
|
|
self->pCon);
|
|
}
|
|
if( self->iChannel != 0 && self->iChannel != -10 )
|
|
{
|
|
sCount.Monitors[self->iChannel - 1] =
|
|
GetCounts((pCounter)self->pCounterData,
|
|
self->pCon);
|
|
}
|
|
|
|
/* counts, depending on iChannel */
|
|
if(self->iChannel == -10)
|
|
{
|
|
/* execute the Tcl-script for getting the data */
|
|
pTcl = InterpGetTcl(self->pSics);
|
|
if(!self->pCommand)
|
|
{
|
|
SCWrite(self->pCon,
|
|
"ERROR: command must be configured for user defined scans",
|
|
eError);
|
|
SCSetInterrupt(self->pCon,eAbortBatch);
|
|
return sCount;
|
|
}
|
|
iRet = Tcl_Eval(pTcl,self->pCommand);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
SCWrite(self->pCon,pTcl->result,eError);
|
|
return sCount;
|
|
}
|
|
/* interprete the Tcl result as a list of counts
|
|
WARNING: this may need to be changed when switching to
|
|
future versions of Tcl
|
|
*/
|
|
pAns = strdup(pTcl->result);
|
|
pPtr = strtok(pAns," ");
|
|
if(!pPtr)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: no counts found in Tcl-result",eError);
|
|
}
|
|
sscanf(pPtr,"%f",&fVal);
|
|
sCount.lCount = (long)fVal;
|
|
i = 0;
|
|
while( (pPtr != NULL) && (i < 10))
|
|
{
|
|
pPtr = strtok(NULL," ");
|
|
if(pPtr)
|
|
{
|
|
sscanf(pPtr,"%f",&fVal);
|
|
sCount.Monitors[i] = (long)fVal;
|
|
i++;
|
|
}
|
|
}
|
|
free(pAns);
|
|
}
|
|
else if(self->iChannel == 0)
|
|
{
|
|
sCount.lCount = GetCounts((pCounter)self->pCounterData,self->pCon);
|
|
}
|
|
else
|
|
{
|
|
sCount.lCount = GetMonitor((pCounter)self->pCounterData,
|
|
self->iChannel, self->pCon);
|
|
}
|
|
|
|
/* get time */
|
|
sCount.fTime = GetCountTime((pCounter)self->pCounterData,
|
|
self->pCon);
|
|
|
|
/* stow away */
|
|
DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry));
|
|
self->iCounts++;
|
|
if(self->iCounts > self->iNP){
|
|
self->iNP++;
|
|
}
|
|
return sCount;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
static int ScanLoop(pScanData self)
|
|
{
|
|
int i,iInt,iRet,iStatus;
|
|
|
|
assert(self);
|
|
assert(self->pCon);
|
|
|
|
InvokeCallBack(self->pCall,SCANSTART,self);
|
|
for(i = self->iCounts; i < self->iNP; i++)
|
|
{
|
|
/*--------- drive */
|
|
iRet = self->ScanDrive(self,i);
|
|
/* finished, check for interrupts. Whatever happened, user
|
|
interrupt or HW interrupt, it will be on our connection
|
|
*/
|
|
iInt = SCGetInterrupt(self->pCon);
|
|
switch(iInt)
|
|
{
|
|
case eContinue:
|
|
break;
|
|
case eAbortOperation:
|
|
SCSetInterrupt(self->pCon,eContinue);
|
|
SCWrite(self->pCon,
|
|
"WARNING: skipped scan point due to motor failure",
|
|
eWarning);
|
|
continue;
|
|
break;
|
|
case eAbortScan:
|
|
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
|
|
/* eat the interrupt, the requested op has been
|
|
done
|
|
*/
|
|
SCSetInterrupt(self->pCon,eContinue);
|
|
return 0;
|
|
break;
|
|
default: /* all others */
|
|
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
|
|
return 0;
|
|
break;
|
|
}
|
|
if(!iRet)
|
|
{
|
|
SCWrite(self->pCon,"WARNING: skipped scan point after drive failure",
|
|
eWarning);
|
|
continue;
|
|
}
|
|
|
|
/*-------------- count */
|
|
iRet = self->ScanCount(self, i);
|
|
/* finished, check for interrupts. Whatever happened, user
|
|
interrupt or HW interrupt, it will be on our connection
|
|
*/
|
|
iInt = SCGetInterrupt(self->pCon);
|
|
switch(iInt)
|
|
{
|
|
case eContinue:
|
|
break;
|
|
case eAbortOperation:
|
|
continue;
|
|
break;
|
|
case eAbortScan:
|
|
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
|
|
/* eat the interrupt, the requested op has been
|
|
done
|
|
*/
|
|
SCSetInterrupt(self->pCon,eContinue);
|
|
return 0;
|
|
break;
|
|
default: /* all others */
|
|
SCWrite(self->pCon,"ERROR: Scan aborted",eError);
|
|
return 0;
|
|
break;
|
|
}
|
|
if(!iRet)
|
|
{
|
|
SCWrite(self->pCon,"WARNING: skipped scan point after count failure",
|
|
eWarning);
|
|
continue;
|
|
}
|
|
|
|
/*-------- scan post processing */
|
|
self->CollectScanData(self,i);
|
|
InvokeCallBack(self->pCall,SCANPOINT,self);
|
|
|
|
self->WriteScanPoints(self,i);
|
|
if(self->pRecover)
|
|
{
|
|
WriteRecover(self);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int DoScan(pScanData self, int iNP, int iMode, float fPreset,
|
|
SicsInterp *pSics, SConnection *pCon)
|
|
{
|
|
int iRet;
|
|
char *pPtr = NULL;
|
|
char pBueffel[1024];
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
assert(pSics);
|
|
|
|
self->pCon = pCon;
|
|
self->pSics = pSics;
|
|
|
|
/* check arguments */
|
|
if(iNP <= 0)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: iNP < 0, nothing to do, Scan aborted",eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
if(self->iScanVar <= 0)
|
|
{
|
|
SCWrite(self->pCon,"WARNING: no scan variables given",eWarning);
|
|
}
|
|
|
|
if( (iMode != eTimer) && (iMode != ePreset))
|
|
{
|
|
SCWrite(self->pCon,"ERROR: Invalid counter mode given",eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
if(self->iActive != 0)
|
|
{
|
|
SCWrite(pCon,"ERROR: another scan is still running",eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
|
|
self->iNP = iNP;
|
|
self->iMode = iMode;
|
|
self->fPreset = fPreset;
|
|
|
|
/* do some preprocessing */
|
|
if(self->PrepareScan != NULL)
|
|
{
|
|
iRet = self->PrepareScan(self);
|
|
}
|
|
else
|
|
{
|
|
iRet = 1;
|
|
}
|
|
if(!iRet)
|
|
{
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
|
|
|
|
iRet = self->WriteHeader(self);
|
|
if(!iRet)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: cannot open data file, Scan aborted",
|
|
eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
|
|
self->iActive = 1;
|
|
iRet = ScanLoop(self);
|
|
ScriptScanFinish(self);
|
|
InvokeCallBack(self->pCall,SCANEND,self);
|
|
SendQuieck(QUIECK,self->pFile);
|
|
self->iActive = 0;
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return iRet;
|
|
}
|
|
/*----------------------------------------------------------------------------
|
|
SilentScan does a scan which does not produce a data file. It is intended
|
|
for internal use. Only status messages appear on screen.
|
|
---------------------------------------------------------------------------*/
|
|
int SilentScan(pScanData self, int iNP, int iMode, float fPreset,
|
|
SicsInterp *pSics, SConnection *pCon)
|
|
{
|
|
int iRet;
|
|
char *pPtr = NULL;
|
|
char pBueffel[1024];
|
|
int (*HeaderFunc)(pScanData self), (*ScanFunc)(pScanData self,
|
|
int iPoint);
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
assert(pSics);
|
|
|
|
/* check arguments */
|
|
if(iNP <= 0)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: iNP < 0, nothing to do, Scan aborted",eError);
|
|
return 0;
|
|
}
|
|
if(self->iScanVar <= 0)
|
|
{
|
|
SCWrite(self->pCon,"WARNING: no scan variables given",eWarning);
|
|
}
|
|
|
|
if( (iMode != eTimer) && (iMode != ePreset))
|
|
{
|
|
SCWrite(self->pCon,"ERROR: Invalid counter mode given",eError);
|
|
return 0;
|
|
}
|
|
if(self->iActive != 0)
|
|
{
|
|
SCWrite(pCon,"ERROR: another scan is still running",eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
|
|
HeaderFunc = self->WriteHeader;
|
|
self->WriteHeader = DummyWrite;
|
|
ScanFunc = self->WriteScanPoints;
|
|
self->WriteScanPoints = DummyWrite2;
|
|
self->pCon = pCon;
|
|
self->pSics = pSics;
|
|
self->iNP = iNP;
|
|
self->iMode = iMode;
|
|
self->fPreset = fPreset;
|
|
|
|
/* do some preprocessing */
|
|
iRet = SilentPrepare(self);
|
|
if(!iRet)
|
|
{
|
|
self->WriteHeader = HeaderFunc;
|
|
self->WriteScanPoints = ScanFunc;
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
|
|
self->iActive = 1;
|
|
iRet = ScanLoop(self);
|
|
self->iActive = 0;
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
self->WriteHeader = HeaderFunc;
|
|
self->WriteScanPoints = ScanFunc;
|
|
|
|
return iRet;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int ContinueScan(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
|
int argc, char *argv[])
|
|
{
|
|
int iRet;
|
|
char *pPtr = NULL, pBueffel[512];
|
|
double dVal;
|
|
|
|
assert(pSics);
|
|
assert(pCon);
|
|
|
|
self->pCon = pCon;
|
|
self->pSics = pSics;
|
|
|
|
if(argc < 5)
|
|
{
|
|
SCWrite(pCon,"ERROR: not enough arguments to scan continue",eError);
|
|
return 0;
|
|
}
|
|
|
|
/* get NP */
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&self->iNP);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* interpret Mode */
|
|
if(strcmp(argv[3],"timer") == 0)
|
|
{
|
|
self->iMode = eTimer;
|
|
}
|
|
else if(strcmp(argv[3],"monitor") == 0)
|
|
{
|
|
self->iMode = ePreset;
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s not recognized as valid counter mode",
|
|
argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* preset */
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[4],&dVal);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
self->fPreset = dVal;
|
|
|
|
/* configure counter */
|
|
SetCounterMode((pCounter)self->pCounterData,self->iMode);
|
|
SetCounterPreset((pCounter)self->pCounterData, self->fPreset);
|
|
|
|
|
|
/* new scan data file */
|
|
pPtr = ScanMakeFileName(self->pSics,self->pCon);
|
|
if(!pPtr)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: cannot allocate new data filename, Scan aborted",
|
|
eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
sprintf(pBueffel,"Writing data file: %s ...",pPtr);
|
|
SCWrite(self->pCon,pBueffel,eWarning);
|
|
strcpy(self->pFile,pPtr);
|
|
free(pPtr);
|
|
iRet = self->WriteHeader(self);
|
|
if(!iRet)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: cannot open data file, Scan aborted",
|
|
eError);
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return 0;
|
|
}
|
|
|
|
self->iActive = 1;
|
|
iRet = ScanLoop(self);
|
|
ScriptScanFinish(self);
|
|
InvokeCallBack(self->pCall,SCANEND,self);
|
|
SendQuieck(QUIECK,self->pFile);
|
|
self->iActive = 0;
|
|
self->pCon = NULL;
|
|
self->pSics = NULL;
|
|
return iRet;
|
|
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int GetScanNP(pScanData self)
|
|
{
|
|
assert(self);
|
|
return self->iNP;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
float GetScanPreset(pScanData self)
|
|
{
|
|
assert(self);
|
|
return self->fPreset;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int GetScanCounts(pScanData self,long *lData, int iDataLen)
|
|
{
|
|
int i, iEnd;
|
|
pCountEntry pData = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
assert(self);
|
|
/* hanlde iEnd */
|
|
if(self->iCounts < iDataLen)
|
|
{
|
|
iEnd = self->iCounts;
|
|
}
|
|
else
|
|
{
|
|
iEnd = iDataLen;
|
|
}
|
|
|
|
/* initialise to 0 */
|
|
memset(lData,0,iDataLen*sizeof(long));
|
|
|
|
/* the loop */
|
|
for(i = 0; i < iEnd; i++)
|
|
{
|
|
DynarGet(self->pCounts,i,&pPtr);
|
|
pData = (pCountEntry)pPtr;
|
|
if(pData)
|
|
{
|
|
lData[i] = pData->lCount;
|
|
}
|
|
pData = NULL;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int GetScanMonitor(pScanData self,int iWhich,long *lData, int iDataLen)
|
|
{
|
|
int i, iEnd;
|
|
pCountEntry pData = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
assert(self);
|
|
|
|
/* hanlde iEnd */
|
|
if(self->iCounts < iDataLen)
|
|
{
|
|
iEnd = self->iCounts;
|
|
}
|
|
else
|
|
{
|
|
iEnd = iDataLen;
|
|
}
|
|
|
|
/* initialise to 0 */
|
|
memset(lData,0,iDataLen*sizeof(long));
|
|
|
|
/* the loop */
|
|
for(i = 0; i < iEnd; i++)
|
|
{
|
|
DynarGet(self->pCounts,i,&pPtr);
|
|
pData = (pCountEntry)pPtr;
|
|
if(pData)
|
|
{
|
|
lData[i] = pData->Monitors[iWhich];
|
|
}
|
|
pData = NULL;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int GetScanVar(pScanData self, int iWhich, float *fData, int iDataLen)
|
|
{
|
|
int iEnd, i;
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
/* does it exist ?*/
|
|
if( (iWhich < 0) || (iWhich >= self->iScanVar) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* handle iEnd */
|
|
if(self->iCounts < iDataLen)
|
|
{
|
|
iEnd = self->iCounts;
|
|
}
|
|
else
|
|
{
|
|
iEnd = iDataLen;
|
|
}
|
|
|
|
DynarGet(self->pScanVar,iWhich,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
/* initialise to theoretical values */
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
fData[i] = pVar->fStart + i * pVar->fStep;
|
|
}
|
|
CopyScanVar(pVar,fData, self->iNP);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* not reached */
|
|
assert(0);
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int GetSoftScanVar(pScanData self, int iWhich, float *fData, int iDataLen)
|
|
{
|
|
int iEnd, i;
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
/* does it exist ?*/
|
|
if( (iWhich < 0) || (iWhich >= self->iScanVar) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* handle iEnd */
|
|
if(self->iCounts < iDataLen)
|
|
{
|
|
iEnd = self->iCounts;
|
|
}
|
|
else
|
|
{
|
|
iEnd = iDataLen;
|
|
}
|
|
|
|
DynarGet(self->pScanVar,iWhich,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
/* initialise to theoretical values */
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
fData[i] = pVar->fStart + i * pVar->fStep;
|
|
}
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* not reached */
|
|
assert(0);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int GetScanVarName(pScanData self, int iWhich, char *pName, int iLength)
|
|
{
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
/* does it exist ?*/
|
|
if( (iWhich < 0) || (iWhich >= self->iScanVar) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* get the scan var */
|
|
DynarGet(self->pScanVar,iWhich,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
strncpy(pName,ScanVarName(pVar),iLength);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
int GetScanVarStep(pScanData self, int iWhich, float *fStep)
|
|
{
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
/* does it exist ?*/
|
|
if( (iWhich < 0) || (iWhich >= self->iScanVar) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* get the scan var */
|
|
DynarGet(self->pScanVar,iWhich,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
*fStep = ScanVarStep(pVar);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------------
|
|
ScanIntegrate does an integration of the current scan data. It returns 1 on
|
|
success or one of the integrate error codes defined in integrate.h
|
|
-----------------------------------------------------------------------------*/
|
|
int ScanIntegrate(pScanData self, float *fSum, float *fVar)
|
|
{
|
|
long *lData = NULL;
|
|
int iRet;
|
|
|
|
assert(self);
|
|
|
|
/* no integration if no peak measured */
|
|
if(self->iCounts <= self->iWindow*2)
|
|
return INTEGNOPEAK;
|
|
|
|
/* get some memory */
|
|
lData = (long *)malloc(self->iNP*sizeof(long));
|
|
if(!lData)
|
|
{
|
|
return INTEGNOPEAK;
|
|
}
|
|
/* get counts */
|
|
GetScanCounts(self,lData,self->iNP);
|
|
/* Do it */
|
|
iRet = GabePeakIntegrate(self->iWindow,self->iNP,lData, fSum, fVar);
|
|
free(lData);
|
|
return iRet;
|
|
}
|
|
/*--------------------------------------------------------------------------
|
|
SimScan is a debugging aid for other modules. It simulates a scan on a
|
|
variable in the range from 10 -20 degrees in angle and 100 points. Data
|
|
is created as a Gauss function located at fPos, with a halfwidth of
|
|
FWHM and a height of fHeight. All data is randomized a little in a range
|
|
of 5 counts. The peak will sit on a background of 20 counts. This requires
|
|
a motor a4 to exist as it will be used for x-axis simulation. This routine
|
|
will not stop you from simulating shit if you throw shit at it!
|
|
----------------------------------------------------------------------------*/
|
|
int SimScan(pScanData self, float fPos, float FWHM, float fHeight)
|
|
{
|
|
int i, iRet;
|
|
SConnection *pCon = NULL;
|
|
CountEntry sCount;
|
|
pVarEntry pVar = NULL;
|
|
void *pDings = NULL;
|
|
float x, y, fTmp, fStdDev;
|
|
|
|
|
|
assert(self);
|
|
|
|
InitCountEntry(&sCount);
|
|
|
|
/* go to a clean state */
|
|
ClearScanVar(self);
|
|
|
|
/* put in the scan variable */
|
|
pCon = SCCreateDummyConnection(pServ->pSics);
|
|
if(!pCon)
|
|
{
|
|
return 0;
|
|
}
|
|
iRet = AddScanVar(self,pServ->pSics,pCon,"a4",10., 0.1);
|
|
SCDeleteConnection(pCon);
|
|
if(!iRet)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* do the x-axis of the scan */
|
|
DynarGet(self->pScanVar,0,&pDings);
|
|
pVar = (pVarEntry)pDings;
|
|
if(!pVar)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* create scan data in loop */
|
|
fStdDev = FWHM/2.354;
|
|
for(i = 0; i < 90; i++)
|
|
{
|
|
x = 10. + 0.1 * i;
|
|
AppendScanVar(pVar,x);
|
|
sCount.i = i;
|
|
/* gaussian */
|
|
fTmp = (x - fPos)/fStdDev;
|
|
y = fHeight*0.4* exp(-0.5*fTmp*fTmp);
|
|
/* randomize a little */
|
|
y += 7. * (float)rand()/(float)RAND_MAX;
|
|
/* add a little background */
|
|
sCount.lCount = (long)(10 + y);
|
|
/* stow away */
|
|
DynarReplace(self->pCounts,i,&sCount,sizeof(CountEntry));
|
|
}
|
|
self->iCounts = 90;
|
|
self->iNP = 90;
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
int ScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pScanData pNew = NULL;
|
|
pCounter pCount = NULL;
|
|
pDummy pDum = NULL;
|
|
CommandList *pCom = NULL;
|
|
char pBueffel[512];
|
|
int iRet;
|
|
|
|
if(argc < 5)
|
|
{
|
|
SCWrite(pCon,"ERROR: Insufficient number of arguments to ScanFactory",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
strtolower(argv[1]);
|
|
strtolower(argv[2]);
|
|
pCom = FindCommand(pSics,argv[2]);
|
|
if(!pCom)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot find counter %s",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
pDum = (pDummy)pCom->pData;
|
|
if(!pDum)
|
|
{
|
|
sprintf(pBueffel,"ERROR: counter %s has no data",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
if(!(pDum->pDescriptor->GetInterface(pDum,COUNTID)))
|
|
{
|
|
sprintf(pBueffel,"ERROR: object %s is NO counter",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
pNew = CreateScanObject(argv[4],argv[3],(pCounter)pCom->pData,
|
|
argv[1]);
|
|
if(!pNew)
|
|
{
|
|
SCWrite(pCon,"ERROR: failure to allocate scan data structure",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
iRet = AddCommand(pSics,
|
|
argv[1],
|
|
ScanWrapper,
|
|
DeleteScanObject,
|
|
pNew);
|
|
if(!iRet)
|
|
{
|
|
sprintf(pBueffel,"ERROR: duplicate command %s not created",argv[1]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/*
|
|
ignore this one, this is cheaper then checking for the existence
|
|
of another scan object
|
|
*/
|
|
AddCommand(pSics,
|
|
"stdscan",
|
|
StandardScanWrapper,
|
|
NULL,
|
|
NULL);
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int ScanInterest(int iEvent, void *pEventData, void *pUser,
|
|
commandContext cc)
|
|
{
|
|
pScanData self = NULL;
|
|
SConnection *pCon = NULL;
|
|
char *pPtr = NULL, pItem[20];
|
|
long *lData = NULL;
|
|
int i;
|
|
writeFunc oldWrite;
|
|
|
|
self = (pScanData)pEventData;
|
|
pCon = (SConnection *)pUser;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
|
|
if(iEvent == SCANSTART)
|
|
{
|
|
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
|
return 1;
|
|
}
|
|
else if(iEvent == SCANEND)
|
|
{
|
|
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
|
return 1;
|
|
}
|
|
else if(iEvent == SCANPOINT)
|
|
{
|
|
/* allocate space */
|
|
pPtr = (char *)malloc((self->iNP*20+20)*sizeof(char));
|
|
if(!pPtr)
|
|
{
|
|
return 0;
|
|
}
|
|
memset(pPtr,0,(self->iNP*20+20)*sizeof(char));
|
|
lData = (long *)malloc(self->iNP*sizeof(long));
|
|
if(!lData)
|
|
{
|
|
return 0;
|
|
}
|
|
memset(lData,0,self->iNP*sizeof(long));
|
|
|
|
/* get counts */
|
|
GetScanCounts(self,lData,self->iNP);
|
|
/* format a message */
|
|
|
|
strcpy(pPtr,"scan.Counts= {");
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
sprintf(pItem,"%ld ",lData[i]);
|
|
strcat(pPtr,pItem);
|
|
}
|
|
strcat(pPtr,"}");
|
|
oldWrite = SCGetWriteFunc(pCon);
|
|
SCSetWriteFunc(pCon,SCOnlySockWrite);
|
|
SCWrite(pCon,pPtr,eWarning);
|
|
SCSetWriteFunc(pCon,oldWrite);
|
|
free(lData);
|
|
free(pPtr);
|
|
return 1;
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int ScanDynInterest(int iEvent, void *pEventData, void *pUser,
|
|
commandContext cc)
|
|
{
|
|
pScanData self = NULL;
|
|
SConnection *pCon = NULL;
|
|
void *pPtr;
|
|
pVarEntry pVar;
|
|
pCountEntry pCount = NULL;
|
|
float fVal;
|
|
long lVal;
|
|
int i;
|
|
char pBueffel[256];
|
|
|
|
self = (pScanData)pEventData;
|
|
pCon = (SConnection *)pUser;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
|
|
if(iEvent == SCANSTART)
|
|
{
|
|
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
|
return 1;
|
|
}
|
|
else if(iEvent == SCANEND)
|
|
{
|
|
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
|
return 1;
|
|
}
|
|
else if(iEvent == SCANPOINT)
|
|
{
|
|
i = self->iCounts -1;
|
|
DynarGet(self->pScanVar,0,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar != NULL){
|
|
fVal = GetScanVarPos(pVar,i);
|
|
} else {
|
|
fVal = -9999.99;
|
|
}
|
|
DynarGet(self->pCounts,i,&pPtr);
|
|
pCount =(pCountEntry)pPtr;
|
|
if(pCount != NULL){
|
|
lVal = pCount->lCount;
|
|
} else {
|
|
lVal = -9999.99;
|
|
}
|
|
snprintf(pBueffel,255,"%s.scanpoint = {%d %f %ld}",
|
|
self->objectName,i,fVal,lVal);
|
|
SCWriteInContext(pCon,pBueffel,eValue,cc);
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser,
|
|
commandContext cc)
|
|
{
|
|
pScanData self = NULL;
|
|
SConnection *pCon = NULL;
|
|
char pItem[20];
|
|
long *lData = NULL;
|
|
int *iData = NULL;
|
|
int i;
|
|
|
|
self = (pScanData)pEventData;
|
|
pCon = (SConnection *)pUser;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
|
|
if(iEvent == SCANSTART)
|
|
{
|
|
SCWriteInContext(pCon,"NewScan",eWarning,cc);
|
|
return 1;
|
|
}
|
|
else if(iEvent == SCANEND)
|
|
{
|
|
SCWriteInContext(pCon,"ScanEnd",eWarning,cc);
|
|
return 1;
|
|
}
|
|
else if(iEvent == SCANPOINT)
|
|
{
|
|
/* allocate space */
|
|
lData = (long *)malloc(self->iNP*sizeof(long));
|
|
iData = (int *)malloc(self->iNP*sizeof(int));
|
|
if(!lData || !iData)
|
|
{
|
|
return 0;
|
|
}
|
|
memset(lData,0,self->iNP*sizeof(long));
|
|
memset(iData,0,self->iNP*sizeof(int));
|
|
|
|
/* get counts */
|
|
GetScanCounts(self,lData,self->iNP);
|
|
/* put into network byte order */
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
iData[i] = htonl((int)lData[i]);
|
|
}
|
|
SCPushContext2(pCon,cc);
|
|
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
|
|
SCPopContext(pCon);
|
|
free(lData);
|
|
free(iData);
|
|
return 1;
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int GetVarPar(SConnection *pCon, pScanData self, char *scanname, int i)
|
|
{
|
|
char pBueffel[512];
|
|
void *pPtr = NULL;
|
|
pVarEntry pVar = NULL;
|
|
|
|
assert(pCon);
|
|
assert(self);
|
|
|
|
if(i < 0 || i >= self->iScanVar)
|
|
{
|
|
SCWrite(pCon,"ERROR: scan variable number out of range",eError);
|
|
return 0;
|
|
}
|
|
|
|
DynarGet(self->pScanVar,i,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar != NULL)
|
|
{
|
|
snprintf(pBueffel, 511,"%s.%s = %f = %f",
|
|
scanname,
|
|
ScanVarName(pVar),
|
|
ScanVarStart(pVar),
|
|
ScanVarStep(pVar));
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int AppendVarPos(SConnection *pCon, pScanData self,
|
|
int scanVar, float fPos)
|
|
{
|
|
char pBueffel[512];
|
|
void *pPtr = NULL;
|
|
pVarEntry pVar = NULL;
|
|
|
|
assert(pCon);
|
|
assert(self);
|
|
|
|
if(scanVar < 0 || scanVar >= self->iScanVar)
|
|
{
|
|
SCWrite(pCon,"ERROR: scan variable number out of range",eError);
|
|
return 0;
|
|
}
|
|
|
|
DynarGet(self->pScanVar,scanVar,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar != NULL)
|
|
{
|
|
AppendScanVar(pVar,fPos);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static void PrintScanVars(pScanData self, char *scanname, SConnection *pCon){
|
|
char pBueffel[1024];
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
int i;
|
|
|
|
assert(pCon);
|
|
assert(self);
|
|
|
|
snprintf(pBueffel,1023,"%s.scanvars = { ", scanname);
|
|
for(i = 0; i < self->iScanVar; i++){
|
|
DynarGet(self->pScanVar,i,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar != NULL){
|
|
strncat(pBueffel,ScanVarName(pVar),1023-strlen(pBueffel));
|
|
strcat(pBueffel," ");
|
|
}
|
|
}
|
|
strcat(pBueffel,"}");
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int PrintCountsOrMonitors(pScanData self, SConnection *pCon,
|
|
char *name, int iWhich)
|
|
{
|
|
pDynString data = NULL;
|
|
long *lData = NULL;
|
|
char pBueffel[60];
|
|
int i;
|
|
|
|
if(self->iNP < 1)
|
|
{
|
|
SCWrite(pCon,"ERROR: no scan data available",eError);
|
|
return 0;
|
|
}
|
|
|
|
data = CreateDynString(80,80);
|
|
lData = (long *)malloc(self->iNP*sizeof(long));
|
|
if(data == NULL || lData == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory printing counts",eError);
|
|
return 0;
|
|
}
|
|
memset(lData,0,self->iNP*sizeof(long));
|
|
|
|
if(iWhich < 0)
|
|
{
|
|
GetScanCounts(self,lData,self->iNP);
|
|
snprintf(pBueffel,59,"%s.Counts = {", name);
|
|
}
|
|
else
|
|
{
|
|
GetScanMonitor(self,iWhich,lData,self->iNP);
|
|
snprintf(pBueffel,59,"%s.mon%2.2d = {", name, iWhich);
|
|
}
|
|
DynStringCopy(data,pBueffel);
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
snprintf(pBueffel,59," %ld", lData[i]);
|
|
DynStringConcat(data,pBueffel);
|
|
}
|
|
DynStringConcatChar(data,'}');
|
|
SCWrite(pCon,GetCharArray(data),eValue);
|
|
DeleteDynString(data);
|
|
free(lData);
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int PrintTimes(pScanData self, SConnection *pCon,
|
|
char *name)
|
|
{
|
|
pDynString data = NULL;
|
|
char pBueffel[60];
|
|
int i, iEnd;
|
|
pCountEntry pData = NULL;
|
|
void *pPtr = NULL;
|
|
|
|
if(self->iNP < 1)
|
|
{
|
|
SCWrite(pCon,"ERROR: no scan data available",eError);
|
|
return 0;
|
|
}
|
|
|
|
data = CreateDynString(80,80);
|
|
if(data == NULL)
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory printing counts",eError);
|
|
return 0;
|
|
}
|
|
|
|
snprintf(pBueffel,59,"%s.scantimes = { ",name);
|
|
DynStringCopy(data,pBueffel);
|
|
for(i = 0; i < self->iCounts; i++)
|
|
{
|
|
DynarGet(self->pCounts,i,&pPtr);
|
|
pData = (pCountEntry)pPtr;
|
|
if(pData)
|
|
{
|
|
snprintf(pBueffel,59," %f", pData->fTime);
|
|
DynStringConcat(data,pBueffel);
|
|
}
|
|
}
|
|
DynStringConcatChar(data,'}');
|
|
SCWrite(pCon,GetCharArray(data),eValue);
|
|
DeleteDynString(data);
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int ScanInvokeCallback(pScanData self, SConnection *pCon, char *name)
|
|
{
|
|
int eventID;
|
|
|
|
if(strcmp(name,"scanstart") == 0){
|
|
eventID = SCANSTART;
|
|
}else if(strcmp(name,"scanpoint") == 0){
|
|
eventID = SCANPOINT;
|
|
}else if(strcmp(name,"scanend") == 0){
|
|
eventID = SCANEND;
|
|
} else {
|
|
SCWrite(pCon,"ERROR: callback ID not recognised",eError);
|
|
return 0;
|
|
}
|
|
InvokeCallBack(self->pCall,eventID, self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static void ListScanFunctions(pScanData self, SConnection *pCon){
|
|
pDynString result = NULL;
|
|
char pValue[256], *pPtr = NULL;
|
|
|
|
result = CreateDynString(80,80);
|
|
if(result == NULL){
|
|
SCWrite(pCon,"ERROR: failed to allocate memory in function list",eError);
|
|
return;
|
|
}
|
|
while( (pPtr = (char *)StringDictGetNext(self->scanFunctions,
|
|
pValue,255)) != NULL){
|
|
DynStringConcat(result, pPtr);
|
|
DynStringConcat(result," = ");
|
|
DynStringConcat(result, pValue);
|
|
DynStringConcatChar(result, '\n');
|
|
}
|
|
SCWrite(pCon,GetCharArray(result), eValue);
|
|
DeleteDynString(result);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int InterpretScanFunctions(pScanData self, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
char pValue[256];
|
|
char response[512];
|
|
|
|
if(argc < 3){
|
|
SCWrite(pCon,"ERROR: need subcommand to scan function",eError);
|
|
return 0;
|
|
}
|
|
strtolower(argv[2]);
|
|
if(strcmp(argv[2],"list") == 0){
|
|
ListScanFunctions(self,pCon);
|
|
return 1;
|
|
}
|
|
|
|
if(argc > 3){
|
|
/*
|
|
set case
|
|
*/
|
|
Arg2Text(argc-3,&argv[3],pValue,255);
|
|
if(!StringDictUpdate(self->scanFunctions,argv[2],pValue)){
|
|
snprintf(pValue,255,"ERROR: scan function %s not found",argv[2]);
|
|
SCWrite(pCon,pValue,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
request case
|
|
*/
|
|
if(StringDictGet(self->scanFunctions,argv[2],pValue,255)){
|
|
snprintf(response,511,"%s function %s = %s",argv[0],argv[2],
|
|
pValue);
|
|
SCWrite(pCon,response,eValue);
|
|
return 1;
|
|
} else {
|
|
snprintf(pValue,255,"ERROR: scan function %s not found",argv[2]);
|
|
SCWrite(pCon,pValue,eError);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int DumpScan(pScanData self, SConnection *pCon)
|
|
{
|
|
int i;
|
|
SConnection *oldCon;
|
|
char pFile[1024];
|
|
|
|
if(self->iActive)
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot dump scan while running",eError);
|
|
return 0;
|
|
}
|
|
if(!self->pSics)
|
|
{
|
|
self->pSics = pServ->pSics;
|
|
}
|
|
/*
|
|
* save old file etc status
|
|
*/
|
|
oldCon = self->pCon;
|
|
pFile[0] = '\0';
|
|
strncpy(pFile,self->pFile,1023);
|
|
prepareDataFile(self);
|
|
self->pCon = pCon;
|
|
self->WriteHeader(self);
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
self->WriteScanPoints(self,i);
|
|
}
|
|
SCWrite(pCon,"Scan dumped", eValue);
|
|
self->pCon = oldCon;
|
|
strncpy(self->pFile,pFile,1023);
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|
|
int ScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pScanData self = NULL;
|
|
char pBueffel[512];
|
|
double fStep, fStart, fPreset;
|
|
float *fData = NULL;
|
|
int lNP;
|
|
int iChannel;
|
|
int iRet, iMode,i;
|
|
char *pPtr = NULL, pItem[20];
|
|
long *lData = NULL, lID;
|
|
int *iData;
|
|
void *pVarData = NULL;
|
|
pVarEntry pVar = NULL;
|
|
float fSum, fVar;
|
|
double x;
|
|
float fPos, FWHM, fHeight;
|
|
pSite site = NULL;
|
|
SConnection *conSave;
|
|
|
|
self = (pScanData)pData;
|
|
assert(self);
|
|
|
|
argtolower(argc,argv);
|
|
if(argc < 2)
|
|
{
|
|
sprintf(pBueffel,"ERROR: not enough arguments for %s",argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
first interpret commands which do not require user rights
|
|
*/
|
|
|
|
/*---------- getfile */
|
|
if(strcmp(argv[1],"getfile") == 0)
|
|
{
|
|
sprintf(pBueffel,"scan.File = %s",self->pFile);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
if(strcmp(argv[1],"getscanvars") == 0)
|
|
{
|
|
PrintScanVars(self,argv[0],pCon);
|
|
return 1;
|
|
}
|
|
/*--------- getcounts */
|
|
else if(strcmp(argv[1],"getcounts") == 0)
|
|
{
|
|
return PrintCountsOrMonitors(self,pCon,argv[0],-77);
|
|
}
|
|
/*------------ getmonitor */
|
|
else if(strcmp(argv[1],"getmonitor") == 0)
|
|
{
|
|
if(argc < 3)
|
|
{
|
|
SCWrite(pCon,"ERROR: need monitor number to print",eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&i);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected integer, got %s",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
return PrintCountsOrMonitors(self,pCon,argv[0],i);
|
|
}
|
|
/*--------- gettimes */
|
|
else if(strcmp(argv[1],"gettimes") == 0)
|
|
{
|
|
return PrintTimes(self,pCon,argv[0]);
|
|
}
|
|
/*---------- uucounts */
|
|
else if(strcmp(argv[1],"uucounts") == 0)
|
|
{
|
|
/* get some memory */
|
|
if(self->iNP < 1)
|
|
{
|
|
SCWrite(pCon,"ERROR: no counts available",eError);
|
|
return 0;
|
|
}
|
|
lData = (long *)malloc(self->iNP*sizeof(long));
|
|
iData = (int *)malloc((self->iNP + 1)*sizeof(int));
|
|
if(!lData || !iData )
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory in scan",eError);
|
|
return 0;
|
|
}
|
|
|
|
/* get counts */
|
|
GetScanCounts(self,lData,self->iNP);
|
|
/* copy them */
|
|
memset(iData,0,self->iNP+1);
|
|
iData[0] = htonl(self->iNP);
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
iData[i+1] = htonl(lData[i]);
|
|
}
|
|
SCWriteUUencoded(pCon,"ScanCounts",iData,
|
|
(self->iNP + 1)*sizeof(int));
|
|
return 1;
|
|
}
|
|
/*--------- noscanvar */
|
|
else if(strcmp(argv[1],"noscanvar") == 0)
|
|
{
|
|
sprintf(pBueffel,"%s.noscanvar = %d",argv[0],
|
|
self->iScanVar);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
/*-------- NP */
|
|
else if(strcmp(argv[1],"np") == 0)
|
|
{
|
|
sprintf(pBueffel,"%s.nP = %d",argv[0],
|
|
self->iNP);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
/*--------- getvardata */
|
|
else if(strcmp(argv[1],"getvardata") == 0)
|
|
{
|
|
/* we need an integer parameter saying which */
|
|
if(argc >= 3)
|
|
{
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&i);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected integer, got %s",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SCWrite(pCon,"ERROR: expected number of variable to retrieve data for ",
|
|
eError);
|
|
return 0;
|
|
}
|
|
/* check the int for validity */
|
|
if( (i < 0) || (i >= self->iScanVar))
|
|
{
|
|
SCWrite(pCon,"ERROR: non existent scan variable requested!",eError);
|
|
return 0;
|
|
}
|
|
|
|
/* get some memory */
|
|
fData = (float *)malloc(self->iNP*sizeof(float));
|
|
if(!fData)
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory in scan",eError);
|
|
return 0;
|
|
}
|
|
pPtr = (char *)malloc((self->iNP*20+20)*sizeof(char));
|
|
if(!pPtr)
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory in scan",eError);
|
|
return 0;
|
|
}
|
|
memset(pPtr,0,(self->iNP*20+20)*sizeof(char));
|
|
|
|
/* get data */
|
|
GetScanVar(self,i,fData,self->iNP);
|
|
|
|
/* get name of ScanVar */
|
|
DynarGet(self->pScanVar,i,&pVarData);
|
|
pVar = (pVarEntry)pVarData;
|
|
if(!pVar)
|
|
{
|
|
SCWrite(pCon,"ERROR: Corrupted data structures, inform Programmer",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
/* format them */
|
|
sprintf(pPtr,"scan.%s = ", ScanVarName(pVar));
|
|
for(i = 0; i < self->iNP; i++)
|
|
{
|
|
sprintf(pItem,"{%12.3f} ",fData[i]);
|
|
strcat(pPtr,pItem);
|
|
}
|
|
SCWrite(pCon,pPtr,eValue);
|
|
free(fData);
|
|
free(pPtr);
|
|
return 1;
|
|
}
|
|
/*---------getvarpar */
|
|
else if(strcmp(argv[1],"getvarpar") == 0)
|
|
{
|
|
/* we need an integer parameter saying which */
|
|
if(argc >= 3)
|
|
{
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&i);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected integer, got %s",argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SCWrite(pCon,"ERROR: expected number of variable to retrieve data for ",
|
|
eError);
|
|
return 0;
|
|
}
|
|
return GetVarPar(pCon,self,argv[0],i);
|
|
}
|
|
/*-------- interest */
|
|
else if(strcmp(argv[1],"interest") == 0)
|
|
{
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*-------- interest */
|
|
else if(strcmp(argv[1],"dyninterest") == 0)
|
|
{
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanDynInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon), SCANEND, ScanDynInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanDynInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*-------- uuinterest */
|
|
else if(strcmp(argv[1],"uuinterest") == 0)
|
|
{
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANSTART, ScanUUInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANEND, ScanUUInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
lID = RegisterCallback(self->pCall, SCGetContext(pCon),SCANPOINT, ScanUUInterest,
|
|
pCon, NULL);
|
|
SCRegister(pCon,pSics, self->pCall,lID);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/* ------- uninterest */
|
|
else if(strcmp(argv[1],"uninterest") == 0)
|
|
{
|
|
RemoveCallback2(self->pCall,pCon);
|
|
SCUnregister(pCon,self->pCall);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
|
|
/*------- deal with command needing user rights in all cases */
|
|
|
|
/* check User Rights */
|
|
if(!(SCMatchRights(pCon,usUser)))
|
|
{
|
|
SCWrite(pCon,"ERROR: You are NOT authorised to use scan",eError);
|
|
return 0;
|
|
}
|
|
/*---------- add command */
|
|
if(strcmp(argv[1],"add") == 0)
|
|
{
|
|
if(argc < 5)
|
|
{
|
|
sprintf(pBueffel,
|
|
"ERROR: Insufficient number of arguments given for %s add",
|
|
argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* get numbers */
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&fStart);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[4],&fStep);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = AddScanVar(self,pSics,pCon,argv[2],
|
|
(float)fStart,(float)fStep);
|
|
if(iRet)
|
|
{
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
}
|
|
else if(strcmp(argv[1],"log") == 0)
|
|
{
|
|
if(argc < 3)
|
|
{
|
|
sprintf(pBueffel,
|
|
"ERROR: Insufficient number of arguments given for %s log",
|
|
argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = AddLogVar(self,pSics,pCon,argv[2]);
|
|
if(iRet)
|
|
{
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
}
|
|
/* --------clear */
|
|
else if(strcmp(argv[1],"clear") == 0)
|
|
{
|
|
iRet = ClearScanVar(self);
|
|
if(iRet)
|
|
{
|
|
SCSendOK(pCon);
|
|
}
|
|
else
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot change parameters while scanning",
|
|
eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*------------ dump */
|
|
else if(strcmp(argv[1],"dump") == 0)
|
|
{
|
|
return DumpScan(self,pCon);
|
|
}
|
|
/* --------callback */
|
|
else if(strcmp(argv[1],"callback") == 0)
|
|
{
|
|
if(argc < 3)
|
|
{
|
|
SCWrite(pCon,"ERROR: need callback ID for invocation",eError);
|
|
return 0;
|
|
}
|
|
return ScanInvokeCallback(self,pCon,argv[2]);
|
|
}
|
|
/*------------ configure */
|
|
else if(strcmp(argv[1],"configure") == 0)
|
|
{
|
|
if(argc < 3)
|
|
{
|
|
SCWrite(pCon,"ERROR: missing configure option",eError);
|
|
return 0;
|
|
}
|
|
/* this is for users only */
|
|
if(!SCMatchRights(pCon,usUser))
|
|
return 0;
|
|
strtolower(argv[2]);
|
|
if(strcmp(argv[2],"standard") == 0)
|
|
{
|
|
ResetScanFunctions(self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else if(strcmp(argv[2],"user") == 0)
|
|
{
|
|
ConfigureUserScan(self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else if(strcmp(argv[2],"script") == 0)
|
|
{
|
|
ConfigureScript(self);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
site = getSite();
|
|
if(site != NULL){
|
|
iRet = site->ConfigureScan(self,argv[2]);
|
|
}
|
|
if(!iRet){
|
|
sprintf(pBueffel,"ERROR: option %s not recognized by configure",
|
|
argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
} else {
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
/*------------ functions */
|
|
else if(strcmp(argv[1],"function") == 0)
|
|
{
|
|
return InterpretScanFunctions(self, pCon, argc, argv);
|
|
}
|
|
/*---------- scan */
|
|
else if(strcmp(argv[1],"run") == 0)
|
|
{
|
|
if (argc < 5) {
|
|
sprintf(pBueffel,"ERROR: not enough arguments for %s run",argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* get NP */
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&lNP);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* interpret Mode */
|
|
if(strcmp(argv[3],"timer") == 0)
|
|
{
|
|
iMode = eTimer;
|
|
}
|
|
else if(strcmp(argv[3],"monitor") == 0)
|
|
{
|
|
iMode = ePreset;
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s not recognized as valid counter mode",
|
|
argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* preset */
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[4],&fPreset);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = DoScan(self,(int)lNP,iMode,(float)fPreset,
|
|
pSics,pCon);
|
|
if(iRet)
|
|
{
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
}
|
|
/*------------ continue */
|
|
else if(strcmp(argv[1],"continue") == 0)
|
|
{
|
|
return ContinueScan(self,pSics,pCon,argc,argv);
|
|
}
|
|
/*---------- silent */
|
|
else if(strcmp(argv[1],"silent") == 0)
|
|
{
|
|
if (argc < 5) {
|
|
sprintf(pBueffel,"ERROR: not enough arguments for %s silent",argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* get NP */
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&lNP);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* interpret Mode */
|
|
if(strcmp(argv[3],"timer") == 0)
|
|
{
|
|
iMode = eTimer;
|
|
}
|
|
else if(strcmp(argv[3],"monitor") == 0)
|
|
{
|
|
iMode = ePreset;
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s not recognized as valid counter mode",
|
|
argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
/* preset */
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[4],&fPreset);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = SilentScan(self,(int)lNP,iMode,(float)fPreset,
|
|
pSics,pCon);
|
|
if(iRet)
|
|
{
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
}
|
|
/*----------- getnumchan */
|
|
else if(strcmp(argv[1],"getnumchan") == 0) {
|
|
snprintf(pBueffel,511,"%s.getnumchan = %d", argv[0], GetNMonitor((pCounter)self->pCounterData));
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
}
|
|
/*----------- setchannel */
|
|
else if(strcmp(argv[1],"setchannel") == 0)
|
|
{
|
|
if(argc < 3)
|
|
{
|
|
SCWrite(pCon,"ERROR: setchannel expects an integer argument",eError);
|
|
return 0;
|
|
}
|
|
/* convert to int */
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&iChannel);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected integer, got %s", argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
if( ((iChannel < 0) && (iChannel != -10)) ||
|
|
(iChannel >= GetNMonitor((pCounter)self->pCounterData)) )
|
|
{
|
|
SCWrite(pCon,"ERROR: requested counter channel out of range ",
|
|
eError);
|
|
return 0;
|
|
}
|
|
self->iChannel = iChannel;
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*--------- command */
|
|
else if(strcmp(argv[1],"command") == 0)
|
|
{
|
|
/* inquire */
|
|
if(argc < 3)
|
|
{
|
|
sprintf(pBueffel,"%s.command = %s",argv[0],
|
|
self->pCommand);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
/* set case */
|
|
Arg2Text(argc-2,&argv[2],pBueffel,511);
|
|
if(self->pCommand)
|
|
free(self->pCommand);
|
|
self->pCommand = strdup(pBueffel);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*--------- integration window */
|
|
else if(strcmp(argv[1],"window") == 0)
|
|
{
|
|
if(argc > 2)
|
|
{
|
|
/* set value */
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&iChannel);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
if(iChannel < 0)
|
|
{
|
|
SCWrite(pCon,"ERROR: new integration window size out of range",
|
|
eError);
|
|
return 0;
|
|
}
|
|
self->iWindow = iChannel;
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
/* request the value */
|
|
sprintf(pBueffel,"Integration Window = %d",self->iWindow);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
/*------------- integrate */
|
|
else if(strcmp(argv[1],"integrate") == 0)
|
|
{
|
|
iRet = ScanIntegrate(self,&fSum,&fVar);
|
|
switch(iRet)
|
|
{
|
|
case INTEGLEFT:
|
|
SCWrite(pCon,"ERROR: no left limit found for peak",eError);
|
|
return 0;
|
|
break;
|
|
case INTEGRIGHT:
|
|
SCWrite(pCon,"ERROR: no right limit found for peak",eError);
|
|
return 0;
|
|
break;
|
|
case INTEGNOPEAK:
|
|
SCWrite(pCon,"ERROR: no data found for peak",eError);
|
|
return 0;
|
|
break;
|
|
case INTEGFUNNYBACK:
|
|
SCWrite(pCon,"WARNING: background asymmetric or worse",eWarning);
|
|
default:
|
|
sprintf(pBueffel,"Intensity = %f, Variance = %f",fSum,fVar);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
break;
|
|
}
|
|
}
|
|
/*---------- simscan */
|
|
else if(strcmp(argv[1],"simscan") == 0)
|
|
{
|
|
if(argc < 5)
|
|
{
|
|
SCWrite(pCon,"ERROR expected fPos FWHM Height parameters",eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[2],&x);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
fPos = x;
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&x);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
FWHM = x;
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[4],&x);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
fHeight = x;
|
|
iRet = SimScan(self,fPos,FWHM,fHeight);
|
|
if(!iRet)
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot create simulated scan data",eError);
|
|
return 0;
|
|
}
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
/*----------------- line */
|
|
else if(strcmp(argv[1],"line") == 0)
|
|
{
|
|
Arg2Text(argc-2,&argv[2],pBueffel,511);
|
|
return AppendScanLine(self,pBueffel);
|
|
}
|
|
/*----------------- storecounts */
|
|
else if(strcmp(argv[1],"storecounts") == 0)
|
|
{
|
|
Arg2Text(argc-2,&argv[2],pBueffel,511);
|
|
return StoreScanCounts(self,pBueffel);
|
|
}
|
|
/*----------------- appendvarpos */
|
|
else if(strcmp(argv[1],"appendvarpos") == 0)
|
|
{
|
|
if(argc < 4)
|
|
{
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to appendvarpos",
|
|
eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&i);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&fStep);
|
|
if(iRet != TCL_OK)
|
|
{
|
|
sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
return AppendVarPos(pCon,self,i,(float)fStep);
|
|
}
|
|
/*------- savecounter */
|
|
else if(strcmp(argv[1],"savecounter") == 0)
|
|
{
|
|
conSave = self->pCon;
|
|
self->pCon = pCon;
|
|
CollectCounterData(self);
|
|
self->pCon = conSave;
|
|
if(SCGetInterrupt(pCon) >= eAbortScan){
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"ERROR: %s not recognized as subcommand to %s",
|
|
argv[1], argv[0]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|