- Added code to read SANS TOF frames from a) files and b) from HM
- Fixed an bug causing core dumps on bad Tcl scripts - Started on a syntax checker for SICS
This commit is contained in:
2
Makefile
2
Makefile
@ -59,7 +59,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
||||
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \
|
||||
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \
|
||||
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) ecb.o ecbdriv.o \
|
||||
ecbcounter.o hmdata.o tdchm.o nxscript.o A1931.o
|
||||
ecbcounter.o hmdata.o tdchm.o nxscript.o A1931.o frame.o
|
||||
|
||||
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||
|
@ -503,7 +503,7 @@
|
||||
|
||||
/* get size of our problem */
|
||||
GetHistDim(self->pHM,iDim,&i3);
|
||||
assert(i3 == 3);
|
||||
/* assert(i3 == 3); */
|
||||
|
||||
/* allocate some data */
|
||||
length = 2 + iDim[0]*iDim[1];
|
||||
@ -546,7 +546,7 @@
|
||||
iImage[i] = htonl(iImage[i]);
|
||||
}
|
||||
/*
|
||||
printf("Collpased maximum: %d\n",iMax);
|
||||
printf("Collapsed maximum: %d\n",iMax);
|
||||
*/
|
||||
if(status != 1)
|
||||
{
|
||||
@ -557,14 +557,15 @@
|
||||
else
|
||||
{
|
||||
/*
|
||||
we are in simulation and justcreate some random numbers
|
||||
we are in simulation and just create some random numbers
|
||||
*/
|
||||
for(i = 0; i < iDim[0]; i++)
|
||||
{
|
||||
for(i2 = 0; i2 < iDim[1]; i2++)
|
||||
{
|
||||
iIdx = i*iDim[1] + i2;
|
||||
iImage[iIdx+2] = htonl(random());
|
||||
iImage[iIdx+2] = htonl(random());
|
||||
/* iImage[iIdx+2] = htonl(77);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,18 +185,17 @@ Motor COX SIM -100. 100. .1 2. # counter x
|
||||
ClientPut "Motors initialized"
|
||||
|
||||
#======================== histogram memory
|
||||
MakeHM hm SinqHM
|
||||
#MakeHM hm SIM
|
||||
#MakeHM hm SinqHM
|
||||
MakeHM hm SIM
|
||||
hm configure OverFlowMode Ceil
|
||||
hm configure HistMode PSD
|
||||
hm configure Rank 1
|
||||
hm configure Rank 2
|
||||
hm configure dim0 256
|
||||
hm configure dim1 256
|
||||
hm configure xfac 10
|
||||
hm configure yfac 10
|
||||
hm configure xoff 128
|
||||
hm configure yoff 128
|
||||
hm configure Length 65536
|
||||
hm configure BinWidth 4
|
||||
hm preset 100.
|
||||
hm CountMode Timer
|
||||
|
32
commandlog.c
32
commandlog.c
@ -37,10 +37,29 @@
|
||||
static pCircular pTail = NULL;
|
||||
#define MAXTAIL 1000
|
||||
/*----------------------------------------------------------------------*/
|
||||
void WriteToCommandLog(char *prompt,char *pText)
|
||||
void WriteToCommandLog(char *prompt,char *text)
|
||||
{
|
||||
int iNL = 0, iPos;
|
||||
char *pPtr = NULL;
|
||||
char *pPtr = NULL, *pCopy = NULL, *pText = NULL;
|
||||
char myBuffer[1024];
|
||||
|
||||
/*
|
||||
we change the text, so we need to make a local copy. A copy
|
||||
is dynamically allocated only if it does not fit into
|
||||
myBuffer.
|
||||
*/
|
||||
if(strlen(text) > 1023){
|
||||
pCopy = (char *)malloc((strlen(text)+2)*sizeof(char));
|
||||
if(pCopy == NULL){
|
||||
return;
|
||||
}
|
||||
memset(pCopy,0,(strlen(text)+2)*sizeof(char));
|
||||
strcpy(pCopy,text);
|
||||
pText = pCopy;
|
||||
} else {
|
||||
strcpy(myBuffer,text);
|
||||
pText = myBuffer;
|
||||
}
|
||||
|
||||
/* figure out if we have to do a newline with pText as well */
|
||||
pPtr = strrchr(pText,'\n');
|
||||
@ -56,6 +75,9 @@
|
||||
/* supress status messages */
|
||||
if(strstr(pText,"status =") != NULL)
|
||||
{
|
||||
if(pCopy != NULL){
|
||||
free(pCopy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -64,6 +86,9 @@
|
||||
*/
|
||||
if(strstr(pText,"TRANSACTIONFINISHED") != NULL)
|
||||
{
|
||||
if(pCopy != NULL){
|
||||
free(pCopy);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -108,6 +133,9 @@
|
||||
setCircular(pTail,strdup(pText));
|
||||
nextCircular(pTail);
|
||||
}
|
||||
if(pCopy != NULL){
|
||||
free(pCopy);
|
||||
}
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void PrintTail(int iNum, SConnection *pCon)
|
||||
|
8
conman.c
8
conman.c
@ -22,6 +22,9 @@
|
||||
Added compressed writing method.
|
||||
Mark Koennecke, October 2000
|
||||
|
||||
Added simulation mode
|
||||
Mark Koennecke, March 2003
|
||||
|
||||
Copyright: see copyright.h
|
||||
-----------------------------------------------------------------------------*/
|
||||
#include "fortify.h"
|
||||
@ -1169,7 +1172,8 @@ void SCSetWriteFunc(SConnection *self, writeFunc x)
|
||||
}
|
||||
if(pCon->iGrab)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: Request refused, control has been grabbed by somebody else");
|
||||
sprintf(pBueffel,
|
||||
"ERROR: Request refused, control has been grabbed by somebody else");
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
@ -1390,7 +1394,7 @@ void SCSetWriteFunc(SConnection *self, writeFunc x)
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* check no or args */
|
||||
if(argc < 3)
|
||||
{
|
||||
|
4
conman.h
4
conman.h
@ -113,7 +113,9 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
||||
int SCMatchRights(SConnection *pCon, int iCode);
|
||||
int SCGetOutClass(SConnection *self);
|
||||
int SCGetGrab(SConnection *pCon);
|
||||
|
||||
/********************* simulation mode ************************************/
|
||||
void SCSetSimMode(SConnection *pCon, int value);
|
||||
int SCinSimMode(SConnection *pCon);
|
||||
/* **************************** Invocation ******************************** */
|
||||
int SCInvoke(SConnection *self,SicsInterp *pInter,char *pCommand);
|
||||
|
||||
|
11
devexec.c
11
devexec.c
@ -162,7 +162,7 @@
|
||||
{
|
||||
pDevEntry pNew = NULL;
|
||||
int iRet;
|
||||
char pBueffel[132];
|
||||
char pBueffel[132], pError[80];
|
||||
pIDrivable pDrivInt = NULL;
|
||||
pICountable pCountInt = NULL;
|
||||
|
||||
@ -199,16 +199,16 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* start it */
|
||||
/* start it */
|
||||
pDrivInt = pDes->GetInterface(pData,DRIVEID);
|
||||
pCountInt = pDes->GetInterface(pData,COUNTID);
|
||||
if(pDrivInt)
|
||||
{
|
||||
iRet = pDrivInt->SetValue(pData,pCon,fNew);
|
||||
iRet = pDrivInt->SetValue(pData,pCon,fNew);
|
||||
}
|
||||
else if(pCountInt)
|
||||
{
|
||||
iRet = pCountInt->StartCount(pData,pCon);
|
||||
iRet = pCountInt->StartCount(pData,pCon);
|
||||
}
|
||||
else
|
||||
{ /* this is a programmers error */
|
||||
@ -356,6 +356,9 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
check the status of all registered devices. Remove when finished
|
||||
*/
|
||||
iRet = LLDnodePtr2First(self->iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
|
239
frame.c
Normal file
239
frame.c
Normal file
@ -0,0 +1,239 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
A module implementing functionality for reading single time frames
|
||||
from PSD time-of-flight datasets. This can be done either from
|
||||
SINQHM histogram memories or from old data files visible from the
|
||||
SICS server. The result is sent to the demanding client in UUencoded
|
||||
format.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February-March 2003
|
||||
---------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "stringdict.h"
|
||||
#include "counter.h"
|
||||
#include "HistMem.h"
|
||||
#include "HistMem.i"
|
||||
#include "HistDriv.i"
|
||||
#include "hardsup/sinqhm.h"
|
||||
#include "sinqhmdriv.i"
|
||||
#include "nxdict.h"
|
||||
#include "frame.h"
|
||||
/*======================================================================*/
|
||||
static int readHMFrame(SConnection *pCon, pHistMem pHM, int nFrame){
|
||||
HistInt *buffer = NULL;
|
||||
int iDim[MAXDIM], rank, length, status, i;
|
||||
pSINQHM pHist;
|
||||
SinqHMDriv *pTata;
|
||||
|
||||
/*
|
||||
find dimensions and allocate data
|
||||
*/
|
||||
GetHistDim(pHM,iDim,&rank);
|
||||
if(rank < 2){
|
||||
SCWrite(pCon,"ERROR: no PSD data present, cannot send frame",eError);
|
||||
return 0;
|
||||
}
|
||||
length = iDim[0]*iDim[1];
|
||||
buffer = (HistInt *)malloc((length + 2)*sizeof(HistInt));
|
||||
if(!buffer){
|
||||
SCWrite(pCon,"ERROR: out of memory in readHMFrame",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(buffer,0,(length+2)*sizeof(HistInt));
|
||||
|
||||
/*
|
||||
first two values are dimensions
|
||||
*/
|
||||
buffer[0] = htonl(iDim[0]);
|
||||
buffer[1] = htonl(iDim[1]);
|
||||
|
||||
if(isSINQHMDriv(pHM->pDriv) && rank == 3) {
|
||||
/*
|
||||
read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h
|
||||
Again: be friendly: fix out of range frames
|
||||
*/
|
||||
if(nFrame < 0){
|
||||
nFrame = 0;
|
||||
}
|
||||
if(nFrame >= iDim[2]){
|
||||
nFrame = iDim[2]-1;
|
||||
}
|
||||
pTata = (SinqHMDriv *)pHM->pDriv->pPriv;
|
||||
pHist = (pSINQHM)pTata->pMaster;
|
||||
status = SINQHMProject(pHist, 5, 0, nFrame,
|
||||
0, iDim[1], buffer+2,length*sizeof(HistInt));
|
||||
if(status != 1){
|
||||
SCWrite(pCon,"ERROR: SINQHM refused to deliver frame",eError);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
be friendly, just read the 2D data which is there
|
||||
*/
|
||||
status = GetHistogram(pHM,pCon,0,0,length,buffer+2,length*sizeof(HistInt));
|
||||
if(!status){
|
||||
free(buffer);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
enforce network byte order
|
||||
*/
|
||||
for(i = 0; i < length; i++){
|
||||
buffer[i+2] = htonl(buffer[i+2]);
|
||||
}
|
||||
|
||||
SCWriteUUencoded(pCon,"framedata", buffer,(length+2)*sizeof(HistInt));
|
||||
free(buffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*=======================================================================*/
|
||||
static int readFileFrame(SConnection *pCon,
|
||||
char *file, char *dictFile,
|
||||
char *alias, int nFrame){
|
||||
int status, iDim[NX_MAXRANK], rank = 0, type = 0;
|
||||
int iStart[3], iSize[3], length, i;
|
||||
int *buffer = NULL;
|
||||
NXhandle fileHandle;
|
||||
NXdict dictHandle;
|
||||
char error[512];
|
||||
|
||||
status = NXopen(file,NXACC_READ,&fileHandle);
|
||||
if(status != NX_OK){
|
||||
sprintf(error,"ERROR: failed to open %s", file);
|
||||
SCWrite(pCon,error,eError);
|
||||
return 0;
|
||||
}
|
||||
status = NXDinitfromfile(dictFile, &dictHandle);
|
||||
if(status != NX_OK){
|
||||
sprintf(error,"ERROR: failed to open dictionary %s", dictFile);
|
||||
NXclose(&fileHandle);
|
||||
SCWrite(pCon,error,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = NXDopenalias(fileHandle,dictHandle,alias);
|
||||
if(status != NX_OK){
|
||||
sprintf(error,"ERROR: failed to open alias %s", alias);
|
||||
NXclose(&fileHandle);
|
||||
NXDclose(dictHandle,NULL);
|
||||
SCWrite(pCon,error,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = NXgetinfo(fileHandle,&rank,iDim,&type);
|
||||
if(type != NX_INT32 && type != NX_UINT32)type = -1;
|
||||
if(status != NX_OK || rank < 2 || type < 0 ){
|
||||
sprintf(error,"ERROR: Dataset does not match!");
|
||||
NXclose(&fileHandle);
|
||||
NXDclose(dictHandle,NULL);
|
||||
SCWrite(pCon,error,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
allocate space
|
||||
*/
|
||||
length = iDim[0]*iDim[1];
|
||||
buffer = (int *)malloc((length+2)*sizeof(int));
|
||||
if(!buffer){
|
||||
NXclose(&fileHandle);
|
||||
NXDclose(dictHandle,NULL);
|
||||
SCWrite(pCon,"ERROR: out of memory in readFrameFromFile",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(buffer,0,(length+2)*sizeof(int));
|
||||
|
||||
/*
|
||||
first two values: dimensions
|
||||
*/
|
||||
buffer[0] = htonl(iDim[0]);
|
||||
buffer[1] = htonl(iDim[1]);
|
||||
|
||||
if(rank == 2){
|
||||
/*
|
||||
be friendly
|
||||
*/
|
||||
status = NXgetdata(fileHandle,buffer+2);
|
||||
} else {
|
||||
iStart[0] = iStart[1] = 0;
|
||||
iStart[2] = nFrame;
|
||||
iSize[0] = iDim[0];
|
||||
iSize[1] = iDim[1];
|
||||
iSize[2] = 1;
|
||||
status = NXgetslab(fileHandle,buffer+2,iStart,iSize);
|
||||
}
|
||||
if(status != NX_OK){
|
||||
NXclose(&fileHandle);
|
||||
NXDclose(dictHandle,NULL);
|
||||
free(buffer);
|
||||
SCWrite(pCon,"ERROR: failed to read data",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
enforce network byte order
|
||||
*/
|
||||
for(i = 0; i < length; i++){
|
||||
buffer[2+i] = htonl(buffer[2+i]);
|
||||
}
|
||||
|
||||
SCWriteUUencoded(pCon,"framedata",buffer,(length+2)*sizeof(int));
|
||||
NXclose(&fileHandle);
|
||||
NXDclose(dictHandle,NULL);
|
||||
free(buffer);
|
||||
return 1;
|
||||
}
|
||||
/*=======================================================================*/
|
||||
int PSDFrameAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pHistMem pHM;
|
||||
int nFrame;
|
||||
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments to PSDFrame",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"hm") == 0){
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments to PSDFrame",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
pHM = (pHistMem)FindCommandData(pSics,argv[2],"HistMem");
|
||||
if(pHM == NULL){
|
||||
SCWrite(pCon,"ERROR: Did not find histogram memory",eError);
|
||||
return 0;
|
||||
}
|
||||
nFrame = atoi(argv[3]);
|
||||
return readHMFrame(pCon,pHM,nFrame);
|
||||
} else if(strcmp(argv[1],"file") == 0){
|
||||
if(argc < 6 ){
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments to PSDframe file",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
nFrame = atoi(argv[5]);
|
||||
return readFileFrame(pCon,argv[2],argv[3],argv[4],nFrame);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: subcommand to PSDframe not recognised",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*======================================================================*/
|
||||
int MakeFrameFunc(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
return AddCommand(pSics,"PSDframe",PSDFrameAction,NULL,NULL);
|
||||
}
|
||||
|
22
frame.h
Normal file
22
frame.h
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
A module implementing functionality for reading single time frames
|
||||
from PSD time-of-flight datasets. This can be done either from
|
||||
SINQHM histogram memories or from old data files visible from the
|
||||
SICS server.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February-March 2003
|
||||
*/
|
||||
#ifndef SICSFRAME
|
||||
#define SICSFRAME
|
||||
|
||||
int MakeFrameFunc(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int PSDFrameAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
|
||||
#endif
|
32
frame.w
Normal file
32
frame.w
Normal file
@ -0,0 +1,32 @@
|
||||
\subsection{Frame}
|
||||
This module allows to retrieve data frames from a 3D histogram (PSD plus
|
||||
time dimension). This can be done either from a Sinq histogram memory
|
||||
and old data files visible from the SICS server.
|
||||
|
||||
This module has no data structure and only implements the usual
|
||||
interpreter interface functions.
|
||||
|
||||
|
||||
@o frame.h @{
|
||||
/*-------------------------------------------------------------------------
|
||||
A module implementing functionality for reading single time frames
|
||||
from PSD time-of-flight datasets. This can be done either from
|
||||
SINQHM histogram memories or from old data files visible from the
|
||||
SICS server.
|
||||
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February-March 2003
|
||||
*/
|
||||
#ifndef SICSFRAME
|
||||
#define SICSFRAME
|
||||
|
||||
int MakeFrameFunc(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
int PSDFrameAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]);
|
||||
|
||||
|
||||
#endif
|
||||
@}
|
5
macro.c
5
macro.c
@ -438,8 +438,9 @@
|
||||
SCWrite(pCon,pTcl->result,eError);
|
||||
}
|
||||
pCom = Tcl_DStringValue(&command);
|
||||
sprintf(pBueffel,"ERROR: in Tcl line: %s",pCom);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
SCWrite(pCon,"ERROR: in Tcl block:",eError);
|
||||
SCWrite(pCon,pCom,eError);
|
||||
SCWrite(pCon,"ERROR: end of Tcl error block",eError);
|
||||
}
|
||||
else /* SICS error */
|
||||
{
|
||||
|
1
nread.c
1
nread.c
@ -494,6 +494,7 @@ extern VerifyChannel(mkChannel *self); /* defined in network.c */
|
||||
case '\r':
|
||||
case '\n':
|
||||
iStat = CostaTop(pItem->pCon->pStack,pItem->pHold);
|
||||
/* printf("%s\n",pItem->pHold); */
|
||||
if(!iStat)
|
||||
{
|
||||
SCWrite(pItem->pCon,"ERROR: Busy",eError);
|
||||
|
12
nxdata.c
12
nxdata.c
@ -726,12 +726,8 @@
|
||||
NXclosedata(Nfil);
|
||||
|
||||
/* histogram Length */
|
||||
iStat = HistGetOption(pHist,"Length",pBuffer,131);
|
||||
if(!iStat)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
iVal = atoi(pBuffer);
|
||||
GetHistDim(pHist,iDim,&iVal);
|
||||
iVal = iDim[0];
|
||||
if(iVal < 1)
|
||||
{
|
||||
return 0;
|
||||
@ -831,6 +827,10 @@
|
||||
SNputdata1att(Nfil,"sample_mur",NX_FLOAT32, 1,&pVar->fVal,
|
||||
"Units","???");
|
||||
}
|
||||
/* do a3 */
|
||||
SNPutMotor(Nfil,pSics,pCon,"a3",
|
||||
"sample_table_rotation","degree");
|
||||
|
||||
/* write sample environment here */
|
||||
pCom = FindCommand(pSics,"temperature");
|
||||
if(pCom)
|
||||
|
3
ofac.c
3
ofac.c
@ -111,6 +111,7 @@
|
||||
#include "gpibcontroller.h"
|
||||
#include "ecb.h"
|
||||
#include "nxscript.h"
|
||||
#include "frame.h"
|
||||
/*----------------------- Server options creation -------------------------*/
|
||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[])
|
||||
@ -297,6 +298,7 @@
|
||||
AddCommand(pInter,"MakeGPIB",MakeGPIB,NULL,NULL);
|
||||
AddCommand(pInter,"MakeECB",MakeECB,NULL,NULL);
|
||||
AddCommand(pInter,"MakeNXScript",MakeNXScript,NULL,NULL);
|
||||
AddCommand(pInter,"MakePSDFrame",MakeFrameFunc,NULL,NULL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void KillIniCommands(SicsInterp *pSics)
|
||||
@ -360,6 +362,7 @@
|
||||
RemoveCommand(pSics,"MakeGPIB");
|
||||
RemoveCommand(pSics,"MakeECB");
|
||||
RemoveCommand(pSics,"MakeNXScript");
|
||||
RemoveCommand(pSics,"MakePSDFrame");
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,6 +118,9 @@
|
||||
#define PROJECT__SAMPLE 0x0004 /* sum a rectangular part of the PSD
|
||||
detector in time
|
||||
*/
|
||||
#define PROJECT__FRAME 0x0005 /* select a frame from a 3D histogram:
|
||||
2 position dims plus time binning
|
||||
*/
|
||||
/*
|
||||
** ----------------------------------------------------------
|
||||
** Definition of bits in <flag> of TOF edge-array
|
||||
|
@ -2203,6 +2203,80 @@ extern PART_ID sysHighMemPart;
|
||||
exit (KER__BAD_VALUE);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* project_frame reads one time frame of a TOF or PSD histogram
|
||||
*/
|
||||
static int project_frame(int rw_skt, int pkt_size, int nx){
|
||||
struct rply_buff_struct rply;
|
||||
uint *buffer = NULL;
|
||||
uchar *bufPtr;
|
||||
int i, bytesToSend, nSend, bytesSent;
|
||||
register union {
|
||||
void *base;
|
||||
uchar *ch;
|
||||
usint *i2;
|
||||
uint *i4;
|
||||
} hm_pntr;
|
||||
|
||||
printf("PROJECT: Trying to retrieve time frame: %d\n", nx);
|
||||
|
||||
/*
|
||||
check arguments
|
||||
*/
|
||||
if(nx < 0 || nx >= N_bins){
|
||||
printf("PROJECT FRAME: bad time frame requested: 0 < %d < %d\n",
|
||||
nx,N_bins);
|
||||
rply_status_setup (&rply, KER__BAD_VALUE, 0, "Bad argument");
|
||||
rply_status_send (rw_skt, &rply);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
allocate space
|
||||
*/
|
||||
buffer = (uint *)malloc(N_hists*sizeof(uint));
|
||||
if(!buffer){
|
||||
printf ("\n\007 -- SQHM_PROJECT-FRAME: failed to get buffer!\n");
|
||||
rply_status_setup_and_send (rw_skt, &rply, KER__BAD_ALLOC, 0,
|
||||
"Failed to get buffer for projecting data");
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
fill buffer
|
||||
FIX: This works only OK with 4 byte HM data.
|
||||
*/
|
||||
hm_pntr.i4 = Hist_base_addr;
|
||||
for(i = 0; i < N_hists;i++){
|
||||
buffer[i] = htonl(*(hm_pntr.i4 + (i*N_bins) + nx));
|
||||
}
|
||||
|
||||
/*
|
||||
build reply and send data
|
||||
*/
|
||||
rply.bigend = 0x12345678;
|
||||
rply.u.project.n_bins = htonl(N_hists);
|
||||
rply.u.project.bytes_per_bin = htonl(4);
|
||||
rply.u.project.cnts_lo = 0;
|
||||
rply.u.project.cnts_hi = 0;
|
||||
rply_status_setup_and_send (rw_skt, &rply, KER__SUCCESS, 0, NULL);
|
||||
bufPtr = (uchar *)buffer;
|
||||
bytesToSend = N_hists*4;
|
||||
while(bytesToSend > 0){
|
||||
nSend = (bytesToSend > pkt_size) ? pkt_size : bytesToSend;
|
||||
bytesSent = send(rw_skt,bufPtr,nSend,0);
|
||||
if(bytesSent > 0){
|
||||
bytesToSend -= bytesSent;
|
||||
bufPtr += bytesSent;
|
||||
} else {
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
free(buffer);
|
||||
|
||||
return OK;
|
||||
}
|
||||
/*
|
||||
**--------------------------------------------------------------------------*/
|
||||
int do_project (
|
||||
@ -2322,6 +2396,9 @@ extern PART_ID sysHighMemPart;
|
||||
break;
|
||||
/*-----------------------------------------------------------*/
|
||||
case SQHM__TOF: /* Time-of-Flight Mode */
|
||||
if( (sub_code & PROJECT__FRAME) == 0){
|
||||
return project_frame(rw_skt,pkt_size,nx);
|
||||
}
|
||||
|
||||
if ((sub_code & PROJECT__1_DIM) != 0) {
|
||||
printf ("\n\007%s -- SQHM_PROJECT: SQHM__TOF+PROJECT__1_DIM not yet "
|
||||
@ -2389,6 +2466,10 @@ extern PART_ID sysHighMemPart;
|
||||
/*
|
||||
** code for TRICS, AMOR PSD
|
||||
*/
|
||||
if( (sub_code & PROJECT__FRAME) == 0){
|
||||
return project_frame(rw_skt,pkt_size,nx);
|
||||
}
|
||||
|
||||
if(sub_code == PROJECT__COLL){
|
||||
my_nbins = psdXSize * psdYSize;
|
||||
nTime = Tof_edges[0]->n_bins;
|
||||
|
2
telnet.c
2
telnet.c
@ -78,7 +78,7 @@
|
||||
SCWrite(pCon,"Continuing here seriously compromises hacker's ethics",eError);
|
||||
SCWrite(pCon,"You will NOT find valuable data here!",eError);
|
||||
SCWrite(pCon,"The SICS server does NOT allow you to spawn to the system",eError);
|
||||
SCWrite(pCon,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",eError);
|
||||
SCWrite(pCon,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!",eError);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static void SendGA(SConnection *pCon)
|
||||
|
86
utils/check/sicssyntax.tex
Normal file
86
utils/check/sicssyntax.tex
Normal file
@ -0,0 +1,86 @@
|
||||
\documentclass[12pt,a4paper]{article}
|
||||
%%\usepackage[dvips]{graphics}
|
||||
%%\usepackage{epsf}
|
||||
\setlength{\textheight}{24cm}
|
||||
\setlength{\textwidth}{16cm}
|
||||
\setlength{\headheight}{0cm}
|
||||
\setlength{\headsep}{0cm}
|
||||
\setlength{\topmargin}{0cm}
|
||||
\setlength{\oddsidemargin}{0cm}
|
||||
\setlength{\evensidemargin}{0cm}
|
||||
\setlength{\hoffset}{0cm}
|
||||
\setlength{\marginparwidth}{0cm}
|
||||
|
||||
\begin{document}
|
||||
\begin{center}
|
||||
\begin{Large}
|
||||
SICS Syntax Checker\\
|
||||
Implementation Notes\\
|
||||
\end{Large}
|
||||
Mark K\"onnecke\\
|
||||
Mark.Koennecke@psi.ch\\
|
||||
March/April 2003\\
|
||||
Laboratory for Neutron Scattering\\
|
||||
Paul Scherrer Institute\\
|
||||
CH--5232 Villigen--PSI
|
||||
Switzerland
|
||||
\end{center}
|
||||
|
||||
Users wish to check their batch files for syntax errors before
|
||||
submitting them to SICS for the weekend or the night. Unfortunately
|
||||
checking SICS syntax is not so easy as it consists of Tcl syntax plus
|
||||
SICS commands. In order to implement a syntax checker various
|
||||
possibilities exist:\begin{itemize}
|
||||
\item Implement the syntax checker as a calculation mode within
|
||||
SICS. This has the disadvantage that the syntax check can only be run
|
||||
by one person and only when the SICS server is not performing an
|
||||
experiment. This is due to the fact, that SICS has only one set of
|
||||
variables which may be changed dureing the syntax check. In order to
|
||||
prevent corruption the security measures stated above are necessary.
|
||||
\item Use a SICServer with simulated hardware. This would
|
||||
work. Problems are that this is very time consuming to set up and the
|
||||
synchronisation of parameter values with the main SICServer. This has
|
||||
been solved through the sync command and thus this option is available
|
||||
for complex scripts.
|
||||
\item Use a Tcl interpreter with dummy SICS commands as a syntax
|
||||
checker. In many cases batch files are fairly simple and a complete
|
||||
simulation is not needed. The such a option would be sufficient.
|
||||
\end{itemize}
|
||||
\end{document}
|
||||
|
||||
\section{The Tcl Syntax Checker}
|
||||
This section describes the syntax checker built from a Tcl interpreter
|
||||
with dummy routines testing SICS syntax. The dummy procedures only
|
||||
have to test the syntax and else do nothing. Not many such proecdures
|
||||
have to be implemented but a means is needed for mapping names, for
|
||||
instance motor names, to a suitable procedure for checking the syntax.
|
||||
|
||||
This syntax checker can be used in a variety of situations:
|
||||
\begin{itemize}
|
||||
\item Standalone: the preferred mode of operation
|
||||
\item Within SICS: SICS would need to have a second Tcl interpreter
|
||||
for this purpose in order to prevent corruption of the main
|
||||
interpreter. Even then a rogue script could go into an endless loop
|
||||
and thus hang the SICS server. Thus this second interpreter would have
|
||||
to run as a separate process or thread.
|
||||
\item This syntax checker could also help debugging SICS scripts.
|
||||
\end{itemize}
|
||||
|
||||
For each instrument two files are needed for this syntax checker. The
|
||||
first is a common library file which implements the syntax checking
|
||||
procedures and the sics_alias procedure which maps names to
|
||||
procedures. The second is a mapping file which defines the instrument
|
||||
and enables those names the instrument provides. This is much like the
|
||||
instrument initialization file for the main SICS program.
|
||||
|
||||
In order to help in script debugging, a global array with parameter
|
||||
values defined through the user script will be maintained.
|
||||
|
||||
In a latter stage a connection to the main SICS could be added to the
|
||||
system. Through this connection the actual configuration of the
|
||||
instrument could be queried. Also parameter values can be updated in
|
||||
order to help in debugging sophisticated scripts. Moreover this
|
||||
connection could be used to check limit violations.
|
||||
|
||||
|
||||
|
168
utils/check/sicssyntaxlib.tcl
Normal file
168
utils/check/sicssyntaxlib.tcl
Normal file
@ -0,0 +1,168 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# This is the library file for the Tcl syntax checker for SICS commands.
|
||||
# The basic idea is this:
|
||||
# - SICS commands are replaced by Tcl procedures with the same name which
|
||||
# implement the actual syntax check for this command.
|
||||
# - As many SICS commands are object commands a facility is needed to map
|
||||
# syntax checking procedures to names.
|
||||
#
|
||||
# copyright: see file COPYRIGHT
|
||||
#
|
||||
# Mark Koennecke, March 2003
|
||||
#---------------------------------------------------------------------------
|
||||
# sicsSyntaxMap maps the procedure syntaxProc to the name name. The name
|
||||
# is prepended to the argument list in order to make the name available
|
||||
# in the syntax checking procedure as the first argument
|
||||
# This means syntax check procedures have two arguments:
|
||||
# - the name
|
||||
# - the list of remaining parameters as a string. Use syntaxListify
|
||||
# to convert the list to a proper list for further processing
|
||||
#---------------------------------------------------------------------------
|
||||
proc sicsSyntaxMap {name syntaxProc} {
|
||||
append newProc "proc " $name " args " \{ $syntaxProc " "
|
||||
append newProc $name " " "\$args" \}
|
||||
eval $newProc
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# a helper procedure which tests a value if it is numeric
|
||||
#--------------------------------------------------------------------------
|
||||
proc syntaxNumeric {val} {
|
||||
set ret [catch {expr $val *1.} msg]
|
||||
if { $ret == 0} {
|
||||
return 1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# a helper procedure which converts a stringified list back into a proper
|
||||
# list
|
||||
#--------------------------------------------------------------------------
|
||||
proc syntaxListify {uff} {
|
||||
set l [string trim $uff "{}"]
|
||||
return [split $l]
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# a helper procedure which gets a parameter from the global parameter
|
||||
# array or replaces it by the default 77 if it does not exist
|
||||
#-------------------------------------------------------------------------
|
||||
proc syntaxGet {name} {
|
||||
global sicsPar
|
||||
if { [info exists sicsPar($name)] == 1} {
|
||||
return [format "%s = %s" $name \
|
||||
$sicsPar($name)]
|
||||
} else {
|
||||
return [format " %s = 77" $name]
|
||||
}
|
||||
}
|
||||
#------------------------------------------------------------------------
|
||||
# syntaxCounterMode tests if par is a valid counter mode
|
||||
#-----------------------------------------------------------------------
|
||||
proc syntaxCounterMode {par} {
|
||||
set p [string trim [string tolower $par]]
|
||||
switch $p{
|
||||
monitor { return 1}
|
||||
timer {return 1}
|
||||
default { return 0}
|
||||
}
|
||||
}
|
||||
#---------------------------------------------------------------------------
|
||||
# syntaxDummy is a syntax checking procedure which does nothing. This is a
|
||||
# quick fix for SICS commands for which no syntax checking procedure has yet
|
||||
# been defined.
|
||||
#-------------------------------------------------------------------------
|
||||
proc syntaxDummy {name args} {
|
||||
set args [syntaxListify $args]
|
||||
return
|
||||
}
|
||||
#-----------------------------------------------------------------------
|
||||
# syntaxTextPar is a syntax handling procedure for simple text variables
|
||||
#----------------------------------------------------------------------
|
||||
proc syntaxTextPar {name args} {
|
||||
global sicsPar
|
||||
|
||||
set args [syntaxListify $args]
|
||||
if { [llength $args] > 0} {
|
||||
set sicsPar($name) [join $args]
|
||||
} else {
|
||||
if { [info exists sicsPar($name)] == 1} {
|
||||
return [format "%s = %s" $name \
|
||||
$sicsPar($name)]
|
||||
} else {
|
||||
return [format " %s = UNKNOWN" $name]
|
||||
}
|
||||
}
|
||||
}
|
||||
#------------------------------------------------------------------------
|
||||
# syntaxNumPar is a syntax handling procedure for a numeric variable
|
||||
#-----------------------------------------------------------------------
|
||||
proc syntaxNumPar {name args} {
|
||||
global sicsPar
|
||||
|
||||
set args [syntaxListify $args]
|
||||
if { [llength $args] > 0} {
|
||||
if { [syntaxNumeric [lindex $args 0]] == 1} {
|
||||
set sicsPar($name) [lindex $args 0]
|
||||
} else {
|
||||
error [format \
|
||||
"ERROR: expected numeric argument for %s, received: %s" \
|
||||
$name [lindex $args 0]]
|
||||
}
|
||||
} else {
|
||||
return [syntaxGet $name]
|
||||
}
|
||||
}
|
||||
#--------------------------------------------------------------------------
|
||||
# syntaxMotor handles the syntax for a SICS motor
|
||||
#-------------------------------------------------------------------------
|
||||
lappend motSubKey list reset interest uninterest position hardposition
|
||||
lappend motSub hardlowerlim hardupperlim softlowerlim
|
||||
lappend motSub softupperlim softzero fixed interruptmode precision
|
||||
lappend motSub accessmode sign failafter
|
||||
|
||||
proc syntaxMotor {name args} {
|
||||
global sicsPar motSub motSubKey
|
||||
|
||||
set args [syntaxListify $args]
|
||||
#----- value request
|
||||
if { [llength $args] == 0} {
|
||||
return [syntaxGet $name]
|
||||
}
|
||||
#---------- keywords
|
||||
set subcommand [string tolower [lindex $args 0]]
|
||||
if { [lsearch $motSubKey $subcommand] >= 0} {
|
||||
return
|
||||
}
|
||||
#---------- parameters
|
||||
if { [lsearch $motSub $subcommand] < 0} {
|
||||
error [format "ERROR: motor %s does not know subcommand %s" \
|
||||
$name $subcommand]
|
||||
} else {
|
||||
if { [llength $args] > 1 } {
|
||||
set val [lindex $args 1]
|
||||
if { [syntaxNumeric $val] == 0 } {
|
||||
error [format "ERROR: %s.%s expected number, received %s" \
|
||||
$name $subcommand $val]
|
||||
} else {
|
||||
set sicsPar($name.$subcommand) $val
|
||||
}
|
||||
} else {
|
||||
return [syntaxGet $name.$subcommand]
|
||||
}
|
||||
}
|
||||
}
|
||||
#---------------------------------------------------------------------------
|
||||
# syntaxCounter deals with the syntax for a single counter
|
||||
#---------------------------------------------------------------------------
|
||||
proc syntaxCounter {name args} {
|
||||
global sicsPar motSub motSubKey
|
||||
|
||||
set args [syntaxListify $args]
|
||||
if { [llength $args == 0} {
|
||||
error [format "ERROR: subcommand expected to %s" $name]
|
||||
}
|
||||
#--------- get command
|
||||
set subcommand [string trim [string tolower [lindex $args 0]]]
|
||||
switch $subcommand {
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user