Update from PSI

r1039 | ffr | 2006-08-03 09:59:29 +1000 (Thu, 03 Aug 2006) | 2 lines
This commit is contained in:
Ferdi Franceschini
2006-08-03 09:59:29 +10:00
committed by Douglas Clowes
parent 4aa50787c2
commit 074f1cb3cd
63 changed files with 1431 additions and 286 deletions

View File

@ -57,6 +57,7 @@
#include <assert.h>
#include <string.h>
#include <tcl.h>
#include <time.h>
#include "fortify.h"
#include "sics.h"
#include "splitter.h"
@ -151,6 +152,7 @@ static void freeList(int listID);
pNew->pData = pData;
pNew->pNext = NULL;
pNew->startupOnly = startupOnly;
pNew->stat = StatisticsNew(pBueffel);
/* find end of list */
tail = NULL;
@ -232,10 +234,14 @@ static void freeList(int listID);
{
pInterp->pCList = pVictim->pNext;
}
if (pVictim->stat) {
StatisticsKill(pVictim->stat);
}
free(pVictim);
return 1;
}
#define MAXLEN 256
#define MAXCOM 50
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
@ -252,6 +258,7 @@ extern char *SkipSpace(char *pPtr);
char *pPtr;
char **argv = NULL;
commandContext comCon;
Statistics *old;
assert(self);
@ -307,7 +314,9 @@ extern char *SkipSpace(char *pPtr);
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
MacroPush(pCon);
pCon->conStatus = 0;
old = StatisticsBegin(pCommand->stat);
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
StatisticsEnd(old);
/* If a task is registered with the dev exec then conStatus is HWBusy*/
if (pCon->conStatus != HWBusy) {
comCon = SCGetContext(pCon);
@ -444,29 +453,40 @@ extern char *SkipSpace(char *pPtr);
void DeleteInterp(SicsInterp *self)
{
CommandList *pCurrent = NULL;
CommandList *pTemp;
CommandList *pTemp, *tail;
Tcl_Interp *pTcl = NULL;
int i;
assert(self);
self->iDeleting = 1;
/* delete Commandlist */
/* find end of list */
tail = NULL;
pCurrent = self->pCList;
while(pCurrent)
while(pCurrent != NULL)
{
if(pCurrent->KFunc)
tail = pCurrent;
pCurrent = pCurrent->pNext;
}
/* delete Commandlist (reversed order) */
if (tail) {
pCurrent = tail;
while(pCurrent)
{
pCurrent->KFunc(pCurrent->pData);
if(pCurrent->KFunc)
{
pCurrent->KFunc(pCurrent->pData);
}
if(pCurrent->pName)
{
/* printf("Deleting %s\n",pCurrent->pName); */
free(pCurrent->pName);
}
pTemp = pCurrent->pPrevious;
free(pCurrent);
pCurrent = pTemp;
}
if(pCurrent->pName)
{
/* printf("Deleting %s\n",pCurrent->pName); */
free(pCurrent->pName);
}
pTemp = pCurrent->pNext;
free(pCurrent);
pCurrent = pTemp;
}
FreeAliasList(&self->AList); /* M.Z. */

View File

@ -10,6 +10,7 @@
#ifndef SICSINTERPRETER
#define SICSINTERPRETER
#include "Scommon.h"
#include "statistics.h"
#include <tcl.h>
/* M.Z. */
#include "definealias.i"
@ -31,6 +32,7 @@ typedef struct __Clist {
struct __Clist *pNext;
struct __Clist *pPrevious;
int startupOnly;
Statistics *stat;
} CommandList;
typedef struct __SINTER

View File

@ -3,8 +3,9 @@
Mark Koennecke, November 1996
----------------------------------------------------------------------------*/
#ifndef PCODE
#define PCODE
#include <string.h>
#include <sics.h>
#include <splitter.h>
static char *aCode[] = {
"internal",
@ -13,4 +14,19 @@
"spy",
NULL };
static int iCodes = 4;
#endif
/*--------------------------------------------------------------------------*/
int decodeSICSPriv(char *privText){
int code = 0;
strtolower(privText);
while(aCode[code] != NULL){
if(strcmp(aCode[code], privText) == 0){
return code;
}
code++;
}
if(code >= iCodes){
return -1;
}
return -1;
}

View File

@ -99,7 +99,7 @@
if(argc < 2)
{
sprintf(pMessage, "ERROR: Ragument required for %s",argv[0]);
sprintf(pMessage, "ERROR: argument required for %s",argv[0]);
SCWrite(pCon,pMessage,eError);
return 0;
}
@ -149,7 +149,7 @@
return 0;
}
/*----------------------------------------------------------------------*/
static void KillChoco(void *pData)
void KillChoco(void *pData)
{
pChoco self = NULL;

View File

@ -19,6 +19,7 @@
pCodri CHGetDriver(pChoco self);
int CHList(pChoco self, SConnection *pCon, char *name);
/*------------------------------------------------------------------------*/
void KillChoco(void *pData);
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,

View File

@ -85,7 +85,7 @@ controller driver.
\item[SetPar] tries to set the parameter parname to the value
fValue. The last is floating point which covers the frequent
occurence of numeric values.
\item[SetPar2] The same as SetPar but uses test string as input for
\item[SetPar2] The same as SetPar but uses text string as input for
parameter setting.
\item[GetPar] retrieves the parameter parname formatted as text. The
value is put into the buffer pBuffer. iBufLen is the maximum number of
@ -129,6 +129,7 @@ $\langle$chocoint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ pCodri CHGetDriver(pChoco self);@\\
\mbox{}\verb@ int CHList(pChoco self, SConnection *pCon, char *name);@\\
\mbox{}\verb@/*------------------------------------------------------------------------*/@\\
\mbox{}\verb@ void KillChoco(void *pData);@\\
\mbox{}\verb@ int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
@ -366,8 +367,7 @@ $\langle$evada {\footnotesize ?}$\rangle\equiv$
\subsubsection{To Do}
This scheme seems to be quite promising for handling many SICS
objects. The following enhancements could be considered. Allow to set
certain primitive parameters without a drivable interface. And add an
adapter for an environment variable in the controller.
certain primitive parameters without a drivable interface.

View File

@ -72,7 +72,7 @@ controller driver.
\item[SetPar] tries to set the parameter parname to the value
fValue. The last is floating point which covers the frequent
occurence of numeric values.
\item[SetPar2] The same as SetPar but uses test string as input for
\item[SetPar2] The same as SetPar but uses text string as input for
parameter setting.
\item[GetPar] retrieves the parameter parname formatted as text. The
value is put into the buffer pBuffer. iBufLen is the maximum number of
@ -111,6 +111,7 @@ includes:
pCodri CHGetDriver(pChoco self);
int CHList(pChoco self, SConnection *pCon, char *name);
/*------------------------------------------------------------------------*/
void KillChoco(void *pData);
int ChocoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ChocoFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
@ -267,8 +268,7 @@ controller driver:
\subsubsection{To Do}
This scheme seems to be quite promising for handling many SICS
objects. The following enhancements could be considered. Allow to set
certain primitive parameters without a drivable interface. And add an
adapter for an environment variable in the controller.
certain primitive parameters without a drivable interface.

View File

@ -65,6 +65,7 @@
#include "uubuffer.h"
#include "commandlog.h"
#include "stptok.h"
#include "sicshipadaba.h"
/*
#define UUDEB 1
@ -361,6 +362,7 @@ extern pServer pServ;
char pBueffel[132];
SConnection *pVictim = NULL;
Item sItem;
pHdb root = NULL;
pVictim = (SConnection *)pData;
if(!VerifyConnection(pVictim))
@ -388,6 +390,15 @@ extern pServer pServ;
*/
KillCapture(pVictim);
/*
* remove any callbacks which might still be active in the Hipadaba
*/
root = GetHipadabaRoot();
if(root != NULL)
{
InternalRemoveHipadabaCallback(root,pVictim->ident);
}
/*
If we have a grab, release it !
*/

258
devexec.c
View File

@ -9,6 +9,9 @@
revised for use with tasker: Mark Koennecke, September 1997
Locking added: Mark Koennecke, August 2002
Refactored and instrumentation for instrument staticstics added.
Mark Koennecke, July 2006
Copyright:
Labor fuer Neutronenstreuung
@ -39,10 +42,12 @@
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
-----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
#include "fortify.h"
#include "sics.h"
#include "nserver.h"
@ -52,11 +57,52 @@
#include "devexec.h"
#include "status.h"
#include "lld.h"
#include "commandlog.h"
#include "ifile.h"
/*
#define DEBUG 1
*/
/*======================== Logging stuff ==================================*/
static FILE *devLog = NULL;
/*-------------------------------------------------------------------------*/
int openDevexecLog(){
char *fileName = NULL;
char fileBuffer[1024];
if(devLog == NULL){
fileName = IFindOption(pSICSOptions,"devexeclog");
if(fileName != NULL){
strcpy(fileBuffer,fileName);
} else {
fileBuffer[0] = '\0';
fileName = getenv("HOME");
if(fileName != NULL){
strcpy(fileBuffer,fileName);
}
strcat(fileBuffer,"/log/devexec.log");
}
devLog = fopen(fileBuffer,"a+");
}
if(devLog == NULL){
return 0;
} else {
return 1;
}
}
/*-------------------------------------------------------------------------*/
void DevexecLog(char *operation, char *device) {
struct timeval tv;
struct timezone tm;
if(devLog != NULL){
gettimeofday(&tv,&tm);
fprintf(devLog, "DEVEXEC:%s:%s:%ld:%ld\n",operation,device,
tv.tv_sec, tv.tv_usec);
fflush(devLog);
}
}
/*======================== internal data structures =======================*/
typedef struct _DevEntry {
void *pData;
pObjectDescriptor pDescriptor;
@ -64,6 +110,13 @@
char *name;
commandContext comCon;
} DevEntry, *pDevEntry;
/*------------------------------------------------------------------------*/
typedef struct {
pExeList self;
pDevEntry pDev;
pICountable pCountInt;
pIDrivable pDrivInt;
}checkContext, *pCheckContext;
/*-------------------------------------------------------------------------*/
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
float fVal, char *name)
@ -111,6 +164,7 @@
int iLock;
pICallBack pCall;
time_t lastRun;
int paused;
} ExeList;
static pExeList pExecutor = NULL;
@ -167,6 +221,10 @@
free(self);
pServ->pExecutor = NULL;
if(devLog != NULL){
fclose(devLog);
devLog = NULL;
}
}
/*--------------------------------------------------------------------------*/
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
@ -284,6 +342,7 @@
self->iEnd = 0;
pCon->conStatus = HWBusy;
}
DevexecLog("START",pNew->name);
return 1;
}
else
@ -386,7 +445,7 @@
pCon,pCter->pDriv->fPreset);
}
/*--------------------------------------------------------------------------*/
int CheckExeList(pExeList self)
int CheckExeListOld(pExeList self)
{
int iRet;
pDevEntry pDev = NULL;
@ -402,7 +461,7 @@
/* Sometimes this gets called, though nothing is running. There are
cases where this is feasible for maintainance, but in some cases it
is pure rubbish, because nothing runs. This will ne checkd here.
is pure rubbish, because nothing runs. This will be checked here.
*/
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY))
{
@ -421,10 +480,7 @@
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
/*
SCSetContext(self->pOwner,pDev->cmdID,pDev->name);
*/
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
@ -560,6 +616,196 @@
return 0;
}
}
/*-------------------------------------------------------------------------*/
static int checkInterrupt(pCheckContext pCheck, int targetStatus){
if(SCGetInterrupt(pCheck->self->pOwner) != eContinue) {
pCheck->self->iStatus = DEVINT;
SCPopContext(pCheck->self->pOwner);
SetStatus(eEager);
return -1;
} else {
return targetStatus;
}
}
/*--------------------------------------------------------------------------*/
static int initializeCheck(pCheckContext pCheck, pDevEntry pDev){
int eCode;
SCPushContext(pCheck->self->pOwner,
pDev->comCon.transID, pDev->comCon.deviceID);
pCheck->pDev = pDev;
pCheck->pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCheck->pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCheck->pDrivInt != NULL){
eCode = pCheck->pDrivInt->CheckStatus(pDev->pData,pCheck->self->pOwner);
} else if(pCheck->pCountInt != NULL) {
eCode = pCheck->pCountInt->CheckCountStatus(pDev->pData,pCheck->self->pOwner);
}
return eCode;
}
/*--------------------------------------------------------------------------*/
static int finishDevice(pCheckContext pCheck){
int status;
if(pCheck->pCountInt != NULL) {
pCheck->pCountInt->TransferData(pCheck->pDev->pData,pCheck->self->pOwner);
} else if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount = 0;
}
ExeInterest(pCheck->self, pCheck->pDev, "finished");
DevexecLog("STOP",pCheck->pDev->name);
DeleteDevEntry(pCheck->pDev);
LLDnodeDelete(pCheck->self->iList);
status = LLDnodePtr2Prev(pCheck->self->iList);
SCWrite(pCheck->self->pOwner, "", eFinish);
pCheck->self->iStatus = DEVDONE;
return checkInterrupt(pCheck,status);
}
/*-------------------------------------------------------------------------*/
static int errorDevice(pCheckContext pCheck){
int status;
ExeInterest(pCheck->self, pCheck->pDev, "finished with problem");
DevexecLog("STOP",pCheck->pDev->name);
DeleteDevEntry(pCheck->pDev);
LLDnodeDelete(pCheck->self->iList);
status = LLDnodePtr2Prev(pCheck->self->iList);
SCWrite(pCheck->self->pOwner, "", eFinish);
pCheck->self->iStatus = DEVERROR;
if(pCheck->pDrivInt != NULL) {
pCheck->pDrivInt->iErrorCount++;
}
return checkInterrupt(pCheck,status);
}
/*-------------------------------------------------------------------------*/
static int testFinish(pExeList self){
if((self->pOwner == NULL) || (LLDcheck(self->iList) == LIST_EMPTY)) {
self->pOwner = NULL;
self->iRun = 0;
self->iEnd = 1;
self->iStop = 0;
self->lTask = -1;
return 1;
} else {
return 0;
}
}
/*--------------------------------------------------------------------------*/
int CheckExeList(pExeList self)
{
int iRet, status;
checkContext check;
pDevEntry pDev = NULL;
pICountable pCountInt = NULL;
pIDrivable pDrivInt = NULL;
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
/* Sometimes this gets called, though nothing is running. There are
cases where this is feasible for maintainance, but in some cases it
is pure rubbish, because nothing runs. This will be checked here.
*/
if(testFinish(self) == 1){
return 1;
}
/*
check the status of all registered devices. Remove when finished
*/
check.self = self;
status = LLDnodePtr2First(self->iList);
while(status != 0)
{
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
eCode = initializeCheck(&check,pDev);
if(eCode != HWNoBeam && eCode != HWPause && self->paused == 1){
DevexecLog("CONTINUE","ALL");
self->paused = 0;
}
switch(eCode)
{
case HWIdle:
case OKOK:
status = finishDevice(&check);
if(status < 0){
return status;
}
break;
case HWFault: /* real HW error: burning, no net etc.. */
status = errorDevice(&check);
if(status < 0){
return status;
}
break;
case HWNoBeam:
SetStatus(eOutOfBeam);
if(self->paused == 0){
self->paused = 1;
DevexecLog("NOBEAM","ALL");
}
status = checkInterrupt(&check,1);
if(status < 0){
return status;
}
break;
case HWPause:
SetStatus(ePaused);
if(self->paused == 0){
self->paused = 1;
DevexecLog("PAUSE","ALL");
}
status = checkInterrupt(&check,1);
if(status < 0){
/*
* continue in order to wait for devices to come to a stop
*/
ContinueExecution(self);
return status;
}
break;
case HWBusy:
if(check.pDrivInt != NULL)
{
isDriving = 1;
}
else if(check.pCountInt != NULL)
{
isCounting = 1;
}
self->iStatus = DEVBUSY;
break;
case HWPosFault: /* cannot get somewhere... */
status = errorDevice(&check);
if(status < 0){
return status;
}
break;
}
SCPopContext(self->pOwner);
}
status = LLDnodePtr2Next(self->iList);
}
if (isCounting) {
if (isDriving) {
SetStatus(eCountDrive);
} else {
SetStatus(eCounting);
}
} else if (isDriving) {
SetStatus(eDriving);
}
iRet = LLDnodePtr2First(self->iList);
return testFinish(self);
}
/*---------------------------------------------------------------------------*/
int Wait4Success(pExeList self)
{

View File

@ -171,5 +171,6 @@
pExeList GetExecutor(void);
void SetExecutor(pExeList pExe);
/*----------------------- Logging -----------------------------------------*/
void DevexecLog(char *op, char *device);
#endif

View File

@ -353,7 +353,8 @@ to the global SICS device executor.
\mbox{}\verb@ @\\
\mbox{}\verb@ pExeList GetExecutor(void);@\\
\mbox{}\verb@ void SetExecutor(pExeList pExe);@\\
\mbox{}\verb@ @\\
\mbox{}\verb@/*----------------------- Logging -----------------------------------------*/@\\
\mbox{}\verb@ void DevexecLog(char *op, char *device); @\\
\mbox{}\verb@#endif @\\
\mbox{}\verb@@$\diamond$
\end{list}

View File

@ -299,7 +299,8 @@ to the global SICS device executor.
pExeList GetExecutor(void);
void SetExecutor(pExeList pExe);
/*----------------------- Logging -----------------------------------------*/
void DevexecLog(char *op, char *device);
#endif
@}

