Files
sics/mesure.c
koennecke 91d4af0541 - Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
2009-02-13 09:00:03 +00:00

1693 lines
45 KiB
C

/*-------------------------------------------------------------------------
M E S U R E
An object for doing four circle diffractometer measurements with
a single counter.
copyright: see copyright.h
Mark Koennecke, April 1998
heavily reworked: Mark Koennecke, February-March 2005
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <tcl.h>
#include <math.h>
#include <assert.h>
#include "fortify.h"
#include "sics.h"
#include "motor.h"
#include "o2t.h"
#include "scan.h"
#include "scan.i"
#include "stdscan.h"
#include "danu.h"
#include "integrate.h"
#include "hkl.h"
#include "matrix/matrix.h"
#include "hkl.i"
#include "sicsvar.h"
#include "evcontroller.h"
#include "mesure.h"
#include "nxscript.h"
#include "fourtable.h"
#include "lld.h"
#include "stdscan.h"
#include "exeman.h"
extern void SNXFormatTime(char *pBueffel, int iLen);
extern float nintf(float f);
#define ANGERR 0.2
/*
#define MESSDEBUG 1
define MESSDEBUG for simulated peaks. This helps in debugging
this code and the initial data correction code
*/
extern void SNXFormatTime(char *pBueffel, int iLen); /* nxutil.c */
/*------------------- the data structure -----------------------------------*/
typedef struct __Mesure {
pObjectDescriptor pDes; /* standard object descriptor */
pICallBack pCall; /* callback interface for automatic notification */
pScanData pScanner; /* scan object to use for scans */
pHKL pCryst; /* hkl object for crystallographic calc
and reflection driving */
pMotor pOmega; /* motor for omega scans */
pMotor p2Theta; /* motor for 2 theta scans */
char *pCOmega; /* name of omega motor */
char *pC2Theta; /* name of 2 theta motor */
char *pFileRoot; /* where to write files */
pDataNumber pDanu; /* where to get data file number */
FILE *fRefl; /* reflection profile file */
FILE *fHKL; /* integrated intensity file */
int iLogFile; /* log file num at connection */
SConnection *pCon; /* log file owning connection */
char *pCurrentFile; /* current file root */
char headerTemplate[512];
int iCount; /* count of reflection */
int CountMode; /* timer or preset */
int np; /* number of scan points */
float fPreset; /* counting preset */
float fStep; /* omega step widths */
long *lCounts; /* array to store counting values */
float fPosition[4]; /* the real positions after driving */
int iCompact; /* true if compact scan ouput. */
int weak; /* weak flag: remeasure weak reflections */
long weakThreshold; /* threshold when a peak is so weak that is has to
remeasured */
int fastScan; /* flag for using fastscans for scanning reflections */
int psiMode; /* 1 for psi scan mode, 0 else */
int psd; /* a flag for making 2D detector scans */
int stepTable; /* mapping of two theta ranges to step width and
variable to scan */
} Mesure;
/*-------------------------------------------------------------------------*/
static int SaveMesure(void *pData, char *name, FILE * fd)
{
pMesure self = (pMesure) pData;
fprintf(fd, "#Four Circle Dataset Module %s\n", name);
if (self->CountMode == eTimer) {
fprintf(fd, "%s countmode timer\n", name);
} else {
fprintf(fd, "%s countmode monitor\n", name);
}
fprintf(fd, "%s np %d\n", name, self->np);
fprintf(fd, "%s preset %f\n", name, self->fPreset);
fprintf(fd, "%s step %f\n", name, self->fStep);
fprintf(fd, "%s weakthreshold %ld\n", name, self->weakThreshold);
fprintf(fd, "%s compact %d\n", name, self->iCompact);
fprintf(fd, "%s psd %d\n", name, self->psd);
fprintf(fd, "%s weak %d\n", name, self->weak);
fprintf(fd, "%s fastscan %d\n", name, self->fastScan);
SaveFourCircleTable(self->stepTable, name, fd);
return 1;
}
/*-------------------------------------------------------------------------*/
static void ListMesure(pMesure self, char *name, SConnection * pCon)
{
Tcl_DString list;
char pBuffer[132];
Tcl_DStringInit(&list);
if (self->CountMode == eTimer) {
snprintf(pBuffer, 131, "%s.countmode timer\n", name);
} else {
snprintf(pBuffer, 131, "%s.countmode monitor\n", name);
}
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.np %d\n", name, self->np);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.preset %f\n", name, self->fPreset);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.step %f\n", name, self->fStep);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.weakthreshold %ld\n", name,
self->weakThreshold);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.compact %d\n", name, self->iCompact);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.psd %d\n", name, self->psd);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.weak %d\n", name, self->weak);
Tcl_DStringAppend(&list, pBuffer, -1);
snprintf(pBuffer, 131, "%s.fastscan %d\n", name, self->fastScan);
Tcl_DStringAppend(&list, pBuffer, -1);
SCWrite(pCon, Tcl_DStringValue(&list), eValue);
Tcl_DStringFree(&list);
}
/*--------------------------------------------------------------------------*/
pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMotor pOmega,
char *pOm, pMotor p2Theta, char *p2t,
char *pFileRoot, pDataNumber pDanu, char *hdTemplate)
{
pMesure pNew = NULL;
assert(pCryst);
assert(pScanner);
assert(pOmega);
assert(pFileRoot);
assert(pDanu);
/* allocate space............. */
pNew = (pMesure) malloc(sizeof(Mesure));
if (!pNew) {
return NULL;
}
memset(pNew, 0, sizeof(Mesure));
pNew->pDes = CreateDescriptor("Mesure");
pNew->pDes->SaveStatus = SaveMesure;
pNew->pCall = CreateCallBackInterface();
if (!pNew->pDes || !pNew->pCall) {
free(pNew);
return NULL;
}
/* asssign defaults */
pNew->pScanner = pScanner;
pNew->pCryst = pCryst;
pNew->pOmega = pOmega;
pNew->p2Theta = p2Theta;
pNew->pCOmega = strdup(pOm);
pNew->pC2Theta = strdup(p2t);
pNew->pFileRoot = strdup(pFileRoot);
pNew->pDanu = pDanu;
pNew->iCount = 0;
pNew->CountMode = 0;
pNew->np = 50;
pNew->fStep = 0.05;
pNew->fPreset = 2;
pNew->iCompact = 1;
pNew->psd = 0;
pNew->weak = 0;
pNew->weakThreshold = 99999;
pNew->fastScan = 0;
pNew->psiMode = 0;
#ifdef MESSDEBUG
pNew->lCounts = (long *) malloc(90 * sizeof(long));
#endif
pNew->lCounts = (long *) malloc(50 * sizeof(long));
pNew->stepTable = MakeFourCircleTable();
strncpy(pNew->headerTemplate, hdTemplate, 511);
return pNew;
}
/*------------------------------------------------------------------------*/
void DeleteMesure(void *pData)
{
pMesure self = NULL;
self = (pMesure) pData;
if (!pData) {
return;
}
if (self->pDes)
DeleteDescriptor(self->pDes);
if (self->pCall)
DeleteCallBackInterface(self->pCall);
if (self->pFileRoot)
free(self->pFileRoot);
if (self->pCOmega)
free(self->pCOmega);
if (self->fRefl)
MesureClose(self);
if (self->lCounts)
free(self->lCounts);
DeleteFourCircleTable(self->stepTable);
free(self);
}
/*------------------------------------------------------------------------*/
int MesureFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pMesure pNew = NULL;
pHKL pCryst = NULL;
pScanData pScan = NULL;
CommandList *pCom = NULL;
pMotor pMot = NULL, pMot2 = NULL;
pDataNumber pDanu = NULL;
pSicsO2T pO2T = NULL;
char pBueffel[512];
pDummy pDum = NULL;
int iRet;
assert(pCon);
assert(pSics);
/* check no of parameters
inicom name hkl scan omega root danu
*/
if (argc < 9) {
SCWrite(pCon,
"ERROR: Insufficient number of parameters to MesureFactory",
eError);
return 0;
}
/* work parameters one by one, first hkl */
pCom = FindCommand(pSics, argv[2]);
if (pCom) {
pDum = (pDummy) pCom->pData;
if (pDum) {
if (strcmp(pDum->pDescriptor->name, "4-Circle-Calculus") == 0) {
pCryst = (pHKL) pCom->pData;
}
}
}
if (!pCryst) {
sprintf(pBueffel, "ERROR: %s is no four circle calculus object",
argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* scanner */
pCom = FindCommand(pSics, argv[3]);
if (pCom) {
pDum = (pDummy) pCom->pData;
if (pDum) {
if (strcmp(pDum->pDescriptor->name, "ScanObject") == 0) {
pScan = (pScanData) pCom->pData;
}
}
}
if (!pScan) {
sprintf(pBueffel, "ERROR: %s is no scan object", argv[3]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* omega */
pMot = FindMotor(pSics, argv[4]);
if (!pMot) {
sprintf(pBueffel, "ERROR: %s is no motor object ", argv[4]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* 2 theta */
pMot2 = FindMotor(pSics, argv[5]);
if (!pMot2) {
sprintf(pBueffel, "ERROR: %s is no motor object ", argv[5]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* Data Number */
pCom = FindCommand(pSics, argv[7]);
if (pCom) {
pDum = (pDummy) pCom->pData;
if (pDum) {
if (strcmp(pDum->pDescriptor->name, "DataNumber") == 0) {
pDanu = (pDataNumber) pCom->pData;
}
}
}
if (!pDanu) {
sprintf(pBueffel, "ERROR: %s is no DataNumber object", argv[7]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* finally create the thing */
pNew = CreateMesure(pCryst, pScan, pMot, argv[4], pMot2, argv[5],
argv[6], pDanu, argv[8]);
if (!pNew) {
SCWrite(pCon, "ERROR: no memory in MesureFactory", eError);
return 0;
}
/* add the new command */
iRet = AddCommand(pSics, argv[1], MesureAction, DeleteMesure, pNew);
if (!iRet) {
sprintf(pBueffel, "ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
return 1;
}
/*------------------------------------------------------------------------
This implements the compact scan output for TRICS scans
*/
static int CompactScanData(pScanData self, int iPoint)
{
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);
/* loop over all scan variables */
status = 1;
memset(pHead, 0, 512 * sizeof(char));
memset(pStatus, 0, 512 * sizeof(char));
memset(pItem, 0, 20 * sizeof(char));
for (i = 0; i < self->iScanVar; i++) {
DynarGet(self->pScanVar, i, &pDings);
pVar = (pVarEntry) pDings;
if (pVar) {
fVal = pVar->pInter->GetValue(pVar->pObject, self->pCon);
AppendScanVar(pVar, 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);
}
if (self->iChannel == 0) {
sCount.lCount = GetCounts((pCounter) self->pCounterData, self->pCon);
} else {
sCount.lCount = GetMonitor((pCounter) self->pCounterData,
self->iChannel, self->pCon);
}
/* stow away */
DynarReplace(self->pCounts, self->iCounts, &sCount, sizeof(CountEntry));
self->iCounts++;
return 1;
}
/*------------------------------------------------------------------------*/
static int getMesureNP(pMesure self, double twoTheta)
{
int np;
np = GetFourCircleScanNP(self->stepTable, twoTheta);
if (np < -800) {
np = self->np;
}
return np;
}
/*-------------------------------------------------------------------------
This is slightly tricky: the crystallography module has a scan tolerance.
This is supposed to be automatically set. In order to do so, I need
the step width which in turn is dependent on two theta. Therefore I calculate
two times: the first time with a scan tolerance of 0 to get two theta, the
second time with the scan tolerance ste to a decent value to get the
real thing.
---------------------------------------------------------------------------*/
static int MesureCalculateSettings(pMesure self, float fHKL[3],
float fSet[4], float fPsi,
SConnection * pCon)
{
int status, np;
float step, tolerance, fHard;
char *scanvar = NULL;
char buffer[256];
SetHKLScanTolerance(self->pCryst, .0);
status = CalculateSettings(self->pCryst, fHKL, fPsi, 0, fSet, pCon);
if (!status) {
return status;
}
step = GetFourCircleStep(self->stepTable, fSet[0]);
if (step < -900.) {
step = self->fStep;
}
np = getMesureNP(self, (double) fSet[0]);
tolerance = (step * (float) np) / 2. + .2;
SetHKLScanTolerance(self->pCryst, tolerance);
status = CalculateSettings(self->pCryst, fHKL, fPsi, 0, fSet, pCon);
if (status != 1) {
return status;
}
scanvar = GetFourCircleScanVar(self->stepTable, fSet[0]);
if (scanvar != NULL && strcmp(scanvar, "om") != 0) {
tolerance *= 2.;
strcpy(buffer, "ERROR: 2theta limit problem:");
if (!MotorCheckBoundary(self->p2Theta, fSet[0] - tolerance, &fHard,
buffer, 256 - strlen(buffer))) {
SCWrite(pCon, buffer, eWarning);
return 0;
}
if (!MotorCheckBoundary(self->p2Theta, fSet[0] + tolerance, &fHard,
buffer, 256 - strlen(buffer))) {
SCWrite(pCon, buffer, eWarning);
return 0;
}
}
return status;
}
/*--------------------------------------------------------------------------*/
int MesureReflection(pMesure self, float fHKL[3], float fPsi,
SConnection * pCon)
{
int iRet;
float fSet[4];
assert(self);
iRet = MesureCalculateSettings(self, fHKL, fSet, fPsi, pCon);
if (!iRet) {
return iRet;
}
return MesureGenReflection(self, fHKL, fSet, pCon);
}
/*-----------------------------------------------------------------------*/
static int DriveToReflection(pMesure self, float fSet[4],
SConnection * pCon)
{
int iRet, i;
float fDelta;
char pBueffel[132];
iRet = DriveSettings(self->pCryst, fSet, pCon);
if (!iRet) {
return iRet;
}
/* store achieved position for reporting */
iRet = GetCurrentPosition(self->pCryst, pCon, self->fPosition);
if (iRet != 1) {
return iRet;
}
/*
check if we are really there.
*/
for (i = 0; i < 4; i++) {
fDelta = fSet[i] - self->fPosition[i];
if (fDelta < 0.)
fDelta = -fDelta;
if (fDelta > ANGERR) {
snprintf(pBueffel, 131,
"ERROR: angle %d positioned badly, aborting Reflection", i);
SCWrite(pCon, pBueffel, eError);
return 0;
}
}
return 1;
}
/*-----------------------------------------------------------------------
test if this scan has to be remeasured because it is weak
------------------------------------------------------------------------*/
int weakScan(pMesure self, double twoTheta)
{
int i, np;
long low = 99999, high = -99999;
/*
the scan is always OK if we do not test for weak conditions or we are in psd mode
*/
if (self->weak == 0 || self->psd == 1) {
return 0;
}
np = getMesureNP(self, twoTheta);
GetScanCounts(self->pScanner, self->lCounts, np);
for (i = 0; i < np; i++) {
if (self->lCounts[i] < low) {
low = self->lCounts[i];
}
if (self->lCounts[i] > high) {
high = self->lCounts[i];
}
}
/*
I am using the weakest point here as a rough estimate of
the background
*/
if (high - 2 * low > self->weakThreshold) {
return 0;
} else {
return 1;
}
}
/*-----------------------------------------------------------------------*/
static int PerformPSDScan(pMesure self, char *scanVar, float fStart,
float step, int np, float two_theta)
{
int status;
char pCommand[1024];
char countMode[20];
Tcl_Interp *pTcl;
float fPreset;
/*
PSD scans are done by calling the routine Tcl procedure tricsscan with the
appropriate parameters. tricsscan does only omega scans!
*/
if (self->CountMode == eTimer) {
strcpy(countMode, "timer");
} else {
strcpy(countMode, "monitor");
}
fPreset = GetFourCirclePreset(self->stepTable, (double) two_theta);
if (fPreset < .0) {
fPreset = self->fPreset;
}
snprintf(pCommand, 1023, "tricsscan %f %f %d %s %f", fStart, step, np,
countMode, fPreset);
pTcl = InterpGetTcl(pServ->pSics);
status = Tcl_Eval(pTcl, pCommand);
if (status != TCL_OK) {
return 0;
} else {
return 1;
}
}
/*------------------------------------------------------------------------*/
static int ScanReflection(pMesure self, float twoTheta, SConnection * pCon)
{
float fStart, stepWidth, fPreset;
int iRet, np;
char pBueffel[132];
char *scanVar = NULL;
/* calculate scan start */
iRet = MotorGetSoftPosition(self->pOmega, pCon, &fStart);
if (!iRet) {
return iRet;
}
scanVar = GetFourCircleScanVar(self->stepTable, (double) twoTheta);
if (strcmp(scanVar, "NOT FOUND") == 0) {
free(scanVar);
scanVar = strdup(self->pCOmega);
stepWidth = self->fStep;
} else {
stepWidth = GetFourCircleStep(self->stepTable, (double) twoTheta);
}
np = getMesureNP(self, (double) twoTheta);
if (stepWidth != self->fStep) {
snprintf(pBueffel, 130, "Using stepwidth %f, %d points", stepWidth,
np);
SCWrite(pCon, pBueffel, eWarning);
}
fStart -= (np / 2) * stepWidth;
/*
special case: psd mode
*/
if (self->psd == 1) {
iRet = PerformPSDScan(self, scanVar, fStart, stepWidth, np, twoTheta);
free(scanVar);
return iRet;
}
/*
below is the code for a single counter scan.
TODO: (maybe) make this clearer and separate this into another subroutine
Set the scan up
*/
ClearScanVar(self->pScanner);
AddScanVar(self->pScanner, pServ->pSics, pCon, self->pCOmega,
fStart, stepWidth);
snprintf(pBueffel, 131, "Scanning om from %f with step %f", fStart,
stepWidth);
SCWrite(pCon, pBueffel, eLog);
/*
Oksana does not want o2t scans to be tightly coupled, this is why we
cannot use the normal o2t scan variable. Instead we calculate new limits and
steps for 2 theta and use it as a second scan variable
*/
if (strstr(scanVar, "o2t") != NULL) {
iRet = MotorGetSoftPosition(self->p2Theta, pCon, &fStart);
if (!iRet) {
return iRet;
}
stepWidth *= 2.;
fStart -= (np / 2.) * stepWidth;
AddScanVar(self->pScanner, pServ->pSics, pCon, self->pC2Theta,
fStart, stepWidth);
snprintf(pBueffel, 131, "Scanning 2theta from %f with step %f", fStart,
stepWidth);
SCWrite(pCon, pBueffel, eLog);
}
/*
as np can change, we have to reallocate enough space
*/
if (self->lCounts != NULL) {
free(self->lCounts);
self->lCounts = (long *) malloc(np * sizeof(long));
if (self->lCounts == NULL) {
SCWrite(pCon, "ERROR: out of memory for scan scan data", eError);
SCSetInterrupt(pCon, eAbortScan);
return 0;
}
memset(self->lCounts, 0, np * sizeof(long));
}
/*
* determine preset
*/
fPreset = GetFourCirclePreset(self->stepTable, (double) twoTheta);
if (fPreset < .0) {
fPreset = self->fPreset;
}
/* do the scan */
free(scanVar);
if (self->iCompact) {
self->pScanner->CollectScanData = CompactScanData;
}
if (self->fastScan >= 1) {
self->pScanner->ScanDrive = ScanFastDrive;
}
iRet = SilentScan(self->pScanner, np, self->CountMode,
fPreset, pServ->pSics, pCon);
if (weakScan(self, twoTheta)) {
/*
look for interrupts before restarting scan
*/
if (iRet == 0) {
if (SCGetInterrupt(pCon) >= eAbortBatch) {
return 0;
} else {
SCSetInterrupt(pCon, eContinue);
}
}
/*
redo scan with preset * 5
*/
SCWrite(pCon, "Remeasuring weak reflection", eLog);
iRet = SilentScan(self->pScanner, np, self->CountMode,
fPreset * 5., pServ->pSics, pCon);
}
ResetScanFunctions(self->pScanner);
return iRet;
}
/*------------------------------------------------------------------------*/
int MesureGenReflection(pMesure self, float fHKL[3], float fSet[4],
SConnection * pCon)
{
int iRet, i;
char pBueffel[132];
assert(self);
iRet = DriveToReflection(self, fSet, pCon);
if (!iRet) {
return iRet;
}
iRet = ScanReflection(self, fSet[0], pCon);
return iRet;
}
/*--------------------------------------------------------------------------*/
int MesureStart(pMesure self, SConnection * pCon)
{
char pFilename[512], pRoot[512];
char pBueffel[1024];
char pBuff[132];
int iYear, iNum, iTaus;
float fVal, fUB[9];
pSicsVariable pVar = NULL;
char *pFile = NULL, *pPtr;
float zero, pos;
pMotor pMot = NULL;
FILE *temp = NULL;
assert(self);
assert(pCon);
/* close open files if so */
if (self->fRefl != NULL) {
MesureClose(self);
}
/* create filename root */
pFile = makeFilename(pServ->pSics, pCon);
if (!pFile) {
return 0;
}
pPtr = strrchr(pFile, (int) '.');
pPtr++;
*pPtr = '\0';
self->pCurrentFile = strdup(pFile);
free(pFile);
strncpy(pRoot, self->pCurrentFile, 511);
/* do the logfile */
strcpy(pFilename, pRoot);
strcat(pFilename, "log");
/* TODO
self->iLogFile = SCAddLogFile(pCon,pFilename);
*/
self->pCon = pCon;
/*
we do not need reflection files when doing a PSD scan
*/
if (self->psd == 1) {
sprintf(pBueffel, "Logging to %s.log", pRoot);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
/* open the reflection file */
sprintf(pBueffel, "Writing to %s.log, .ccl, .rfl", pRoot);
SCWrite(pCon, pBueffel, eValue);
strcpy(pFilename, pRoot);
strcat(pFilename, "ccl");
self->fRefl = fopen(pFilename, "w");
if (!self->fRefl) {
sprintf(pBueffel, "ERROR: SERIOUS TROUBLE: cannot open %s!",
pFilename);
SCWrite(pCon, pBueffel, eError);
SCSetInterrupt(pCon, eAbortBatch);
return 0;
}
temp = fopen(self->headerTemplate, "r");
if (temp == NULL) {
SCWrite(pCon, "ERROR: failed to open header template", eError);
}
if (temp != NULL && self->fRefl != NULL) {
WriteTemplate(self->fRefl, temp, pFilename, NULL, pCon, pServ->pSics);
fclose(temp);
}
/* open hkl-data file */
strcpy(pFilename, pRoot);
strcat(pFilename, "rfl");
self->fHKL = fopen(pFilename, "w");
if (!self->fHKL) {
sprintf(pBueffel, "ERROR: SERIOUS TROUBLE: cannot open %s!",
pFilename);
SCWrite(pCon, pBueffel, eError);
SCSetInterrupt(pCon, eAbortBatch);
return 0;
}
fputs(pFilename, self->fHKL);
fputs("\n", self->fHKL);
/* write some header data */
SNXFormatTime(pBueffel, 1024);
fprintf(self->fHKL, "filetime = %s\n", pBueffel);
GetLambda(self->pCryst, &fVal);
fprintf(self->fHKL, "lambda = %f Angstroem\n", fVal);
GetUB(self->pCryst, fUB);
fprintf(self->fHKL,
"UB = %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f\n",
fUB[0], fUB[1], fUB[2], fUB[3], fUB[4], fUB[5], fUB[6], fUB[7],
fUB[8]);
/* write sample & user info */
strcpy(pBueffel, "CCL, Instr=TRICS, ");
pVar = FindVariable(pServ->pSics, "sample");
if (pVar) {
fprintf(self->fHKL, "sample = %s\n", pVar->text);
sprintf(pBuff, "sample = %s, ", pVar->text);
strcat(pBueffel, pBuff);
}
pVar = FindVariable(pServ->pSics, "user");
if (pVar) {
fprintf(self->fHKL, "user = %s \n", pVar->text);
sprintf(pBuff, "user = %s", pVar->text);
strcat(pBueffel, pBuff);
}
return 1;
}
/*---------------------------------------------------------------------------*/
int MesureReopen(pMesure self, char *fileroot, SConnection * pCon)
{
char pBueffel[1024];
char pFile[512];
assert(self);
assert(fileroot);
assert(pCon);
/* close pending files */
if (self->fRefl != NULL) {
MesureClose(self);
}
/* log file */
strcpy(pFile, self->pFileRoot);
strcat(pFile, "/");
strcat(pFile, fileroot);
strcat(pFile, ".log");
/* TODO:
self->iLogFile = SCAddLogFile(pCon,pFile);
*/
self->pCon = pCon;
/*
No reopening of reflection files in psd mode
*/
if (self->psd == 1) {
return 1;
}
/* check if this is possible */
strcpy(pFile, self->pFileRoot);
strcat(pFile, "/");
strcat(pFile, fileroot);
strcat(pFile, ".col");
self->fRefl = fopen(pFile, "r");
if (!self->fRefl) {
sprintf(pBueffel, "ERROR: there is no such measurement at %s",
fileroot);
SCWrite(pCon, pBueffel, eError);
return 0;
}
fclose(self->fRefl);
/* well seems to exist, open for append */
self->fRefl = fopen(pFile, "a");
/* rfl file */
strcpy(pFile, self->pFileRoot);
strcat(pFile, "/");
strcat(pFile, fileroot);
self->pCurrentFile = strdup(pFile);
strcat(pFile, ".rfl");
self->fHKL = fopen(pFile, "a");
return 1;
}
/*------------------------------------------------------------------------*/
int MesureClose(pMesure self)
{
assert(self);
/* TODO
* SCDelLogFile(self->pCon,self->iLogFile);
*/
if (self->psd == 1) {
self->pCon = NULL;
self->iLogFile = -1;
if (self->pCurrentFile)
free(self->pCurrentFile);
return 1;
}
if (self->fRefl) {
fclose(self->fRefl);
self->fRefl = NULL;
}
if (self->fHKL) {
fclose(self->fHKL);
self->fHKL = NULL;
}
self->pCon = NULL;
self->iLogFile = -1;
if (self->pCurrentFile)
free(self->pCurrentFile);
return 1;
}
/*---------------------------------------------------------------------------*/
static double getProtonAverage(pMesure self)
{
int np, i;
long *lData = NULL, lSum = 0;
np = GetScanNP(self->pScanner);
lData = (long *) malloc((np + 1) * sizeof(long));
if (lData == NULL || np == 0) {
return 0.;
}
memset(lData, 0, (np + 1) * sizeof(long));
GetScanMonitor(self->pScanner, 2, lData, np);
for (i = 0; i < np; i++) {
lSum += lData[i];
}
return (double) lSum / (double) np;
}
/*---------------------------------------------------------------------------*/
static int WriteReflection(pMesure self, float fHKL[3], SConnection * pCon)
{
float fSum, fSigma, fSet[4], fTemp, fPreset, fStep;
double prot;
static float fMax = 10.;
int iRet, i, ii, iLF, iNP;
char pBueffel[512], pNum[10], pTime[132];
pEVControl pEva = NULL;
pDummy pPtr = NULL;
pIDrivable pDriv = NULL;
assert(self);
assert(pCon);
memset(pTime, 0, 132 * sizeof(char));
#ifdef MESSDEBUG
self->np = 90;
fMax += 10;
SimScan(self->pScanner, 14., 0.5, fMax);
if (fMax > 1000) {
fMax = 10.;
}
#endif
/*
no writing in PSD mode
*/
if (self->psd == 1) {
return 1;
}
/* get necessary data */
fSum = 0.;
fSigma = 0.;
iRet = ScanIntegrate(self->pScanner, &fSum, &fSigma);
if (iRet != 1) {
switch (iRet) {
case INTEGLEFT:
sprintf(pBueffel,
"WARNING: integration failed --> no left side to: %f %f %f",
fHKL[0], fHKL[1], fHKL[2]);
break;
case INTEGRIGHT:
sprintf(pBueffel,
"WARNING: integration failed -->no right side to: %f %f %f",
fHKL[0], fHKL[1], fHKL[2]);
break;
case INTEGNOPEAK:
sprintf(pBueffel,
"WARNING: integration failed -->no peak found: %f %f %f",
fHKL[0], fHKL[1], fHKL[2]);
break;
case INTEGFUNNYBACK:
sprintf(pBueffel,
"WARNING: integration problem, asymmetric background: %f %f %f",
fHKL[0], fHKL[1], fHKL[2]);
break;
}
SCWrite(pCon, pBueffel, eWarning);
}
iNP = GetScanNP(self->pScanner);
GetScanCounts(self->pScanner, self->lCounts, iNP);
/* write it */
if (self->fRefl) {
fprintf(self->fRefl,
"%4d %7.3f %7.3f %7.3f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
self->iCount, fHKL[0], fHKL[1], fHKL[2], self->fPosition[0],
self->fPosition[1], self->fPosition[2], self->fPosition[3],
fSum, fSigma);
}
if (self->fHKL) {
fprintf(self->fHKL,
"%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
self->iCount, fHKL[0], fHKL[1], fHKL[2], self->fPosition[0],
self->fPosition[1], self->fPosition[2], self->fPosition[3],
fSum, fSigma);
}
sprintf(pBueffel,
"%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
self->iCount, fHKL[0], fHKL[1], fHKL[2], self->fPosition[0],
self->fPosition[1], self->fPosition[2], self->fPosition[3], fSum,
fSigma);
SCWrite(pCon, pBueffel, eLog);
/* get temperature */
fTemp = -777.77;
pEva = (pEVControl) FindCommandData(pServ->pSics, "temperature",
"Environment Controller");
if (pEva == NULL) {
pPtr = (pDummy) FindCommandData(pServ->pSics, "temperature",
"RemObject");
if (pPtr != NULL) {
pDriv = pPtr->pDescriptor->GetInterface(pPtr, DRIVEID);
if (pDriv != NULL) {
fTemp = pDriv->GetValue(pPtr, pCon);
}
}
} else {
iRet = EVCGetPos(pEva, pCon, &fTemp);
}
/* write profile */
if (self->fRefl) {
/* collect data */
SNXFormatTime(pBueffel, 512);
GetScanVarStep(self->pScanner, 0, &fStep);
fPreset = GetScanPreset(self->pScanner);
prot = getProtonAverage(self);
fprintf(self->fRefl, "%3d %7.4f %9.0f %7.3f %12f %s\n", iNP, fStep,
fPreset, fTemp, prot, pBueffel);
for (i = 0; i < iNP; i++) {
for (ii = 0; ii < 10 && i < iNP; ii++) {
fprintf(self->fRefl, " %7ld", self->lCounts[i]);
iLF = 1;
i++;
}
fprintf(self->fRefl, "\n");
i--;
iLF = 0;
}
if (iLF) {
fprintf(self->fRefl, "\n");
}
fflush(self->fRefl);
}
/* write data if compact output */
if (self->iCompact == 1) {
strcpy(pTime, pBueffel);
sprintf(pBueffel, "%3d%8.4f%10.0f%8.3f %s\n", iNP, fStep,
fPreset, fTemp, pTime);
SCWrite(pCon, pBueffel, eValue);
pBueffel[0] = '\0';
for (i = 0; i < iNP; i++) {
for (ii = 0; ii < 10 && i < iNP; ii++) {
sprintf(pNum, " %6ld", self->lCounts[i]);
strcat(pBueffel, pNum);
iLF = 1;
i++;
}
SCWrite(pCon, pBueffel, eValue);
pBueffel[0] = '\0';
i--;
iLF = 0;
}
if (iLF) {
SCWrite(pCon, pBueffel, eValue);
}
}
return 1;
}
/*---------------------------------------------------------------------*/
static FILE *openListFile(char *pName)
{
FILE *fd = NULL;
pDynString filename = NULL;
filename = findBatchFile(pServ->pSics, pName);
if (filename != NULL) {
fd = fopen(GetCharArray(filename), "r");
DeleteDynString(filename);
} else {
fd = fopen(pName, "r");
}
return fd;
}
/*------------------------------------------------------------------------*/
int MesureFile(pMesure self, char *pFile, int iSkip, SConnection * pCon)
{
FILE *fd = NULL;
char pBueffel[512], pTime[132], pError[256];
int i, iRet;
float fHKL[3], fPsi = .0;
assert(self);
assert(pCon);
/* well before doing a thing, open the list file */
fd = openListFile(pFile);
if (!fd) {
sprintf(pBueffel, "ERROR: reflection file %s NOT found!", pFile);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* check that files are open, if not open */
if (self->fRefl == NULL) {
MesureStart(self, pCon);
}
/* make a mark */
SNXFormatTime(pTime, 131);
sprintf(pBueffel, "Starting at list %s at %s", pFile, pTime);
SCWrite(pCon, pBueffel, eLog);
/* skippy! */
for (i = 0; i < iSkip; i++) {
fgets(pBueffel, 510, fd);
}
self->iCount = iSkip;
if (self->psiMode > 0) {
SCWrite(pCon, "WARNING: measuring in psi mode", eWarning);
}
/* loop through space and measure! */
while (fgets(pBueffel, 510, fd) != NULL) {
for (i = 0; i < 3; i++)
fHKL[i] = 0.;
if (self->psiMode > 0) {
iRet = sscanf(pBueffel, "%f%f%f%f",
&fHKL[0], &fHKL[1], &fHKL[2], &fPsi);
if (iRet != 4) {
snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel);
SCWrite(pCon, pError, eWarning);
continue;
}
} else {
iRet = sscanf(pBueffel, "%f%f%f", &fHKL[0], &fHKL[1], &fHKL[2]);
if (iRet != 3) {
snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel);
SCWrite(pCon, pError, eWarning);
continue;
}
}
self->iCount++;
iRet = MesureReflection(self, fHKL, fPsi, pCon);
if (iRet == 0) {
if (SCGetInterrupt(pCon) >= eAbortBatch) {
return 0;
} else {
SCSetInterrupt(pCon, eContinue);
continue;
}
}
WriteReflection(self, fHKL, pCon);
}
/* we are done */
SNXFormatTime(pTime, 131);
sprintf(pBueffel, "Finishing list %s at %s", pFile, pTime);
SCWrite(pCon, pBueffel, eLog);
fclose(fd);
return 1;
}
/*------------------------------------------------------------------------*/
int TestFile(pMesure self, char *pFile, SConnection * pCon)
{
FILE *fd = NULL;
char pBueffel[512], pError[256];
int i, iRet;
float fHKL[3], fSet[4], fPsi = .0;
int count = 0, good = 0;
assert(self);
assert(pCon);
/* well before doing a thing, open the list file */
fd = openListFile(pFile);
if (!fd) {
sprintf(pBueffel, "ERROR: reflection file %s NOT found!", pFile);
SCWrite(pCon, pBueffel, eError);
return 0;
}
if (self->psiMode > 0) {
SCWrite(pCon, "WARNING: measuring in psi mode", eWarning);
}
/* loop through space and test! */
while (fgets(pBueffel, 510, fd) != NULL) {
for (i = 0; i < 3; i++)
fHKL[i] = 0.;
if (self->psiMode > 0) {
iRet = sscanf(pBueffel, "%f%f%f%f",
&fHKL[0], &fHKL[1], &fHKL[2], &fPsi);
if (iRet != 4) {
snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel);
SCWrite(pCon, pError, eWarning);
continue;
}
} else {
iRet = sscanf(pBueffel, "%f%f%f", &fHKL[0], &fHKL[1], &fHKL[2]);
if (iRet != 3) {
snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel);
SCWrite(pCon, pError, eWarning);
continue;
}
}
count++;
iRet = MesureCalculateSettings(self, fHKL, fSet, fPsi, pCon);
if (iRet == 1) {
good++;
}
}
fclose(fd);
snprintf(pBueffel, 511,
"Of %d reflections on file, %d are good and %d are rotten",
count, good, count - good);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
/*------------------------------------------------------------------------*/
int MesureGenFile(pMesure self, char *pFile, int iSkip, SConnection * pCon)
{
FILE *fd = NULL;
char pBueffel[512], pTime[132];
int i, iRet, iH, iK, iL;
float fHKL[3], fSet[4];
char pDum[4];
assert(self);
assert(pCon);
/* well before doing a thing, open the list file */
fd = openListFile(pFile);
if (!fd) {
sprintf(pBueffel, "ERROR: reflection file %s NOT found!", pFile);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* check that files are open, if not open */
if (self->fRefl == NULL) {
MesureStart(self, pCon);
}
/* make a mark */
SNXFormatTime(pTime, 131);
sprintf(pBueffel, "Starting at list %s at %s", pFile, pTime);
SCWrite(pCon, pBueffel, eLog);
/* skippy! */
for (i = 0; i < iSkip; i++) {
fgets(pBueffel, 510, fd);
}
self->iCount = iSkip;
/* loop through space and measure! */
while (fgets(pBueffel, 510, fd) != NULL) {
for (i = 0; i < 3; i++)
fHKL[i] = 0.;
for (i = 0; i < 4; i++)
fSet[i] = 0.;
iRet = sscanf(pBueffel, "%4d%4d%4d%s%f%f%f%f",
&iH, &iK, &iL, pDum,
&fSet[0], &fSet[1], &fSet[2], &fSet[3]);
fHKL[0] = (float) iH;
fHKL[1] = (float) iK;
fHKL[2] = (float) iL;
self->iCount++;
iRet = MesureGenReflection(self, fHKL, fSet, pCon);
if (iRet == 0) {
if (SCGetInterrupt(pCon) >= eAbortBatch) {
return 0;
} else {
SCSetInterrupt(pCon, eContinue);
continue;
}
}
WriteReflection(self, fHKL, pCon);
}
/* we are done */
SNXFormatTime(pTime, 131);
sprintf(pBueffel, "Finishing list %s at %s", pFile, pTime);
SCWrite(pCon, pBueffel, eLog);
fclose(fd);
return 1;
}
/*--------------------------------------------------------------------------*/
int MesureSetPar(pMesure self, char *name, float fVal)
{
if (strcmp(name, "np") == 0) {
#ifndef MESSDEBUG
self->np = (int) fVal;
if (self->lCounts)
free(self->lCounts);
self->lCounts = (long *) malloc(self->np * sizeof(long));
if (!self->lCounts) {
return 0;
}
#else
#endif
return 1;
} else if (strcmp(name, "step") == 0) {
self->fStep = fVal;
return 1;
} else if (strcmp(name, "weakthreshold") == 0) {
self->weakThreshold = (long) nintf(fVal);
return 1;
} else if (strcmp(name, "preset") == 0) {
self->fPreset = fVal;
return 1;
} else if (strcmp(name, "countmode") == 0) {
if (fVal < 0.05) {
self->CountMode = eTimer;
} else {
self->CountMode = ePreset;
}
return 1;
} else if (strcmp(name, "compact") == 0) {
if (fVal >= 1.) {
self->iCompact = 1;
} else {
self->iCompact = 0;
}
return 1;
} else if (strcmp(name, "psd") == 0) {
if (fVal >= 1.) {
self->psd = 1;
} else {
self->psd = 0;
}
return 1;
} else if (strcmp(name, "weak") == 0) {
if (fVal >= 1.) {
self->weak = 1;
} else {
self->weak = 0;
}
return 1;
} else if (strcmp(name, "fastscan") == 0) {
if (fVal >= 1.) {
self->fastScan = 1;
} else {
self->fastScan = 0;
}
return 1;
} else if (strcmp(name, "psimode") == 0) {
if (fVal >= 1.) {
self->psiMode = 1;
} else {
self->psiMode = 0;
}
return 1;
} else {
return 0;
}
}
/*-------------------------------------------------------------------------*/
int MesureGetPar(pMesure self, char *name, float *fVal)
{
if (strcmp(name, "np") == 0) {
*fVal = self->np;
return 1;
} else if (strcmp(name, "step") == 0) {
*fVal = self->fStep;
return 1;
} else if (strcmp(name, "weakthreshold") == 0) {
*fVal = (float) self->weakThreshold;
return 1;
} else if (strcmp(name, "preset") == 0) {
*fVal = self->fPreset;
return 1;
} else if (strcmp(name, "countmode") == 0) {
if (self->CountMode == eTimer) {
*fVal = 0.;
} else {
*fVal = 1.0;
}
return 1;
} else if (strcmp(name, "compact") == 0) {
*fVal = self->iCompact;
return 1;
} else if (strcmp(name, "psd") == 0) {
*fVal = self->psd;
return 1;
} else if (strcmp(name, "fastscan") == 0) {
*fVal = (float) self->fastScan;
return 1;
} else if (strcmp(name, "weak") == 0) {
*fVal = (float) self->weak;
return 1;
} else if (strcmp(name, "psimode") == 0) {
*fVal = self->psiMode;
return 1;
} else {
return 0;
}
}
/*---------------------------------------------------------------------------*/
int MesureAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
int iRet, iSkip, err;
char pBueffel[1024];
pMesure self = NULL;
double d;
float fVal, fHKL[3], start, end, step;
self = (pMesure) pData;
assert(self);
assert(pCon);
if (argc < 2) {
sprintf(pBueffel, "ERROR: Insufficient arguments to %s", argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/*
catch table processing commands
*/
iRet =
HandleFourCircleCommands(&self->stepTable, pCon, argc, argv, &err);
if (iRet == 1) {
return err;
}
strtolower(argv[1]);
/*------ start */
if (strcmp(argv[1], "open") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
iRet = MesureStart(self, pCon);
if (iRet) {
SCSendOK(pCon);
}
return iRet;
}
/*----------- list*/
else if (strcmp(argv[1], "list") == 0) {
ListMesure(self, argv[0], pCon);
return 1;
}
/*------ file */
else if (strcmp(argv[1], "file") == 0) {
sprintf(pBueffel, "Currently writing to: %s", self->pCurrentFile);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
/*------ nb */
else if (strcmp(argv[1], "nb") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
iRet = SetNOR(self->pCryst, 1);
if (!iRet) {
SCWrite(pCon,
"ERROR: nu motor not configured at hkl, cannot do normal beam",
eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*------ bi */
else if (strcmp(argv[1], "bi") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
iRet = SetNOR(self->pCryst, 0);
SCSendOK(pCon);
return 1;
}
/*--------- close */
else if (strcmp(argv[1], "close") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
MesureClose(self);
return 1;
}
/*-------- reopen */
else if (strcmp(argv[1], "reopen") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
if (argc < 3) {
SCWrite(pCon, "ERROR: expected filename as parameter for reopen",
eError);
return 0;
}
iRet = MesureReopen(self, argv[2], pCon);
if (iRet) {
SCSendOK(pCon);
}
return iRet;
}
/*------- measure */
else if (strcmp(argv[1], "measure") == 0) {
iSkip = 0;
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
if (argc < 3) {
SCWrite(pCon,
"ERROR: expected list file name as parameter for measure ",
eError);
return 0;
}
if (argc >= 4) {
iRet = Tcl_GetInt(pSics->pTcl, argv[3], &iSkip);
if (iRet != TCL_OK) {
sprintf(pBueffel, "ERROR: expected integer, got %s", argv[3]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
}
iRet = MesureFile(self, argv[2], iSkip, pCon);
if (iRet) {
SCSendOK(pCon);
}
return iRet;
}
/*------- calc */
else if (strcmp(argv[1], "calc") == 0) {
if (argc < 3) {
SCWrite(pCon,
"ERROR: expected list file name as parameter for measure ",
eError);
return 0;
}
iRet = TestFile(self, argv[2], pCon);
return iRet;
}
/*------- genlist */
else if (strcmp(argv[1], "genlist") == 0) {
iSkip = 0;
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
if (argc < 3) {
SCWrite(pCon,
"ERROR: expected list file name as parameter for measure ",
eError);
return 0;
}
if (argc >= 4) {
iRet = Tcl_GetInt(pSics->pTcl, argv[3], &iSkip);
if (iRet != TCL_OK) {
sprintf(pBueffel, "ERROR: expected integer, got %s", argv[3]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
}
iRet = MesureGenFile(self, argv[2], iSkip, pCon);
if (iRet) {
SCSendOK(pCon);
}
return iRet;
}
/* ------ writereflection*/
else if (strcmp(argv[1], "writereflection") == 0) {
GetCurrentHKL(self->pCryst, fHKL);
WriteReflection(self, fHKL, pCon);
SCSendOK(pCon);
return 1;
}
/* ------ count mode */
else if (strcmp(argv[1], "countmode") == 0) {
if (argc > 2) { /* set case */
/* check rights */
if (!SCMatchRights(pCon, usUser)) {
SCWrite(pCon, "ERROR: You are not aurhorised to do this!", eError);
return 0;
}
if (strcmp(argv[2], "timer") == 0) {
fVal = 0.;
} else if (strcmp(argv[2], "monitor") == 0) {
fVal = 1.;
} else {
SCWrite(pCon, "ERROR: Invalid parameter for countmode", eError);
return 0;
}
MesureSetPar(self, "countmode", fVal);
SCSendOK(pCon);
return 1;
} else { /* get case */
MesureGetPar(self, "countmode", &fVal);
if (fVal < 0.05) {
sprintf(pBueffel, "%s.countmode = timer", argv[0]);
} else {
sprintf(pBueffel, "%s.countmode = monitor", argv[0]);
}
SCWrite(pCon, pBueffel, eValue);
return 1;
}
}
/*------ can be other pars */
else {
if (argc > 2) { /* set case */
/* check rights */
if (!SCMatchRights(pCon, usUser)) {
SCWrite(pCon, "ERROR: You are not aurhorised to do this!", eError);
return 0;
}
iRet = Tcl_GetDouble(pSics->pTcl, argv[2], &d);
if (iRet != TCL_OK) {
sprintf(pBueffel,
"ERROR: expected numeric value for %s but got %s", argv[1],
argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
fVal = (float) d;
iRet = MesureSetPar(self, argv[1], fVal);
if (iRet) {
SCSendOK(pCon);
return 1;
} else {
sprintf(pBueffel, "ERROR: parameter %s not known", argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
} else { /* get case */
iRet = MesureGetPar(self, argv[1], &fVal);
if (!iRet) {
sprintf(pBueffel, "ERROR: parameter %s not known", argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
sprintf(pBueffel, "%s.%s = %f", argv[0], argv[1], fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
}
}