- Added separate drivable motors for four circle H, K, L
- Added a listen mode to commandlog in order to support the batchEditor - Some small fixes to exe* for BatchEditor
This commit is contained in:
@ -421,7 +421,12 @@ extern char *SkipSpace(char *pPtr);
|
||||
pTcl = (Tcl_Interp *)self->pTcl;
|
||||
if(pTcl)
|
||||
{
|
||||
/*
|
||||
uncommented: the current versions of Tcl (8.3,4) dump core with a
|
||||
memory problem deep in the Tcl library. This causes a core dump on
|
||||
each SICS restart and breaks the use of external tools.
|
||||
Tcl_DeleteInterp(pTcl);
|
||||
*/
|
||||
}
|
||||
|
||||
free(self);
|
||||
|
2
choco.c
2
choco.c
@ -161,8 +161,6 @@
|
||||
{
|
||||
self->pDriv->Close(self->pDriv);
|
||||
self->pDriv->Delete(self->pDriv);
|
||||
if(self->pDriv->pParList)
|
||||
free(self->pDriv->pParList);
|
||||
free(self->pDriv);
|
||||
}
|
||||
if(self->pDes)
|
||||
|
@ -27,8 +27,6 @@
|
||||
|
||||
/* in conman.c */
|
||||
int TelnetWrite(mkChannel *pSock, char *pText);
|
||||
|
||||
|
||||
/*-------------------- the command log file pointer ---------------------*/
|
||||
static FILE *fd = NULL;
|
||||
static FILE *fauto = NULL;
|
||||
@ -122,6 +120,13 @@
|
||||
fprintf(fauto,"%s %s\n",prompt, pText);
|
||||
}
|
||||
}
|
||||
|
||||
/* to all listening sockets. The check is necessary to resolve a shutdown problem */
|
||||
if(pServ->pTasker != NULL)
|
||||
{
|
||||
TaskSignal(pServ->pTasker,COMLOG,pText);
|
||||
}
|
||||
|
||||
/* tail buffer */
|
||||
if(pTail != NULL)
|
||||
{
|
||||
|
51
conman.c
51
conman.c
@ -103,6 +103,7 @@ extern pServer pServ;
|
||||
memset(pCon,0,sizeof(SConnection));
|
||||
pCon->ident = 0;
|
||||
pCon->next = freeConnections;
|
||||
pCon->listening = 0;
|
||||
freeConnections = pCon;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -174,6 +175,7 @@ extern pServer pServ;
|
||||
pRes->eInterrupt = eContinue;
|
||||
pRes->lMagic = CONMAGIC;
|
||||
pRes->iLogin = 0;
|
||||
pRes->listening = 0;
|
||||
pRes->conStart = time(NULL);
|
||||
pRes->write = SCNormalWrite;
|
||||
for(i = 0; i < 10; i++)
|
||||
@ -203,11 +205,6 @@ extern pServer pServ;
|
||||
pRes->iUserRights = iUser;
|
||||
pRes->iGrab = TokenGrabActive();
|
||||
|
||||
NETInfo(pRes->pSock,pHost,131);
|
||||
sprintf(pBueffel,"Accepted connection on socket %d from %s",
|
||||
pRes->pSock->sockid, pHost);
|
||||
SICSLogWrite(pBueffel,eInternal);
|
||||
WriteToCommandLog("SYS >", pBueffel);
|
||||
|
||||
return pRes;
|
||||
|
||||
@ -395,7 +392,7 @@ extern pServer pServ;
|
||||
}
|
||||
|
||||
/* log the kill */
|
||||
if(pVictim->pSock)
|
||||
if(pVictim->pSock && pVictim->iLogin == 1)
|
||||
{
|
||||
sprintf(pBueffel,"Deleting connection %d",pVictim->pSock->sockid);
|
||||
WriteToCommandLog("SYS>",pBueffel);
|
||||
@ -599,7 +596,9 @@ static int doSockWrite(SConnection *self, char *buffer)
|
||||
if(!iRet)
|
||||
{
|
||||
SCnoSock(self);
|
||||
WriteToCommandLog("SYS> ","Connection broken on send");
|
||||
if(!self->listening && self->iLogin == 1){
|
||||
WriteToCommandLog("SYS> ","Connection broken on send");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1358,6 +1357,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
config Rights User Password sets and verifies new user rights
|
||||
config File Filename Logs to another file
|
||||
config output normal | withcode Sets output mode
|
||||
config listen 0 | 1 enables commandlog listen mode
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
int ConfigCon(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
@ -1402,6 +1402,27 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(argv[1],"listen") == 0)
|
||||
{
|
||||
if(argc < 3)
|
||||
{
|
||||
snprintf(pBueffel,511,"listen = %d", pCon->listening);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCon->listening = atoi(argv[2]);
|
||||
if(pCon->listening != 0 && pCon->listening != 1)
|
||||
{
|
||||
pCon->listening = 0;
|
||||
SCWrite(pCon,"ERROR: config listen only accepts 0 or 1 as arguments",eError);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check no or args */
|
||||
if(argc < 3)
|
||||
@ -1747,6 +1768,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
char *pPtr = NULL;
|
||||
int iRet;
|
||||
char *pUser = NULL, *pPassword = NULL;
|
||||
char pHost[132], pBueffel[512];
|
||||
|
||||
self = (SConnection *)pData;
|
||||
if(!VerifyConnection(self))
|
||||
@ -1810,6 +1832,11 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
SCWrite(self,"Login OK",eError);
|
||||
self->iLogin = 1;
|
||||
SCSetRights(self,iRet);
|
||||
NETInfo(self->pSock,pHost,131);
|
||||
sprintf(pBueffel,"Accepted connection on socket %d from %s",
|
||||
self->pSock->sockid, pHost);
|
||||
SICSLogWrite(pBueffel,eInternal);
|
||||
WriteToCommandLog("SYS >", pBueffel);
|
||||
free(pPtr);
|
||||
return 1;
|
||||
}
|
||||
@ -1863,11 +1890,19 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
||||
else if(iSignal == SICSBROADCAST)
|
||||
{
|
||||
pPtr = (char *)pSigData;
|
||||
if(pPtr)
|
||||
if(pPtr != NULL)
|
||||
{
|
||||
SCWrite(self,pPtr,eWarning);
|
||||
}
|
||||
}
|
||||
else if(iSignal == COMLOG && self->listening == 1)
|
||||
{
|
||||
pPtr = (char *)pSigData;
|
||||
if(pPtr != NULL)
|
||||
{
|
||||
doSockWrite(self,pPtr);
|
||||
}
|
||||
}
|
||||
else if(iSignal == TOKENRELEASE)
|
||||
{
|
||||
self->iGrab = 0;
|
||||
|
4
conman.h
4
conman.h
@ -49,6 +49,7 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
||||
int iOutput;
|
||||
writeFunc write; /* function doing
|
||||
writing */
|
||||
int listening; /* for listening to commandlog or other data */
|
||||
|
||||
/* execution context */
|
||||
int eInterrupt;
|
||||
@ -72,8 +73,7 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
||||
*/
|
||||
int iLogin;
|
||||
time_t conStart;
|
||||
|
||||
} SConnection;
|
||||
} SConnection;
|
||||
|
||||
#include "nserver.h"
|
||||
|
||||
|
@ -103,6 +103,7 @@
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
self->isUpToDate = 0;
|
||||
self->badStatusCount = 0;
|
||||
self->tStart = time(&tX);
|
||||
InvokeCallBack(self->pCall,COUNTSTART,pCon);
|
||||
return iRet;
|
||||
@ -224,11 +225,12 @@
|
||||
eCt = self->pDriv->GetStatus(self->pDriv,&fControl);
|
||||
if(eCt == HWFault)
|
||||
{
|
||||
self->badStatusCount++;
|
||||
iRet = self->pDriv->GetError(self->pDriv,&iErr,pError,79);
|
||||
sprintf(pBueffel,"WARNING: %s ",pError);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
iRet = self->pDriv->TryAndFixIt(self->pDriv,iErr);
|
||||
if(iRet == COTERM)
|
||||
if(iRet == COTERM || self->badStatusCount > 3)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Cannot fix counter problem, aborting",eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
@ -247,6 +249,7 @@
|
||||
sMon.fCurrent = fControl;
|
||||
sMon.fPreset = self->pDriv->fPreset;
|
||||
sMon.pName = self->name;
|
||||
self->badStatusCount = 0; /* clear: we managed to read OK */
|
||||
if(self->iCallbackCounter > 20)
|
||||
{
|
||||
InvokeCallBack(self->pCall,MONITOR,&sMon);
|
||||
|
@ -23,6 +23,7 @@
|
||||
pICallBack pCall;
|
||||
unsigned long tStart;
|
||||
int iCallbackCounter;
|
||||
int badStatusCount;
|
||||
} Counter, *pCounter;
|
||||
|
||||
/*----------------------------- birth & death -----------------------------*/
|
||||
|
365
diffscan.c
Normal file
365
diffscan.c
Normal file
@ -0,0 +1,365 @@
|
||||
/*-------------------------------------------------------------------
|
||||
diffscan is an operator which can perform a fast differential scan
|
||||
while a motor is running.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, November 2004
|
||||
---------------------------------------------------------------------*/
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <tcl.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "diffscan.h"
|
||||
#include "drive.h"
|
||||
#include "counter.h"
|
||||
|
||||
#define DIFFMONITOR 0
|
||||
#define SKIP 1
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
static void KillDiffScan(void *data){
|
||||
pDiffScan self = (pDiffScan)data;
|
||||
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
|
||||
if(self->pDes != NULL){
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
if(self->parArray != NULL){
|
||||
ObParDelete(self->parArray);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int SaveDiffScan(void *data, char *name, FILE *fd){
|
||||
pDiffScan self = (pDiffScan)data;
|
||||
if(self == NULL){
|
||||
return 0;
|
||||
}
|
||||
fprintf(fd,"%s monitor %f\n",name,ObVal(self->parArray,DIFFMONITOR));
|
||||
fprintf(fd,"%s skip %f\n",name,ObVal(self->parArray,SKIP));
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pDiffScan pNew = NULL;
|
||||
int status;
|
||||
|
||||
pNew = (pDiffScan)malloc(sizeof(DiffScan));
|
||||
if(pNew == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating differential scan",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew,0,sizeof(DiffScan));
|
||||
pNew->pDes = CreateDescriptor("DiffScan");
|
||||
pNew->parArray = ObParCreate(2);
|
||||
if(!pNew->pDes || !pNew->parArray){
|
||||
SCWrite(pCon,"ERROR: out of memory creating differential scan",
|
||||
eError);
|
||||
KillDiffScan(pNew);
|
||||
return 0;
|
||||
}
|
||||
ObParInit(pNew->parArray, DIFFMONITOR,"monitor",4.0,usUser);
|
||||
ObParInit(pNew->parArray, SKIP,"skip",.0,usUser);
|
||||
pNew->pDes->SaveStatus = SaveDiffScan;
|
||||
|
||||
if(argc > 1) {
|
||||
status = AddCommand(pSics,argv[2],
|
||||
DiffScanWrapper,
|
||||
KillDiffScan,
|
||||
pNew);
|
||||
|
||||
} else {
|
||||
status = AddCommand(pSics,"diffscan",
|
||||
DiffScanWrapper,
|
||||
KillDiffScan,
|
||||
pNew);
|
||||
|
||||
}
|
||||
if(status != 1){
|
||||
SCWrite(pCon,"ERROR: duplicate diffscan not created",eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pDiffScan self = NULL;
|
||||
pScanData pScan = NULL;
|
||||
ObPar *par = NULL;
|
||||
char pBueffel[255];
|
||||
int status;
|
||||
|
||||
self = (pDiffScan)pData;
|
||||
assert(self);
|
||||
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: need arguments to diffscan",eError);
|
||||
return 0;
|
||||
}
|
||||
if(!SCMatchRights(pCon,usUser)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
first try to find a scan object and to run
|
||||
*/
|
||||
strtolower(argv[1]);
|
||||
pScan = (pScanData)FindCommandData(pSics,argv[1],"ScanObject");
|
||||
if(pScan != NULL && argc > 2){
|
||||
status = RunDiffScan(self,pScan,pCon, atof(argv[2]));
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
if we end here we are treating variables
|
||||
*/
|
||||
if(argc > 2){
|
||||
/*
|
||||
set case
|
||||
*/
|
||||
return ObParSet(self->parArray,argv[0],argv[1],atof(argv[2]),pCon);
|
||||
} else {
|
||||
/*
|
||||
get case
|
||||
*/
|
||||
par = ObParFind(self->parArray,argv[1]);
|
||||
if(par != NULL){
|
||||
snprintf(pBueffel,255,"%s.%s = %f",argv[0],argv[1],par->fVal);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
} else {
|
||||
snprintf(pBueffel,255,"ERROR: parameter %s not found",argv[1]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static int StartDiffScan(pDiffScan self, pScanData pScan,
|
||||
SConnection *pCon, float fEnd){
|
||||
pVarEntry pVar = NULL;
|
||||
void *pPtr = NULL;
|
||||
pCounter pCount = NULL;
|
||||
char pBueffel[255];
|
||||
int status;
|
||||
|
||||
/*
|
||||
error checks
|
||||
*/
|
||||
if(pScan->iScanVar < 1) {
|
||||
SCWrite(pCon,"ERROR: no scan variable to diffscan",eError);
|
||||
return 0;
|
||||
}
|
||||
if(pScan->iScanVar > 1) {
|
||||
snprintf(pBueffel,255,
|
||||
"WARNING: diffscan handles only first scan variable, %d %s",
|
||||
pScan->iScanVar - 1,
|
||||
"scan variables ignored");
|
||||
SCWrite(pCon,pBueffel, eWarning);
|
||||
}
|
||||
|
||||
/*
|
||||
initialize data structure
|
||||
*/
|
||||
self->scanObject = pScan;
|
||||
self->scanObject->pCon = pCon;
|
||||
self->skip = (int)ObVal(self->parArray,SKIP);
|
||||
self->scaleMonitor = (int)ObVal(self->parArray,DIFFMONITOR);
|
||||
self->normalizationScale = -1;
|
||||
pScan->iCounts = 0;
|
||||
|
||||
/*
|
||||
get variable
|
||||
*/
|
||||
DynarGet(pScan->pScanVar,0,&pPtr);
|
||||
pVar = (pVarEntry)pPtr;
|
||||
if(pVar == NULL){
|
||||
SCWrite(pCon,"ERROR: cannot access scan variable",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
drive to start position
|
||||
*/
|
||||
status = Drive(pCon,pServ->pSics,ScanVarName(pVar),ScanVarStart(pVar));
|
||||
if(status != 1){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Configure counter. We operate in timer mode with a very long
|
||||
preset mode. Stopping is done explicitly in the diffscan task
|
||||
*/
|
||||
SetCounterMode(pScan->pCounterData,eTimer);
|
||||
SetCounterPreset(pScan->pCounterData,3600.);
|
||||
|
||||
/*
|
||||
start motor and counter
|
||||
*/
|
||||
status = pVar->pInter->SetValue(pVar->pObject,pCon,fEnd);
|
||||
if(status != OKOK){
|
||||
/*
|
||||
errors will already have been reported in SetValue
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
pCount = (pCounter)pScan->pCounterData;
|
||||
assert(pCount);
|
||||
status = pCount->pCountInt->StartCount(pCount,pCon);
|
||||
if(status != OKOK){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static float normalizeEntry(pCountEntry pCount, pCountEntry last,
|
||||
long monValue, int scaleMon){
|
||||
int i;
|
||||
float fScale;
|
||||
float value;
|
||||
long diff;
|
||||
|
||||
/*
|
||||
calculate scale
|
||||
*/
|
||||
diff = pCount->Monitors[scaleMon-1] - last->Monitors[scaleMon-1];
|
||||
if(diff > 0) {
|
||||
fScale = (float)monValue/(float)diff;
|
||||
} else {
|
||||
fScale = 0.;
|
||||
}
|
||||
value = ((float)(pCount->lCount - last->lCount))*fScale;
|
||||
pCount->lCount = (long)value;
|
||||
for(i = 0; i < 10; i++){
|
||||
pCount->Monitors[i] = (pCount->Monitors[i] - last->Monitors[i])*fScale;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static void copyCountData(pCountEntry last, pCountEntry pCount){
|
||||
memcpy(last,pCount,sizeof(CountEntry));
|
||||
}
|
||||
/*---------------------------------------------------------------------*/
|
||||
static int DiffScanTask(void *pData){
|
||||
pCounter pCount = NULL;
|
||||
pCountEntry data;
|
||||
pVarEntry pVar = NULL;
|
||||
void *pPtr = NULL;
|
||||
float fPos, countValue;
|
||||
int status, finish = 1, count;
|
||||
char pBueffel[255];
|
||||
long rawCount, rawMon;
|
||||
CountEntry rawCopy;
|
||||
|
||||
pDiffScan self = (pDiffScan)pData;
|
||||
|
||||
/*
|
||||
manage skip
|
||||
*/
|
||||
if(self->skip > 0){
|
||||
if(self->skipCount > self->skip){
|
||||
self->skipCount = 0;
|
||||
} else {
|
||||
self->skipCount++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
read motor status
|
||||
*/
|
||||
DynarGet(self->scanObject->pScanVar,0,&pPtr);
|
||||
pVar = (pVarEntry)pPtr;
|
||||
status = pVar->pInter->CheckStatus(pVar->pObject,self->scanObject->pCon);
|
||||
if(status != HWBusy) {
|
||||
finish = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
read values
|
||||
*/
|
||||
status = GetDrivablePosition(pVar->pObject,self->scanObject->pCon,
|
||||
&fPos);
|
||||
if(status == 0){
|
||||
return finish;
|
||||
}
|
||||
AppendScanVar(pVar,fPos);
|
||||
pCount = (pCounter)self->scanObject->pCounterData;
|
||||
pCount->pCountInt->TransferData(pCount,self->scanObject->pCon);
|
||||
CollectCounterData(self->scanObject);
|
||||
|
||||
/*
|
||||
normalize (or not)
|
||||
*/
|
||||
DynarGet(self->scanObject->pCounts,self->scanObject->iCounts-1,&pPtr);
|
||||
data = (pCountEntry)pPtr;
|
||||
copyCountData(&rawCopy,data);
|
||||
if(self->normalizationScale < 0){
|
||||
countValue = (float)data->lCount;
|
||||
rawCount = data->lCount;
|
||||
rawMon = data->Monitors[self->scaleMonitor-1];
|
||||
self->normalizationScale = data->Monitors[self->scaleMonitor-1];
|
||||
} else {
|
||||
if(data->Monitors[self->scaleMonitor -1] -
|
||||
self->last.Monitors[self->scaleMonitor-1] < 5) {
|
||||
SCWrite(self->scanObject->pCon,
|
||||
"WARNING: low count rate",eWarning);
|
||||
}
|
||||
rawCount = data->lCount;
|
||||
rawMon = data->Monitors[self->scaleMonitor-1];
|
||||
countValue = normalizeEntry(data,&self->last,
|
||||
self->normalizationScale,
|
||||
self->scaleMonitor);
|
||||
}
|
||||
copyCountData(&self->last,&rawCopy);
|
||||
|
||||
/*
|
||||
print progress
|
||||
*/
|
||||
snprintf(pBueffel,255,"%5d %12.4f %12.4f RAW: %10d %10d",
|
||||
self->scanObject->iCounts -1,
|
||||
fPos, countValue, rawCount,
|
||||
rawMon);
|
||||
SCWrite(self->scanObject->pCon,pBueffel,eWarning);
|
||||
InvokeCallBack(self->scanObject->pCall,SCANPOINT,self->scanObject);
|
||||
|
||||
/*
|
||||
check for interrupt
|
||||
*/
|
||||
if(SCGetInterrupt(self->scanObject->pCon) >= eAbortScan){
|
||||
finish = 0;
|
||||
}
|
||||
|
||||
return finish;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
int RunDiffScan(pDiffScan self, pScanData pScan,
|
||||
SConnection *pCon, float fEnd){
|
||||
long lID;
|
||||
pCounter pCount = NULL;
|
||||
|
||||
if(StartDiffScan(self,pScan,pCon,fEnd) != 1) {
|
||||
return 0;
|
||||
}
|
||||
InvokeCallBack(self->scanObject->pCall,SCANSTART,self->scanObject);
|
||||
|
||||
|
||||
lID = TaskRegister(pServ->pTasker,DiffScanTask,NULL,NULL,self,10);
|
||||
TaskWait(pServ->pTasker,lID);
|
||||
|
||||
|
||||
pCount = (pCounter)self->scanObject->pCounterData;
|
||||
pCount->pCountInt->Halt(pCount);
|
||||
InvokeCallBack(self->scanObject->pCall,SCANEND,self->scanObject);
|
||||
|
||||
return 1;
|
||||
}
|
47
diffscan.h
Normal file
47
diffscan.h
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
diffscan is an operator which can perform a fast differential scan
|
||||
while a motor is running.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, November 2004
|
||||
---------------------------------------------------------------------*/
|
||||
#ifndef SICSDIFFSCAN
|
||||
#define SICSDIFFSCAN
|
||||
#include "obpar.h"
|
||||
#include "scan.h"
|
||||
#include "scan.i"
|
||||
|
||||
typedef struct {
|
||||
pObjectDescriptor pDes;
|
||||
ObPar *parArray;
|
||||
int normalizationScale;
|
||||
int scaleMonitor;
|
||||
CountEntry last;
|
||||
int skip;
|
||||
int skipCount;
|
||||
pScanData scanObject;
|
||||
} DiffScan, *pDiffScan;
|
||||
|
||||
/*==================================================================*/
|
||||
|
||||
/**
|
||||
* RunDiffScan runs a differential scan.
|
||||
* @param self The Diffscan object to use
|
||||
* @param pScan The scan object to use for configuration and for
|
||||
* for storing the results.
|
||||
* @param pCon The connection to use for output and errors.
|
||||
* @param fEnd The end value for the diffscan
|
||||
*/
|
||||
int RunDiffScan(pDiffScan self, pScanData pScan,
|
||||
SConnection *pCon, float fEnd);
|
||||
/*==================== interpreter wrappers ==========================*/
|
||||
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
|
||||
|
||||
#endif
|
97
diffscan.w
Normal file
97
diffscan.w
Normal file
@ -0,0 +1,97 @@
|
||||
\subsection{Differential Scan}
|
||||
This is a special very fast but inaccurate scan method. The scan motor is
|
||||
set into motion and counts are collected on the fly, while the motor
|
||||
is moving. As neither the motor speed, nor the counters response nor
|
||||
the source stability can be relied upon to result in equally spaced
|
||||
and well defined counts, the counts have to be scaled according to the
|
||||
difference in monitor counts towards the previous count. This is why
|
||||
this is called differential scan. This is not a
|
||||
precise scan. But is a very fast one which helps locating peaks or
|
||||
during alignment.
|
||||
|
||||
This is implemented as an operator on top of the standard scan
|
||||
module. All scan details, scan variables etc have to be configured in
|
||||
the main scan module. This object then just runs the diff scan and
|
||||
stores the result in the main scan object for further processing. For
|
||||
instance peak location. The end of the scan is calculated from the
|
||||
start, step and NP of the main scan module. be aware that these values
|
||||
have no well defined meaning during this kind of scan, NP will be
|
||||
corrected to account for the points actually measured.
|
||||
|
||||
As motors cannot be guaranteed to run simulataneously, only one scan
|
||||
variable is suported for this.
|
||||
|
||||
The actual control of this scan is hidden in a task function which is
|
||||
responsible for storing the data and stopping when the motor has
|
||||
finished driving.
|
||||
|
||||
In order to do a differential scan a data structure is required:
|
||||
@d diffscandat @{
|
||||
typedef struct {
|
||||
pObjectDescriptor pDes;
|
||||
ObPar *parArray;
|
||||
int normalizationScale;
|
||||
int scaleMonitor;
|
||||
CountEntry last;
|
||||
int skip;
|
||||
int skipCount;
|
||||
pScanData scanObject;
|
||||
} DiffScan, *pDiffScan;
|
||||
@}
|
||||
The fields:
|
||||
\begin{description}
|
||||
\item[pDes] The standard object descriptor.
|
||||
\item[parArray] An array of parameters for the module.
|
||||
\item[normalizationScale] The scale to which to scale counts during
|
||||
counting.This will be the monitor difference between the first and the
|
||||
second point.
|
||||
\item[lastMonitor] is the last monitor read for caluclating differences.
|
||||
\item[scaleMonitor] The monitor to use for scaling. This should better
|
||||
be a monitor with a high count rate for acurate scaling.
|
||||
\item[skip] How many cycles of the main loop to skip between
|
||||
recordings.
|
||||
\item[skipCount] Counter for skipped cycles. Together with skip this
|
||||
is a means to limit the sampling rate of diffscan.
|
||||
\item[scanObject] The scan object we are operating upon.
|
||||
\end{description}
|
||||
|
||||
The external interface to this module is like this:
|
||||
@d diffscanint @{
|
||||
/**
|
||||
* RunDiffScan runs a differential scan.
|
||||
* @@param self The Diffscan object to use
|
||||
* @@param pScan The scan object to use for configuration and for
|
||||
* for storing the results.
|
||||
* @@param pCon The connection to use for output and errors.
|
||||
* @@param fEnd The end value for the diffscan
|
||||
*/
|
||||
int RunDiffScan(pDiffScan self, pScanData pScan,
|
||||
SConnection *pCon, float fEnd);
|
||||
/*==================== interpreter wrappers ==========================*/
|
||||
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
|
||||
@}
|
||||
|
||||
@o diffscan.h @{
|
||||
/*-------------------------------------------------------------------
|
||||
diffscan is an operator which can perform a fast differential scan
|
||||
while a motor is running.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, November 2004
|
||||
---------------------------------------------------------------------*/
|
||||
#ifndef SICSDIFFSCAN
|
||||
#define SICSDIFFSCAN
|
||||
#include "obpar.h"
|
||||
#include "scan.h"
|
||||
#include "scan.i"
|
||||
@<diffscandat@>
|
||||
/*==================================================================*/
|
||||
@<diffscanint@>
|
||||
#endif
|
||||
@}
|
9
event.h
9
event.h
@ -1,5 +1,5 @@
|
||||
|
||||
#line 88 "event.w"
|
||||
#line 89 "event.w"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
E V E N T
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
int Text2Event(char *pText);
|
||||
|
||||
#line 101 "event.w"
|
||||
#line 102 "event.w"
|
||||
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
#define BATCHEND 16
|
||||
#define DRIVSTAT 17
|
||||
|
||||
#line 103 "event.w"
|
||||
#line 104 "event.w"
|
||||
|
||||
|
||||
/*--------------- Signals for the Signalfunction of each task ------------*/
|
||||
@ -54,7 +54,8 @@
|
||||
#define SICSBROADCAST 301
|
||||
#define TOKENGRAB 302
|
||||
#define TOKENRELEASE 303
|
||||
#define COMLOG 304
|
||||
|
||||
#line 106 "event.w"
|
||||
#line 107 "event.w"
|
||||
|
||||
#endif
|
||||
|
@ -105,6 +105,7 @@ $\langle$VSIG {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@#define SICSBROADCAST 301@\\
|
||||
\mbox{}\verb@#define TOKENGRAB 302@\\
|
||||
\mbox{}\verb@#define TOKENRELEASE 303@\\
|
||||
\mbox{}\verb@#define COMLOG 304@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
@ -121,7 +122,7 @@ number which ocurred.
|
||||
data is the string to send.
|
||||
\item[TOKENGRAB] A connection has successfully grabbed the control token.
|
||||
\item[TOKENRELEASE] A connection has released the control token.
|
||||
|
||||
\item[COMLOG] A command log message. This is to implement listen mode to the command log.
|
||||
\end{description}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
|
3
event.w
3
event.w
@ -75,6 +75,7 @@ possible codes are defined.
|
||||
#define SICSBROADCAST 301
|
||||
#define TOKENGRAB 302
|
||||
#define TOKENRELEASE 303
|
||||
#define COMLOG 304
|
||||
@}
|
||||
\begin{description}
|
||||
\item[SICSINT] An interrupt has ocurred. The signal data is the interrupt
|
||||
@ -83,7 +84,7 @@ number which ocurred.
|
||||
data is the string to send.
|
||||
\item[TOKENGRAB] A connection has successfully grabbed the control token.
|
||||
\item[TOKENRELEASE] A connection has released the control token.
|
||||
|
||||
\item[COMLOG] A command log message. This is to implement listen mode to the command log.
|
||||
\end{description}
|
||||
@o event.h -d @{
|
||||
/*----------------------------------------------------------------------------
|
||||
|
4
exebuf.c
4
exebuf.c
@ -59,7 +59,9 @@ int exeBufAppend(pExeBuf self, char *line){
|
||||
assert(self);
|
||||
|
||||
status = DynStringConcat(self->bufferContent,line);
|
||||
DynStringConcatChar(self->bufferContent,'\n');
|
||||
if(strrchr(line,(int)'\n') == NULL){
|
||||
DynStringConcatChar(self->bufferContent,'\n');
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
31
exeman.c
31
exeman.c
@ -169,6 +169,9 @@ static int runBatchBuffer(pExeMan self, SConnection *pCon,
|
||||
pExeBuf buffer = NULL;
|
||||
int status;
|
||||
|
||||
if(!SCMatchRights(pCon,usUser)) {
|
||||
return 0;
|
||||
}
|
||||
filePath = locateBatchBuffer(self,name);
|
||||
if(filePath == NULL){
|
||||
snprintf(pBueffel,255,"ERROR: batch buffer %s not found in path",
|
||||
@ -558,13 +561,24 @@ static int printBuffer(pExeMan self, SConnection *pCon,
|
||||
int argc, char *argv[]){
|
||||
pDynString filePath = NULL;
|
||||
char pLine[512];
|
||||
pExeBuf buf;
|
||||
void *pPtr = NULL;
|
||||
FILE *fd = NULL;
|
||||
|
||||
if(argc < 3){
|
||||
SCWrite(pCon,"ERROR: argument required for exe print",eError);
|
||||
return 0;
|
||||
if(self->exeStackPtr >= 0) {
|
||||
DynarGet(self->exeStack,self->exeStackPtr,&pPtr);
|
||||
buf = (pExeBuf) pPtr;
|
||||
if(buf != NULL){
|
||||
filePath = locateBatchBuffer(self,exeBufName(buf));
|
||||
}
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: no default buffer to print, argument required",eError);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
filePath = locateBatchBuffer(self,argv[2]);
|
||||
}
|
||||
filePath = locateBatchBuffer(self,argv[2]);
|
||||
if(filePath == NULL){
|
||||
snprintf(pLine,255,"ERROR: batch buffer %s not found in path",
|
||||
argv[2]);
|
||||
@ -610,7 +624,7 @@ static int enqueueBuffer(pExeMan self, SConnection *pCon,
|
||||
buf = exeBufCreate("enqueue");
|
||||
if(buf == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory",eError);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
status = exeBufLoad(buf,GetCharArray(filePath));
|
||||
DeleteDynString(filePath);
|
||||
@ -727,9 +741,6 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return status;
|
||||
}else if(strcmp(argv[1],"info") == 0){
|
||||
status = infoHandler(self,pCon,argc,argv);
|
||||
if(status){
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
return status;
|
||||
}else if(strcmp(argv[1],"print") == 0){
|
||||
status = printBuffer(self,pCon,argc,argv);
|
||||
@ -755,7 +766,11 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
}
|
||||
return status;
|
||||
} else {
|
||||
return runBatchBuffer(self,pCon,pSics,pBufferName);
|
||||
status = runBatchBuffer(self,pCon,pSics,pBufferName);
|
||||
if(self->exeStackPtr < 0){
|
||||
SCWrite(pCon,"EXE TERMINATED",eWarning);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: need argument to manage batch buffers",eError);
|
||||
|
10
fomerge.c
10
fomerge.c
@ -488,12 +488,12 @@ static int *calculateSum(HistInt *data, int iDet, int iTime)
|
||||
int i, j, iIndex;
|
||||
int *sum = NULL;
|
||||
|
||||
sum = (int *)malloc(iDet*sizeof(int));
|
||||
sum = (int *)malloc(iTime*sizeof(int));
|
||||
if(!sum)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(sum,0,iDet*sizeof(int));
|
||||
memset(sum,0,iTime*sizeof(int));
|
||||
|
||||
for(i = 0; i < iDet; i++)
|
||||
{
|
||||
@ -593,14 +593,14 @@ static int putElastic(SicsInterp *pSics, SConnection *pCon,
|
||||
/*
|
||||
copy sum to make compiler happy
|
||||
*/
|
||||
lSum = (long *)malloc(iDet*sizeof(long));
|
||||
lSum = (long *)malloc(iTime*sizeof(long));
|
||||
if(lSum == NULL)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in putElastc",eError);
|
||||
SCWrite(pCon,"ERROR: out of memory in putElastic",eError);
|
||||
free(sum);
|
||||
return NX_ERROR;
|
||||
}
|
||||
for(i = 0; i < iDet; i++)
|
||||
for(i = 0; i < iTime; i++)
|
||||
{
|
||||
lSum[i] = sum[i];
|
||||
}
|
||||
|
@ -555,6 +555,7 @@
|
||||
{
|
||||
return StringDictAddPair(self->pOption,name, value);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics)
|
||||
@ -1055,6 +1056,8 @@ static int checkHMEnd(pHistMem self, char *text){
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(argv[1],"preset") == 0) /* preset */
|
||||
{
|
||||
|
@ -49,9 +49,9 @@
|
||||
#include "HistDriv.i"
|
||||
#include "histsim.h"
|
||||
|
||||
/*
|
||||
|
||||
#define TESTVAL 128
|
||||
/*
|
||||
|
||||
define TESTVAL to set the simulated histogram to a fixed value for
|
||||
testing
|
||||
@ -175,7 +175,7 @@
|
||||
#ifdef TESTVAL
|
||||
for(ii = iStart; ii < iEnd; ii++)
|
||||
{
|
||||
lData[ii] = TESTVAL;
|
||||
lData[ii-iStart] = TESTVAL;
|
||||
}
|
||||
#else
|
||||
if(iSet == 1)
|
||||
|
14
hkl.c
14
hkl.c
@ -1205,8 +1205,20 @@ ente:
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int GetHKLFromAngles(pHKL self, SConnection *pCon, float fHKL[3])
|
||||
{
|
||||
int status;
|
||||
float fAng[4];
|
||||
|
||||
status = GetCurrentPosition(self,pCon,fAng);
|
||||
if(status == 1)
|
||||
{
|
||||
angle2HKL(self,fAng[0], fAng[1], fAng[2], fAng[3],fHKL);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int GetCommandData(int argc, char *argv[], float fHKL[3],
|
||||
float *fPsi, int *iHamil, SConnection *pCon)
|
||||
|
1
hkl.h
1
hkl.h
@ -34,6 +34,7 @@
|
||||
int GetLambda(pHKL self, float *fVal);
|
||||
int GetCurrentHKL(pHKL self, float fVal[3]);
|
||||
int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]);
|
||||
int GetHKLFromAngles(pHKL self, SConnection *pCon, float fVal[3]);
|
||||
|
||||
int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,
|
||||
float fSet[4],SConnection *pCon);
|
||||
|
2
hkl.i
2
hkl.i
@ -25,6 +25,8 @@
|
||||
pSelVar pMono;
|
||||
long lID;
|
||||
float scanTolerance;
|
||||
float targetHKL[3];
|
||||
int targetDirty;
|
||||
} HKL;
|
||||
|
||||
|
||||
|
86
hkl.tex
86
hkl.tex
@ -8,6 +8,9 @@ provided by Jean Allibon, ILL with the MAD four circle diffractometer
|
||||
control program in ANSI-C. For theory, see the contribution by
|
||||
W.C. Hamilton in the International Tables for Crystallography, 1974 edition.
|
||||
|
||||
There is a sister object to HKL which uses HKL to implement virtual motors for
|
||||
H, K, and L. See below for the description
|
||||
|
||||
The object uses the following object data structure:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
@ -33,6 +36,8 @@ $\langle$hkldat {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ pSelVar pMono;@\\
|
||||
\mbox{}\verb@ long lID;@\\
|
||||
\mbox{}\verb@ float scanTolerance;@\\
|
||||
\mbox{}\verb@ float targetHKL[3];@\\
|
||||
\mbox{}\verb@ int targetDirty;@\\
|
||||
\mbox{}\verb@ } HKL;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
@ -65,6 +70,9 @@ checking.
|
||||
\item[pMono] The selector variable doing the wavelength.
|
||||
\item[scanTolerance] The hkl module refuses to position a reflection if it is
|
||||
to close to omega limits for scanning. This is the tolerance to use.
|
||||
\item[targetHKL] The target HKL values to support the H, K, L virtual motors
|
||||
\item[targetDirty] A flag which is set when the virtual motors have to recalculate the
|
||||
settings and to drive.
|
||||
\end{description}
|
||||
|
||||
The wavelength is a bit tricky. As it would be to time consuming to read two
|
||||
@ -102,6 +110,7 @@ $\langle$hklint {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ int GetLambda(pHKL self, float *fVal);@\\
|
||||
\mbox{}\verb@ int GetCurrentHKL(pHKL self, float fVal[3]);@\\
|
||||
\mbox{}\verb@ int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]);@\\
|
||||
\mbox{}\verb@ int GetHKLFromAngles(pHKL self, SConnection *pCon, float fVal[3]); @\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,@\\
|
||||
\mbox{}\verb@ float fSet[4],SConnection *pCon);@\\
|
||||
@ -166,6 +175,7 @@ pointer to the connection object doing the command for error messages and
|
||||
everything. The error returns are the same as with CalculateSettings
|
||||
well. With the addition of HKJMOTFAIL, which means that a motor failed to
|
||||
drive properly.
|
||||
\item[GetHKLFromAngles] calculates the current HKL from Angles.
|
||||
\item[DriveSettings] drives to the the settings given in fSet.
|
||||
\item[HKLAction] is the interpreter wrapper function for the HKL object.
|
||||
\end{description}
|
||||
@ -220,3 +230,79 @@ drive properly.
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\subsubsection{The Crystallographic Virtual Motor Object}
|
||||
This module implements virtual motors H, K and L on top of the HKL object. It was choosen to implement this
|
||||
in a separate module because the hkl module is already big and complex enough. The problem is how to
|
||||
keep track of the necessary settings for HKL because the motors are interrelated. This is solved in the
|
||||
following scheme:
|
||||
\begin{itemize}
|
||||
\item Starting any of the motors H, K or L results in new values to be set in the HKL internal data
|
||||
structure and a dirty flag to be set.
|
||||
\item On a call to the drivable interfaces status function the dirty flag is checked and, if
|
||||
appropriate, the motor positions are recalculated and the motors started.
|
||||
\item H, K and L values are recalculated from motors on each read.
|
||||
\end{itemize}
|
||||
For each virtual motor an internal data structure is required:
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap5}
|
||||
$\langle$hklmotdat {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@typedef struct __HKLMOT {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pHKL pHkl;@\\
|
||||
\mbox{}\verb@ pIDrivable pDriv;@\\
|
||||
\mbox{}\verb@ int index;@\\
|
||||
\mbox{}\verb@ }HKLMot, *pHKLMot;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
The fields are:\begin{description}
|
||||
\item[pDes] The required object descriptor.
|
||||
\item[pHkl] The HKL object to use for calculations.
|
||||
\item[pDriv] The drivable interface.
|
||||
\item[index] The index of the motors target in the targetHKL array in the HKL structure.
|
||||
\end{description}
|
||||
The target HKL and the dirty flag is in the main HKL data structure.
|
||||
|
||||
There is no external interface to this, all the functionality is hidden in the drivable interface
|
||||
functions. The interpreter interface is minimal: only a value request is supported. There is
|
||||
however a factory function in order to install the HKL motors into the interpreter.
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap6}
|
||||
\verb@"hklmot.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------------------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ Virtual motor interface to reciprocal space coordinates H, K and L for a four circle diffractometer.@\\
|
||||
\mbox{}\verb@ Requires a HKL object for calculations.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, February 2005@\\
|
||||
\mbox{}\verb@--------------------------------------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHKLMOT@\\
|
||||
\mbox{}\verb@#define SICSHKLMOT@\\
|
||||
\mbox{}\verb@/*====================== data structure ==============================================================*/@\\
|
||||
\mbox{}\verb@@$\langle$hklmotdat {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@/*======================= interpreter interface ======================================================*/@\\
|
||||
\mbox{}\verb@int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
|
65
hkl.w
65
hkl.w
@ -8,6 +8,9 @@ provided by Jean Allibon, ILL with the MAD four circle diffractometer
|
||||
control program in ANSI-C. For theory, see the contribution by
|
||||
W.C. Hamilton in the International Tables for Crystallography, 1974 edition.
|
||||
|
||||
There is a sister object to HKL which uses HKL to implement virtual motors for
|
||||
H, K, and L. See below for the description
|
||||
|
||||
The object uses the following object data structure:
|
||||
@d hkldat @{
|
||||
typedef struct __HKL {
|
||||
@ -28,6 +31,8 @@ The object uses the following object data structure:
|
||||
pSelVar pMono;
|
||||
long lID;
|
||||
float scanTolerance;
|
||||
float targetHKL[3];
|
||||
int targetDirty;
|
||||
} HKL;
|
||||
@}
|
||||
|
||||
@ -53,6 +58,9 @@ checking.
|
||||
\item[pMono] The selector variable doing the wavelength.
|
||||
\item[scanTolerance] The hkl module refuses to position a reflection if it is
|
||||
to close to omega limits for scanning. This is the tolerance to use.
|
||||
\item[targetHKL] The target HKL values to support the H, K, L virtual motors
|
||||
\item[targetDirty] A flag which is set when the virtual motors have to recalculate the
|
||||
settings and to drive.
|
||||
\end{description}
|
||||
|
||||
The wavelength is a bit tricky. As it would be to time consuming to read two
|
||||
@ -85,6 +93,7 @@ module:
|
||||
int GetLambda(pHKL self, float *fVal);
|
||||
int GetCurrentHKL(pHKL self, float fVal[3]);
|
||||
int GetCurrentPosition(pHKL self, SConnection *pCon, float fPosition[4]);
|
||||
int GetHKLFromAngles(pHKL self, SConnection *pCon, float fVal[3]);
|
||||
|
||||
int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,
|
||||
float fSet[4],SConnection *pCon);
|
||||
@ -141,6 +150,7 @@ pointer to the connection object doing the command for error messages and
|
||||
everything. The error returns are the same as with CalculateSettings
|
||||
well. With the addition of HKJMOTFAIL, which means that a motor failed to
|
||||
drive properly.
|
||||
\item[GetHKLFromAngles] calculates the current HKL from Angles.
|
||||
\item[DriveSettings] drives to the the settings given in fSet.
|
||||
\item[HKLAction] is the interpreter wrapper function for the HKL object.
|
||||
\end{description}
|
||||
@ -178,3 +188,58 @@ drive properly.
|
||||
@<hklint@>
|
||||
#endif
|
||||
@}
|
||||
|
||||
\subsubsection{The Crystallographic Virtual Motor Object}
|
||||
This module implements virtual motors H, K and L on top of the HKL object. It was choosen to implement this
|
||||
in a separate module because the hkl module is already big and complex enough. The problem is how to
|
||||
keep track of the necessary settings for HKL because the motors are interrelated. This is solved in the
|
||||
following scheme:
|
||||
\begin{itemize}
|
||||
\item Starting any of the motors H, K or L results in new values to be set in the HKL internal data
|
||||
structure and a dirty flag to be set.
|
||||
\item On a call to the drivable interfaces status function the dirty flag is checked and, if
|
||||
appropriate, the motor positions are recalculated and the motors started.
|
||||
\item H, K and L values are recalculated from motors on each read.
|
||||
\end{itemize}
|
||||
For each virtual motor an internal data structure is required:
|
||||
@d hklmotdat @{
|
||||
typedef struct __HKLMOT {
|
||||
pObjectDescriptor pDes;
|
||||
pHKL pHkl;
|
||||
pIDrivable pDriv;
|
||||
int index;
|
||||
}HKLMot, *pHKLMot;
|
||||
@}
|
||||
The fields are:\begin{description}
|
||||
\item[pDes] The required object descriptor.
|
||||
\item[pHkl] The HKL object to use for calculations.
|
||||
\item[pDriv] The drivable interface.
|
||||
\item[index] The index of the motors target in the targetHKL array in the HKL structure.
|
||||
\end{description}
|
||||
The target HKL and the dirty flag is in the main HKL data structure.
|
||||
|
||||
There is no external interface to this, all the functionality is hidden in the drivable interface
|
||||
functions. The interpreter interface is minimal: only a value request is supported. There is
|
||||
however a factory function in order to install the HKL motors into the interpreter.
|
||||
|
||||
@o hklmot.h @{
|
||||
/*------------------------------------------------------------------------------------------------------
|
||||
Virtual motor interface to reciprocal space coordinates H, K and L for a four circle diffractometer.
|
||||
Requires a HKL object for calculations.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February 2005
|
||||
--------------------------------------------------------------------------------------------------------*/
|
||||
#ifndef SICSHKLMOT
|
||||
#define SICSHKLMOT
|
||||
/*====================== data structure ==============================================================*/
|
||||
@<hklmotdat@>
|
||||
/*======================= interpreter interface ======================================================*/
|
||||
int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||
int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@}
|
||||
|
247
hklmot.c
Normal file
247
hklmot.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*------------------------------------------------------------------------------------------------------
|
||||
Virtual motor interface to reciprocal space coordinates H, K and L for a four circle diffractometer.
|
||||
Requires a HKL object for calculations.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February 2005
|
||||
--------------------------------------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include "sics.h"
|
||||
#include "fortify.h"
|
||||
#include "motor.h"
|
||||
#include "matrix/matrix.h"
|
||||
#include "hkl.h"
|
||||
#include "hkl.i"
|
||||
#include "hklmot.h"
|
||||
/*=================== Object Descriptor Interface ===================================================*/
|
||||
static void *HKLGetInterface(void *pData, int iID){
|
||||
pHKLMot self = NULL;
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
if(self == NULL){
|
||||
return NULL;
|
||||
}
|
||||
if(iID == DRIVEID){
|
||||
return self->pDriv;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*=================== Drivable Interface ============================================================*/
|
||||
static int HKLHalt(void *pData){
|
||||
pHKLMot self = NULL;
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
assert(self != NULL);
|
||||
|
||||
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
|
||||
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
|
||||
if(self->pHkl->iNOR == 1){
|
||||
self->pHkl->pNu->pDrivInt->Halt(self->pHkl->pNu);
|
||||
} else {
|
||||
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
|
||||
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------------------------*/
|
||||
static int HKLCheckLimits(void *self, float fVal, char *error, int errLen){
|
||||
/*
|
||||
There is no meaningful implementation here. This gets called when starting the motor.
|
||||
At that stage not all other values may be known. If the calculation failes, this will die
|
||||
at status check time.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------*/
|
||||
static long HKLSetValue(void *pData, SConnection *pCon, float fVal){
|
||||
pHKLMot self = NULL;
|
||||
|
||||
if(!SCMatchRights(pCon,usUser)){
|
||||
return 0;
|
||||
}
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
assert(self != NULL);
|
||||
|
||||
self->pHkl->targetHKL[self->index] = fVal;
|
||||
self->pHkl->targetDirty = 1;
|
||||
return OKOK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------------------------------*/
|
||||
static int checkMotors(pHKLMot self, SConnection *pCon){
|
||||
int status;
|
||||
|
||||
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
|
||||
if(status != HWIdle && status != OKOK){
|
||||
return status;
|
||||
}
|
||||
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
|
||||
if(status != HWIdle && status != OKOK){
|
||||
return status;
|
||||
}
|
||||
if(self->pHkl->iNOR == 1){
|
||||
status = self->pHkl->pNu->pDrivInt->CheckStatus(self->pHkl->pNu, pCon);
|
||||
if(status != HWIdle && status != OKOK){
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
|
||||
if(status != HWIdle && status != OKOK){
|
||||
return status;
|
||||
}
|
||||
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
|
||||
if(status != HWIdle && status != OKOK){
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return HWIdle;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------------------------*/
|
||||
static int HKLCheckStatus(void *pData, SConnection *pCon){
|
||||
pHKLMot self = NULL;
|
||||
int status;
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
assert(self != NULL);
|
||||
if(self->pHkl->targetDirty == 1){
|
||||
status = RunHKL(self->pHkl,self->pHkl->targetHKL,.0,0,pCon);
|
||||
if(status != 1){
|
||||
return HWFault;
|
||||
}
|
||||
self->pHkl->targetDirty = 0;
|
||||
return HWBusy;
|
||||
} else {
|
||||
return checkMotors(self,pCon);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------------------------*/
|
||||
static float HKLGetValue(void *pData, SConnection *pCon){
|
||||
pHKLMot self = NULL;
|
||||
float fVal[3];
|
||||
int status;
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
assert(self != NULL);
|
||||
|
||||
|
||||
status = GetHKLFromAngles(self->pHkl,pCon,fVal);
|
||||
if(status != 1){
|
||||
SCWrite(pCon,"ERROR: failed to read positions or convert to HKL",eError);
|
||||
return -9999.99;
|
||||
}
|
||||
return fVal[self->index];
|
||||
}
|
||||
/*=============================== Live and Death ====================================*/
|
||||
static pHKLMot MakeHKLMot(pHKL pHkl, int index){
|
||||
pHKLMot self = NULL;
|
||||
|
||||
assert(pHkl != NULL);
|
||||
assert(index >= 0 && index < 3);
|
||||
|
||||
self = (pHKLMot)malloc(sizeof(HKLMot));
|
||||
if(self == NULL){
|
||||
return NULL;
|
||||
}
|
||||
memset(self,0,sizeof(HKLMot));
|
||||
self->pDes = CreateDescriptor("HKLMot");
|
||||
self->pDriv = CreateDrivableInterface();
|
||||
if(self->pDes == NULL || self->pDriv == NULL){
|
||||
free(self);
|
||||
return NULL;
|
||||
}
|
||||
self->pDes->GetInterface = HKLGetInterface;
|
||||
self->pDriv->Halt = HKLHalt;
|
||||
self->pDriv->CheckLimits = HKLCheckLimits;
|
||||
self->pDriv->SetValue = HKLSetValue;
|
||||
self->pDriv->CheckStatus = HKLCheckStatus;
|
||||
self->pDriv->GetValue = HKLGetValue;
|
||||
self->pHkl = pHkl;
|
||||
self->index = index;
|
||||
return self;
|
||||
}
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
static void KillHklMot(void *pData){
|
||||
pHKLMot self = NULL;
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
if(self == NULL){
|
||||
return;
|
||||
}
|
||||
if(self->pDes != NULL){
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
if(self->pDriv){
|
||||
free(self->pDriv);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*=============================== Interpreter Interface ============================*/
|
||||
int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
|
||||
pHKLMot self = NULL;
|
||||
float value;
|
||||
char pBuffer[132];
|
||||
|
||||
self = (pHKLMot)pData;
|
||||
assert(self != NULL);
|
||||
|
||||
value = self->pDriv->GetValue(self,pCon);
|
||||
if(value < -9000.){
|
||||
snprintf(pBuffer,131,"ERROR: failed to read %s",argv[0]);
|
||||
SCWrite(pCon,pBuffer,eError);
|
||||
return 0;
|
||||
}
|
||||
snprintf(pBuffer,131,"%s = %f", argv[0], value);
|
||||
SCWrite(pCon,pBuffer,eValue);
|
||||
return 1;
|
||||
}
|
||||
/*------------------------------------------------------------------------------------------*/
|
||||
int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
|
||||
pHKL pHkl;
|
||||
pHKLMot pMot = NULL;
|
||||
char pBuffer[131];
|
||||
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: Insifficient number of arguments to HKLMotInstall",eError);
|
||||
return 0;
|
||||
}
|
||||
strtolower(argv[1]);
|
||||
pHkl = (pHKL)FindCommandData(pSics,argv[1],"4-Circle-Calculus");
|
||||
if(pHkl == NULL){
|
||||
snprintf(pBuffer,131,"ERROR: %s is not present or no HKL object",argv[1]);
|
||||
SCWrite(pCon,pBuffer,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMot = MakeHKLMot(pHkl, 0);
|
||||
if(pMot == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating H Motor",eError);
|
||||
return 0;
|
||||
}
|
||||
if(!AddCommand(pSics,"H",HKLMotAction,KillHklMot,pMot)){
|
||||
SCWrite(pCon,"ERROR: duplicate command H not created",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMot = MakeHKLMot(pHkl, 1);
|
||||
if(pMot == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating K Motor",eError);
|
||||
return 0;
|
||||
}
|
||||
if(!AddCommand(pSics,"K",HKLMotAction,KillHklMot,pMot)){
|
||||
SCWrite(pCon,"ERROR: duplicate command K not created",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pMot = MakeHKLMot(pHkl, 2);
|
||||
if(pMot == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating L Motor",eError);
|
||||
return 0;
|
||||
}
|
||||
if(!AddCommand(pSics,"L",HKLMotAction,KillHklMot,pMot)){
|
||||
SCWrite(pCon,"ERROR: duplicate command L not created",eError);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
27
hklmot.h
Normal file
27
hklmot.h
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
/*------------------------------------------------------------------------------------------------------
|
||||
Virtual motor interface to reciprocal space coordinates H, K and L for a four circle diffractometer.
|
||||
Requires a HKL object for calculations.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February 2005
|
||||
--------------------------------------------------------------------------------------------------------*/
|
||||
#ifndef SICSHKLMOT
|
||||
#define SICSHKLMOT
|
||||
/*====================== data structure ==============================================================*/
|
||||
|
||||
typedef struct __HKLMOT {
|
||||
pObjectDescriptor pDes;
|
||||
pHKL pHkl;
|
||||
pIDrivable pDriv;
|
||||
int index;
|
||||
}HKLMot, *pHKLMot;
|
||||
|
||||
/*======================= interpreter interface ======================================================*/
|
||||
int HKLMotAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||
int HKLMotInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
|
||||
|
16
macro.c
16
macro.c
@ -129,7 +129,7 @@
|
||||
SConnection *pCon = NULL;
|
||||
CommandList *pCommand = NULL;
|
||||
char *lastCommand = NULL, comBuffer[132];
|
||||
int iRet,i;
|
||||
int iRet = 0,i;
|
||||
int iMacro;
|
||||
|
||||
/* get the datastructures */
|
||||
@ -194,7 +194,7 @@
|
||||
}
|
||||
|
||||
/* finish */
|
||||
if(iRet)
|
||||
if(iRet == 1)
|
||||
{
|
||||
return TCL_OK;
|
||||
}
|
||||
@ -328,6 +328,10 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
Tcl_DeleteCommand(pInter,"socket");
|
||||
Tcl_DeleteCommand(pInter,"vwait");
|
||||
Tcl_DeleteCommand(pInter,"exec");
|
||||
|
||||
/*
|
||||
install protected exec command
|
||||
*/
|
||||
Tcl_CreateObjCommand(pInter,"exec",ProtectedExec,NULL,KillExec);
|
||||
|
||||
return pInter;
|
||||
@ -847,8 +851,9 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
|
||||
iRet = Tcl_Eval(pTcl,pBueffel);
|
||||
if(iRet == TCL_OK)
|
||||
{ /* possibly a bug here */
|
||||
SCWrite(pCon,pTcl->result,eStatus);
|
||||
{
|
||||
strncpy(pBueffel,pTcl->result,1023);
|
||||
SCWrite(pCon,pBueffel,eStatus);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -862,7 +867,8 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
||||
else
|
||||
{
|
||||
Tcl_UnsetVar(pTcl,SICSERROR,TCL_GLOBAL_ONLY);
|
||||
SCWrite(pCon,pTcl->result,eError);
|
||||
strncpy(pBueffel,pTcl->result,1023);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
2
make_gen
2
make_gen
@ -19,7 +19,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
||||
histmem.o histdriv.o histsim.o interface.o callback.o \
|
||||
event.o emon.o evcontroller.o evdriver.o simev.o perfmon.o \
|
||||
danu.o nxdict.o varlog.o stptok.o nread.o \
|
||||
scan.o fitcenter.o telnet.o token.o wwildcard.o\
|
||||
scan.o fitcenter.o telnet.o token.o wwildcard.o hklmot.o\
|
||||
tclev.o hkl.o integrate.o optimise.o dynstring.o nxutil.o \
|
||||
mesure.o uubuffer.o commandlog.o udpquieck.o \
|
||||
rmtrail.o help.o nxupdate.o confvirtualmot.o \
|
||||
|
12
network.c
12
network.c
@ -169,7 +169,7 @@ CreateSocketAdress(
|
||||
|
||||
assert(self != NULL);
|
||||
|
||||
if(timeout > 0)
|
||||
if(timeout >= 0)
|
||||
{
|
||||
/* select first */
|
||||
tmo.tv_usec = (timeout % 1000) * 1000;
|
||||
@ -256,13 +256,15 @@ CreateSocketAdress(
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
i = sizeof(struct linger);
|
||||
lili.l_onoff = 1;
|
||||
lili.l_linger = 1;
|
||||
/* setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_LINGER,&lili,i);
|
||||
i = 1;
|
||||
setsockopt(pRes->sockid,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
|
||||
*/ pRes->iType = SOCKET;
|
||||
*/
|
||||
pRes->iType = SOCKET;
|
||||
pRes->lMagic = NETMAGIC;
|
||||
return pRes;
|
||||
}
|
||||
@ -386,7 +388,7 @@ CreateSocketAdress(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
if(timeout >= 0)
|
||||
{
|
||||
/* setup for select first */
|
||||
tmo.tv_usec = (timeout % 1000) *1000;
|
||||
@ -739,7 +741,7 @@ This old version may be removed in some stage. It has two problems:
|
||||
}
|
||||
assert(self->iType == UDP);
|
||||
|
||||
if(timeout > 0)
|
||||
if(timeout >= 0)
|
||||
{
|
||||
/* setup for select first */
|
||||
tmo.tv_usec = (timeout % 1000) *1000;
|
||||
|
2
nread.c
2
nread.c
@ -86,7 +86,7 @@ extern VerifyChannel(mkChannel *self); /* defined in network.c */
|
||||
|
||||
assert(pTask);
|
||||
assert(iPasswdTimeout > 0);
|
||||
assert(iReadTimeout > 0);
|
||||
assert(iReadTimeout >= 0);
|
||||
|
||||
pNew = (pNetRead)malloc(sizeof(NetReader));
|
||||
if(!pNew)
|
||||
|
12
nxscript.c
12
nxscript.c
@ -160,7 +160,7 @@ static int handleFileOperations(SConnection *pCon, pNXScript self,
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments for file operation",
|
||||
eError);
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
be considerate: close files left open
|
||||
@ -180,11 +180,13 @@ static int handleFileOperations(SConnection *pCon, pNXScript self,
|
||||
if(status != NX_OK){
|
||||
sprintf(buffer,"ERROR: failed to open %s",argv[2]);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
return -1;
|
||||
}
|
||||
status = NXDinitfromfile(argv[3],&self->dictHandle);
|
||||
if(status != NX_OK){
|
||||
sprintf(buffer,"ERROR: failed to open dictionary %s",argv[3]);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
return -1;
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
@ -261,6 +263,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
|
||||
eError);
|
||||
return;
|
||||
}
|
||||
memset(dummy,0,80*sizeof(char));
|
||||
|
||||
/*
|
||||
find counter
|
||||
@ -897,6 +900,8 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pNXScript self = (pNXScript)pData;
|
||||
char *pFile = NULL;
|
||||
int status;
|
||||
|
||||
/*
|
||||
preliminary checks
|
||||
*/
|
||||
@ -934,7 +939,10 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
|
||||
|
||||
|
||||
if(handleFileOperations(pCon,self,argc,argv)){
|
||||
status = handleFileOperations(pCon,self,argc,argv);
|
||||
if(status < 0){
|
||||
return 0;
|
||||
} else if(status == 1){
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
4
ofac.c
4
ofac.c
@ -108,6 +108,7 @@
|
||||
#include "exeman.h"
|
||||
#include "oscillate.h"
|
||||
#include "diffscan.h"
|
||||
#include "hklmot.h"
|
||||
/*----------------------- Server options creation -------------------------*/
|
||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -291,6 +292,8 @@
|
||||
MakeOscillator,NULL,NULL);
|
||||
AddCommand(pInter,"MakeDiffScan",
|
||||
MakeDiffScan,NULL,NULL);
|
||||
AddCommand(pInter,"MakeHKLMot",
|
||||
HKLMotInstall,NULL,NULL);
|
||||
|
||||
|
||||
/*
|
||||
@ -352,6 +355,7 @@
|
||||
RemoveCommand(pSics,"MakeBatchManager");
|
||||
RemoveCommand(pSics,"MakeOscillator");
|
||||
RemoveCommand(pSics,"MakeDiffScan");
|
||||
RemoveCommand(pSics,"MakeHKLMot");
|
||||
|
||||
/*
|
||||
remove site specific installation commands
|
||||
|
@ -134,6 +134,10 @@ int writeRS232(prs232 self, void *data, int dataLen)
|
||||
if(pPtr != NULL)
|
||||
free(pPtr);
|
||||
|
||||
if(iRet != 1){
|
||||
return BADSEND;
|
||||
}
|
||||
|
||||
return iRet;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
@ -213,17 +217,21 @@ int readRS232TillTerm(prs232 self, void *data, int *datalen){
|
||||
replylen = *datalen;
|
||||
iRet = NETReadTillTermNew(self->pSock,self->timeout,self->replyTerminator,
|
||||
(char *)data, replylen);
|
||||
if(self->debug > 0)
|
||||
if(self->debug > 0 && iRet == 1)
|
||||
{
|
||||
printf("RS232 IN/TERM : %s",(char *)data);
|
||||
if(strchr((char *)data,'\n') == NULL)
|
||||
{
|
||||
puts("");
|
||||
puts("");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
if(iRet == 0)
|
||||
{
|
||||
if(self->debug > 0)
|
||||
{
|
||||
printf("RS232 IN/TERM : TIMEOUT:%s\n",(char *)data);
|
||||
}
|
||||
return TIMEOUT;
|
||||
}
|
||||
else if(iRet == -1)
|
||||
@ -307,9 +315,9 @@ int transactRS232(prs232 self, void *send, int sendLen,
|
||||
write data
|
||||
*/
|
||||
iRet = writeRS232(self,send,sendLen);
|
||||
if(iRet < 0)
|
||||
if(iRet <= 0)
|
||||
{
|
||||
return iRet;
|
||||
return BADSEND;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -320,12 +328,23 @@ int transactRS232(prs232 self, void *send, int sendLen,
|
||||
reply, replyLen);
|
||||
if(self->debug > 0)
|
||||
{
|
||||
printf("RS232 IN/TRANS: %s",(char *)reply);
|
||||
if(strchr((char *)reply,'\n') == NULL)
|
||||
if(iRet == 1)
|
||||
{
|
||||
puts("");
|
||||
printf("RS232 IN/TRANS: %s",(char *)reply);
|
||||
if(strchr((char *)reply,'\n') == NULL)
|
||||
{
|
||||
puts("");
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
else if(iRet == 0)
|
||||
{
|
||||
printf("RS232 IN/TRANS: TIMEOUT\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("RS232 IN/TRANS/INCOMPLETE: %s",(char *)reply);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
if(iRet == 0)
|
||||
{
|
||||
@ -362,7 +381,7 @@ void getRS232Error(int iCode, char *errorBuffer,
|
||||
break;
|
||||
case TIMEOUT:
|
||||
strncpy(errorBuffer,
|
||||
"Timeout reading data",
|
||||
"Timeout or network error when reading data",
|
||||
errorBufferLen);
|
||||
break;
|
||||
case FAILEDCONNECT:
|
||||
@ -374,6 +393,9 @@ void getRS232Error(int iCode, char *errorBuffer,
|
||||
strncpy(errorBuffer,"Did not find terminator in read buffer",
|
||||
errorBufferLen);
|
||||
break;
|
||||
case BADSEND:
|
||||
strncpy(errorBuffer,"Network problem: failed to send",errorBufferLen);
|
||||
break;
|
||||
default:
|
||||
strncpy(errorBuffer,strerror(errno),
|
||||
errorBufferLen);
|
||||
@ -407,6 +429,21 @@ int initRS232(prs232 self)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
void closeRS232(prs232 self)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
if(self->pSock != NULL)
|
||||
{
|
||||
if(pServ->pReader != NULL){
|
||||
NetReadRemoveUserSocket(pServ->pReader,self->pSock->sockid);
|
||||
}
|
||||
NETClosePort(self->pSock);
|
||||
free(self->pSock);
|
||||
self->pSock = NULL;
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
prs232 createRS232(char *host, int iPort)
|
||||
{
|
||||
|
@ -22,6 +22,8 @@
|
||||
#define TIMEOUT -2702
|
||||
#define FAILEDCONNECT -2703
|
||||
#define INCOMPLETE -2704
|
||||
#define BADREAD -2705
|
||||
#define BADSEND -2706
|
||||
|
||||
/*----------------------- a data structure ----------------------------*/
|
||||
|
||||
@ -63,6 +65,7 @@
|
||||
int errorBufferLen);
|
||||
|
||||
int initRS232(prs232 self);
|
||||
void closeRS232(prs232 self);
|
||||
prs232 createRS232(char *host, int iPort);
|
||||
void KillRS232(void *pData);
|
||||
|
||||
|
@ -69,6 +69,7 @@ The following interface functions are provided:
|
||||
int errorBufferLen);
|
||||
|
||||
int initRS232(prs232 self);
|
||||
void closeRS232(prs232 self);
|
||||
prs232 createRS232(char *host, int iPort);
|
||||
void KillRS232(void *pData);
|
||||
@}
|
||||
@ -102,6 +103,7 @@ directly followed by a read.
|
||||
iCode.
|
||||
\item[initRS232] tries to close and reopen the RS232 connection. This is
|
||||
useful for the automatic fixing of communication problems encountered.
|
||||
\item[closeRS232] closes a network connection but does not delete the datastructure.
|
||||
\item[createRS232] creates a new rs232 data structure with all
|
||||
parameters at default values. The connection is NOT opened.
|
||||
\end{description}
|
||||
@ -130,6 +132,8 @@ parameters at default values. The connection is NOT opened.
|
||||
#define TIMEOUT -2702
|
||||
#define FAILEDCONNECT -2703
|
||||
#define INCOMPLETE -2704
|
||||
#define BADREAD -2705
|
||||
#define BADSEND -2706
|
||||
|
||||
/*----------------------- a data structure ----------------------------*/
|
||||
@<rs232dat@>
|
||||
|
158
sans2.tcl
158
sans2.tcl
@ -1,33 +1,48 @@
|
||||
# --------------------------------------------------------------------------
|
||||
# Initialization script for the instrument SANSII at SINQ
|
||||
#
|
||||
# Dr. Mark Koennecke, January - ???? 2003
|
||||
# Dr. Mark Koennecke, January - March 2003
|
||||
#
|
||||
# Changes:
|
||||
# Pavel Strunz, 15.04.2003: - changed backlash dz (0.15 --> 0.005)
|
||||
# Pavel Strunz, 16.04.2003: - changed NVS forbiden gaps according to the actual NVS037
|
||||
# Pavel Strunz, 23.04.2003: - changed backlash for all ecb motors
|
||||
# Pavel Strunz, 29.04.2003: - hakle.tcl sourced
|
||||
# Pavel Strunz, 20.11.2003: - source sans2geometry, sans2measurement
|
||||
# Pavel Strunz, 03.12.2003: - source scan_a, sans2wavelength, nvs interrupt changed from 3 to 0
|
||||
#---------------------------------------------------------------------------
|
||||
# O P T I O N S
|
||||
set root "/afs/psi.ch/user/k/koennecke/src/sics"
|
||||
set root "/home/SANS2"
|
||||
|
||||
set scriptroot $root/sans2_sics
|
||||
|
||||
|
||||
# first all the server options are set
|
||||
|
||||
ServerOption SaveFile $root/tmp/sans2stat.tcl
|
||||
ServerOption statusfile $root/data/2003/sans2stat.tcl
|
||||
# File to save the status of the instrument too
|
||||
|
||||
ServerOption ReadTimeOut 10
|
||||
ServerOption ReadTimeOut 5
|
||||
# timeout when checking for commands. In the main loop SICS checks for
|
||||
# pending commands on each connection with the above timeout, has
|
||||
# PERFORMANCE impact!
|
||||
|
||||
ServerOption AcceptTimeOut 10
|
||||
ServerOption AcceptTimeOut 5
|
||||
# timeout when checking for connection req.
|
||||
# Similar to above, but for connections
|
||||
|
||||
ServerOption ReadUserPasswdTimeout 500000
|
||||
# time to wiat for a user/passwd to be sent from a client. Increase this
|
||||
# time to wait for a user/passwd to be sent from a client. Increase this
|
||||
# if there is a problem connecting to a server due to network overload\
|
||||
|
||||
ServerOption LogFileBaseName $root/tmp/sans2log
|
||||
ServerOption LogFileBaseName $root/log/sans2log
|
||||
# the path and base name of the internal server logfile to which all
|
||||
# activity will be logged.
|
||||
|
||||
ServerOption ServerPort 2915
|
||||
ServerOption LogFileDir $root/log
|
||||
# This is where log files from command log go
|
||||
|
||||
ServerOption ServerPort 2911
|
||||
# the port number the server is going to listen at. The client MUST know
|
||||
# this number in order to connect. It is in client.ini
|
||||
|
||||
@ -46,9 +61,11 @@ TokenInit connan
|
||||
|
||||
# than the SICS users are specified
|
||||
# Syntax: SicsUser name password userRightsCode
|
||||
SicsUser Manager Joachim 1
|
||||
SicsUser User Kohl 2
|
||||
SicsUser Spy 007 1
|
||||
SicsUser Manager Manager 1
|
||||
SicsUser lnsmanager lnsSICSlns 1
|
||||
SicsUser User Looser 2
|
||||
SicsUser sans2user 04lns1 2
|
||||
SicsUser Spy 007 3
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# S I M P L E V A R I A B L E S
|
||||
@ -68,7 +85,7 @@ VarMake User Text User
|
||||
VarMake SubTitle Text User
|
||||
VarMake environment Text User
|
||||
VarMake comment Text User
|
||||
VarMake samplename Text User
|
||||
#VarMake samplename Text User
|
||||
VarMake email Text User
|
||||
VarMake fax Text User
|
||||
VarMake phone Text User
|
||||
@ -77,20 +94,21 @@ VarMake sample Text User
|
||||
VarMake BatchRoot Text User
|
||||
VarMake starttime Text User
|
||||
BatchRoot $root
|
||||
#BatchRoot $root/command
|
||||
|
||||
VarMake sampletable Text User
|
||||
|
||||
#----------- Initialize data storage stuff
|
||||
VarMake SicsDataPath Text Mugger
|
||||
SicsDataPath $root/tmp/
|
||||
SicsDataPath $root/data/2004/
|
||||
SicsDataPath lock
|
||||
VarMake SicsDataPrefix Text Mugger
|
||||
SicsDataPrefix sansII
|
||||
SicsDataPrefix sans2
|
||||
SicsDataPrefix lock
|
||||
VarMake SicsDataPostFix Text Mugger
|
||||
SicsDataPostFix ".hdf"
|
||||
SicsDataPostFix lock
|
||||
MakeDataNumber SicsDataNumber $root/tmp/DataNumber
|
||||
MakeDataNumber SicsDataNumber $root/data/2004/DataNumber
|
||||
|
||||
#=========================================================================
|
||||
# Initialize ECB system
|
||||
@ -113,7 +131,7 @@ ecbauto
|
||||
#-------------- ECB Motors
|
||||
# Motor name ecb ecb-controller ecb-motor-index hardlowerlimit hardupperlimit
|
||||
|
||||
Motor sr ecb ecb1 1 -10000. 10000.
|
||||
Motor sr ecb ecb1 1 -17500. 17500.
|
||||
sr encoder 0
|
||||
sr control 0
|
||||
sr range 1
|
||||
@ -130,7 +148,7 @@ sr offset 0
|
||||
sr dtolerance .01
|
||||
sr step2deg 1
|
||||
sr step2dig 0
|
||||
sr backlash .15
|
||||
sr backlash 500
|
||||
|
||||
Motor stx ecb ecb1 2 -16000. 16000.
|
||||
stx encoder 0
|
||||
@ -149,7 +167,7 @@ stx offset 0
|
||||
stx dtolerance .01
|
||||
stx step2deg 1
|
||||
stx step2dig 0
|
||||
stx backlash .15
|
||||
stx backlash 500
|
||||
|
||||
Motor stz ecb ecb1 3 6500. 20000.
|
||||
stz encoder 0
|
||||
@ -168,7 +186,7 @@ stz offset 0
|
||||
stz dtolerance .01
|
||||
stz step2deg 1
|
||||
stz step2dig 0
|
||||
stz backlash .15
|
||||
stz backlash 500
|
||||
|
||||
Motor sc ecb ecb1 4 -2000. 70000.
|
||||
sc encoder 0
|
||||
@ -187,7 +205,7 @@ sc offset 0
|
||||
sc dtolerance .01
|
||||
sc step2deg 1
|
||||
sc step2dig 0
|
||||
sc backlash .15
|
||||
sc backlash 1000
|
||||
|
||||
Motor gu ecb ecb1 5 -10000. 10000.
|
||||
gu encoder 0
|
||||
@ -206,7 +224,7 @@ gu offset 0
|
||||
gu dtolerance .02
|
||||
gu step2deg 1
|
||||
gu step2dig 0
|
||||
gu backlash .15
|
||||
gu backlash 100
|
||||
|
||||
Motor gl ecb ecb1 6 -10000. 10000.
|
||||
gl encoder 0
|
||||
@ -225,7 +243,7 @@ gl offset 0
|
||||
gl dtolerance .02
|
||||
gl step2deg 1
|
||||
gl step2dig 0
|
||||
gl backlash .15
|
||||
gl backlash 100
|
||||
|
||||
|
||||
Motor tu ecb ecb1 7 -10000. 10000.
|
||||
@ -245,7 +263,7 @@ tu offset 0
|
||||
tu dtolerance .01
|
||||
tu step2deg 1
|
||||
tu step2dig 0
|
||||
tu backlash .15
|
||||
tu backlash 100
|
||||
|
||||
|
||||
Motor tl ecb ecb1 8 -10000. 10000.
|
||||
@ -265,7 +283,7 @@ tl offset 0
|
||||
tl dtolerance .01
|
||||
tl step2deg 1
|
||||
tl step2dig 0
|
||||
tl backlash .15
|
||||
tl backlash 100
|
||||
|
||||
Motor om ecb ecb1 9 -10000. 10000.
|
||||
om encoder 1
|
||||
@ -284,7 +302,7 @@ om offset 0
|
||||
om dtolerance .01
|
||||
om step2deg 1
|
||||
om step2dig 10
|
||||
om backlash .15
|
||||
om backlash 100
|
||||
|
||||
Motor sz ecb ecb1 10 -10000. 10000.
|
||||
sz encoder 0
|
||||
@ -303,7 +321,7 @@ sz offset 0
|
||||
sz dtolerance .001
|
||||
sz step2deg 1
|
||||
sz step2dig 0
|
||||
sz backlash .15
|
||||
sz backlash 100
|
||||
|
||||
Motor sx ecb ecb1 11 -10000. 10000.
|
||||
sx encoder 0
|
||||
@ -322,7 +340,7 @@ sx offset 0
|
||||
sx dtolerance .01
|
||||
sx step2deg 1
|
||||
sx step2dig 0
|
||||
sx backlash .15
|
||||
sx backlash 100
|
||||
|
||||
Motor sy ecb ecb1 12 -10000. 10000.
|
||||
sy encoder 0
|
||||
@ -341,9 +359,9 @@ sy offset 0
|
||||
sy dtolerance .001
|
||||
sy step2deg 1
|
||||
sy step2dig 0
|
||||
sy backlash .15
|
||||
sy backlash 100
|
||||
|
||||
Motor dz ecb ecb1 13 1.05 6.0
|
||||
Motor dz ecb ecb1 13 0.905 6.015
|
||||
dz encoder 0
|
||||
dz control 0
|
||||
dz range 1
|
||||
@ -360,9 +378,9 @@ dz offset 0
|
||||
dz dtolerance .001
|
||||
dz step2deg 53076
|
||||
dz step2dig 0
|
||||
dz backlash .15
|
||||
dz backlash .005
|
||||
|
||||
Motor dh ecb ecb1 14 -14000. 16000.
|
||||
Motor dh ecb ecb1 14 -10100. 16400.
|
||||
dh encoder 0
|
||||
dh control 0
|
||||
dh range 1
|
||||
@ -379,9 +397,9 @@ dh offset 0
|
||||
dh dtolerance .001
|
||||
dh step2deg 1
|
||||
dh step2dig 0
|
||||
dh backlash .15
|
||||
dh backlash 100
|
||||
|
||||
Motor dv ecb ecb1 15 -14000. 25000.
|
||||
Motor dv ecb ecb1 15 -14600. 25400.
|
||||
dv encoder 0
|
||||
dv control 0
|
||||
dv range 1
|
||||
@ -398,7 +416,7 @@ dv offset 0
|
||||
dv dtolerance .001
|
||||
dv step2deg 1
|
||||
dv step2dig 0
|
||||
dv backlash .15
|
||||
dv backlash 100
|
||||
|
||||
Motor az1 ecb ecb1 16 -3900. 0.
|
||||
az1 encoder 0
|
||||
@ -417,7 +435,7 @@ az1 offset 0
|
||||
az1 dtolerance .001
|
||||
az1 step2deg 1
|
||||
az1 step2dig 0
|
||||
az1 backlash .15
|
||||
az1 backlash 200
|
||||
|
||||
Motor atz ecb ecb1 17 -3900. 0.
|
||||
atz encoder 0
|
||||
@ -436,7 +454,7 @@ atz offset 0
|
||||
atz dtolerance .001
|
||||
atz step2deg 1
|
||||
atz step2dig 0
|
||||
atz backlash .15
|
||||
atz backlash 200
|
||||
|
||||
#===========================================================================
|
||||
# The ECB system has the drawback that only one out of 8 motors in a rack
|
||||
@ -531,12 +549,16 @@ proc sans2rack args {
|
||||
}
|
||||
return
|
||||
}
|
||||
Publish sans2rack User #---------for testing purposes
|
||||
Publish sans2rack User
|
||||
anticollision script sans2rack
|
||||
#====================== PSI Motoren ===================================
|
||||
Motor ome EL734 sans2 4000 2 1
|
||||
Motor chi EL734 sans2 4000 2 2
|
||||
Motor tilt EL734 sans2 4000 3 1
|
||||
Motor ome EL734 sans2 4000 3 1
|
||||
Motor chi EL734 sans2 4000 3 2
|
||||
Motor phi EL734 sans2 4000 3 3
|
||||
Motor tilt EL734 sans2 4000 2 1
|
||||
|
||||
SicsAlias ome traz "These motors are used to drive SANS I translation table"
|
||||
SicsAlias chi trax "while ome is sample z and chi is sample x (TG070704)"
|
||||
#====================== Multi Motor Setup ==============================
|
||||
MakeMulti detector
|
||||
detector alias dz x
|
||||
@ -565,9 +587,9 @@ gonio endconfig
|
||||
MakeMulti table
|
||||
table alias om om
|
||||
table alias sz z
|
||||
table alias sx x
|
||||
table alias sx x
|
||||
table alias sy y
|
||||
table endconfig
|
||||
table endconfig#
|
||||
#====================== HISTOGRAM MEMORY ================================
|
||||
MakeCounter counter ecb ecb1
|
||||
MakeECB tdc gpib 0 7
|
||||
@ -587,27 +609,57 @@ banana init
|
||||
banana exponent 6
|
||||
banana CountMode timer
|
||||
banana preset 100
|
||||
#=========================== velocity selector ========================
|
||||
VelocitySelector nvs tilt SIM
|
||||
=========================== velocity selector ========================
|
||||
set dorn(Host) psts233
|
||||
set dorn(Port) 3004
|
||||
set dorn(Channel) 4
|
||||
set dorn(Timeout) 20000
|
||||
set dorn(MinControl) 6500
|
||||
VelocitySelector nvs tilt dornier2003 dorn
|
||||
#VelocitySelector nvs tilt SIM
|
||||
nvs add -20 28800
|
||||
nvs add 3600 4300
|
||||
nvs add 7600 9600
|
||||
nvs add 13400 13450
|
||||
nvs add 24200 24250
|
||||
nvs add 3600 4500
|
||||
nvs add 7800 10500
|
||||
nvs add 21500 23500
|
||||
nvs status
|
||||
nvs interrupt 0
|
||||
MakeSANSWave lambda nvs
|
||||
emon unregister nvswatch
|
||||
#===================================== auxiliary hardware ==============
|
||||
set distoCON [gpib attach 0 14 0 13 0 1]
|
||||
|
||||
#--------- for the Hakle Feucht
|
||||
MakeRS232Controller h50 psts233 3005
|
||||
#===================================== data file writing ================
|
||||
MakeNXScript
|
||||
#===================================== install commands ==================
|
||||
MakeDrive
|
||||
MakeRuenBuffer
|
||||
commandlog auto
|
||||
#=================================== load specific command file ===========
|
||||
source $root/sans2com.tcl
|
||||
MakePSDFrame
|
||||
SerialInit
|
||||
#--------- drive command
|
||||
MakeDrive
|
||||
SicsAlias drive dr
|
||||
#----------- for adding scripted content to the status file
|
||||
MakeTclInt bckintern
|
||||
#----- alias for temperature
|
||||
DefineAlias tt temperature
|
||||
#=================================== load specific command files ===========
|
||||
source $scriptroot/sans2com.tcl
|
||||
source $scriptroot/hakle.tcl
|
||||
source $scriptroot/hakle50.tcl
|
||||
source $scriptroot/HaakeSetup.tcl
|
||||
source $scriptroot/A1931Setup.tcl
|
||||
source $scriptroot/sans2geometry.tcl
|
||||
source $scriptroot/sans2measurement.tcl
|
||||
source $scriptroot/sans2wavelength.tcl
|
||||
source $scriptroot/scan_a.tcl
|
||||
# initialisation for IPS-120 superconducting magnet power supply
|
||||
# this definition does not harm other devices used through the same channel
|
||||
ips init localhost 4000 7
|
||||
#=================================== load display definition =============
|
||||
source $root/sans2dis.tcl
|
||||
|
||||
|
||||
#source $scriptroot/sans2dis.tcl
|
||||
|
||||
#=======================================================================
|
||||
disto
|
||||
|
@ -40,7 +40,7 @@
|
||||
*name, float start, float step);
|
||||
/**
|
||||
* InitScanVar clears the list of scan points
|
||||
* @param pvar The scna variable to clear
|
||||
* @param pvar The scan variable to clear
|
||||
*/
|
||||
void InitScanVar(pVarEntry pVar);
|
||||
/**
|
||||
|
@ -161,6 +161,10 @@
|
||||
SDE sVal;
|
||||
int iRet;
|
||||
|
||||
if(pResult != NULL)
|
||||
{
|
||||
pResult[0] = '\0';
|
||||
}
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
|
7
telnet.c
7
telnet.c
@ -96,7 +96,7 @@
|
||||
char *pPtr = NULL;
|
||||
char *pLogin = NULL;
|
||||
char *pUser = NULL, *pPasswd = NULL;
|
||||
char pBuffer[512];
|
||||
char pBuffer[512], pHost[131];
|
||||
int iRet;
|
||||
time_t shit;
|
||||
|
||||
@ -178,6 +178,11 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
NETInfo(self->pCon->pSock,pHost,131);
|
||||
sprintf(pBuffer,"Accepted connection on socket %d from %s",
|
||||
self->pCon->pSock->sockid, pHost);
|
||||
SICSLogWrite(pBuffer,eInternal);
|
||||
WriteToCommandLog("SYS >", pBuffer);
|
||||
SendWelcome(self->pCon);
|
||||
SCSetRights(self->pCon,iRet);
|
||||
self->iLogin = 1;
|
||||
|
Reference in New Issue
Block a user