Files
sics/scan.c
cvs 7780648e8a - New napi5.c with fix for deep group linking problem
- New file name scheme implemented


SKIPPED:
	psi/amorscan.c
2004-01-14 15:01:10 +00:00

2584 lines
72 KiB
C

/*--------------------------------------------------------------------------
S C A N
Implementation file for the SICS scan command.
Mark Koennecke, October 1997, June 2001
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 "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"
extern void SNXFormatTime(char *pBuffer, int iLen);
/*
from nxdata.c
*/
/*------------------------------------------------------------------------*/
char *ScanMakeFileName(SicsInterp *pSics, SConnection *pCon)
{
pSicsVariable pPath = NULL, pPref = NULL, pEnd = NULL;
char *pRes = NULL;
int iLen, iNum, iYear;
char pNumText[10];
CommandList *pCom = NULL;
/*
make a simulated filename if in simulation mode
*/
if(pServ->simMode)
return strdup("sim001001901.sim");
pRes = makeFilename(pSics,pCon);
if(pRes == NULL)
{
pRes = strdup("emergency.scn");
}
return pRes;
}
/*--------------------- VarEntry Management --------------------------------*/
static void DeleteVarEntry(void *pData)
{
pVarEntry pVar = NULL;
pVar = (pVarEntry)pData;
assert(pVar);
if(pVar->fData)
{
free(pVar->fData);
}
free(pVar);
}
/*---------------------------------------------------------------------------*/
static void DeleteCountEntry(void *pData)
{
free(pData);
}
/*--------------------------------------------------------------------------*/
static int DummyWrite(pScanData self)
{
return 1;
}
/*--------------------------------------------------------------------------*/
static int DummyWrite2(pScanData self, int iPoint)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static int WriteHeader(pScanData self)
{
int i, iRet;
FILE *fd;
char pBuffer[512], pError[512], *pPtr, *pName;
CommandList *pCom = NULL;
pSicsVariable pVar = NULL;
pDummy pDum = NULL;
pIDrivable pDriv = NULL;
float fVal;
pMotor pMot = NULL;
pVarEntry pScanVar = NULL;
void *pVoid = NULL;
assert(self->pSics);
assert(self->pCon);
/* open data file */
self->fd = fopen(self->pFile,"w");
if(!self->fd)
{
SCWrite(self->pCon,"ERROR: cannot write data file",eError);
return 0;
}
/* open header description file */
fd = fopen(self->pHeaderFile,"r");
if(!fd)
{
SCWrite(self->pCon,"ERROR: cannot open header description file",eError);
return 0;
}
/* loop through description file and act along the way */
while(fgets(pBuffer,511,fd) != NULL)
{
pPtr = strstr(pBuffer,"!!VAR(");
if(pPtr) /* handle a Sics variable */
{
/* extract the name */
pName = pPtr + 6; /* first char of name */
*pPtr = '\0'; /* this is the starter of the line */
pPtr = pName;
while( (*pPtr != '\0') && (*pPtr != ')') )
{
pPtr++;
}
*pPtr = '\0';
/* find the variable */
pCom = FindCommand(self->pSics,pName);
if(!pCom)
{
sprintf(pError,"ERROR: variable %s NOT found",pName);
SCWrite(self->pCon,pError,eError);
continue;
}
pVar = (pSicsVariable)pCom->pData;
if(!pVar)
{
sprintf(pError,"ERROR: variable %s NOT found",pName);
SCWrite(self->pCon,pError,eError);
continue;
}
switch(pVar->eType)
{
case veFloat:
sprintf(pError,"%f",pVar->fVal);
break;
case veInt:
sprintf(pError,"%d",pVar->iVal);
break;
case veText:
sprintf(pError,"%s",pVar->text);
break;
}
/* finally write */
fprintf(self->fd,"%s %s\n",pBuffer,pError);
continue;
}/* end variable */
/*------- Drivable */
pPtr = strstr(pBuffer,"!!DRIV(");
if(pPtr)
{
/* extract the name */
pName = pPtr + 7; /* first char of name */
*pPtr = '\0'; /* this is the starter of the line */
pPtr = pName;
while( (*pPtr != '\0') && (*pPtr != ')') )
{
pPtr++;
}
*pPtr = '\0';
/* find the variable */
pCom = FindCommand(self->pSics,pName);
if(!pCom)
{
sprintf(pError,"ERROR: variable %s NOT found",pName);
SCWrite(self->pCon,pError,eError);
continue;
}
pDum = (pDummy)pCom->pData;
if(!pDum)
{
sprintf(pError,"ERROR: variable %s is NOT drivable",pName);
SCWrite(self->pCon,pError,eError);
continue;
}
pDriv = (pIDrivable)pDum->pDescriptor->GetInterface(pDum,DRIVEID);
if(!pDriv)
{
sprintf(pError,"ERROR: variable %s is NOT drivable",pName);
SCWrite(self->pCon,pError,eError);
continue;
}
fVal = pDriv->GetValue(pDum,self->pCon);
fprintf(self->fd,"%s %f\n",pBuffer,fVal);
continue;
} /* end drive */
/*------- zero point */
pPtr = strstr(pBuffer,"!!ZERO(");
if(pPtr)
{
/* extract the name */
pName = pPtr + 7; /* first char of name */
*pPtr = '\0'; /* this is the starter of the line */
pPtr = pName;
while( (*pPtr != '\0') && (*pPtr != ')') )
{
pPtr++;
}
*pPtr = '\0';
/* find the motor */
pMot = FindMotor(self->pSics,pName);
if(!pMot)
{
sprintf(pError,"ERROR: motor %s NOT found",pName);
SCWrite(self->pCon,pError,eError);
continue;
}
iRet = MotorGetPar(pMot,"softzero",&fVal);
if(!iRet)
{
SCWrite(self->pCon,"ERROR: failed to read zero point",eError);
continue;
}
fprintf(self->fd,"%s %f\n",pBuffer,fVal);
continue;
} /* end zero point */
/* ------- date */
pPtr = strstr(pBuffer,"!!DATE!!");
if(pPtr)
{
*pPtr = '\0';
SNXFormatTime(pError,511);
fprintf(self->fd,"%s %s\n",pBuffer,pError);
continue;
}
/*-------- filename */
pPtr = strstr(pBuffer,"!!FILE!!");
if(pPtr)
{
*pPtr = '\0';
fprintf(self->fd,"%s %s\n",pBuffer,self->pFile);
continue;
}
/*------------ scanzero */
pPtr = strstr(pBuffer,"!!SCANZERO!!");
if(pPtr)
{
*pPtr = '\0';
/* write zero point of first scan variable if motor */
DynarGet(self->pScanVar,0,&pVoid);
pScanVar = (pVarEntry)pVoid;
if(pScanVar)
{
pMot = NULL;
pMot = FindMotor(self->pSics,pScanVar->Name);
if(pMot != NULL)
{
MotorGetPar(pMot,"softzero",&fVal);
fprintf(self->fd,"%s zero = %8.3f\n",pScanVar->Name, fVal);
}
}
}
/* --------- plain text */
fprintf(self->fd,"%s",pBuffer);
} /* end while */
/* remember position for seeking to it for writing data */
self->lPos = ftell(self->fd);
fclose(fd);
return 1;
}
/*--------------------------------------------------------------------------*/
static int WriteScanPoints(pScanData self, int iPoint)
{
int i, i2;
char pLine[512], pItem[30], pInfo[512];
pVarEntry pVar = NULL;
pCountEntry pData = NULL;
void *pPtr = NULL;
assert(self->pCon);
assert(self->pSics);
/* 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 header */
fseek(self->fd,self->lPos, SEEK_SET);
if(self->iChannel != 0)
{
fprintf(self->fd,"WARNING: Scanning monitor %d\n",self->iChannel);
}
/* make the data header */
sprintf(pLine,"%-5s","NP");
strcpy(pInfo,"Scanning Variables: ");
for(i = 0; i < self->iScanVar;i++)
{
DynarGet(self->pScanVar,i,&pPtr);
pVar = (pVarEntry)pPtr;
if(pVar)
{
sprintf(pItem,"%-9.9s ",pVar->Name);
strcat(pLine,pItem);
sprintf(pItem,"%s, ",pVar->Name);
strcat(pInfo,pItem);
}
}
strcat(pLine," Counts ");
strcat(pLine,"Monitor1 ");
strcat(pLine,"Monitor2 ");
strcat(pLine,"Monitor3 ");
strcat(pLine,"Time ");
sprintf(pItem,"\n%d Points,",self->iNP);
strcat(pInfo,pItem);
if(self->iMode == eTimer)
{
strcat(pInfo," Mode: Timer,");
}
else
{
strcat(pInfo," Mode: Monitor,");
}
sprintf(pItem," Preset %f",self->fPreset);
strcat(pInfo,pItem);
fprintf(self->fd,"%s\n",pInfo);
fprintf(self->fd,"%s\n",pLine);
/* now the scan points */
for(i = 0; i < self->iCounts; i++)
{
sprintf(pLine,"%-5d",i);
/* print vars */
for(i2 = 0; i2 < self->iScanVar; i2++)
{
DynarGet(self->pScanVar,i2,&pPtr);
pVar = (pVarEntry)pPtr;
if(pVar)
{
sprintf(pItem,"%-10.3f",pVar->fData[i]);
strcat(pLine,pItem);
}
}
/* print Counts & Monitor */
DynarGet(self->pCounts,i,&pPtr);
pData = (pCountEntry)pPtr;
if(pData)
{
sprintf(pItem," %-12ld",pData->lCount);
strcat(pLine,pItem);
sprintf(pItem,"%-12ld",pData->Monitors[0]);
strcat(pLine,pItem);
sprintf(pItem,"%-12ld",pData->Monitors[1]);
strcat(pLine,pItem);
sprintf(pItem,"%-12ld",pData->Monitors[2]);
strcat(pLine,pItem);
sprintf(pItem,"%-6.1f",pData->fTime);
strcat(pLine,pItem);
}
fprintf(self->fd,"%s\n",pLine);
}
/* done */
fprintf(self->fd,"END-OF-DATA\n");
fclose(self->fd);
self->fd = NULL;
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 int ScanDrive(pScanData self, int iPoint);
static int ScanCount(pScanData self, int iPoint);
static int CollectScanData(pScanData self, int iPoint);
static int PrepareScan(pScanData self);
/*--------------------------------------------------------------------------*/
pScanData CreateScanObject(char *pRecover, char *pHeader,pCounter pCount)
{
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);
if( (!pNew->pScanVar) || (!pNew->pCounts) )
{
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;
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);
}
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;
self->posSoft = 0;
return 1;
}
/*-------------------------------------------------------------------------*/
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
char *name, float fStart, float fStep)
{
CommandList *pCom = NULL;
pIDrivable pDriv = NULL;
pDummy pData = NULL;
VarEntry pVar;
char pBueffel[512];
if(self->iActive)
{
SCWrite(pCon,"ERROR: cannot change parameters while scan is running",
eError);
return 0;
}
/* find the thing */
pCom = FindCommand(pSics,name);
if(!pCom)
{
sprintf(pBueffel,"ERROR: Cannot find variable %s to scan",name);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pData = (pDummy)pCom->pData;
if(!pData)
{
sprintf(pBueffel,"ERROR: Cannot find data for variable %s",name);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pDriv = pData->pDescriptor->GetInterface(pData,DRIVEID);
if(!pDriv)
{
sprintf(pBueffel,"ERROR: variable %s is NOT driveable and cannot be scanned",name);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* got everything, fill in the VarEntry structure */
strcpy(pVar.Name,name);
pVar.pInter = pDriv;
pVar.pObject = pData;
pVar.fStart = fStart;
pVar.fStep = fStep;
pVar.fData = NULL;
/* put it away */
DynarPutCopy(self->pScanVar,self->iScanVar,&pVar,sizeof(VarEntry));
self->iScanVar++;
return 1;
}
/*--------------------------------------------------------------------------*/
int ClearScanVar(pScanData self)
{
if(self->iActive)
{
return 0;
}
self->iScanVar = 0;
return 1;
}
/*-------------------------------------------------------------------------*/
struct RecoHead {
int iScanVar;
int iNP;
int iMode;
float fPreset;
int iCounts;
int iChannel;
};
struct VarHead {
char pName[256];
float fStart;
float fStep;
};
/*--------------------------------------------------------------------------*/
static int WriteRecover(pScanData self)
{
FILE *fd;
struct RecoHead sHead;
struct VarHead sVar;
void *pData;
pVarEntry pVar = NULL;
pCountEntry pCount = NULL;
int i;
fd = fopen(self->pRecover,"wb");
if(!fd)
{
return 0;
}
/* write Header */
sHead.iScanVar = self->iScanVar;
sHead.iNP = self->iNP;
sHead.iMode = self->iMode;
sHead.fPreset = self->fPreset;
sHead.iCounts = self->iCounts;
sHead.iChannel = self->iChannel;
fwrite(&sHead,sizeof(struct RecoHead),1,fd);
/* write scan vars */
for(i = 0; i < self->iScanVar; i++)
{
DynarGet(self->pScanVar,i,&pData);
pVar = (pVarEntry)pData;
if(pVar)
{
strcpy(sVar.pName,pVar->Name);
sVar.fStep = pVar->fStep;
sVar.fStart = pVar->fStart;
fwrite(&sVar,sizeof(struct VarHead),1,fd);
fwrite(pVar->fData,sizeof(float),sHead.iNP,fd);
}
pData = NULL;
}
/* write counts */
for(i = 0; i < self->iCounts; i++)
{
DynarGet(self->pCounts,i,&pData);
pCount = (pCountEntry)pData;
if(pCount)
{
fwrite(pCount,sizeof(CountEntry),1,fd);
}
}
fclose(fd);
return 1;
}
/*-------------------------------------------------------------------------*/
static int ReadRecover(pScanData self)
{
FILE *fd;
struct RecoHead sHead;
struct VarHead sVar;
pVarEntry pVar;
void *pData;
CountEntry CountData;
int i,iRet;
assert(self);
assert(self->pCon);
fd = fopen(self->pRecover,"rb");
if(!fd)
{
return 0;
}
/* read Header */
iRet = fread(&sHead,sizeof(struct RecoHead),1,fd);
if(iRet != 1)
{
SCWrite(self->pCon,"ERROR: Recover File corrupted",eError);
fclose(fd);
return 0;
}
self->iNP = sHead.iNP;
self->iMode = sHead.iMode;
self->fPreset = sHead.fPreset;
self->iCounts = sHead.iCounts;
self->iChannel = sHead.iChannel;
/* read Scan Variables */
self->iScanVar = 0;
for(i = 0; i < sHead.iScanVar; i++)
{
iRet = fread(&sVar,sizeof(struct VarHead),1,fd);
if(iRet != 1)
{
SCWrite(self->pCon,"ERROR: Recover File corrupted",eError);
fclose(fd);
return 0;
}
AddScanVar(self,self->pSics,self->pCon,
sVar.pName, sVar.fStart, sVar.fStep);
DynarGet(self->pScanVar,i,&pData);
pVar = (pVarEntry)pData;
pVar->fData = (float *)malloc(sHead.iNP*sizeof(float));
if(!pVar->fData)
{
SCWrite(self->pCon,"ERROR: out of memory in scan::ReadRecover",eError);
fclose(fd);
return 0;
}
fread(pVar->fData,sizeof(float),sHead.iNP,fd);
}
/* read counts */
for(i = 0; i < sHead.iCounts; i++)
{
fread(&CountData,sizeof(CountEntry),1,fd);
DynarPutCopy(self->pCounts,i,&CountData,sizeof(CountEntry));
}
fclose(fd);
return 1;
}
/*--------------------------------------------------------------------------*/
static int PrepareScan(pScanData self)
{
pVarEntry pVar = NULL;
void *pDings;
int i, iRet;
float fVal;
char pBueffel[512];
char pMessage[1024];
assert(self);
assert(self->iNP > 0);
assert(self->pCon);
/* check boundaries of scan variables and allocate storage */
for(i = 0; i < self->iScanVar; i++)
{
DynarGet(self->pScanVar,i,&pDings);
pVar = (pVarEntry)pDings;
if(pVar)
{
/* start value */
fVal = pVar->fStart;
iRet = pVar->pInter->CheckLimits(pVar->pObject,
fVal,pBueffel,511);
if(!iRet)
{
sprintf(pMessage,"ERROR: %s, scan aborted",pBueffel);
SCWrite(self->pCon,pBueffel,eError);
return 0;
}
/* end value */
fVal = pVar->fStart + (self->iNP - 1) * pVar->fStep;
iRet = pVar->pInter->CheckLimits(pVar->pObject,
fVal,pBueffel,511);
if(!iRet)
{
sprintf(pMessage,"ERROR: %s, scan aborted",pBueffel);
SCWrite(self->pCon,pBueffel,eError);
return 0;
}
/* allocate data space */
if(pVar->fData)
{
free(pVar->fData);
pVar->fData = NULL;
}
pVar->fData = (float *)malloc(self->iNP * sizeof(float));
if(!pVar->fData)
{
SCWrite(self->pCon,"ERROR: out of memory in scan, aborting",eError);
return 0;
}
memset(pVar->fData,0,self->iNP * sizeof(float));
}
else
{
SCWrite(self->pCon,
"WARNING: Internal error, no scan variable, I try to continue",
eWarning);
}
pVar = NULL;
} /* end for */
/* configure counter */
SetCounterMode((pCounter)self->pCounterData,self->iMode);
SetCounterPreset((pCounter)self->pCounterData, self->fPreset);
self->iCounts = 0;
return 1;
}
/*--------------------------------------------------------------------------*/
int NonCheckPrepare(pScanData self)
{
pVarEntry pVar = NULL;
void *pDings;
int i, iRet;
float fVal;
char pBueffel[512];
char pMessage[1024];
assert(self);
assert(self->iNP > 0);
assert(self->pCon);
/* allocate storage for scan variables */
for(i = 0; i < self->iScanVar; i++)
{
DynarGet(self->pScanVar,i,&pDings);
pVar = (pVarEntry)pDings;
if(pVar)
{
/* start value */
fVal = pVar->fStart;
/* allocate data space */
if(pVar->fData)
{
free(pVar->fData);
pVar->fData = NULL;
}
pVar->fData = (float *)malloc(self->iNP * sizeof(float));
if(!pVar->fData)
{
SCWrite(self->pCon,"ERROR: out of memory in scan, aborting",eError);
return 0;
}
memset(pVar->fData,0,self->iNP * sizeof(float));
}
else
{
SCWrite(self->pCon,
"WARNING: Internal error, no scan variable, I try to continue",
eWarning);
}
pVar = NULL;
} /* end for */
/* configure counter */
SetCounterMode((pCounter)self->pCounterData,self->iMode);
SetCounterPreset((pCounter)self->pCounterData, self->fPreset);
self->iCounts = 0;
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);
int StoreScanCounts(pScanData self, char *data)
{
CountEntry sCount;
char pNumber[20], *pPtr;
int iCount = 0;
if(data == NULL)
{
SCWrite(self->pCon,"WARNING: StoreScanCounst called without data",eWarning);
return 1;
}
/* parse the data */
pPtr = data;
pPtr = stptok(pPtr,pNumber,19," \t");
if(pPtr != NULL)
{
sCount.lCount = atoi(pNumber);
}
else
{
SCWrite(self->pCon,"ERROR: No data in StoreScanCounts",eError);
return 0;
}
while((pPtr = stptok(pPtr,pNumber,19," \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++;
return 1;
}
/*--------------------------------------------------------------------------*/
static int StartToDrive(pScanData self, int iPoint)
{
pVarEntry pVar = NULL;
void *pDings;
int i, iRet, status;
float fVal;
pDummy pDum;
char pBueffel[512];
assert(self);
assert(self->pCon);
/* loop over all scan variables */
status = 1;
for(i = 0; i < self->iScanVar; i++)
{
DynarGet(self->pScanVar,i,&pDings);
pVar = (pVarEntry)pDings;
if(pVar)
{
pDum = (pDummy)pVar->pObject;
fVal = pVar->fStart + iPoint * pVar->fStep;
iRet = StartDevice(pServ->pExecutor,
pVar->Name,
pDum->pDescriptor,
pVar->pObject,
self->pCon,
fVal);
if(!iRet)
{
sprintf(pBueffel,"ERROR: Failed to start %s",pVar->Name);
SCWrite(self->pCon,pBueffel,eError);
status = 0;
break;
}
}
}
return status;
}
/*------------------------------------------------------------------------*/
static int CollectScanDataIntern(pScanData self, int iPoint, int jochenFlag)
{
pVarEntry pVar = NULL;
void *pDings;
int i, iRet, status;
float fVal;
char pStatus[512], pItem[20];
char pHead[512];
CountEntry sCount;
char *pAns = NULL, *pPtr = NULL ;
Tcl_Interp *pTcl;
assert(self);
assert(self->pCon);
/* prepare output header */
sprintf(pHead,"%-5.5s","NP");
sprintf(pStatus,"%-5d",iPoint);
/* loop over all scan variables */
status = 1;
for(i = 0; i < self->iScanVar; i++)
{
DynarGet(self->pScanVar,i,&pDings);
pVar = (pVarEntry)pDings;
if(pVar)
{
if(jochenFlag == 1 &&
strcmp(pVar->pObject->pDescriptor->name, "Motor") == 0)
{
MotorGetSoftPosition((pMotor)pVar->pObject,self->pCon,&fVal);
}
else
{
fVal = pVar->pInter->GetValue(pVar->pObject,self->pCon);
}
pVar->fData[iPoint] = fVal;
sprintf(pItem,"%-10.10s",pVar->Name);
strcat(pHead,pItem);
sprintf(pItem,"%-10.3f",fVal);
strcat(pStatus,pItem);
}
}
/* store counter data */
/* 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 */
strcat(pHead,"Counts ");
if(self->iChannel == -10)
{
/* execute the Tcl-script for getting the data */
pTcl = (Tcl_Interp *)self->pSics->pTcl;
if(!self->pCommand)
{
SCWrite(self->pCon,
"ERROR: command must be configured for user defined scans",
eError);
SCSetInterrupt(self->pCon,eAbortBatch);
return 0;
}
iRet = Tcl_Eval(pTcl,self->pCommand);
if(iRet != TCL_OK)
{
SCWrite(self->pCon,pTcl->result,eError);
return 0;
}
/* 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);
return 0;
}
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);
}
sprintf(pItem,"%-15d",sCount.lCount);
strcat(pStatus,pItem);
/* get time */
sCount.fTime = GetCountTime((pCounter)self->pCounterData,
self->pCon);
strcat(pHead,"Monitor1 ");
sprintf(pItem,"%-12d",sCount.Monitors[0]);
strcat(pStatus,pItem);
strcat(pHead,"Monitor2 ");
sprintf(pItem,"%-12d",sCount.Monitors[1]);
strcat(pStatus,pItem);
strcat(pHead,"Monitor3 ");
sprintf(pItem,"%-12d",sCount.Monitors[2]);
strcat(pStatus,pItem);
strcat(pHead,"Time ");
sprintf(pItem,"%-6.1f",sCount.fTime);
strcat(pStatus,pItem);
/* write progress */
strcat(pHead,"\n");
strcat(pStatus,"\n");
SCWrite(self->pCon,pHead,eWarning);
SCWrite(self->pCon,pStatus,eWarning);
/* stow away */
DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry));
self->iCounts++;
return 1;
}
/*---------------------------------------------------------------------------*/
static int CollectScanData(pScanData self, int iPoint)
{
return CollectScanDataIntern(self,iPoint,0);
}
/*--------------------------------------------------------------------------*/
static int CollectScanDataJochen(pScanData self, int iPoint)
{
return CollectScanDataIntern(self,iPoint,1);
}
/*------------------------------------------------------------------------*/
static int ScanDrive(pScanData self, int iPoint)
{
int iRet;
long lTask;
int status;
iRet = StartToDrive(self,iPoint);
if(!iRet)
{
SCWrite(self->pCon,"ERROR: Cannot Drive, Scan aborted",eError);
status = 0;
}
else
{
status = 1;
}
/* wait for finish */
lTask = GetDevexecID(pServ->pExecutor);
if(lTask > 0)
{
TaskWait(pServ->pTasker,lTask);
}
return status;
}
/*--------------------------------------------------------------------------*/
static int ScanCount(pScanData self, int iPoint)
{
pDummy pDum;
int iRet;
long lTask;
pDum = (pDummy)self->pCounterData;
iRet = StartDevice(pServ->pExecutor,
"ScanCounter",
pDum->pDescriptor,
self->pCounterData,
self->pCon,
self->fPreset);
if(!iRet)
{
SCWrite(self->pCon,"ERROR: Cannot Count, Scan aborted",eError);
return 0;
}
SetStatus(eCounting);
/* wait for finish */
lTask = GetDevexecID(pServ->pExecutor);
if(lTask > 0);
{
TaskWait(pServ->pTasker,lTask);
}
return 1;
}
/*---------------------------------------------------------------------------*/
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);
if(!iRet)
{
return 0;
}
/* 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;
}
/*-------------- count */
iRet = self->ScanCount(self, i);
if(!iRet)
{
return 0;
}
/* 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;
}
/*-------- 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;
}
/* allocate a new 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);
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 = PrepareScan(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 RecoverScan(pScanData self, SicsInterp *pSics, SConnection *pCon)
{
int iRet;
char *pPtr = NULL, pBueffel[512];
assert(pSics);
assert(pCon);
self->pCon = pCon;
self->pSics = pSics;
/* read recover file */
iRet = ReadRecover(self);
if(!iRet)
{
return iRet;
}
/* 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);
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;
}
/* copy the actual scan data */
memcpy(fData,pVar->fData,iEnd*sizeof(float));
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,pVar->Name,iLength);
return 1;
}
else
{
return 0;
}
}
/*---------------------------------------------------------------------*/
int isScanVarSoft(pScanData self){
return self->posSoft;
}
/*-------------------------------------------------------------------------*/
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 = pVar->fStep;
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);
/* 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;
}
pVar->fData = (float *)malloc(90*sizeof(float));
if(!pVar->fData)
{
return 0;
}
/* create scan data in loop */
fStdDev = FWHM/2.354;
for(i = 0; i < 90; i++)
{
x = pVar->fData[i] = 10. + 0.1 * i;
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);
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;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int ScanInterest(int iEvent, void *pEventData, void *pUser)
{
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)
{
SCWrite(pCon,"NewScan",eWarning);
return 1;
}
else if(iEvent == SCANEND)
{
SCWrite(pCon,"ScanEnd",eWarning);
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,"{%d} ",lData[i]);
strcat(pPtr,pItem);
}
oldWrite = SCGetWriteFunc(pCon);
SCSetWriteFunc(pCon,SCOnlySockWrite);
SCWrite(pCon,pPtr,eWarning);
SCSetWriteFunc(pCon,oldWrite);
free(lData);
free(pPtr);
return 1;
}
return 1;
}
/*--------------------------------------------------------------------------*/
static int ScanUUInterest(int iEvent, void *pEventData, void *pUser)
{
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)
{
SCWrite(pCon,"NewScan",eWarning);
return 1;
}
else if(iEvent == SCANEND)
{
SCWrite(pCon,"ScanEnd",eWarning);
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]);
}
SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int));
free(lData);
free(iData);
return 1;
}
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;
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;
}
/*--------- getcounts */
else if(strcmp(argv[1],"getcounts") == 0)
{
/* get some memory */
if(self->iNP < 1)
{
SCWrite(pCon,"ERROR: no counts available",eError);
return 0;
}
lData = (long *)malloc(self->iNP*sizeof(long));
if(!lData)
{
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 counts */
GetScanCounts(self,lData,self->iNP);
/* format them */
strcpy(pPtr,"scan.Counts= ");
for(i = 0; i < self->iNP; i++)
{
sprintf(pItem,"{%d} ",lData[i]);
strcat(pPtr,pItem);
}
SCWrite(pCon,pPtr,eValue);
free(lData);
free(pPtr);
return 1;
}
/*---------- 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(pSics->pTcl,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 = ", pVar->Name);
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;
}
/*-------- interest */
else if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
return 1;
}
/*-------- uuinterest */
else if(strcmp(argv[1],"uuinterest") == 0)
{
lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
lID = RegisterCallback(self->pCall, 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(pSics->pTcl,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(pSics->pTcl,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;
}
/* --------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;
}
/*------------ configure */
else if(strcmp(argv[1],"configure") == 0)
{
if(argc < 3)
{
SCWrite(pCon,"ERROR: missing configure option",eError);
return 0;
}
/* this is for userss 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],"soft") == 0)
{
ResetScanFunctions(self);
self->CollectScanData = CollectScanDataJochen;
self->posSoft = 1;
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;
}
}
}
/*---------- scan */
else if(strcmp(argv[1],"run") == 0)
{
/* get NP */
iRet = Tcl_GetInt(pSics->pTcl,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(pSics->pTcl,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;
}
/*---------- silent */
else if(strcmp(argv[1],"silent") == 0)
{
/* get NP */
iRet = Tcl_GetInt(pSics->pTcl,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(pSics->pTcl,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;
}
/*--------- recover */
else if(strcmp(argv[1],"recover") == 0)
{
iRet = RecoverScan(self,pSics,pCon);
if(iRet)
{
SCSendOK(pCon);
}
return iRet;
}
/*----------- 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(pSics->pTcl,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(pSics->pTcl,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(pSics->pTcl,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(pSics->pTcl,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(pSics->pTcl,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);
}
else
{
sprintf(pBueffel,"ERROR: %s not recognized as subcommand to %s",
argv[1], argv[0]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}