View File

@ -387,7 +387,7 @@
}
else if(iRet == DEVINT)
{
sprintf(pBueffel,"Driving Interrupted!");
sprintf(pBueffel,"ERROR: Driving Interrupted!");
SCWrite(pCon,pBueffel,eError);
ClearExecutor(GetExecutor());
SetStatus(eOld);

View File

@ -71,13 +71,29 @@
static long EVIDrive(void *pData, SConnection *pCon, float fVal)
{
pEVControl self = NULL;
int iRet, iCode, i, iFix;
int iRet, iCode, i, iFix, savedStatus;
char pError[132], pBueffel[256];
Tcl_Interp *pTcl = NULL;
self = (pEVControl)pData;
assert(self);
assert(pCon);
if (self->runScript != NULL) {
savedStatus = GetStatus();
SetStatus(eBatch);
pTcl = InterpGetTcl(pServ->pSics);
snprintf(pBueffel, sizeof(pBueffel), "%s %f", self->runScript, fVal);
iRet = Tcl_Eval(pTcl,pBueffel);
SetStatus(savedStatus);
if(iRet != TCL_OK)
{
SCPrintf(pCon, eError,
"ERROR: %s while processing runscript for %s",
pTcl->result,self->pName);
}
}
self->fTarget = fVal;
self->eMode = EVDrive;
self->iStop = 0;
@ -848,6 +864,10 @@ static void ErrReport(pEVControl self)
{
free(self->creationArgs);
}
if (self->runScript != NULL)
{
free(self->runScript);
}
free(self);
}
/*--------------------------------------------------------------------------*/
@ -855,7 +875,7 @@ static void ErrReport(pEVControl self)
{
char pBueffel[256], pError[132];
int iRet;
assert(self);
assert(pCon);
@ -1025,7 +1045,14 @@ static void ErrReport(pEVControl self)
snprintf(pBueffel,255,"%s.errorScript = UNDEFINED", self->pName);
}
SCWrite(pCon,pBueffel, eValue);
if(self->runScript != NULL)
{
SCPrintf(pCon, eValue, "%s.runScript = %s", self->pName, self->runScript);
}
else
{
SCPrintf(pCon, eValue, "%s.runScript = none", self->pName);
}
return 1;
}
/*-------------------------------------------------------------------------*/
@ -1161,10 +1188,10 @@ static void ErrReport(pEVControl self)
}
else /* parameter request */
{
strtolower(argv[1]);
/*
catch case of errorScript
*/
strtolower(argv[1]);
if(strcmp(argv[1],"errorscript") == 0)
{
if(self->errorScript != NULL)
@ -1180,6 +1207,22 @@ static void ErrReport(pEVControl self)
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*
catch case of runScript
*/
if(strcmp(argv[1],"runscript") == 0)
{
if(self->runScript != NULL)
{
SCPrintf(pCon, eValue,"%s.runScript = %s",self->pName,
self->runScript);
}
else
{
SCPrintf(pCon, eValue,"%s.runScript = none",self->pName);
}
return 1;
}
/*
catch case for drivername
*/
@ -1208,10 +1251,10 @@ static void ErrReport(pEVControl self)
}
else /* try to set parameter */
{
strtolower(argv[1]);
/*
first catch case of errorScript
*/
strtolower(argv[1]);
if(strcmp(argv[1],"errorscript") == 0)
{
if(self->errorScript != NULL)
@ -1223,6 +1266,24 @@ static void ErrReport(pEVControl self)
SCparChange(pCon);
return 1;
}
/*
catch case of runScript
*/
if(strcmp(argv[1],"runscript") == 0)
{
if(self->runScript != NULL)
{
free(self->runScript);
}
if (strcasecmp(argv[2],"none") == 0) {
self->runScript = NULL;
} else {
self->runScript = Arg2Tcl(argc-2,&argv[2],NULL,0);
}
SCSendOK(pCon);
SCparChange(pCon);
return 1;
}
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
if(iRet != TCL_OK)
{
@ -1263,6 +1324,9 @@ static int EVSaveStatus(void *pData, char *name, FILE *fil)
if(evc->errorScript != NULL) {
fprintf(fil, " %s errorScript %s\n", evc->pName, evc->errorScript);
}
if(evc->runScript != NULL) {
fprintf(fil, " %s runScript %s\n", evc->pName, evc->runScript);
}
}
fprintf(fil, "}\n");
}

View File

@ -1,5 +1,5 @@
#line 227 "evcontroller.w"
#line 232 "evcontroller.w"
/*--------------------------------------------------------------------------
E N V I R O N M E N T C O N T R O L L E R
@ -14,7 +14,7 @@
#define SICSEVCONTROL
#include "varlog.h"
#line 148 "evcontroller.w"
#line 153 "evcontroller.w"
/*--------------------------- live & death --------------------------------*/
typedef struct __EVControl *pEVControl;
@ -45,6 +45,6 @@
#line 240 "evcontroller.w"
#line 245 "evcontroller.w"
#endif

View File

@ -1,5 +1,5 @@
#line 244 "evcontroller.w"
#line 249 "evcontroller.w"
/*-------------------------------------------------------------------------
Environment controller datastructure
@ -43,9 +43,10 @@
int iStop;
SCStore conn;
char *creationArgs;
char *runScript;
void *pPrivate;
void (*KillPrivate)(void *pData);
} EVControl;
#line 262 "evcontroller.w"
#line 267 "evcontroller.w"

View File

@ -54,6 +54,7 @@ $\langle$evdata {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ int iStop;@\\
\mbox{}\verb@ SCStore conn;@\\
\mbox{}\verb@ char *creationArgs;@\\
\mbox{}\verb@ char *runScript;@\\
\mbox{}\verb@ void *pPrivate;@\\
\mbox{}\verb@ void (*KillPrivate)(void *pData);@\\
\mbox{}\verb@ } EVControl;@\\
@ -88,6 +89,10 @@ holding the logging information. Then there is a switch, iWarned, which is
used to prevent execessive output on environment controller error handling.
iTcl is a boolean stating if the driver used is a proper C language driver
or a Tcl driver.
creationArgs are the arguments needed to recreate the device. runScript
is a script called on every run or drive command. This script is intended
to set control parameters depending on the targetValue. The script is
called with the target temperature as argument.
This is followed by the void pointer for use by a derived
class. KillPrivate is a pointer to a function capable of deleting pPrivate
properly.

View File

@ -49,6 +49,7 @@ used by EVControl:
int iStop;
SCStore conn;
char *creationArgs;
char *runScript;
void *pPrivate;
void (*KillPrivate)(void *pData);
} EVControl;
@ -76,6 +77,10 @@ holding the logging information. Then there is a switch, iWarned, which is
used to prevent execessive output on environment controller error handling.
iTcl is a boolean stating if the driver used is a proper C language driver
or a Tcl driver.
creationArgs are the arguments needed to recreate the device. runScript
is a script called on every run or drive command. This script is intended
to set control parameters depending on the targetValue. The script is
called with the target temperature as argument.
This is followed by the void pointer for use by a derived
class. KillPrivate is a pointer to a function capable of deleting pPrivate
properly.

View File

@ -1,5 +1,5 @@
#line 265 "evcontroller.w"
#line 270 "evcontroller.w"
/*-------------------------------------------------------------------------
Environment device driver datastructure
@ -12,7 +12,7 @@
#define DEVREDO 2
#line 87 "evcontroller.w"
#line 92 "evcontroller.w"
typedef struct __EVDriver {
int (*SetValue)(pEVDriver self, float fNew);
@ -31,7 +31,7 @@
void (*KillPrivate)(void *pData);
} EVDriver;
#line 276 "evcontroller.w"
#line 281 "evcontroller.w"
/*-------------------- life & death of a driver --------------------------*/
pEVDriver CreateEVDriver(int argc, char *argv[]);

2
exe.w
View File

@ -171,6 +171,8 @@ int MakeExeManager(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
char *name);
@}
@o exeman.i -d @{

View File

@ -1,5 +1,5 @@
#line 207 "exe.w"
#line 209 "exe.w"
/**
* Buffer handling code for the Exe Buffer batch file processing
@ -89,7 +89,7 @@
*/
char *exeBufName(pExeBuf self);
#line 220 "exe.w"
#line 222 "exe.w"
#endif

View File

@ -1,5 +1,5 @@
#line 198 "exe.w"
#line 200 "exe.w"
/*--------------------------------------------------------------------
Internal header file for the exe buffer module. Do not edit. This is
@ -16,6 +16,6 @@ typedef struct __EXEBUF{
int lineno;
} ExeBuf;
#line 203 "exe.w"
#line 205 "exe.w"

View File

@ -15,13 +15,13 @@
#include <ctype.h>
#include "fortify.h"
#include "sics.h"
#include "exebuf.h"
#include "exeman.h"
#include "sdynar.h"
#include "dynstring.h"
#include "lld.h"
#include "exeman.i"
#include "splitter.h"
#include "exebuf.h"
#include "exeman.i"
#include "exeman.h"
/*-------------------------------------------------------------------*/
static void KillExeMan(void *data){
@ -175,9 +175,9 @@ static pDynString locateBatchBuffer(pExeMan self, char *name){
DeleteDynString(result);
return NULL;
}
/*-------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
static int runBatchBuffer(pExeMan self, SConnection *pCon,
SicsInterp *pSics, char *name){
SicsInterp *pSics, char *name){
pDynString filePath = NULL;
char pBueffel[256];
pExeBuf buffer = NULL;
@ -214,6 +214,17 @@ static int runBatchBuffer(pExeMan self, SConnection *pCon,
self->exeStackPtr--;
return status;
}
/*-------------------------------------------------------------------*/
int runExeBatchBuffer(void *pData, SConnection *pCon,
SicsInterp *pSics, char *name){
int status, oldEcho;
pExeMan self = (pExeMan)pData;
oldEcho = self->echo;
self->echo = 1;
status = runBatchBuffer(self,pCon,pSics,name);
self->echo = oldEcho;
return status;
}
/*========================== path management ========================*/
static int handleBatchPath(pExeMan self, SConnection *pCon, int argc,
char *argv[]){
@ -374,6 +385,18 @@ static int startUpload(pExeMan self, SConnection *pCon){
}
return 1;
}
/*-------------------------------------------------------------------*/
static int clearUpload(pExeMan self, SConnection *pCon){
if(SCGetRights(pCon) > usUser){
SCWrite(pCon,"ERROR: no permission to clear buffer upload",eError);
return 0;
}
if(self->uploadBuffer != NULL){
exeBufDelete(self->uploadBuffer);
self->uploadBuffer = NULL;
}
return 1;
}
/*---------------------------------------------------------------------*/
static int appendLine(pExeMan self, SConnection *pCon,
int argc, char *argv[]){
@ -958,6 +981,12 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
SCSendOK(pCon);
}
return status;
}else if(strcmp(argv[1],"clearupload") == 0){
status = clearUpload(self,pCon);
if(status){
SCSendOK(pCon);
}
return status;
}else if(strcmp(argv[1],"info") == 0){
status = infoHandler(self,pCon,argc,argv);
return status;

View File

@ -13,5 +13,7 @@ int MakeExeManager(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics,
char *name);
#endif

View File

@ -1,5 +1,5 @@
#line 176 "exe.w"
#line 178 "exe.w"
/*-------------------------------------------------------------------
Internal header file for the exe manager module. Do not edit. This
@ -20,5 +20,5 @@ typedef struct __EXEMAN{
int echo;
}ExeMan, *pExeMan;
#line 181 "exe.w"
#line 183 "exe.w"

View File

@ -483,11 +483,34 @@ static int updateHMFMData(SicsInterp *pSics, SConnection *pCon)
return 1;
}
/*-------------------------------------------------------------------*/
static int *calculateSum(HistInt *data, int iDet, int iTime)
static int *calculateDetSum(HistInt *data, int iDet, int iTime)
{
int i, j, iIndex;
int *sum = NULL;
sum = (int *)malloc(iDet*sizeof(int));
if(!sum)
{
return NULL;
}
memset(sum,0,iDet*sizeof(int));
for(i = 0; i < iDet; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
{
sum[i] += data[iIndex+j];
}
}
return sum;
}
/*-------------------------------------------------------------------*/
static int *calculateTimeSum(HistInt *data, int iDet, int iTime)
{
int i, j;
int *sum = NULL;
sum = (int *)malloc(iTime*sizeof(int));
if(!sum)
{
@ -495,16 +518,16 @@ static int *calculateSum(HistInt *data, int iDet, int iTime)
}
memset(sum,0,iTime*sizeof(int));
for(i = 0; i < iDet; i++)
for(i = 0; i < iTime; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
for(j = 0; j < iDet; j++)
{
sum[i] += data[iIndex+j];
sum[i] += data[j*iTime + i];
}
}
return sum;
}
/*--------------------------------------------------------------------*/
static void checkSum(HistInt *sum, int iDet, char *name, SConnection *pCon){
int i, count;
@ -557,7 +580,7 @@ static int putSum(SicsInterp *pSics, SConnection *pCon,
return NX_ERROR;
}
sum = calculateSum(data,iDet,iTime);
sum = calculateDetSum(data,iDet,iTime);
if(!sum)
{
SCWrite(pCon,"ERROR: out of memory summing bank",eError);
@ -592,7 +615,7 @@ static int putElastic(SicsInterp *pSics, SConnection *pCon,
}
fTimeBin = GetHistTimeBin(pMem,&iTime);
iDet = getFMdim(MIDDLE);
sum = calculateSum(GetHistogramPointer(pMem,pCon),iDet,iTime);
sum = calculateTimeSum(GetHistogramPointer(pMem,pCon),iDet,iTime);
if(!sum)
{
SCWrite(pCon,"ERROR: out of memory calculating elastic peak position",

View File

@ -11,14 +11,14 @@
#ifndef FOURTABLE
#define FOURTABLE
int MakeFourCircleTable(void);
int MakeFourCircleTable();
void DeleteFourCircleTable(int handle);
int HandleFourCircleCommands(int *table, SConnection *pCon,
int HandleFourCircleCommands(int *handle, SConnection *pCon,
int argc, char *argv[], int *err);
char *GetFourCircleScanVar(int handle, double two_theta);
int GetFourCircleScanNP(int handle, double two_theta);
double GetFourCircleStep(int handle, double two_theta);
float GetFourCirclePreset(int handle, double two_theta);
int SaveFourCircleTable(int handle, char *objName, FILE *fd);
float GetFourCirclePreset(int handle, double twoTheta);
int GetFourCircleScanNP(int handle, double twoTheta);
#endif

View File

@ -70,7 +70,7 @@
return 0;
fprintf(fd,"%s length %f\n",name, self->length);
fprintf(fd,"%s zero %f\n",name, self->zero);
fprintf(fd,"%s softzero %f\n",name, self->zero);
return 1;
}
@ -275,20 +275,20 @@
}
}
/* zero point */
if(strcmp(argv[1],"zero") == 0)
if(strcmp(argv[1],"softzero") == 0)
{
if(argc >= 3)
{
iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&dVal);
if(iRet != TCL_OK)
{
SCWrite(pCon,"ERROR: zero parameter not recognised as number",
SCWrite(pCon,"ERROR: softzero parameter not recognised as number",
eError);
return 0;
}
if(!SCMatchRights(pCon,usUser))
{
SCWrite(pCon,"ERROR: Insufficient privilege to change zero point",
SCWrite(pCon,"ERROR: Insufficient privilege to change softzero point",
eError);
return 0;
}
@ -298,7 +298,7 @@
}
else
{
sprintf(pBueffel,"%s.zero = %f",argv[0],self->zero);
sprintf(pBueffel,"%s.softzero = %f",argv[0],self->zero);
SCWrite(pCon,pBueffel,eValue);
return 1;
}

4
lld.c
View File

@ -208,6 +208,10 @@ void LLDdelete( int List )
assert( (unsigned) List < ListCount );
if(ListControl == NULL)
{
return;
}
Tmp = ListControl[ List ].first ; /* dummies are also deleted !!! */
while( NULL != Tmp ) /* still assuming last node has */
{ /* a NULL next pointer ... */

68
macro.c
View File

@ -61,16 +61,15 @@
#include <string.h>
#include <stdio.h>
#include <tcl.h>
#include "SCinter.h"
#include "conman.h"
#include "macro.h"
#include <sics.h>
#include "status.h"
#include "obdes.h"
#include "macro.h"
#include "splitter.h"
#include "ifile.h"
#include "Dbg.h"
#include "servlog.h"
#include "stringdict.h"
#include "exeman.h"
#define SICSERROR "005567SICS"
/*----------------------------------------------------------------------------
@ -131,7 +130,8 @@
char *lastCommand = NULL, comBuffer[132];
int iRet = 0,i;
int iMacro;
Statistics *old;
/* get the datastructures */
pSics = (struct __SicsUnknown *)pData;
assert(pSics);
@ -180,7 +180,9 @@
/* invoke */
iMacro = SCinMacro(pCon);
SCsetMacro(pCon,1);
old=StatisticsBegin(pCommand->stat);
iRet = pCommand->OFunc(pCon,pSinter,pCommand->pData,margc, myarg);
StatisticsEnd(old);
SCsetMacro(pCon,iMacro);
/*
lastUnkown gets deeply stacked with each SICS command exec'd.
@ -431,6 +433,21 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
}
/*--------------------------------------------------------------------------*/
int MacroFileEvalNew(SConnection *pCon, SicsInterp *pInter, void *pData,
int argc, char *argv[])
{
void *pCom = NULL;
pCom = FindCommandData(pInter,"exe","ExeManager");
assert(pCom != NULL);
if(argc < 2){
SCWrite(pCon,"ERROR: no batch buffer to execute specified",
eError);
return 0;
}
return runExeBatchBuffer(pCom,pCon,pInter,argv[1]);
}
/*----------------------------------------------------------------------*/
int MacroFileEval(SConnection *pCon, SicsInterp *pInter, void *pData,
int argc, char *argv[])
{
@ -459,8 +476,8 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
/* open filename */
if( argc < 2)
{
SCWrite(pCon,"ERROR: No filename specified ",eError);
return 0;
SCWrite(pCon,"ERROR: No filename specified ",eError);
return 0;
}
fp = fopen(argv[1],"r");
if(!fp)
@ -490,7 +507,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
{
iChar = fgetc(fp);
if(iChar == EOF)
{
{
iChar = (int)'\n';
iRun = 0;
}
@ -505,11 +522,11 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
SetStatus(eEager);
FirstWord(pCom,pBueffel);
if(FindCommand(pInter,pBueffel) != NULL)
{
{
sprintf(pBueffel,"%s:%d>> %s",pFile,iLine,pCom);
SCWrite(pCon,pBueffel,eValue);
if(pWhere != NULL)
{
{
free(pWhere);
}
pWhere = strdup(pBueffel);
@ -524,16 +541,16 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
{ /* Tcl error */
if(strlen(pTcl->result) > 2)
{
/*
local copy in order to resolve a valgrind error
*/
strncpy(pBueffel,pTcl->result,511);
/*
local copy in order to resolve a valgrind error
*/
strncpy(pBueffel,pTcl->result,511);
SCWrite(pCon,pBueffel,eError);
}
pCom = Tcl_DStringValue(&command);
SCWrite(pCon,"ERROR: in Tcl block:",eError);
SCWrite(pCon,"ERROR: in Tcl block:",eError);
SCWrite(pCon,pCom,eError);
SCWrite(pCon,"ERROR: end of Tcl error block",eError);
SCWrite(pCon,"ERROR: end of Tcl error block",eError);
}
else /* SICS error */
{
@ -546,7 +563,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
fclose(fp);
Tcl_DStringFree(&command);
SCWrite(pCon,"ERROR: batch processing interrupted",eError);
SetStatus(eEager);
SetStatus(eEager);
return 0;
}
else
@ -865,7 +882,7 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
}
/* make a string */
pCommand = Arg2Tcl(argc,argv,pBueffel,sizeof(pBueffel));
pCommand = Arg2Tcl0(argc-1,argv+1,pBueffel,sizeof(pBueffel),self->command);
if (!pCommand) {
SCWrite(pCon, "ERROR: no more memory", eError);
return 0;
@ -895,8 +912,6 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
}
return 1; /* not reached */
}
#include "access.c"
/*--------------------------------------------------------------------------*/
int TclPublish(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -924,17 +939,8 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
}
/* try convert last parameter to user code */
iUser = 0;
strtolower(argv[2]);
while(aCode[iUser] != NULL)
{
if(strcmp(aCode[iUser],argv[2]) == 0)
{
break;
}
iUser++;
}
if(iUser > iCodes)
iUser = decodeSICSPriv(argv[2]);
if(iUser < 0)
{
sprintf(pBueffel,"ERROR: cannot identify %s as a valid user code",
argv[2]);

View File

@ -8,7 +8,7 @@
COBJ = Sclient.o network.o ifile.o intcli.o $(FORTIFYOBJ)
SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
servlog.o sicvar.o nserver.o SICSmain.o motorlist.o\
sicsexit.o costa.o task.o $(FORTIFYOBJ)\
sicsexit.o costa.o task.o $(FORTIFYOBJ) access.o\
macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \
devexec.o mumo.o mumoconf.o selector.o selvar.o fupa.o lld.o \
lld_blob.o strrepl.o lin2ang.o fomerge.o napi4.o napi5.o \
@ -30,7 +30,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
sinfox.o sicslist.o cone.o
sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o
MOTOROBJ = motor.o simdriv.o
COUNTEROBJ = countdriv.o simcter.o counter.o

View File

@ -32,6 +32,7 @@
#include "nxscript.h"
#include "fourtable.h"
#include "lld.h"
#include "stdscan.h"
extern void SNXFormatTime(char *pBueffel, int iLen);
extern float nintf(float f);
@ -65,6 +66,7 @@
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 */
@ -146,7 +148,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMotor pOmega,
char *pOm, pMotor p2Theta, char *p2t,
char *pFileRoot,
pDataNumber pDanu)
pDataNumber pDanu, char *hdTemplate)
{
pMesure pNew = NULL;
@ -197,7 +199,8 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
pNew->lCounts = (long *)malloc(90*sizeof(long));
#endif
pNew->lCounts = (long *)malloc(50*sizeof(long));
pNew->stepTable = MakeFourCircleTable();
pNew->stepTable = MakeFourCircleTable();
strncpy(pNew->headerTemplate,hdTemplate,511);
return pNew;
}
/*------------------------------------------------------------------------*/
@ -249,7 +252,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
/* check no of parameters
inicom name hkl scan omega root danu
*/
if(argc < 8)
if(argc < 9)
{
SCWrite(pCon,
"ERROR: Insufficient number of parameters to MesureFactory",eError);
@ -336,7 +339,7 @@ static void ListMesure(pMesure self, char *name, SConnection *pCon)
/* finally create the thing */
pNew = CreateMesure(pCryst,pScan,pMot,argv[4], pMot2, argv[5],
argv[6],pDanu);
argv[6],pDanu,argv[8]);
if(!pNew)
{
SCWrite(pCon,"ERROR: no memory in MesureFactory",eError);
@ -759,7 +762,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
char *pFile = NULL, *pPtr;
float zero, pos;
pMotor pMot = NULL;
FILE *temp = NULL;
assert(self);
assert(pCon);
@ -813,6 +816,19 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
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);
@ -855,59 +871,6 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon)
sprintf(pBuff,"user = %s",pVar->text);
strcat(pBueffel,pBuff);
}
fprintf(self->fRefl,"%s\n",pBueffel);
fprintf(self->fRefl,"lambda = %f Angstroem\n",fVal);
fprintf(self->fRefl,
"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]);
/*
* zero points for Juerg
*/
pBueffel[0] = '\0';
if(self->pCryst->pTheta != NULL){
MotorGetPar(self->pCryst->pTheta,"softzero",&zero);
snprintf(pBuff,131,"stt.zero = %f ", zero);
strcat(pBueffel,pBuff);
}
if(self->pCryst->pOmega != NULL){
MotorGetPar(self->pCryst->pOmega,"softzero",&zero);
snprintf(pBuff,131,"om.zero = %f ", zero);
strcat(pBueffel,pBuff);
}
if(self->pCryst->pChi != NULL){
MotorGetPar(self->pCryst->pChi,"softzero",&zero);
snprintf(pBuff,131,"chi.zero = %f ", zero);
strcat(pBueffel,pBuff);
}
if(self->pCryst->pPhi != NULL){
MotorGetPar(self->pCryst->pPhi,"softzero",&zero);
snprintf(pBuff,131,"phi.zero = %f ", zero);
strcat(pBueffel,pBuff);
}
fprintf(self->fRefl,"%s\n",pBueffel);
/*
* CEX motors ....
*/
pBueffel[0] = '\0';
pMot = FindCommandData(pServ->pSics,"cex1","Motor");
if(pMot != NULL){
MotorGetSoftPosition(pMot,pCon,&pos);
snprintf(pBuff,131,"cex1 = %f ",pos);
strcat(pBueffel,pBuff);
}
pMot = FindCommandData(pServ->pSics,"cex2","Motor");
if(pMot != NULL){
MotorGetSoftPosition(pMot,pCon,&pos);
snprintf(pBuff,131,"cex2 = %f ",pos);
strcat(pBueffel,pBuff);
}
if(strlen(pBueffel) > 1) {
fprintf(self->fRefl,"%s\n",pBueffel);
}
return 1;
}
/*---------------------------------------------------------------------------*/

View File

@ -17,8 +17,8 @@
/*--------------------- live & death --------------------------------------*/
pMesure CreateMesure(pHKL pCryst, pScanData pScanner,
pMotor pOmega, char *pom,
pMotor p2Theta, char *p2t,
char *pFileRoot,pDataNumber pDanu);
pMotor p2Theta, char *p2t,
char *pFileRoot,pDataNumber pDanu, char *headerTemplate);
void DeleteMesure(void *pData);
int MesureFactory(SConnection *pCon, SicsInterp *pSics, void *pData,

View File

@ -30,7 +30,8 @@ $\langle$mesureint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@/*--------------------- live & death --------------------------------------*/@\\
\mbox{}\verb@ pMesure CreateMesure(pHKL pCryst, pScanData pScanner, @\\
\mbox{}\verb@ pMotor pOmega, char *pom,@\\
\mbox{}\verb@ char *pFileRoot,pDataNumber pDanu);@\\
\mbox{}\verb@ pMotor p2Theta, char *p2t,@\\
\mbox{}\verb@ char *pFileRoot,pDataNumber pDanu, char *headerTemplate);@\\
\mbox{}\verb@ void DeleteMesure(void *pData);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int MesureFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
@ -117,11 +118,13 @@ $\langle$fourtableint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@@\\
\mbox{}\verb@ int MakeFourCircleTable();@\\
\mbox{}\verb@ void DeleteFourCircleTable(int handle);@\\
\mbox{}\verb@ int HandleFourCircleCommands(int handle, SConnection *pCon, @\\
\mbox{}\verb@ int HandleFourCircleCommands(int *handle, SConnection *pCon, @\\
\mbox{}\verb@ int argc, char *argv[], int *err);@\\
\mbox{}\verb@ char *GetFourCircleScanVar(int handle, double two_theta);@\\
\mbox{}\verb@ double GetFourCircleStep(int handle, double two_theta);@\\
\mbox{}\verb@ int SaveFourCircleTable(int handle, char *objName, FILE *fd);@\\
\mbox{}\verb@ float GetFourCirclePreset(int handle, double twoTheta);@\\
\mbox{}\verb@ int GetFourCircleScanNP(int handle, double twoTheta);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}

View File

@ -26,7 +26,7 @@ The interface to this object consists of these functions:
pMesure CreateMesure(pHKL pCryst, pScanData pScanner,
pMotor pOmega, char *pom,
pMotor p2Theta, char *p2t,
char *pFileRoot,pDataNumber pDanu);
char *pFileRoot,pDataNumber pDanu, char *headerTemplate);
void DeleteMesure(void *pData);
int MesureFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
@ -100,11 +100,13 @@ interface to this module is:
@d fourtableint @{
int MakeFourCircleTable();
void DeleteFourCircleTable(int handle);
int HandleFourCircleCommands(int handle, SConnection *pCon,
int HandleFourCircleCommands(int *handle, SConnection *pCon,
int argc, char *argv[], int *err);
char *GetFourCircleScanVar(int handle, double two_theta);
double GetFourCircleStep(int handle, double two_theta);
int SaveFourCircleTable(int handle, char *objName, FILE *fd);
float GetFourCirclePreset(int handle, double twoTheta);
int GetFourCircleScanNP(int handle, double twoTheta);
@}
Many functions takes as the first argument a handle to the four circle table as
created by MakeFourCircleTable.

View File

@ -492,6 +492,8 @@ extern void KillPiPiezo(void *pData);
pM = (pMotor)self;
/* MotorHalt(pM); */
if(pM->name)
free(pM->name);

View File

@ -83,7 +83,7 @@ static long MOLISetValue(void *data, SConnection *pCon, float val){
return test;
} else {
tuktuk.running = 1;
LLDnodeDataFrom(self,&tuktuk);
LLDnodeDataFrom(self,&tuktuk);
}
iRet = LLDnodePtr2Next(self);
}

View File

@ -35,6 +35,7 @@
#include "site.h"
#include "tcldrivable.h"
#include "nserver.h"
#include "sicshipadaba.h"
int ServerSetupInterrupt(int iPort, pNetRead pNet, pTaskMan pTasker);
/*
@ -42,6 +43,8 @@
*/
extern void StopExit(void); /* in SICSmain.c */
extern int openDevexecLog(); /* in devexec.c */
/* ========================= Less dreadful file statics =================== */
#define DEFAULTINIFILE "servo.tcl"
@ -215,6 +218,8 @@
assert(pCom);
assert(pCom->pData);
self->pExecutor = (pExeList)pCom->pData;
openDevexecLog();
DevexecLog("START","SICS");
/* initialize Interrupt Port */
@ -304,6 +309,7 @@
/* clear all pending bullshit */
ClearExecutor(self->pExecutor);
DevexecLog("STOP","SICS");
/* shut telnet down */
KillTelnet();
@ -396,6 +402,7 @@
KillFreeConnections();
killSICSHipadaba();
/* make fortify print his findings */
Fortify_DumpAllMemory(iFortifyScope);

View File

@ -394,10 +394,12 @@ static void updateHMDim(NXScript *self, pHistMem mem){
timeBin = GetHistTimeBin(mem,&timeLength);
if(timeLength > 2){
sprintf(dummy,"%d",timeLength);
status = NXDupdate(self->dictHandle,"timedim",dummy);
if(status == 0) {
NXDadd(self->dictHandle,"timedim",dummy);
}
} else {
sprintf(dummy,"%d",1);
}
status = NXDupdate(self->dictHandle,"timedim",dummy);
if(status == 0) {
NXDadd(self->dictHandle,"timedim",dummy);
}
}
/*----------------------------------------------------------------------

10
obdes.c
View File

@ -44,6 +44,7 @@
#include "obdes.h"
#include "conman.h"
#include "servlog.h"
#include "hipadaba.h"
/*-------------------------------------------------------------------------*/
static void *DefaultGetInterface(void *pData,int iID)
@ -67,6 +68,7 @@
}
pRes->name = strdup(name);
pRes->pKeys = NULL;
pRes->parNode = NULL;
pRes->SaveStatus = DefaultSave;
pRes->GetInterface = DefaultGetInterface;
return pRes;
@ -77,6 +79,14 @@
assert(self);
if(self->name) free(self->name);
if(self->pKeys) IFDeleteOptions(self->pKeys);
/*
* delate a parameter node only when not linked elsewhere
*/
if(self->parNode != NULL){
if(self->parNode->mama == NULL){
DeleteHipadabaNode(self->parNode);
}
}
free(self);
}

View File

@ -23,12 +23,14 @@
#define SICSDESCRIPTOR
#include <stdio.h>
#include <ifile.h>
#include <hipadaba.h>
typedef struct {
char *name;
int (*SaveStatus)(void *self, char *name,FILE *fd);
void *(*GetInterface)(void *self, int iInterfaceID);
IPair *pKeys;
pHdb parNode;
} ObjectDescriptor, *pObjectDescriptor;
/*---------------------------------------------------------------------------*/

17
ofac.c
View File

@ -118,6 +118,7 @@
#include "sinfox.h"
#include "sicslist.h"
#include "cone.h"
#include "sicshipadaba.h"
/*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -207,8 +208,11 @@
/* permanent commands */
AddCommand(pInter,"Sics_Exitus",SicsExit,NULL,NULL);
AddCommand(pInter,"FileEval",MacroFileEval,NULL,NULL);
AddCommand(pInter,"InternEval",InternalFileEval,NULL,NULL);
/*
AddCommand(pInter,"FileWhere",MacroWhere,WhereKill,NULL);
*/
AddCommand(pInter,"ClientPut",ClientPut,NULL,NULL);
AddCommand(pInter,"broadcast",Broadcast,NULL,NULL);
AddCommand(pInter,"transact",TransactAction,NULL,NULL);
@ -242,6 +246,7 @@
AddCommand(pInter,"scriptcallback",CallbackScript,NULL,NULL);
AddCommand(pInter,"help",SicsHelp,KillHelp,NULL);
AddCommand(pInter,"list",SicsList,NULL,NULL);
AddCommand(pInter,"InstallHdb",InstallSICSHipadaba,NULL,NULL);
/* commands to do with the executor. Only StopExe carries the
DeleteFunction in order to avoid double deletion. All the
@ -371,7 +376,7 @@
RemoveCommand(pSics,"MakeLin2Ang");
RemoveCommand(pSics,"MakeSync");
RemoveCommand(pSics,"MakeHMControl");
/* RemoveCommand(pSics,"MakeRS232Controller"); */
RemoveCommand(pSics,"MakeRS232Controller");
RemoveCommand(pSics,"MakeMaxDetector");
RemoveCommand(pSics,"AntiColliderInstall");
RemoveCommand(pSics,"MakeGPIB");
@ -407,6 +412,7 @@
/* insert here initialization routines ... */
INIT(SiteInit); /* site specific initializations */
INIT(StatisticsInit);
}
/*--------------------------------------------------------------------------*/
@ -423,18 +429,15 @@
InitGeneral();
/* general initialization */
InitIniCommands(pSics,pServ->pTasker);
/* create a connection */
pCon = SCCreateDummyConnection(pSics);
if(!pCon)
{
return 0;
}
/* removed (gives double output to stdout)
pCon->iFiles = 1;
pCon->pFiles[0] = stdout;
*/
MakeExeManager(pCon,pSics,NULL,1, NULL);
InitIniCommands(pSics,pServ->pTasker);
pCon->iFiles = 0;
/* evaluate the file */

View File

@ -22,6 +22,7 @@
#include "scan.i"
#include "fitcenter.h"
#include "optimise.h"
#include "stdscan.h"
#ifdef CYGNUS
#define MAXFLOAT 9999999.99
@ -83,7 +84,6 @@
{
return 1;
}
/*------------------------------------------------------------------------*/
pOptimise CreateOptimiser(pCounter pCount)
@ -466,6 +466,197 @@
return iReturn;
}
/*------------------------------------------------------------------------
* We use the scan object here for counting. The reason is that this
* handles well in the common case of a single counter but also has
* provisions for other counting methods through the scan modules
* scripting mechanism
* ------------------------------------------------------------------------*/
static long ClimbCount(pOptimise self, SConnection *pCon)
{
int status;
long data[1];
int (*CollectFunc)(pScanData self, int iPoint) = NULL;
SilentPrepare(self->pScanner);
status = self->pScanner->ScanCount(self->pScanner,0);
if(status != 1)
{
return status;
}
if(self->pScanner->CollectScanData == CollectScanData)
{
CollectFunc = self->pScanner->CollectScanData;
self->pScanner->CollectScanData = CollectSilent;
}
status = self->pScanner->CollectScanData(self->pScanner,0);
if(CollectFunc != NULL)
{
self->pScanner->CollectScanData = CollectFunc;
}
if(status != 1)
{
return status;
}
GetScanCounts(self->pScanner,data,1);
return data[0];
}
/*------------------------------------------------------------------------*/
static int ClimbDrive(SConnection *pCon,char *name, float value)
{
int status;
status = Start2Run(pCon,pServ->pSics,name,value);
if(status != 1)
{
return DRIVEERROR;
}
status = Wait4Success(GetExecutor());
if(status != DEVDONE)
{
return DRIVEERROR;
}
return 1;
}
/*-------------------------------------------------------------------------*/
static int ClimbVariable(pOptimise self, SConnection *pCon, int i)
{
pOVarEntry pOvar;
void *pData;
int status, direction = 1;
long oneCount, twoCount, lastCount, currentCount;
float varValue, startValue;
char buffer[256];
int (*CollectFunc)(pScanData self, int iPoint) = NULL;
assert(self);
assert( (i >= 0) && (i < self->iVar));
assert(pCon);
/* get variable data */
DynarGet(self->pVariables,i,&pData);
pOvar = (pOVarEntry)pData;
startValue = pOvar->fCenter;
/*
* prepare scan object
*/
self->pScanner->pCon = pCon;
self->pScanner->pSics = pServ->pSics;
self->pScanner->iNP = 1;
self->pScanner->iMode = self->eCount;
self->pScanner->fPreset = self->fPreset;
/*
* test for upwards direction
*/
varValue = pOvar->fCenter + pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
oneCount = ClimbCount(self,pCon);
if(oneCount < 0)
{
return SCANERROR;
}
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
varValue = pOvar->fCenter - pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
twoCount = ClimbCount(self,pCon);
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
if(twoCount < 0)
{
return SCANERROR;
}
if(oneCount > twoCount)
{
direction = 1;
lastCount = oneCount;
}
else
{
direction = -1;
lastCount = twoCount;
}
/*
* drive to the last best position
*/
varValue = pOvar->fCenter + direction*pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
currentCount = lastCount;
/*
* climb upwards as long as possible
*/
while(1)
{
pOvar->fCenter = varValue;
varValue = pOvar->fCenter + direction * pOvar->fStep;
status = ClimbDrive(pCon,pOvar->pName,varValue);
if(!status)
{
return DRIVEERROR;
}
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
currentCount = ClimbCount(self,pCon);
if(currentCount < 0)
{
return SCANERROR;
}
if(SCGetInterrupt(pCon) != eContinue)
{
return SCANABORT;
}
snprintf(buffer,255,"Climbing %s, value = %f, count = %ld",
pOvar->pName, varValue, currentCount);
SCWrite(pCon,buffer,eWarning);
if(currentCount <= lastCount)
{
/*
* we are finished. Drive to previous position and
* break
*/
status = ClimbDrive(pCon,pOvar->pName,pOvar->fCenter);
if(!status)
{
return DRIVEERROR;
}
break;
}
else
{
/*
* go on, we are not over the top yet
*/
lastCount = currentCount;
}
}
pOvar->fShift = ABS(startValue - pOvar->fCenter);
return 1;
}
/*---------------------------------------------------------------------------*/
static int CheckSuccess(pOptimise self)
{
@ -530,6 +721,45 @@
}
return MAXCYCLE;
}
/*---------------------------------------------------------------------------*/
int OptimiserClimb(pOptimise self, SConnection *pCon)
{
int i, iRet, iCycle, iRedoVar = 0;
char pBueffel[256];
assert(self);
if(self->iVar < 1)
{
SCWrite(pCon,"ERROR: Nothing to optimise",eError);
return 0;
}
iRet = OptimiserInit(self,pCon);
if(!iRet)
{
return iRet;
}
for(iCycle = 0; iCycle < self->iMaxCycles; iCycle++)
{
sprintf(pBueffel,"Optimiser cycle %d of %d started",iCycle, self->iMaxCycles);
SCWrite(pCon,pBueffel,eStatus);
for(i = iRedoVar; i < self->iVar; i++)
{
iRet = ClimbVariable(self,pCon,i);
if(iRet <= 0)
{
return iRet;
}
}
iRet = CheckSuccess(self);
if(iRet)
{
return 1;
}
}
return MAXCYCLE;
}
/*--------------------------------------------------------------------------*/
int MakeOptimiser(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -717,6 +947,52 @@
break;
}
}
/*-------- climb */
else if(strcmp(argv[1],"climb") == 0)
{
/* check rights */
if(!SCMatchRights(pCon,usUser))
{
SCWrite(pCon,"ERROR: You are not aurhorised to do this!",eError);
return 0;
}
iRet = OptimiserClimb(self,pCon);
switch(iRet)
{
case PEAKLOST:
SCWrite(pCon,"ERROR: lost the peak, sorry!",eError);
return 0;
break;
case MAXCYCLE:
sprintf(pBueffel,"ERROR: could not optimise peak in %d cycles",
self->iMaxCycles);
SCWrite(pCon,pBueffel,eError);
return 0;
break;
case SCANERROR:
SCWrite(pCon,"ERROR: failed to scan the peak",eError);
return 0;
break;
case SCANABORT:
SCWrite(pCon,"ERROR: Scan was aborted, Optimiser follows",eError);
return 0;
break;
case DRIVEERROR:
SCWrite(pCon,"ERROR: Failure to drive variable to new position",eError);
return 0;
break;
case 1:
SCWrite(pCon,"At long last, I finished optimising the peak",eValue);
return 1;
break;
default:
SCWrite(pCon,"ERROR: Unidentified error krept into Optimiser",eError);
return 0;
break;
}
SCWrite(pCon,"Optimiser climbed successfully",eValue);
return 1;
}
/* ------ count mode */
if(strcmp(argv[1],"countmode") == 0)
{

View File

@ -170,7 +170,6 @@ static int StartOscillation(pOscillator self, SConnection *pCon){
static void KillOscillator(void *data){
pOscillator self = (pOscillator)data;
if(self != NULL){
StopOscillation(self);
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}

View File

@ -552,7 +552,11 @@ int SCWriteSycamore(SConnection *pCon, char *pBuffer, int iOut)
if (iOut == eEvent) {
DynStringConcat(pMsgString, " type=");
DynStringConcat(pMsgString, pEventType[pCon->conEventType]);
/* Default type to VALUECHANGE if conEventType not set */
if (-1 == pCon->conEventType)
DynStringConcat(pMsgString, pEventType[0]);
else
DynStringConcat(pMsgString, pEventType[pCon->conEventType]);
/* DynStringConcat(pMsgString, " status=");
DynStringConcat(pMsgString, pStatus[pCon->conStatus]);*/
}

View File

@ -534,7 +534,6 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
float fValue;
long lID;
char *endp;
char *argv0;
char *cmd;
/*
char acce[128], inte[128];
@ -559,10 +558,7 @@ int RemobAction(SConnection *pCon, SicsInterp *pSics, void *pData,
snprintf(inte, sizeof(inte), "!%s.interruptmode", remob->name);
*/
argv0 = argv[0];
argv[0] = remob->name;
cmd = Arg2Tcl(argc, argv, buf, sizeof buf);
argv[0] = argv0;
cmd = Arg2Tcl0(argc-1, argv+1, buf, sizeof buf, remob->name);
if (cmd) {
RemTransact(remserver, rc, pCon, cmd, ">", NULL);
if (cmd != buf) free(cmd);

View File

@ -52,6 +52,7 @@ $\langle$scanvar {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ float fStep;@\\
\mbox{}\verb@ float *fData;@\\
\mbox{}\verb@ int dataList;@\\
\mbox{}\verb@ int logVar;@\\
\mbox{}\verb@ }VarEntry, *pVarEntry;@\\
\mbox{}\verb@@$\diamond$
\end{list}
@ -88,6 +89,14 @@ $\langle$scanvarint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char@\\
\mbox{}\verb@ *name, float start, float step);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * make a variable which is logged during the scan but not driven.@\\
\mbox{}\verb@ * @{\tt @}\verb@param pSics The interpreter in order to locate the variable.@\\
\mbox{}\verb@ * @{\tt @}\verb@param pCon A connection object for error reporting@\\
\mbox{}\verb@ * @{\tt @}\verb@param name The name of the variable to log@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ pVarEntry MakeLogVar(SicsInterp *pSics, @\\
\mbox{}\verb@ SConnection *pCon, char *name);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * InitScanVar clears the list of scan points@\\
\mbox{}\verb@ * @{\tt @}\verb@param pvar The scna variable to clear@\\
\mbox{}\verb@ */@\\
@ -145,6 +154,21 @@ $\langle$scanvarint {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ * @{\tt @}\verb@param np The number of slots in fData.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ void CopyScanVar(pVarEntry pVar, float *fData, int np);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * CheckScanVar checks if the scan variable can be driven through the@\\
\mbox{}\verb@ * whole range.@\\
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to check@\\
\mbox{}\verb@ * @{\tt @}\verb@param pCon The connection object to which to report errors.@\\
\mbox{}\verb@ * @{\tt @}\verb@param np The number of points to check for.@\\
\mbox{}\verb@ * @{\tt @}\verb@return 0 on failuyre, 1 on success@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int CheckScanVar(pVarEntry pVar, SConnection *pCon, int np);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * queries if the variable is alogged variable or a drive one.@\\
\mbox{}\verb@ * @{\tt @}\verb@param pVar The variable to query.@\\
\mbox{}\verb@ * @{\tt @}\verb@return 1 if log var, 0 else@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int isLogVar(pVarEntry pVar);@\\
\mbox{}\verb@@$\diamond$
\end{list}
\vspace{-1ex}
@ -451,6 +475,15 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$
\begin{list}{}{} \item
\mbox{}\verb@@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * make a filename according to SICS rules for this scan@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ char *ScanMakeFileName(SicsInterp *pSics, SConnection *pCon);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ * write the header bits from the template@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ void WriteTemplate(FILE *fd, FILE *temp, char *filename, pScanData pScan, @\\
\mbox{}\verb@ SConnection *pCon, SicsInterp *pSics);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * write the header of the scan file@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int WriteHeader(pScanData self);@\\
@ -474,6 +507,10 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ */ @\\
\mbox{}\verb@ int NonCheckPrepare(pScanData self);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * prepare for a scan without complaining...@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int SilentPrepare(pScanData self);@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * ScanDrive handles driving to the scan point iPoint.@\\
\mbox{}\verb@ */ @\\
\mbox{}\verb@ int ScanDrive(pScanData self, int iPoint);@\\
@ -494,6 +531,7 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ */@\\
\mbox{}\verb@ int CollectScanData(pScanData self, int iPoint);@\\
\mbox{}\verb@ int CollectScanDataJochen(pScanData self, int iPoint);@\\
\mbox{}\verb@ int CollectSilent(pScanData self, int iPoint);@\\
\mbox{}\verb@/*===================================================================*/@\\
\mbox{}\verb@ /**@\\
\mbox{}\verb@ * Script invocation for writing the scan header.@\\

38
scan.w
View File

@ -47,6 +47,7 @@ Scan variables are held in this data structure:
float fStep;
float *fData;
int dataList;
int logVar;
}VarEntry, *pVarEntry;
@}
The VarEntry structure holds the data for each single scan variable.
@ -69,6 +70,14 @@ Scan variables have an interface:
*/
pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char
*name, float start, float step);
/**
* make a variable which is logged during the scan but not driven.
* @@param pSics The interpreter in order to locate the variable.
* @@param pCon A connection object for error reporting
* @@param name The name of the variable to log
*/
pVarEntry MakeLogVar(SicsInterp *pSics,
SConnection *pCon, char *name);
/**
* InitScanVar clears the list of scan points
* @@param pvar The scna variable to clear
@ -127,6 +136,21 @@ Scan variables have an interface:
* @@param np The number of slots in fData.
*/
void CopyScanVar(pVarEntry pVar, float *fData, int np);
/**
* CheckScanVar checks if the scan variable can be driven through the
* whole range.
* @@param pVar The scan variable to check
* @@param pCon The connection object to which to report errors.
* @@param np The number of points to check for.
* @@return 0 on failuyre, 1 on success
*/
int CheckScanVar(pVarEntry pVar, SConnection *pCon, int np);
/**
* queries if the variable is alogged variable or a drive one.
* @@param pVar The variable to query.
* @@return 1 if log var, 0 else
*/
int isLogVar(pVarEntry pVar);
@}
\subsubsection{The Scan Object}
@ -396,6 +420,15 @@ format of this template is documented in the SICS managers
documentation.
@d stdscan @{
/**
* make a filename according to SICS rules for this scan
*/
char *ScanMakeFileName(SicsInterp *pSics, SConnection *pCon);
/*
* write the header bits from the template
*/
void WriteTemplate(FILE *fd, FILE *temp, char *filename, pScanData pScan,
SConnection *pCon, SicsInterp *pSics);
/**
* write the header of the scan file
*/
@ -419,6 +452,10 @@ documentation.
* second version of PrepareScan which does not check scan limits
*/
int NonCheckPrepare(pScanData self);
/**
* prepare for a scan without complaining...
*/
int SilentPrepare(pScanData self);
/**
* ScanDrive handles driving to the scan point iPoint.
*/
@ -440,6 +477,7 @@ documentation.
*/
int CollectScanData(pScanData self, int iPoint);
int CollectScanDataJochen(pScanData self, int iPoint);
int CollectSilent(pScanData self, int iPoint);
/*===================================================================*/
/**
* Script invocation for writing the scan header.

View File

@ -21,7 +21,7 @@
float fStep;
float *fData;
int dataList;
int logVar;
int logVar;
}VarEntry, *pVarEntry;
/*---------------------------------------------------------------------*/
@ -35,22 +35,21 @@
* @param start The start position from which to scan
* @param step The step width with which to scan.
* @return A pointer to a new scan variable object on success, NULL
* else NULL
* else
*/
pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char
*name, float start, float step);
/*
* Make a variable which is logged during the scan
* @param pSics The SICS interpreter to search for the variable
* @param pCon A connection to report problems to
* @param name The name of the variable to log
* @return A pointer to a new scan variable object on success, NULL
* else NULL
/**
* make a variable which is logged during the scan but not driven.
* @param pSics The interpreter in order to locate the variable.
* @param pCon A connection object for error reporting
* @param name The name of the variable to log
*/
pVarEntry MakeLogVar(SicsInterp *pSics, SConnection *pCon, char *name);
pVarEntry MakeLogVar(SicsInterp *pSics,
SConnection *pCon, char *name);
/**
* InitScanVar clears the list of scan points
* @param pvar The scan variable to clear
* @param pvar The scna variable to clear
*/
void InitScanVar(pVarEntry pVar);
/**
@ -76,14 +75,6 @@
* @return The step width for the scan.
*/
float ScanVarStep(pVarEntry pVar);
/**
* check if the scan is possible, i.e the scan variable does
* not violate the limits in the scan
* @param pVar The scan variable to check
* @param pCon The connection to report errors to
* @return 1 when OK, 0 when the limits are violated.
*/
int CheckScanVar(pVarEntry pVar, SConnection *pCon, int np);
/**
* StartScanVar starts the scan variable to drive to the next
* position.
@ -115,7 +106,19 @@
*/
void CopyScanVar(pVarEntry pVar, float *fData, int np);
/**
* enquires if a variable is a logged variable or a proper scan variable
*/
* CheckScanVar checks if the scan variable can be driven through the
* whole range.
* @param pVar The scan variable to check
* @param pCon The connection object to which to report errors.
* @param np The number of points to check for.
* @return 0 on failuyre, 1 on success
*/
int CheckScanVar(pVarEntry pVar, SConnection *pCon, int np);
/**
* queries if the variable is alogged variable or a drive one.
* @param pVar The variable to query.
* @return 1 if log var, 0 else
*/
int isLogVar(pVarEntry pVar);
#endif

6
sics.h
View File

@ -36,6 +36,12 @@
extern pServer pServ;
/**
* Decode privilege text. Implemented in access.c
* @param the text to decode
* @return -1 if code invalid, else the privilege code
*/
int decodeSICSPriv(char *privText);
#endif

View File

@ -136,14 +136,7 @@
"float",
NULL
};
static char *cAccess[] = {
"internal",
"mugger",
"user",
"spy",
NULL
};
int VarFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
@ -196,30 +189,8 @@
}
/* argv[3] must be the access code, check that now */
i = 0;
while(cAccess[i] != NULL)
{
if(strcmp(argv[3],cAccess[i]) == 0)
{
break;
}
i++;
}
switch(i)
{
case 0:
iCode = usInternal;
break;
case 1:
iCode = usMugger;
break;
case 2:
iCode = usUser;
break;
case 3:
iCode = usSpy;
break;
default:
i = decodeSICSPriv(argv[3]);
if(i < 0){
sprintf(pBueffel," %s access code %s not recognized",
argv[1], argv[3]);
SCWrite(pCon,pBueffel,eError);
@ -227,7 +198,7 @@
}
/* now we can actually install the variable */
pRes = VarCreate(iCode,eType,argv[1]);
pRes = VarCreate(i,eType,argv[1]);
if(!pRes)
{
sprintf(pBueffel,"Memory Error creating variable %s", argv[1]);

View File

@ -400,12 +400,18 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType;
return 1;
}
/*--------------------------------------------------------------------------*/
char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) {
int i, l, firstArgToQuote, quote;
char *Arg2Tcl0(int argc, char *argv[], char *buffer, int buffersize, char *prepend) {
int i, l, firstArgToQuote, quote, prependlen;
char ch;
char *res, *arg;
l = 0;
if (prepend) {
prependlen = strlen(prepend);
l = prependlen + 1;
} else {
prependlen = 0;
l = 0;
}
firstArgToQuote = argc;
quote = 0;
for (i=0; i<argc; i++) {
@ -443,6 +449,11 @@ char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) {
if (buffer == NULL) return NULL;
}
res = buffer;
if (prepend) {
strcpy(res, prepend);
res += prependlen;
*res++ = ' ';
}
for (i=0; i<argc; i++) {
if (i >= firstArgToQuote) *res++ = '"';
arg = argv[i];
@ -464,6 +475,10 @@ char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) {
*res='\0';
return buffer;
}
/*--------------------------------------------------------------------------*/
char *Arg2Tcl(int argc, char *argv[], char *buffer, int buffersize) {
return Arg2Tcl0(argc, argv, buffer, buffersize, NULL);
}
/*============================================================================
Testprogram, can be activated by defining MAIN

View File

@ -87,5 +87,10 @@ typedef struct _TokenEntry {
if (result != NULL && result != buffer) free(result);
!*/
char *Arg2Tcl0(int argc, char *argv[], char *buffer, int buffersize, char *prepend);
/*!
This function is added for convenience, and acts similar to Arg2Tcl.
If prepend is not NULL, its contents appear untreated before the args.
A space is used as separator.
!*/
#endif

234
stdscan.c
View File

@ -64,8 +64,240 @@ static char *fixExtension(char *filename)
}
return fixExtension(pRes);
}
/*-------------------------------------------------------------------------*/
void WriteTemplate(FILE *fd, FILE *temp, char *filename, pScanData pScan,
SConnection *pCon, SicsInterp *pSics)
{
char pBuffer[512], pError[512], *pPtr, *pName;
CommandList *pCom = NULL;
pSicsVariable pVar = NULL;
pDummy pDum = NULL;
pIDrivable pDriv = NULL;
pMotor pMot = NULL;
pVarEntry pScanVar = NULL;
void *pVoid = NULL;
float fVal;
int iRet;
/* loop through description file and act along the way */
while(fgets(pBuffer,511,temp) != 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(pSics,pName);
if(!pCom)
{
sprintf(pError,"ERROR: variable %s NOT found",pName);
SCWrite(pCon,pError,eError);
continue;
}
pVar = (pSicsVariable)pCom->pData;
if(!pVar)
{
sprintf(pError,"ERROR: variable %s NOT found",pName);
SCWrite(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(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(pSics,pName);
if(!pCom)
{
sprintf(pError,"ERROR: variable %s NOT found",pName);
SCWrite(pCon,pError,eError);
continue;
}
pDum = (pDummy)pCom->pData;
if(!pDum)
{
sprintf(pError,"ERROR: variable %s is NOT drivable",pName);
SCWrite(pCon,pError,eError);
continue;
}
pDriv = (pIDrivable)pDum->pDescriptor->GetInterface(pDum,DRIVEID);
if(!pDriv)
{
sprintf(pError,"ERROR: variable %s is NOT drivable",pName);
SCWrite(pCon,pError,eError);
continue;
}
fVal = pDriv->GetValue(pDum,pCon);
fprintf(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(pSics,pName);
if(!pMot)
{
sprintf(pError,"ERROR: motor %s NOT found",pName);
SCWrite(pCon,pError,eError);
continue;
}
iRet = MotorGetPar(pMot,"softzero",&fVal);
if(!iRet)
{
SCWrite(pCon,"ERROR: failed to read zero point",eError);
continue;
}
fprintf(fd,"%s %f\n",pBuffer,fVal);
continue;
} /* end zero point */
/*---------- scripted info */
pPtr = strstr(pBuffer,"!!SCRIPT(");
if(pPtr)
{
/* extract the name */
pName = pPtr + 9; /* first char of name */
*pPtr = '\0'; /* this is the starter of the line */
pPtr = pName;
while( (*pPtr != '\0') && (*pPtr != ')') )
{
pPtr++;
}
*pPtr = '\0';
if(Tcl_Eval(InterpGetTcl(pSics),pName) == TCL_OK)
{
fprintf(fd,"%s\n",Tcl_GetStringResult(InterpGetTcl(pSics)));
}
else
{
SCWrite(pCon,"ERROR: failed to execute Tcl command",eError);
strncpy(pBuffer, Tcl_GetStringResult(InterpGetTcl(pSics)), 511);
SCWrite(pCon,pBuffer,eError);
continue;
}
}
/* ------- date */
pPtr = strstr(pBuffer,"!!DATE!!");
if(pPtr)
{
*pPtr = '\0';
SNXFormatTime(pError,511);
fprintf(fd,"%s %s\n",pBuffer,pError);
continue;
}
/*-------- filename */
pPtr = strstr(pBuffer,"!!FILE!!");
if(pPtr)
{
*pPtr = '\0';
fprintf(fd,"%s %s\n",pBuffer,filename);
continue;
}
/*------------ scanzero */
pPtr = strstr(pBuffer,"!!SCANZERO!!");
if(pPtr && pScan != NULL)
{
*pPtr = '\0';
/* write zero point of first scan variable if motor */
DynarGet(pScan->pScanVar,0,&pVoid);
pScanVar = (pVarEntry)pVoid;
if(pScanVar)
{
pMot = NULL;
pMot = FindMotor(pSics,ScanVarName(pScanVar));
if(pMot != NULL)
{
MotorGetPar(pMot,"softzero",&fVal);
fprintf(fd,"%s zero = %8.3f\n",ScanVarName(pScanVar),
fVal);
}
}
}
/* --------- plain text */
fprintf(fd,"%s",pBuffer);
} /* end while */
}
/*---------------------------------------------------------------------------*/
int WriteHeader(pScanData self)
{
int i, iRet;
FILE *fd;
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;
}
WriteTemplate(self->fd,fd,self->pFile,
self, self->pCon, self->pSics);
/* remember position for seeking to it for writing data */
self->lPos = ftell(self->fd);
fclose(fd);
fclose(self->fd);
self->fd = NULL;
return 1;
}
/*---------------------------------------------------------------------------*/
int WriteHeaderOld(pScanData self)
{
int i, iRet;
FILE *fd;
@ -615,7 +847,7 @@ int prepareDataFile(pScanData self){
return CollectScanDataIntern(self,iPoint,1);
}
/*------------------------------------------------------------------------*/
static int CollectSilent(pScanData self, int iPoint)
int CollectSilent(pScanData self, int iPoint)
{
pVarEntry pVar = NULL;
void *pDings;

View File

@ -11,8 +11,15 @@
#ifndef SICSSTDSCAN
#define SICSSTDSCAN
/**
* make a filename according to SICS rules for this scan
*/
char *ScanMakeFileName(SicsInterp *pSics, SConnection *pCon);
/*
* write the header bits from the template
*/
void WriteTemplate(FILE *fd, FILE *temp, char *filename, pScanData pScan,
SConnection *pCon, SicsInterp *pSics);
/**
* write the header of the scan file
*/
@ -36,7 +43,9 @@
* second version of PrepareScan which does not check scan limits
*/
int NonCheckPrepare(pScanData self);
/**
* prepare for a scan without complaining...
*/
int SilentPrepare(pScanData self);
/**
* ScanDrive handles driving to the scan point iPoint.
@ -59,6 +68,7 @@
*/
int CollectScanData(pScanData self, int iPoint);
int CollectScanDataJochen(pScanData self, int iPoint);
int CollectSilent(pScanData self, int iPoint);
/*===================================================================*/
/**
* Script invocation for writing the scan header.

View File

@ -192,22 +192,24 @@ static int TASHalt(void *pData){
}
/*--------------------------------------------------------------------------*/
static void writeMotPos(SConnection *pCon, char *name,
static void writeMotPos(SConnection *pCon, int silent, char *name,
float val, float target){
char pBueffel[132];
snprintf(pBueffel,131,"Driving %5s from %8.3f to %8.3f",
name, val, target);
SCWrite(pCon,pBueffel,eWarning);
if(silent != 1) {
snprintf(pBueffel,131,"Driving %5s from %8.3f to %8.3f",
name, val, target);
SCWrite(pCon,pBueffel,eWarning);
}
}
/*---------------------------------------------------------------------------*/
static int startMotors(ptasMot self, tasAngles angles,
SConnection *pCon, int driveQ, int driveTilt){
float val;
double curve;
int status;
int status, silent;
silent = self->math->silent;
/*
monochromator
*/
@ -220,7 +222,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"a1",val, angles.monochromator_two_theta/2.);
writeMotPos(pCon,silent,"a1",val, angles.monochromator_two_theta/2.);
val = self->math->motors[A2]->pDrivInt->GetValue(self->math->motors[A2],pCon);
if(ABS(val - angles.monochromator_two_theta) > MOTPREC){
@ -231,7 +233,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"a2",val, angles.monochromator_two_theta);
writeMotPos(pCon,silent,"a2",val, angles.monochromator_two_theta);
if(self->math->motors[MCV] != NULL){
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
@ -245,7 +247,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"mcv",val, curve);
writeMotPos(pCon,silent,"mcv",val, curve);
}
if(self->math->motors[MCH] != NULL){
@ -260,7 +262,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"mch",val, curve);
writeMotPos(pCon,silent,"mch",val, curve);
}
/*
@ -277,7 +279,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,self->math->motors[A5]->name,
writeMotPos(pCon,silent,self->math->motors[A5]->name,
val, angles.analyzer_two_theta/2.);
val = self->math->motors[A6]->pDrivInt->GetValue(self->math->motors[A6],pCon);
@ -289,7 +291,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"a6",val, angles.analyzer_two_theta);
writeMotPos(pCon,silent,"a6",val, angles.analyzer_two_theta);
if(self->math->motors[ACV] != NULL){
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
@ -303,7 +305,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"acv",val, curve);
writeMotPos(pCon,silent,"acv",val, curve);
}
if(self->math->motors[ACH] != NULL){
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
@ -319,7 +321,7 @@ static int startMotors(ptasMot self, tasAngles angles,
}
}
}
writeMotPos(pCon,"ach",val, curve);
writeMotPos(pCon,silent,"ach",val, curve);
}
if(driveQ == 0){
@ -338,7 +340,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"a3",val, angles.a3);
writeMotPos(pCon,silent,"a3",val, angles.a3);
val = self->math->motors[A4]->pDrivInt->GetValue(self->math->motors[A4],pCon);
if(ABS(val - angles.sample_two_theta) > MOTPREC){
@ -349,7 +351,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"a4",val, angles.sample_two_theta);
writeMotPos(pCon,silent,"a4",val, angles.sample_two_theta);
if(driveTilt == 1){
val = self->math->motors[SGL]->pDrivInt->GetValue(self->math->motors[SGL],pCon);
@ -361,7 +363,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"sgl",val, angles.sgl);
writeMotPos(pCon,silent,"sgl",val, angles.sgl);
val = self->math->motors[SGU]->pDrivInt->GetValue(self->math->motors[SGU],pCon);
if(ABS(val - angles.sgu) > MOTPREC){
@ -372,7 +374,7 @@ static int startMotors(ptasMot self, tasAngles angles,
return status;
}
}
writeMotPos(pCon,"sgu",val, angles.sgu);
writeMotPos(pCon,silent,"sgu",val, angles.sgu);
}
self->math->mustDrive = 0;
return OKOK;

View File

@ -197,6 +197,8 @@ static int TASUBHeader(pScanData self)
int fx;
tasReflection r;
double kfix;
pSicsVariable sVar = NULL;
float f1, f2, f3, f4;
assert(self);
assert(pTAS);
@ -345,6 +347,57 @@ static int TASUBHeader(pScanData self)
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
*/
@ -639,6 +692,7 @@ static int TASUBScanDrive(pScanData self, int iPoint)
int iTAS = 0;
pMotor pMot;
pTAS->ub->silent = 1;
/*
loop through all the scan variables
*/
@ -668,6 +722,7 @@ static int TASUBScanDrive(pScanData self, int iPoint)
else
{
status = Wait4Success(GetExecutor());
pTAS->ub->silent = 0;
}
return 1;
}
@ -776,6 +831,8 @@ static int TASUBScanCount(pScanData self, int iPoint)
/* loop over all scan variables */
status = 1;
pTAS->ub->silent = 0;
for(i = 0; i < self->iScanVar; i++)
{
DynarGet(self->pScanVar,i,&pDings);

70
tasub.c
View File

@ -241,6 +241,10 @@ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData,
SCWrite(pCon,"ERROR: need name to install tasUB",eError);
return 0;
}
if(argc > 2 && argc < 14){
SCWrite(pCon,"ERROR: not enough motor names specified form MakeTasUB",eError);
return 0;
}
pNew = MakeTasUB();
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating tasUB",eError);
@ -250,19 +254,39 @@ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData,
/*
assign motors
*/
pNew->motors[0] = FindMotor(pSics,"a1");
pNew->motors[1] = FindMotor(pSics,"a2");
pNew->motors[2] = FindMotor(pSics,"mcv");
pNew->motors[3] = FindMotor(pSics,"mch");
pNew->motors[4] = FindMotor(pSics,"a3");
pNew->motors[5] = FindMotor(pSics,"a4");
pNew->motors[6] = FindMotor(pSics,"sgu");
pNew->motors[7] = FindMotor(pSics,"sgl");
pNew->motors[8] = FindMotor(pSics,"a5");
pNew->motors[9] = FindMotor(pSics,"a6");
pNew->motors[10] = FindMotor(pSics,"acv");
pNew->motors[11] = FindMotor(pSics,"ach");
if(argc < 14){
/*
* default names and assignement
*/
pNew->motors[0] = FindMotor(pSics,"a1");
pNew->motors[1] = FindMotor(pSics,"a2");
pNew->motors[2] = FindMotor(pSics,"mcv");
pNew->motors[3] = FindMotor(pSics,"mch");
pNew->motors[4] = FindMotor(pSics,"a3");
pNew->motors[5] = FindMotor(pSics,"a4");
pNew->motors[6] = FindMotor(pSics,"sgu");
pNew->motors[7] = FindMotor(pSics,"sgl");
pNew->motors[8] = FindMotor(pSics,"a5");
pNew->motors[9] = FindMotor(pSics,"a6");
pNew->motors[10] = FindMotor(pSics,"acv");
pNew->motors[11] = FindMotor(pSics,"ach");
} else {
/*
* user defined names
*/
pNew->motors[0] = FindMotor(pSics,argv[2]);
pNew->motors[1] = FindMotor(pSics,argv[3]);
pNew->motors[2] = FindMotor(pSics,argv[4]);
pNew->motors[3] = FindMotor(pSics,argv[5]);
pNew->motors[4] = FindMotor(pSics,argv[6]);
pNew->motors[5] = FindMotor(pSics,argv[7]);
pNew->motors[6] = FindMotor(pSics,argv[8]);
pNew->motors[7] = FindMotor(pSics,argv[9]);
pNew->motors[8] = FindMotor(pSics,argv[10]);
pNew->motors[9] = FindMotor(pSics,argv[11]);
pNew->motors[10] = FindMotor(pSics,argv[12]);
pNew->motors[11] = FindMotor(pSics,argv[13]);
}
/*
curvature motors may be missing, anything else is a serious problem
*/
@ -275,6 +299,7 @@ int TasUBFactory(SConnection *pCon,SicsInterp *pSics, void *pData,
status += testMotor(pNew, pCon,"a5",A5);
status += testMotor(pNew, pCon,"a6",A6);
if(status != 8){
SCWrite(pCon,"ERROR: a required motor is mssing, tasub NOT installed",eError);
return 0;
}
@ -1489,6 +1514,25 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
SCWrite(pCon,pBueffel,eValue);
return 1;
}
} else if(strcmp(argv[1],"silent") == 0){
if(argc > 2){
strtolower(argv[2]);
if(!SCMatchRights(pCon,usUser)){
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&newSS);
if(status != TCL_OK){
SCWrite(pCon,"ERROR: failed to convert argument to number",eError);
return 0;
}
self->silent = newSS;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel,131,"%s.silent = %d",argv[0],self->silent);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
} else {
snprintf(pBueffel,131,"ERROR: subcommand %s to %s not defined",argv[1],
argv[0]);

View File

@ -30,6 +30,7 @@
pMotor motors[12];
tasReflection r1, r2;
int ubValid;
int silent;
}tasUB, *ptasUB;

View File

@ -32,6 +32,7 @@ A data structure:
pMotor motors[12];
tasReflection r1, r2;
int ubValid;
int silent;
}tasUB, *ptasUB;
@}
\begin{description}
@ -55,6 +56,9 @@ A data structure:
runtime.
\item[r1,r2] The indexs of the reflections used for calculating the orientation
matrix.
\item[ubValid] a flag denoting if the UB is valid.
\item[silent] A flga which when 1 suppresses the printing of motor positions
when driving. Usefule for scans.
\end{description}
For the virtual motors, there must be a data structure, too:

