- Mapped fileeval to exe manager - Updates for TRICS file formats SKIPPED: psi/libpsi.a psi/sinqhmdriv.c psi/sinqhttp.c psi/tabledrive.c psi/tasscan.c psi/hardsup/asynsrv_utility.c psi/hardsup/sinqhm.c
1290 lines
33 KiB
C
1290 lines
33 KiB
C
/*--------------------------------------------------------------------------
|
|
This is the implementation for the TAS scan code. It mainly implements
|
|
writing of the ILL file format, which the TAS'lers adore.
|
|
|
|
Mark Koennecke, May 2005, using code from an earlier TASAMAD emulation
|
|
core.
|
|
---------------------------------------------------------------------------*/
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <time.h>
|
|
#include <ctype.h>
|
|
#include <tcl.h>
|
|
#include <fortify.h>
|
|
#include <sics.h>
|
|
#include <sicsvar.h>
|
|
#include <counter.h>
|
|
#include <motor.h>
|
|
#include <scan.h>
|
|
#include <scan.i>
|
|
#include <lld.h>
|
|
#include "scanvar.h"
|
|
#include <evcontroller.h>
|
|
#include <splitter.h>
|
|
#include <status.h>
|
|
#include "tasscanub.h"
|
|
#include "nxscript.h"
|
|
/*------------------------------------------------------------------------
|
|
a little local utility for making a line of characters
|
|
-------------------------------------------------------------------------*/
|
|
static void charLine(char *pBueffel, char c)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0; i < 80; i++)
|
|
{
|
|
pBueffel[i] = c;
|
|
}
|
|
pBueffel[80] = '\n';
|
|
pBueffel[81] = '\0';
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static void strtoupper(char *pText)
|
|
{
|
|
assert(pText);
|
|
|
|
while(*pText != '\0')
|
|
{
|
|
*pText = toupper(*pText);
|
|
pText++;
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static void strcenter(char *str, char *target, int iLength)
|
|
{
|
|
int iPtr, i;
|
|
|
|
/*
|
|
catch the error if target is to long
|
|
*/
|
|
if(strlen(str) >= iLength)
|
|
{
|
|
strncpy(target,str,iLength);
|
|
}
|
|
|
|
iPtr = (iLength - strlen(str))/2;
|
|
for(i = 0; i < iPtr;i++)
|
|
{
|
|
target[i] = ' ';
|
|
}
|
|
target[iPtr] = '\0';
|
|
strcat(target,str);
|
|
for(i = iPtr + strlen(str); i < iLength - 1; i++)
|
|
{
|
|
target[i] = ' ';
|
|
}
|
|
target[iLength-1] = '\0';
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static char *GetVarText(char *name) {
|
|
pSicsVariable pVar = NULL;
|
|
|
|
pVar = (pSicsVariable)FindCommandData(pServ->pSics,name, "SicsVariable");
|
|
if(pVar != NULL){
|
|
return pVar->text;
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------------------
|
|
helper function for TASHeader
|
|
------------------------------------------------------------------------*/
|
|
static void writePolFile(FILE *fd, pTASdata pTAS){
|
|
char pLine[132];
|
|
FILE *fpol = NULL;
|
|
|
|
assert(fd);
|
|
assert(pTAS);
|
|
|
|
fpol = fopen(GetVarText("polfile"),"r");
|
|
if(!fpol){
|
|
/*
|
|
error gets reported anyway later on
|
|
*/
|
|
return;
|
|
}
|
|
|
|
while(fgets(pLine,131,fpol) != NULL){
|
|
if(strstr(pLine,"\n") == NULL){
|
|
fprintf(fd,"POLAN: %s\n", pLine);
|
|
} else {
|
|
fprintf(fd,"POLAN: %s", pLine);
|
|
}
|
|
}
|
|
fclose(fpol);
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static char *findLastPoint(char *text)
|
|
{
|
|
char *pPtr;
|
|
int i;
|
|
|
|
pPtr = text + strlen(text) - 1;
|
|
for(i = strlen(text); i > 0; i--, pPtr--)
|
|
{
|
|
if(*pPtr == '.')
|
|
{
|
|
return pPtr;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
/*-----------------------------------------------------------------------
|
|
readDrivable tries to read the value of one of the magnet currents.
|
|
All errors are ignored because most of the time currents will not be
|
|
present in the system.
|
|
-----------------------------------------------------------------------*/
|
|
static float readDrivable(char *val, SConnection *pCon){
|
|
pIDrivable pDriv;
|
|
CommandList *pCom;
|
|
pDummy pDum;
|
|
pMotor pMot = NULL;
|
|
float fVal;
|
|
|
|
/*
|
|
if motor: read motor
|
|
*/
|
|
pMot = FindMotor(pServ->pSics,val);
|
|
if(pMot != NULL){
|
|
MotorGetSoftPosition(pMot,pCon,&fVal);
|
|
return fVal;
|
|
}
|
|
|
|
/*
|
|
else: read general drivable
|
|
*/
|
|
pCom = FindCommand(pServ->pSics,val);
|
|
if(pCom != NULL){
|
|
pDriv = GetDrivableInterface(pCom->pData);
|
|
if(pDriv != NULL){
|
|
return pDriv->GetValue(pCom->pData,pCon);
|
|
}
|
|
}
|
|
return -999.99;
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static float GetVarFloat(char *name){
|
|
pSicsVariable pVar = NULL;
|
|
|
|
pVar = (pSicsVariable)FindCommandData(pServ->pSics,name, "SicsVariable");
|
|
if(pVar != NULL){
|
|
return pVar->fVal;
|
|
} else {
|
|
return -999.99;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------
|
|
TASHeader writes the header of a TAS data file. The format is an
|
|
obscure format from ILL ( not ill but Institute Laue Langevin). No
|
|
documentation about this exists except the files themselves. This is long
|
|
and tiresome code.
|
|
---------------------------------------------------------------------------*/
|
|
static int TASUBHeader(pScanData self)
|
|
{
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
int i, iCount, status, iFileNO;
|
|
char pBueffel[1024], pHeader[1024], pWork[132], pWork2[60], pTen[12], *pcPtr;
|
|
time_t iDate;
|
|
struct tm *psTime;
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
pMotor pMot;
|
|
float fVal, fVal2;
|
|
CommandList *pCom = NULL;
|
|
pDummy pDum = NULL;
|
|
pIDrivable pDrive = NULL;
|
|
pEVControl pTem = NULL;
|
|
int fx;
|
|
tasReflection r;
|
|
double kfix;
|
|
pSicsVariable sVar = NULL;
|
|
float f1, f2, f3, f4;
|
|
|
|
assert(self);
|
|
assert(pTAS);
|
|
assert(self->pCon);
|
|
assert(self->pSics);
|
|
|
|
/* open data file */
|
|
self->fd = fopen(self->pFile,"w");
|
|
if(!self->fd)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: cannot write data file",eError);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
extract the file number from the name for entry into the
|
|
datafile
|
|
*/
|
|
pcPtr = findLastPoint(self->pFile);
|
|
if(pcPtr != NULL)
|
|
{
|
|
pcPtr -= 6; /* 6 digits for number */
|
|
for(i = 0; i < 6; i++, pcPtr++)
|
|
{
|
|
pWork[i] = *pcPtr;
|
|
}
|
|
pWork[6] = '\0';
|
|
iFileNO = atoi(pWork);
|
|
}
|
|
else
|
|
{
|
|
SCWrite(self->pCon,"WARNING: failed to decode file number",eWarning);
|
|
}
|
|
|
|
/* the bizarre R, A, V header */
|
|
charLine(pBueffel,'R');
|
|
fputs(pBueffel,self->fd);
|
|
fprintf(self->fd,"%8d%8d%8d\n",iFileNO,1,0);
|
|
fputs("ILL TAS data in the new ASCII format follow after the line VV...V\n",
|
|
self->fd);
|
|
charLine(pBueffel,'A');
|
|
fputs(pBueffel,self->fd);
|
|
fprintf(self->fd,"%8d%8d\n",42,0);
|
|
|
|
/*
|
|
format time to TAS format
|
|
*/
|
|
iDate = time(NULL);
|
|
psTime = localtime(&iDate);
|
|
memset(pWork,0,59);
|
|
strftime(pWork,59,"%d-%b-%Y %H:%M:%S",psTime);
|
|
fprintf(self->fd,"%-10s%-12s%-s\n",GetVarText("instrument"),
|
|
GetVarText("user"),pWork);
|
|
|
|
charLine(pBueffel,'V');
|
|
fputs(pBueffel,self->fd);
|
|
|
|
/*
|
|
output a plethora of parameters
|
|
*/
|
|
fprintf(self->fd,"INSTR: %s\n",GetVarText("instrument"));
|
|
fprintf(self->fd,"EXPNO: \n");
|
|
fprintf(self->fd,"USER_: %s\n",GetVarText("user"));
|
|
fprintf(self->fd,"LOCAL: %s\n",GetVarText("local"));
|
|
fprintf(self->fd,"FILE_: %d\n",iFileNO);
|
|
fprintf(self->fd,"DATE_: %s\n",pWork);
|
|
fprintf(self->fd,"TITLE: %s\n",GetVarText("title"));
|
|
fprintf(self->fd,"COMND: %s\n",GetVarText("lastscancommand"));
|
|
fprintf(self->fd,
|
|
"POSQE: QH=%8.4f, QK=%8.4f, QL=%8.4f, EN=%8.4f, UN=MEV\n",
|
|
pTAS->ub->current.qh,
|
|
pTAS->ub->current.qk,
|
|
pTAS->ub->current.qk,
|
|
getTasPar(pTAS->ub->current,EN));
|
|
/*
|
|
build the steps line
|
|
*/
|
|
sprintf(pBueffel,"STEPS: ");
|
|
for(i = 0; i < self->iScanVar; i++)
|
|
{
|
|
DynarGet(self->pScanVar,i,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
strncpy(pWork2,ScanVarName(pVar),59);
|
|
strtoupper(pWork2);
|
|
sprintf(pWork,"D%s=%8.4f, ",pWork2,ScanVarStep(pVar));
|
|
strcat(pBueffel,pWork);
|
|
}
|
|
}
|
|
strcat(pBueffel,"\n");
|
|
fputs(pBueffel,self->fd);
|
|
|
|
/*
|
|
a lot of parameters
|
|
*/
|
|
fprintf(self->fd,"PARAM: DM=%8.4f, DA=%8.4f, SM=%2d, SS=%2d, SA=%2d\n",
|
|
pTAS->ub->machine.monochromator.dd,
|
|
pTAS->ub->machine.analyzer.dd,
|
|
pTAS->ub->machine.monochromator.ss,
|
|
pTAS->ub->machine.ss_sample,
|
|
pTAS->ub->machine.analyzer.ss);
|
|
if(pTAS->ub->tasMode == KICONST){
|
|
fx = 2;
|
|
kfix = getTasPar(pTAS->ub->current,KI);
|
|
} else {
|
|
fx = 1;
|
|
kfix = getTasPar(pTAS->ub->current,KF);
|
|
}
|
|
|
|
fprintf(self->fd,"PARAM: FX=%3d, KFIX=%8.4f\n",
|
|
fx,
|
|
kfix);
|
|
fprintf(self->fd,"PARAM: ALF1=%8.4f, ALF2=%8.4f, ALF3=%8.4f, ALF4=%8.4f\n",
|
|
GetVarFloat("alf1"),
|
|
GetVarFloat("alf2"),
|
|
GetVarFloat("alf3"),
|
|
GetVarFloat("alf4"));
|
|
fprintf(self->fd,"PARAM: BET1=%8.4f, BET2=%8.4f, BET3=%8.4f, BET4=%8.4f\n",
|
|
GetVarFloat("bet1"),
|
|
GetVarFloat("bet2"),
|
|
GetVarFloat("bet3"),
|
|
GetVarFloat("bet4"));
|
|
fprintf(self->fd,"PARAM: ETAM=%8.4f, ETAA=%8.4f\n",
|
|
GetVarFloat("etam"),
|
|
GetVarFloat("etaa"));
|
|
|
|
fprintf(self->fd,"PARAM: AS=%8.4f, BS=%8.4f, CS=%8.4f\n",
|
|
pTAS->ub->cell.a,
|
|
pTAS->ub->cell.b,
|
|
pTAS->ub->cell.c);
|
|
fprintf(self->fd,"PARAM: AA=%8.4f, BB=%8.4f, CC=%8.4f\n",
|
|
pTAS->ub->cell.alpha,
|
|
pTAS->ub->cell.beta,
|
|
pTAS->ub->cell.gamma);
|
|
|
|
r = pTAS->ub->r1;
|
|
fprintf(self->fd,"PARAM: AX=%8.4f, AY=%8.4f, AZ=%8.4f\n",
|
|
r.qe.qh,
|
|
r.qe.qk,
|
|
r.qe.ql);
|
|
|
|
r = pTAS->ub->r2;
|
|
fprintf(self->fd,"PARAM: BX=%8.4f, BY=%8.4f, BZ=%8.4f\n",
|
|
r.qe.qh,
|
|
r.qe.qk,
|
|
r.qe.ql);
|
|
|
|
/*
|
|
* write mupad stuff if available
|
|
*/
|
|
sVar = FindCommandData(pServ->pSics,"w1","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f1 = sVar->fVal;
|
|
sVar = FindCommandData(pServ->pSics,"w2","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f2 = sVar->fVal;
|
|
}
|
|
sVar = FindCommandData(pServ->pSics,"w3","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f3 = sVar->fVal;
|
|
}
|
|
sVar = FindCommandData(pServ->pSics,"w4","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f4 = sVar->fVal;
|
|
}
|
|
fprintf(self->fd,"PARAM: W1=%8.4f, W2=%8.4f, W3=%8.4f, W4=%8.4f\n",
|
|
f1, f2, f3, f4);
|
|
|
|
sVar = FindCommandData(pServ->pSics,"p1","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f1 = sVar->fVal;
|
|
}
|
|
sVar = FindCommandData(pServ->pSics,"p2","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f2 = sVar->fVal;
|
|
}
|
|
sVar = FindCommandData(pServ->pSics,"p3","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f3 = sVar->fVal;
|
|
}
|
|
sVar = FindCommandData(pServ->pSics,"p4","SicsVariable");
|
|
if(sVar != NULL)
|
|
{
|
|
f4 = sVar->fVal;
|
|
}
|
|
fprintf(self->fd,"PARAM: P1=%8.4f, P2=%8.4f, P3=%8.4f, P4=%8.4f\n",
|
|
f1, f2, f3, f4);
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
write currents if in polarisation mode
|
|
*/
|
|
if(pTAS->iPOL >= 0){
|
|
fprintf(self->fd,"VARIA: ");
|
|
iCount = 0;
|
|
for(i = 0; i < 8; i++)
|
|
{
|
|
snprintf(pWork2,59,"i%1.1d",i);
|
|
fVal = readDrivable(pWork2,self->pCon);
|
|
strtoupper(pWork2);
|
|
fprintf(self->fd,"%-8s=%8.4f, ",pWork2,fVal);
|
|
iCount++;
|
|
}
|
|
fprintf(self->fd,"\n");
|
|
}
|
|
|
|
/*
|
|
write motors
|
|
*/
|
|
fprintf(self->fd,"VARIA: ");
|
|
iCount = 0;
|
|
pCom = pServ->pSics->pCList;
|
|
while(pCom != NULL)
|
|
{
|
|
pDum = (pDummy)pCom->pData;
|
|
if(pDum != NULL )
|
|
{
|
|
if(strcmp(pDum->pDescriptor->name,"Motor") == 0)
|
|
{
|
|
fVal = readDrivable(pCom->pName,self->pCon);
|
|
if(iCount == 3)
|
|
{
|
|
iCount = 0;
|
|
fprintf(self->fd,"\nVARIA: ");
|
|
}
|
|
strcpy(pWork2,pCom->pName);
|
|
strtoupper(pWork2);
|
|
fprintf(self->fd,"%-8s=%8.4f, ",pWork2,fVal);
|
|
iCount++;
|
|
}
|
|
}
|
|
pCom = pCom->pNext;
|
|
}
|
|
fprintf(self->fd,"\n");
|
|
|
|
/*
|
|
write zeros
|
|
*/
|
|
fprintf(self->fd,"ZEROS: ");
|
|
iCount = 0;
|
|
pCom = pServ->pSics->pCList;
|
|
while(pCom != NULL)
|
|
{
|
|
pDum = (pDummy)pCom->pData;
|
|
if(pDum != NULL )
|
|
{
|
|
if(strcmp(pDum->pDescriptor->name,"Motor") == 0)
|
|
{
|
|
pMot = (pMotor)pCom->pData;
|
|
if(pMot)
|
|
{
|
|
status = MotorGetPar(pMot,"softzero",&fVal);
|
|
if(!status)
|
|
{
|
|
fVal = -9999.77;
|
|
}
|
|
fVal *= -1;
|
|
if(iCount == 3)
|
|
{
|
|
iCount = 0;
|
|
fprintf(self->fd,"\nZEROS: ");
|
|
}
|
|
strcpy(pWork2,pCom->pName);
|
|
strtoupper(pWork2);
|
|
fprintf(self->fd,"%-8s=%8.4f, ",pWork2,fVal);
|
|
iCount++;
|
|
}
|
|
}
|
|
}
|
|
pCom = pCom->pNext;
|
|
}
|
|
fprintf(self->fd,"\n");
|
|
|
|
if(pTAS->iPOL >= 0){
|
|
writePolFile(self->fd,pTAS);
|
|
}
|
|
|
|
/*
|
|
write counter parameters
|
|
*/
|
|
fVal = GetCounterPreset(self->pCounterData);
|
|
if(GetCounterMode(self->pCounterData) == eTimer)
|
|
{
|
|
fprintf(self->fd,"PARAM: TI=%8.4f\n",fVal);
|
|
}
|
|
else
|
|
{
|
|
fprintf(self->fd,"PARAM: MN=%8f\n",fVal);
|
|
}
|
|
|
|
/*
|
|
write temperature data
|
|
*/
|
|
pCom = FindCommand(self->pSics,"temperature");
|
|
if(pCom)
|
|
{
|
|
pDum = (pDummy)pCom->pData;
|
|
pDrive = pDum->pDescriptor->GetInterface(pDum,DRIVEID);
|
|
if(pDrive) /* a proper environment device */
|
|
{
|
|
fVal = pDrive->GetValue(pDum,self->pCon);
|
|
pTem = (pEVControl)pCom->pData;
|
|
EVCGetPar(pTem,"target",&fVal2);
|
|
fprintf(self->fd,"PARAM: TT=%8.4f, RT=%8.4f\n",fVal, fVal2);
|
|
}
|
|
}
|
|
|
|
/*
|
|
build both the format and the data header line,
|
|
start with the scan variables
|
|
*/
|
|
if(pTAS->iPOL >= 0 ){
|
|
strcpy(pBueffel,"FORMT: (I4,I4,");
|
|
strcpy(pHeader," PNT PAL");
|
|
} else {
|
|
strcpy(pBueffel,"FORMT: (I4,1X,");
|
|
strcpy(pHeader," PNT ");
|
|
}
|
|
for(i = 0; i < self->iScanVar; i++)
|
|
{
|
|
DynarGet(self->pScanVar,i,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
strcat(pBueffel,"F9.4,1X,");
|
|
strncpy(pWork2,pVar->Name,59);
|
|
strtoupper(pWork2);
|
|
strcenter(pWork2,pTen,11);
|
|
strcat(pHeader,pTen);
|
|
}
|
|
}
|
|
/*
|
|
put the standard counter things
|
|
*/
|
|
strcat(pBueffel,"F8.0,1X,F8.0,1X,F9.2,1X,F8.0,1X,F8.0,1X,");
|
|
strcat(pHeader," M1 M2 TIME CNTS M3 ");
|
|
/*
|
|
now the additional variables
|
|
*/
|
|
for(i = 0; i < pTAS->addCount; i++)
|
|
{
|
|
if(i == pTAS->addCount -1){
|
|
strcat(pBueffel,"F9.4");
|
|
} else {
|
|
strcat(pBueffel,"F9.4,1X,");
|
|
}
|
|
strcpy(pWork2,pTAS->out[i]);
|
|
strtoupper(pWork2);
|
|
strcenter(pWork2,pTen,11);
|
|
strcat(pHeader,pTen);
|
|
}
|
|
strcat(pBueffel,")");
|
|
|
|
/*
|
|
write the final bit
|
|
*/
|
|
fprintf(self->fd,"%s\nDATA_:\n%s\n",pBueffel,pHeader);
|
|
|
|
/*
|
|
write header to screen as well
|
|
*/
|
|
SCWrite(self->pCon,pHeader,eWarning);
|
|
|
|
/*
|
|
close the file, we will reopen later with append for the data
|
|
*/
|
|
fclose(self->fd);
|
|
self->fd = NULL;
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------
|
|
TASScanPoint writes the data at each ScanPoint
|
|
---------------------------------------------------------------------------*/
|
|
static int TASUBScanPoint(pScanData self, int iPoint)
|
|
{
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
int i, status, iPtr;
|
|
float fVal;
|
|
pMotor pMot = NULL;
|
|
long m1, m2, m3, cnts;
|
|
char pBueffel[1024], pWork[80], pError[132];
|
|
|
|
/*
|
|
after polarisation analysis, this has to be ignored as it is called
|
|
another time from the ScanLoop
|
|
*/
|
|
if(pTAS->iIgnore){
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
reopen file for appending
|
|
*/
|
|
self->fd = fopen(self->pFile,"a");
|
|
if(!self->fd)
|
|
{
|
|
SCWrite(self->pCon,"ERROR: cannot append to data file",eError);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
write point number
|
|
*/
|
|
if(pTAS->iPOL >= 0)
|
|
{
|
|
sprintf(pBueffel,"%3d %3d",iPoint+1,pTAS->iPOL);
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBueffel,"%4d ", iPoint+1);
|
|
}
|
|
|
|
/*
|
|
write the scan variables
|
|
*/
|
|
for(i = 0; i < self->iScanVar; i++)
|
|
{
|
|
DynarGet(self->pScanVar,i,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
fVal = readDrivable(ScanVarName(pVar),self->pCon);
|
|
}
|
|
sprintf(pWork,"%9.4f ", fVal);
|
|
strcat(pBueffel,pWork);
|
|
}
|
|
|
|
/*
|
|
write monitors and counters
|
|
*/
|
|
m1 = GetMonitor(self->pCounterData,1,self->pCon);
|
|
m2 = GetMonitor(self->pCounterData,2,self->pCon);
|
|
m3 = GetMonitor(self->pCounterData,3,self->pCon);
|
|
cnts = GetCounts(self->pCounterData,self->pCon);
|
|
fVal = GetCountTime(self->pCounterData, self->pCon);
|
|
sprintf(pWork,"%8ld %8ld %9.2f %8ld %8ld ",m1,m2,fVal, cnts, m3);
|
|
strcat(pBueffel,pWork);
|
|
|
|
/*
|
|
write additional parameters
|
|
*/
|
|
for(i = 0; i < pTAS->addCount; i++)
|
|
{
|
|
fVal = -999.99;
|
|
fVal = readDrivable(pTAS->out[i],self->pCon);
|
|
if(fVal < -990.){
|
|
snprintf(pError,131,"WARNING: problem reading %s",
|
|
pTAS->out[i]);
|
|
SCWrite(self->pCon, pError,eWarning);
|
|
}
|
|
sprintf(pWork,"%9.4f ", fVal);
|
|
strcat(pBueffel,pWork);
|
|
}
|
|
|
|
/*
|
|
write both to file and onto screen
|
|
*/
|
|
fprintf(self->fd,"%s\n",pBueffel);
|
|
SCWrite(self->pCon,pBueffel,eWarning);
|
|
|
|
/*
|
|
close the file
|
|
*/
|
|
fclose(self->fd);
|
|
self->fd = NULL;
|
|
return 1;
|
|
|
|
}
|
|
/*------------------------------------------------------------------------
|
|
TASScanDrive starts all the motors necessary to drive to a new scan
|
|
position. It thereby takes care of the TAS calculation if necessary.
|
|
-------------------------------------------------------------------------*/
|
|
static int TASUBScanDrive(pScanData self, int iPoint)
|
|
{
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
pVarEntry pVar = NULL;
|
|
void *pPtr = NULL;
|
|
int i, status, iPtr;
|
|
int iTAS = 0;
|
|
pMotor pMot;
|
|
|
|
/*
|
|
loop through all the scan variables
|
|
*/
|
|
for(i = 0; i < self->iScanVar; i++)
|
|
{
|
|
DynarGet(self->pScanVar,i,&pPtr);
|
|
pVar = (pVarEntry)pPtr;
|
|
if(pVar)
|
|
{
|
|
StartMotor(pServ->pExecutor,self->pSics, self->pCon, pVar->Name,
|
|
pVar->fStart + iPoint * pVar->fStep);
|
|
/*
|
|
Ignore errors. TAS scans continues when a motor runs into
|
|
a limit.
|
|
*/
|
|
}
|
|
}
|
|
|
|
/*
|
|
now wait for our motors to arrive, thereby ignoring any error
|
|
returns. DO NOT WAIT if fast scan!
|
|
*/
|
|
if(pTAS->iFast)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
status = Wait4Success(GetExecutor());
|
|
}
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------
|
|
RunPolScan does a polarized scan
|
|
------------------------------------------------------------------------*/
|
|
static int RunPolScan(pScanData self, int iPoint)
|
|
{
|
|
FILE *fd = NULL;
|
|
char buffer[132];
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
|
|
fd = fopen(GetVarText("polfile"),"r");
|
|
if(!fd){
|
|
SCWrite(self->pCon,"ERROR: failed to open polarisation analysis file",
|
|
eError);
|
|
return 0;
|
|
}
|
|
pTAS->iPOL = 0;
|
|
while(fgets(buffer,131,fd) != NULL){
|
|
/*
|
|
ignore all errors here
|
|
*/
|
|
InterpExecute(self->pSics,self->pCon,buffer);
|
|
strtolower(buffer);
|
|
if(strstr(buffer,"co") != NULL){
|
|
pTAS->iPOL++;
|
|
self->WriteScanPoints(self,iPoint);
|
|
}
|
|
/*
|
|
but allow for interrupts
|
|
*/
|
|
if(SCGetInterrupt(self->pCon) != eContinue){
|
|
break;
|
|
}
|
|
}
|
|
pTAS->iIgnore = 1;
|
|
fclose(fd);
|
|
pTAS->iPOL = 1;
|
|
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------------
|
|
TASScanCount starts the counter for a TAS scan or runs the polarization
|
|
analysis.
|
|
---------------------------------------------------------------------------*/
|
|
static int TASUBScanCount(pScanData self, int iPoint)
|
|
{
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
float fVal;
|
|
int status, iRet;
|
|
Status eOld;
|
|
|
|
pTAS->iIgnore = 0;
|
|
/*
|
|
call the polarisation scan function if necessary
|
|
*/
|
|
if(pTAS->iPOL >= 0)
|
|
{
|
|
return RunPolScan(self, iPoint);
|
|
}
|
|
|
|
/*
|
|
this is easy, just an ordinary scan, start a counter
|
|
*/
|
|
fVal = GetCounterPreset(self->pCounterData);
|
|
eOld = GetStatus();
|
|
status = DoCount(self->pCounterData,fVal,self->pCon,0);
|
|
iRet = Wait4Success(GetExecutor());
|
|
if(iRet == DEVINT)
|
|
{
|
|
SCWrite(self->pCon,"Counting aborted due to Interrupt",eStatus);
|
|
status = 0;
|
|
}
|
|
else if(iRet == DEVERROR)
|
|
{
|
|
SCWrite(self->pCon,"Counting finished with Problems",eStatus);
|
|
status = 0;
|
|
}
|
|
else
|
|
{
|
|
status = 1;
|
|
}
|
|
SetStatus(eOld);
|
|
|
|
return status;
|
|
}
|
|
/*--------------------------------------------------------------------------
|
|
TAS stores the scan data. This is necessary in order to support things
|
|
like peak or center which require the scan data for operation
|
|
--------------------------------------------------------------------------*/
|
|
static int TASUBCollect(pScanData self, int iPoint)
|
|
{
|
|
pVarEntry pVar = NULL;
|
|
void *pDings;
|
|
int i, iRet, status, iPtr;
|
|
float fVal;
|
|
CountEntry sCount;
|
|
char *pAns = NULL, *pPtr = NULL ;
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
pMotor pMot;
|
|
char pError[132];
|
|
|
|
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;
|
|
fVal = readDrivable(ScanVarName(pVar),self->pCon);
|
|
if(fVal < -990)
|
|
{
|
|
snprintf(pError,131,"WARNING: failed to read %s",
|
|
ScanVarName(pVar));
|
|
SCWrite(self->pCon,pError,eWarning);
|
|
}
|
|
AppendScanVar(pVar,fVal);
|
|
}
|
|
|
|
/* 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 */
|
|
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++;
|
|
return 1;
|
|
}
|
|
/*-----------------------------------------------------------------------
|
|
prepare2Parse removes all unnecessary delimiters from the parse string.
|
|
These are: ' =
|
|
----------------------------------------------------------------------*/
|
|
static void prepare2Parse(char *line)
|
|
{
|
|
int i, iLang;
|
|
|
|
iLang = strlen(line);
|
|
for(i = 0; i < iLang; i++)
|
|
{
|
|
if(line[i] == ',' || line[i] == '=')
|
|
{
|
|
line[i] = ' ';
|
|
}
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------*/
|
|
extern char *stptok(const char *s, char *t, int len, char *brk);
|
|
extern char*trim(char *txt);
|
|
/*-----------------------------------------------------------------------
|
|
During a TAS scan additional output variables can be printed. These are
|
|
defined in a text variable called ouput. ParseOutput now parses this
|
|
variable and enters the variables found in there into the TAS data
|
|
structure so that they can be printed during the scan.
|
|
------------------------------------------------------------------------*/
|
|
static void ParseOutput(pTASdata pTAS, SConnection *pCon)
|
|
{
|
|
char *pText = NULL, *pPtr, pToken[20], pWarn[256];
|
|
int iPtr;
|
|
|
|
/*
|
|
get a copy of output
|
|
*/
|
|
pText = (char *)malloc((strlen(GetVarText("output"))+1)*sizeof(char));
|
|
if(!pText)
|
|
{
|
|
SCWrite(pCon,"WARNING: out of memory while parsing output variable",
|
|
eWarning);
|
|
return;
|
|
}
|
|
strcpy(pText,GetVarText("output"));
|
|
|
|
/*
|
|
wash it
|
|
*/
|
|
prepare2Parse(pText);
|
|
|
|
/*
|
|
parse
|
|
*/
|
|
pTAS->addCount = 0;
|
|
pPtr = pText;
|
|
while(pPtr != NULL)
|
|
{
|
|
pPtr = stptok(pPtr,pToken,20," ,=");
|
|
if(strlen(pToken) < 1 || pPtr == NULL)
|
|
continue;
|
|
|
|
if(FindCommand(pServ->pSics,trim(pToken)))
|
|
{
|
|
strncpy(pTAS->out[pTAS->addCount],trim(pToken),10);
|
|
pTAS->addCount++;
|
|
}
|
|
else
|
|
{
|
|
strtolower(pToken);
|
|
if(strcmp(pToken,"unknown") != 0) {
|
|
sprintf(pWarn,"WARNING: ignored invalid token > %s < in output",
|
|
pToken);
|
|
SCWrite(pCon,pWarn,eWarning);
|
|
}
|
|
}
|
|
}
|
|
free(pText);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
int TASUBPrepare(pScanData self)
|
|
{
|
|
int status;
|
|
pTASdata pTAS = (pTASdata)self->pSpecial;
|
|
time_t iDate;
|
|
struct tm *psTime;
|
|
char pWork[70];
|
|
char pLine[1024];
|
|
|
|
status = NonCheckPrepare(self);
|
|
|
|
ParseOutput(pTAS,self->pCon);
|
|
|
|
/*
|
|
print some status information for the looser
|
|
*/
|
|
iDate = time(NULL);
|
|
psTime = localtime(&iDate);
|
|
memset(pWork,0,69);
|
|
strftime(pWork,69,"%d-%b-%Y %H:%M:%S",psTime);
|
|
snprintf(pLine,1023,"%8s %3d Points Scan %3d Scanned Variable(s) %s",
|
|
GetVarText("instrument"),
|
|
pTAS->pScan->iNP, pTAS->pScan->iScanVar,
|
|
pWork);
|
|
SCWrite(self->pCon,pLine,eWarning);
|
|
|
|
if(GetCounterMode(pTAS->pScan->pCounterData) == eTimer)
|
|
{
|
|
sprintf(pLine," %8f Seconds per point",
|
|
GetCounterPreset(pTAS->pScan->pCounterData));
|
|
}
|
|
else
|
|
{
|
|
sprintf(pLine," %8f Monitor Counts per point",
|
|
GetCounterPreset(pTAS->pScan->pCounterData));
|
|
|
|
}
|
|
SCWrite(self->pCon,pLine,eWarning);
|
|
SCWrite(self->pCon," ",eWarning);
|
|
SCWrite(self->pCon," ",eWarning);
|
|
|
|
/*
|
|
snprintf(pLine,1023,
|
|
" %12s %6s HKLE: %5.2f %5.2f %5.2f %8.4f %6.3f %6.3f %6.3f %6.3f",
|
|
GetVarText("title"),
|
|
GetVarText("user"),
|
|
pTAS->tasPar[QH]->fVal - (pTAS->pScan->iNP/2)*pTAS->tasPar[DQH]->fVal,
|
|
pTAS->tasPar[QK]->fVal - (pTAS->pScan->iNP/2)*pTAS->tasPar[DQL]->fVal,
|
|
pTAS->tasPar[QL]->fVal - (pTAS->pScan->iNP/2)*pTAS->tasPar[DQK]->fVal,
|
|
pTAS->tasPar[EN]->fVal - (pTAS->pScan->iNP/2)*pTAS->tasPar[DEN]->fVal,
|
|
pTAS->tasPar[DQH]->fVal,
|
|
pTAS->tasPar[DQK]->fVal,
|
|
pTAS->tasPar[DQL]->fVal,
|
|
pTAS->tasPar[DEN]->fVal);
|
|
SCWrite(pCon,pLine,eWarning);
|
|
*/
|
|
if(pTAS->ub->tasMode == KICONST)
|
|
{
|
|
snprintf(pLine,1023," Constant KI Scan: KI= %7.4f Angs-1; EI= %9.4f",
|
|
getTasPar(pTAS->ub->current,KI),
|
|
getTasPar(pTAS->ub->current,EI));
|
|
}
|
|
else
|
|
{
|
|
snprintf(pLine,1023," Constant KF Scan: KF= %7.4f Angs-1; EF= %9.4f",
|
|
getTasPar(pTAS->ub->current,KF),
|
|
getTasPar(pTAS->ub->current,EF));
|
|
}
|
|
SCWrite(self->pCon,pLine,eWarning);
|
|
|
|
return status;
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
static void TASUBDump(pTASdata self, SicsInterp *pSics, SConnection *pCon,
|
|
int argc, char *argv[]){
|
|
float v[3], ub[3][3], cell[6];
|
|
int status, i, j;
|
|
pNXScript nxscript = NULL;
|
|
char pBueffel[256];
|
|
tasReflection r;
|
|
|
|
if(argc < 4){
|
|
SCWrite(pCon,"ERROR: not enough argument to dump tasub",eError);
|
|
return;
|
|
}
|
|
|
|
nxscript = (pNXScript)FindCommandData(pSics,argv[2],"NXScript");
|
|
if(nxscript == NULL){
|
|
snprintf(pBueffel,255,"ERROR: %s is no NXScript object",
|
|
argv[2]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return;
|
|
}
|
|
if(nxscript->fileHandle == NULL){
|
|
SCWrite(pCon,"ERROR: files is closed, cannot write",eError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
write cell
|
|
*/
|
|
snprintf(pBueffel,255,"%s_cell",argv[3]);
|
|
cell[0] = self->ub->cell.a;
|
|
cell[1] = self->ub->cell.b;
|
|
cell[2] = self->ub->cell.c;
|
|
cell[3] = self->ub->cell.alpha;
|
|
cell[4] = self->ub->cell.beta;
|
|
cell[5] = self->ub->cell.gamma;
|
|
status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,cell);
|
|
if(status != NX_OK){
|
|
snprintf(pBueffel,255,"ERROR: failed to write cell to %s_cell",argv[3]);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
}
|
|
|
|
/*
|
|
write planenormal
|
|
*/
|
|
for(i = 0; i < 3; i++){
|
|
v[i] = self->ub->machine.planeNormal[i][0];
|
|
}
|
|
snprintf(pBueffel,255,"%s_norm",argv[3]);
|
|
status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,v);
|
|
if(status != NX_OK){
|
|
snprintf(pBueffel,255,"ERROR: failed to write plane_normal to %s_norm",argv[3]);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
}
|
|
|
|
/*
|
|
write orienting reflections
|
|
*/
|
|
snprintf(pBueffel,255,"%s_vec1",argv[3]);
|
|
r = self->ub->r1;
|
|
v[0] = r.qe.qh;
|
|
v[1] = r.qe.qk;
|
|
v[2] = r.qe.ql;
|
|
status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,v);
|
|
if(status != NX_OK){
|
|
snprintf(pBueffel,255,"ERROR: failed to write plane vector 1 to %s_vec1",argv[3]);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
}
|
|
snprintf(pBueffel,255,"%s_vec2",argv[3]);
|
|
r = self->ub->r2;
|
|
v[0] = r.qe.qh;
|
|
v[1] = r.qe.qk;
|
|
v[2] = r.qe.ql;
|
|
status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,v);
|
|
if(status != NX_OK){
|
|
snprintf(pBueffel,255,"ERROR: failed to write plane vector 2 to %s_vec2",argv[3]);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
}
|
|
|
|
/*
|
|
write UB
|
|
*/
|
|
for(i = 0; i < 3; i++){
|
|
for(j = 0; j < 3; j++){
|
|
ub[i][j] = self->ub->machine.UB[i][j];
|
|
}
|
|
}
|
|
snprintf(pBueffel,255,"%s_ub",argv[3]);
|
|
status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,ub);
|
|
if(status != NX_OK){
|
|
snprintf(pBueffel,255,"ERROR: failed to write UB to %s_ub",argv[3]);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
int TASUBScan(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pTASdata self = NULL;
|
|
char pBueffel[256];
|
|
int np;
|
|
|
|
self = (pTASdata)pData;
|
|
assert(self);
|
|
|
|
self->pScan->pSpecial = self;
|
|
|
|
if(argc < 2) {
|
|
SCWrite(pCon,"ERROR: not enough arguments to tasscan",eError);
|
|
return 0;
|
|
}
|
|
strtolower(argv[1]);
|
|
|
|
if(strcmp(argv[1],"pol") == 0){
|
|
if(argc > 2){
|
|
if(!SCMatchRights(pCon,usUser)){
|
|
return 0;
|
|
}
|
|
self->iPOL = atoi(argv[2]);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBueffel,255,"%s.pol = %d",argv[0],self->iPOL);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}else if(strcmp(argv[1],"fast") == 0){
|
|
if(argc > 2){
|
|
if(!SCMatchRights(pCon,usUser)){
|
|
return 0;
|
|
}
|
|
self->iFast = atoi(argv[2]);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else {
|
|
snprintf(pBueffel,255,"%s.fast = %d",argv[0],self->iFast);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
} else if(strcmp(argv[1],"prepare") == 0){
|
|
return TASUBPrepare(self->pScan);
|
|
} else if(strcmp(argv[1],"nxdump") == 0){
|
|
TASUBDump(self,pSics,pCon,argc,argv);
|
|
return 1;
|
|
} else if(strcmp(argv[1],"drive") == 0){
|
|
if(argc < 5) {
|
|
SCWrite(pCon,"ERROR: insufficient number of arguments to tasscan drive",
|
|
eError);
|
|
return 0;
|
|
}
|
|
np = atoi(argv[4]);
|
|
return TASUBScanDrive(self->pScan,np);
|
|
} else if(strcmp(argv[1],"header") == 0){
|
|
return TASUBHeader(self->pScan);
|
|
} else if(strcmp(argv[1],"count") == 0){
|
|
if(argc < 7) {
|
|
SCWrite(pCon,"ERROR: insufficient number of arguments to tasscan count",
|
|
eError);
|
|
return 0;
|
|
}
|
|
np = atoi(argv[4]);
|
|
return TASUBScanCount(self->pScan,np);
|
|
} else if(strcmp(argv[1],"collect") == 0){
|
|
if(argc < 5) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to tasscan collect",
|
|
eError);
|
|
return 0;
|
|
}
|
|
np = atoi(argv[4]);
|
|
return TASUBCollect(self->pScan,np);
|
|
} else if(strcmp(argv[1],"writepoint") == 0){
|
|
if(argc < 5) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to tasscan writepoint",
|
|
eError);
|
|
return 0;
|
|
}
|
|
np = atoi(argv[4]);
|
|
return TASUBScanPoint(self->pScan,np);
|
|
} else {
|
|
SCWrite(pCon,"ERROR: subcommand to tasscan not understood",eError);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/*---------------------------------------------------------------------*/
|
|
static void KillTAS(void *pData){
|
|
pTASdata self = (pTASdata)pData;
|
|
if(self == NULL){
|
|
return;
|
|
}
|
|
if(self->pDes != NULL){
|
|
DeleteDescriptor(self->pDes);
|
|
}
|
|
free(self);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
int TASUBScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]){
|
|
pTASdata pNew = NULL;
|
|
char pBueffel[512];
|
|
int i;
|
|
char *pVar[] = {
|
|
"polfile",
|
|
"instrument",
|
|
"user",
|
|
"local",
|
|
"title",
|
|
"lastscancommand",
|
|
"output",
|
|
NULL
|
|
};
|
|
|
|
|
|
if(argc < 3){
|
|
SCWrite(pCon,"ERROR: not enough arguments to TASUBScanFactory",eError);
|
|
return 0;
|
|
}
|
|
|
|
pNew = (pTASdata)malloc(sizeof(TASdata));
|
|
if(!pNew){
|
|
SCWrite(pCon,"ERROR: out of memory creating tasscan object",eError);
|
|
return 0;
|
|
}
|
|
memset(pNew,0,sizeof(TASdata));
|
|
pNew->pDes = CreateDescriptor("TAS Scan Stuff");
|
|
if(!pNew->pDes){
|
|
SCWrite(pCon,"ERROR: out of memory creating tasscan object",eError);
|
|
free(pNew);
|
|
return 0;
|
|
}
|
|
|
|
pNew->pScan = (pScanData)FindCommandData(pSics,argv[1],"ScanObject");
|
|
if(!pNew->pScan){
|
|
snprintf(pBueffel,511,"ERROR: cannot locate scan object %s", argv[1]);
|
|
free(pNew);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
pNew->counter = (pCounter)pNew->pScan->pCounterData;
|
|
|
|
pNew->ub = (ptasUB)FindCommandData(pSics,argv[2],"TAS-UB");
|
|
if(!pNew->ub){
|
|
snprintf(pBueffel,511,"ERROR: cannot locate TAS-UB object %s", argv[2]);
|
|
free(pNew);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
|
|
i = 0;
|
|
while(pVar[i] != NULL){
|
|
if(FindCommandData(pSics,pVar[i],"SicsVariable") == NULL){
|
|
snprintf(pBueffel,511,"ERROR: variable %s missing", pVar[i]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
free(pNew);
|
|
return 0;
|
|
}
|
|
i++;
|
|
}
|
|
return AddCommand(pSics,"tasscan",TASUBScan,KillTAS,pNew);
|
|
}
|