PSI sics-cvs-psi-complete-tree-post-site-support
This commit is contained in:
299
nxscript.c
299
nxscript.c
@@ -7,18 +7,25 @@
|
||||
copyright: see file COPYRIGHT
|
||||
|
||||
Mark Koennecke, February 2003
|
||||
Mark Koennecke, January 2004
|
||||
------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <tcl.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include "fortify.h"
|
||||
#include "sics.h"
|
||||
#include "splitter.h"
|
||||
#include "HistMem.h"
|
||||
#include "motor.h"
|
||||
#include "counter.h"
|
||||
#include "sicsvar.h"
|
||||
#include "danu.h"
|
||||
#include "udpquieck.h"
|
||||
#include "nxdict.h"
|
||||
#include "nxscript.h"
|
||||
@@ -28,6 +35,86 @@ typedef struct {
|
||||
NXhandle fileHandle;
|
||||
NXdict dictHandle;
|
||||
} NXScript, *pNXScript;
|
||||
/*------------------------------------------------------------------------*/
|
||||
char *makeFilename(SicsInterp *pSics, SConnection *pCon) {
|
||||
pSicsVariable pPath = NULL, pPref = NULL, pEnd = NULL;
|
||||
char *pRes = NULL;
|
||||
int iLen, iNum, iYear, thousand;
|
||||
char pNumText[10], pBueffel[256];
|
||||
CommandList *pCom = NULL;
|
||||
DIR *dir = NULL;
|
||||
|
||||
/* Try, get all the Variables */
|
||||
pPath = FindVariable(pSics,"sicsdatapath");
|
||||
pPref = FindVariable(pSics,"sicsdataprefix");
|
||||
pCom = FindCommand(pSics,"sicsdatanumber");
|
||||
pEnd = FindVariable(pSics,"sicsdatapostfix");
|
||||
|
||||
if( (!pPath) || (!pPref) || (!pCom) || (!pEnd) ){
|
||||
SCWrite(pCon,
|
||||
"ERROR: cannot read variables for automatic data file name creation",
|
||||
eError);
|
||||
SCWrite(pCon,
|
||||
"ERROR: This is a VERY, VERY, VERY serious installation problem",
|
||||
eError);
|
||||
SCWrite(pCon,"ERROR: your data will be dumped into emergency.hdf",eError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* find length */
|
||||
iLen = strlen(pPath->text) + 4; /* extra 4 for dir number */
|
||||
iLen += strlen(pPref->text);
|
||||
iLen += 9; /* for number + year */
|
||||
iLen += strlen(pEnd->text);
|
||||
iLen += 10; /* safety margin */
|
||||
|
||||
/* allocate memory */
|
||||
pRes = (char *)malloc(iLen*sizeof(char));
|
||||
if(!pRes){
|
||||
SCWrite(pCon,"ERROR: no memory in makeFilename",eError);
|
||||
return NULL;
|
||||
}
|
||||
memset(pRes,0,iLen);
|
||||
|
||||
/* increment the data file number */
|
||||
iNum = IncrementDataNumber(pCom->pData,&iYear);
|
||||
if(iNum < 0){
|
||||
SCWrite(pCon,"ERROR: cannot increment data number!",eError);
|
||||
SCWrite(pCon,"ERROR: your data will be dumped to emergency.hdf",eError);
|
||||
free(pRes);
|
||||
return NULL;
|
||||
}
|
||||
strcpy(pRes,pPath->text);
|
||||
thousand = (int)floor(iNum/1000.);
|
||||
snprintf(pNumText,9,"%3.3d",thousand);
|
||||
strcat(pRes,pNumText);
|
||||
|
||||
/*
|
||||
check for existence of directory and create if neccessary
|
||||
*/
|
||||
dir = opendir(pRes);
|
||||
if(dir == NULL){
|
||||
mkdir(pRes,S_IRWXU | S_IRGRP | S_IXGRP);
|
||||
snprintf(pBueffel,255,"Creating dir: %s", pRes);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
} else {
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
/*
|
||||
build the rest of the filename
|
||||
*/
|
||||
strcat(pRes,"/");
|
||||
strcat(pRes,pPref->text);
|
||||
sprintf(pNumText,"%4.4d",iYear);
|
||||
strcat(pRes,pNumText);
|
||||
strcat(pRes,"n");
|
||||
sprintf(pNumText,"%5.5d",iNum);
|
||||
strcat(pRes,pNumText);
|
||||
strcat(pRes,pEnd->text);
|
||||
|
||||
return pRes;
|
||||
}
|
||||
/*======================== Action =======================================*/
|
||||
static int handleFileOperations(SConnection *pCon, pNXScript self,
|
||||
int argc, char *argv[]){
|
||||
@@ -40,6 +127,10 @@ static int handleFileOperations(SConnection *pCon, pNXScript self,
|
||||
close everything! and send a message to trigger file synchronisation
|
||||
to the central server
|
||||
*/
|
||||
if(self->fileHandle == NULL){
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
i = 511;
|
||||
iVal = NX_CHAR;
|
||||
NXgetattr(self->fileHandle,"file_name",buffer,&i,&iVal);
|
||||
@@ -54,8 +145,10 @@ static int handleFileOperations(SConnection *pCon, pNXScript self,
|
||||
access = NXACC_RDWR;
|
||||
} else if(strcmp(argv[1],"create4") == 0){
|
||||
access = NXACC_CREATE4;
|
||||
unlink(argv[2]); /* kill file for overwrite */
|
||||
} else if(strcmp(argv[1],"create5") == 0){
|
||||
access = NXACC_CREATE5;
|
||||
unlink(argv[2]); /* kill file for overwrite */
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@@ -78,7 +171,6 @@ static int handleFileOperations(SConnection *pCon, pNXScript self,
|
||||
/*
|
||||
now initialize ourselves
|
||||
*/
|
||||
unlink(argv[2]); /* kill file for overwrite */
|
||||
status = NXopen(argv[2],access,&self->fileHandle);
|
||||
if(status != NX_OK){
|
||||
sprintf(buffer,"ERROR: failed to open %s",argv[2]);
|
||||
@@ -138,7 +230,7 @@ static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
|
||||
*/
|
||||
strcpy(buffer,argv[2]);
|
||||
strcat(buffer,"_null");
|
||||
if(NXDget(self->dictHandle,buffer,dummy,255)){
|
||||
if(NXDdefget(self->dictHandle,buffer,dummy,255)){
|
||||
MotorGetPar(brumm,"softzero",&fVal);
|
||||
status = NXDputalias(self->fileHandle,self->dictHandle,buffer, &fVal);
|
||||
if(status != NX_OK){
|
||||
@@ -210,7 +302,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
|
||||
fVal = GetCountTime(cter,pCon);
|
||||
strcpy(newAlias,argv[2]);
|
||||
strcat(newAlias,"_time");
|
||||
if(NXDget(self->dictHandle,newAlias,dummy,79)){
|
||||
if(NXDdefget(self->dictHandle,newAlias,dummy,79)){
|
||||
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
|
||||
if(status != NX_OK){
|
||||
sprintf(buffer,"ERROR: failed to write count time to %s", newAlias);
|
||||
@@ -224,7 +316,7 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
|
||||
*/
|
||||
for(i = 0; i < 10; i++){
|
||||
sprintf(newAlias,"%s_%2.2d",argv[2],i);
|
||||
if(NXDget(self->dictHandle,newAlias,dummy,79)){
|
||||
if(NXDdefget(self->dictHandle,newAlias,dummy,79)){
|
||||
counts = GetMonitor(cter,i,pCon);
|
||||
icounts = (int)counts;
|
||||
status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,
|
||||
@@ -234,6 +326,34 @@ static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
|
||||
|
||||
return;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void updateHMDim(NXScript *self, pHistMem mem){
|
||||
int iDim[MAXDIM];
|
||||
int i, rank, timeLength, status;
|
||||
char dummy[40], value[20];
|
||||
const float *timeBin;
|
||||
|
||||
/*
|
||||
update the dimension variables in the dictionary
|
||||
*/
|
||||
GetHistDim(mem,iDim,&rank);
|
||||
for(i = 0; i < rank; i++){
|
||||
sprintf(dummy,"dim%1.1d", i);
|
||||
sprintf(value,"%d",iDim[i]);
|
||||
status = NXDupdate(self->dictHandle,dummy,value);
|
||||
if(status == 0) {
|
||||
NXDadd(self->dictHandle,dummy,value);
|
||||
}
|
||||
}
|
||||
timeBin = GetHistTimeBin(mem,&timeLength);
|
||||
if(timeLength > 2){
|
||||
sprintf(dummy,"%d",timeLength);
|
||||
status = NXDupdate(self->dictHandle,"timedim",dummy);
|
||||
if(status == 0) {
|
||||
NXDadd(self->dictHandle,"timedim",dummy);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------
|
||||
The sequence of things is important in here: The code for updating
|
||||
the dimensions variables also applies the time binning to the length.
|
||||
@@ -244,11 +364,9 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
|
||||
pNXScript self,
|
||||
int argc, char *argv[]){
|
||||
pHistMem mem = NULL;
|
||||
int status, start, length, iDim[MAXDIM], rank, i, subset = 0;
|
||||
int status, start, length, i, subset = 0;
|
||||
HistInt *iData = NULL;
|
||||
char buffer[256], dummy[40], value[20];
|
||||
const float *timeBin;
|
||||
int timeLength;
|
||||
char buffer[256];
|
||||
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to puthm",
|
||||
@@ -272,26 +390,7 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
|
||||
start = 0;
|
||||
length = GetHistLength(mem);
|
||||
|
||||
/*
|
||||
update the dimension variables in the dictionary
|
||||
*/
|
||||
GetHistDim(mem,iDim,&rank);
|
||||
for(i = 0; i < rank; i++){
|
||||
sprintf(dummy,"dim%1.1d", i);
|
||||
sprintf(value,"%d",iDim[i]);
|
||||
status = NXDupdate(self->dictHandle,dummy,value);
|
||||
if(status == 0) {
|
||||
NXDadd(self->dictHandle,dummy,value);
|
||||
}
|
||||
}
|
||||
timeBin = GetHistTimeBin(mem,&timeLength);
|
||||
if(timeLength > 2){
|
||||
sprintf(dummy,"%d",timeLength);
|
||||
status = NXDupdate(self->dictHandle,"timedim",dummy);
|
||||
if(status == 0) {
|
||||
NXDadd(self->dictHandle,"timedim",dummy);
|
||||
}
|
||||
}
|
||||
updateHMDim(self,mem);
|
||||
|
||||
/*
|
||||
check for further arguments specifying a subset
|
||||
@@ -314,6 +413,105 @@ static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
read HM
|
||||
*/
|
||||
if(subset){
|
||||
iData = (HistInt *)malloc(length*sizeof(HistInt));
|
||||
if(!iData){
|
||||
SCWrite(pCon,"ERROR: out of memory for reading histogram memory",
|
||||
eError);
|
||||
return;
|
||||
}
|
||||
memset(iData,0,length*sizeof(HistInt));
|
||||
status = GetHistogramDirect(mem,pCon,0,start,start+length,iData,
|
||||
length*sizeof(HistInt));
|
||||
}else{
|
||||
/*
|
||||
status = GetHistogram(mem,pCon,0,start,length,iData,
|
||||
length*sizeof(HistInt));
|
||||
*/
|
||||
iData = GetHistogramPointer(mem,pCon);
|
||||
if(iData == NULL){
|
||||
status = 0;
|
||||
} else {
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
if(!status){
|
||||
SCWrite(pCon,"ERROR: failed to read histogram memory",eError);
|
||||
if(subset){
|
||||
free(iData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
finally: write
|
||||
*/
|
||||
status = NXDputalias(self->fileHandle, self->dictHandle,argv[2],iData);
|
||||
if(status != NX_OK){
|
||||
sprintf(buffer,"ERROR: failed to write histogram memory data");
|
||||
SCWrite(pCon,buffer,eError);
|
||||
}
|
||||
|
||||
if(subset){
|
||||
free(iData);
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------
|
||||
defunct as of december 2003
|
||||
*/
|
||||
static void putHistogramMemoryChunked(SConnection *pCon, SicsInterp *pSics,
|
||||
pNXScript self,
|
||||
int argc, char *argv[]){
|
||||
pHistMem mem = NULL;
|
||||
int status, start, length, i, noChunks, chunkDim[MAXDIM], rank;
|
||||
HistInt *iData = NULL;
|
||||
char buffer[256];
|
||||
int subset;
|
||||
|
||||
if(argc < 5){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to puthmchunked",
|
||||
eError);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
find Histogram Memory
|
||||
*/
|
||||
mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
|
||||
if(!mem){
|
||||
sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
default: everything
|
||||
*/
|
||||
start = 0;
|
||||
length = GetHistLength(mem);
|
||||
|
||||
updateHMDim(self,mem);
|
||||
|
||||
/*
|
||||
check for an argument defining the number of chunks
|
||||
*/
|
||||
status = Tcl_GetInt(InterpGetTcl(pSics),argv[4],&noChunks);
|
||||
if(status != TCL_OK){
|
||||
sprintf(buffer,"ERROR: failed to convert %s to integer",
|
||||
argv[4]);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
read HM
|
||||
*/
|
||||
@@ -392,7 +590,7 @@ static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
|
||||
/*
|
||||
build definition string
|
||||
*/
|
||||
status = NXDget(self->dictHandle,argv[2],buffer,254);
|
||||
status = NXDdefget(self->dictHandle,argv[2],buffer,254);
|
||||
if(!status){
|
||||
sprintf(buffer,"ERROR: alias %s for time binning not found",
|
||||
argv[2]);
|
||||
@@ -470,7 +668,7 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
|
||||
}
|
||||
data[i] = (float)dVal;
|
||||
} else {
|
||||
sprintf(buffer,"WARNING: failed to find array element %d", i);
|
||||
snprintf(buffer,254,"WARNING: failed to find array element %d", i);
|
||||
SCWrite(pCon,buffer,eError);
|
||||
}
|
||||
}
|
||||
@@ -478,7 +676,7 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
|
||||
/*
|
||||
build definition string
|
||||
*/
|
||||
status = NXDget(self->dictHandle,argv[2],buffer,254);
|
||||
status = NXDdefget(self->dictHandle,argv[2],buffer,254);
|
||||
if(!status){
|
||||
sprintf(buffer,"ERROR: alias %s for array not found",
|
||||
argv[2]);
|
||||
@@ -486,7 +684,7 @@ static void putArray(SConnection *pCon, SicsInterp *pSics,
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
sprintf(defString,"%s -dim {%d} ",buffer,length);
|
||||
snprintf(defString,511,"%s -dim {%d} ",buffer,length);
|
||||
|
||||
/*
|
||||
write it!
|
||||
@@ -559,7 +757,7 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
|
||||
return 1;
|
||||
}
|
||||
Arg2Text(argc-3,&argv[3],buffer,1023);
|
||||
status = NXDget(self->dictHandle,argv[2],defString,1023);
|
||||
status = NXDdefget(self->dictHandle,argv[2],defString,1023);
|
||||
if(status != NX_OK){
|
||||
sprintf(buffer,"ERROR: alias %s not found in puttext",
|
||||
argv[2]);
|
||||
@@ -631,12 +829,28 @@ static void makeLink(SConnection *pCon, SicsInterp *pSics,
|
||||
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void updateDictVar(SConnection *pCon, pNXScript self, int argc,
|
||||
char *argv[]){
|
||||
int status;
|
||||
|
||||
if(self->dictHandle == NULL){
|
||||
SCWrite(pCon,"ERROR: cannot update variable, dictionary not open",
|
||||
eError);
|
||||
return;
|
||||
}
|
||||
if(argc < 4){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to updateDictVar",
|
||||
eError);
|
||||
return;
|
||||
}
|
||||
NXDupdate(self->dictHandle,argv[2],argv[3]);
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int argc, char *argv[]){
|
||||
pNXScript self = (pNXScript)pData;
|
||||
|
||||
char *pFile = NULL;
|
||||
/*
|
||||
preliminary checks
|
||||
*/
|
||||
@@ -650,6 +864,18 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
}
|
||||
strtolower(argv[1]);
|
||||
|
||||
if(strcmp(argv[1],"makefilename") == 0){
|
||||
pFile = makeFilename(pSics,pCon);
|
||||
if(pFile != NULL){
|
||||
SCWrite(pCon,pFile,eValue);
|
||||
free(pFile);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: failed to create filename",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(handleFileOperations(pCon,self,argc,argv)){
|
||||
return 1;
|
||||
}
|
||||
@@ -662,6 +888,11 @@ int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"updatedictvar") == 0){
|
||||
updateDictVar(pCon,self,argc,argv);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(strstr(argv[1],"put") != NULL){
|
||||
handlePut(pCon,pSics,self,argc,argv);
|
||||
return 1;
|
||||
|
||||
Reference in New Issue
Block a user