View File

@ -162,7 +162,7 @@ int TclIntAction(SConnection *pCon, SicsInterp *pSics, void *pData,
cmd = Arg2Tcl(argc-2, &argv[2],pBuffer,1023);
if (cmd) {
if(self->fd != NULL){
fprintf(self->fd,"%s\n",pBuffer);
fprintf(self->fd,"%s\n",cmd);
}
if (cmd != pBuffer) free(cmd);
SCSendOK(pCon);

View File

@ -541,6 +541,7 @@ static int cellFromUBWrapper(pUBCALC self, SConnection *pCon){
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pUBCALC self = (pUBCALC)pData;
char pBuffer[512];
assert(self);
if(argc < 2){
@ -550,7 +551,15 @@ int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
strtolower(argv[1]);
if(strcmp(argv[1],"cell") == 0){
return readCell(pCon, self, argc, argv);
if(argc > 3){
return readCell(pCon, self, argc, argv);
} else {
snprintf(pBuffer,511,"ubcalc cell = %f %f %f %f %f %f",
self->direct.a, self->direct.b, self->direct.c,
self->direct.alpha, self->direct.beta,self->direct.gamma);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if(strcmp(argv[1],"ref1") == 0){
return readReflection(pCon,pSics, &self->r1,argc,argv);
} else if(strcmp(argv[1],"ref2") ==0){

View File

@ -120,6 +120,7 @@
{
deleteCircular(self->pTail);
}
free(self); /* M.Z. */
return 1;
}
/*--------------------------------------------------------------------------*/