1790 lines
49 KiB
C
1790 lines
49 KiB
C
/*-----------------------------------------------------------------------
|
|
N X S C R I P T
|
|
|
|
This is a class for scripting the contents of NeXus files from
|
|
SICS.
|
|
|
|
copyright: see file COPYRIGHT
|
|
|
|
Mark Koennecke, February 2003
|
|
Mark Koennecke, January 2004
|
|
added putHdb and putHdbSlab, Mark Koennecke, December 2008
|
|
------------------------------------------------------------------------*/
|
|
#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"
|
|
#include "sicsdata.h"
|
|
#include "sicshipadaba.h"
|
|
|
|
extern char *trim(char *str);
|
|
|
|
/* missing in nxdict.h: */
|
|
NXstatus NXDdefget(NXdict handle, char *pKey, char *pBuffer, int iBufLen);
|
|
/*------------------------------------------------------------------------*/
|
|
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 += 10; /* 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, eLog);
|
|
} else {
|
|
closedir(dir);
|
|
}
|
|
|
|
/*
|
|
build the rest of the filename
|
|
*/
|
|
strcat(pRes, "/");
|
|
strcat(pRes, pPref->text);
|
|
snprintf(pNumText,sizeof(pNumText)-1, "%4.4d", iYear);
|
|
strcat(pRes, pNumText);
|
|
strcat(pRes, "n");
|
|
snprintf(pNumText,sizeof(pNumText)-1, "%6.6d", iNum);
|
|
strcat(pRes, pNumText);
|
|
strcat(pRes, pEnd->text);
|
|
|
|
return pRes;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
void changeExtension(char *filename, char *newExtension)
|
|
{
|
|
char *pPtr = NULL;
|
|
|
|
pPtr = strrchr(filename, (int) '.');
|
|
assert(pPtr != NULL);
|
|
|
|
pPtr++;
|
|
assert(strlen(pPtr) >= strlen(newExtension));
|
|
strcpy(pPtr, newExtension);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static int listToArray(SicsInterp * pSics, char *list,
|
|
int intar[NX_MAXRANK])
|
|
{
|
|
int argc, status, i, val;
|
|
CONST char **argv;
|
|
Tcl_Interp *pTcl = InterpGetTcl(pSics);
|
|
|
|
status = Tcl_SplitList(pTcl, list, &argc, &argv);
|
|
if (status != TCL_OK) {
|
|
return status;
|
|
}
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
status = Tcl_GetInt(pTcl, argv[i], &val);
|
|
if (status != TCL_OK) {
|
|
return status;
|
|
}
|
|
intar[i] = val;
|
|
}
|
|
Tcl_Free((char *) argv);
|
|
return TCL_OK;
|
|
}
|
|
|
|
/*======================== Action =======================================*/
|
|
static int handleFileOperations(SConnection * pCon, pNXScript self,
|
|
int argc, char *argv[])
|
|
{
|
|
int status, i, iVal;
|
|
NXaccess access;
|
|
char buffer[512];
|
|
|
|
if (strcmp(argv[1], "close") == 0) {
|
|
/*
|
|
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);
|
|
NXclose(&self->fileHandle);
|
|
NXDclose(self->dictHandle, NULL);
|
|
self->fileHandle = NULL;
|
|
self->dictHandle = NULL;
|
|
SendQuieck(QUIECK, buffer);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "reopen") == 0) {
|
|
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 if (strcmp(argv[1], "createxml") == 0) {
|
|
access = NXACC_CREATEXML;
|
|
} else {
|
|
return 0;
|
|
}
|
|
if (argc < 4) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments for file operation",
|
|
eError);
|
|
return -1;
|
|
}
|
|
/*
|
|
be considerate: close files left open
|
|
*/
|
|
if (self->fileHandle != NULL) {
|
|
NXclose(&self->fileHandle);
|
|
self->fileHandle = NULL;
|
|
}
|
|
if (self->dictHandle != NULL) {
|
|
NXDclose(self->dictHandle, NULL);
|
|
self->dictHandle = NULL;
|
|
}
|
|
/*
|
|
now initialize ourselves
|
|
*/
|
|
status = NXopen(argv[2], access, &self->fileHandle);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to open %s", argv[2]);
|
|
SCWrite(pCon, buffer, eError);
|
|
return -1;
|
|
}
|
|
status = NXDinitfromfile(argv[3], &self->dictHandle);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to open dictionary %s", argv[3]);
|
|
SCWrite(pCon, buffer, eError);
|
|
return -1;
|
|
}
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putMotor(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
int status;
|
|
pMotor brumm = NULL;
|
|
float fVal;
|
|
char buffer[132], dummy[256];
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putmotor",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
find motor
|
|
*/
|
|
brumm = (pMotor) FindCommandData(pSics, argv[3], "Motor");
|
|
if (!brumm) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: motor %s not found!", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
do position
|
|
*/
|
|
status = MotorGetSoftPosition(brumm, pCon, &fVal);
|
|
if (!status) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to read position of %s", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
status = NXDputalias(self->fileHandle, self->dictHandle, argv[2], &fVal);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write %s with alias %s",
|
|
argv[3], argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
if alias_null is available: write zero point
|
|
*/
|
|
strlcpy(buffer, argv[2],131);
|
|
strlcat(buffer, "_null",131);
|
|
if (NXDdefget(self->dictHandle, buffer, dummy, 255)) {
|
|
MotorGetPar(brumm, "softzero", &fVal);
|
|
status =
|
|
NXDputalias(self->fileHandle, self->dictHandle, buffer, &fVal);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,131, "ERROR: failed to write %s zero with alias %s",
|
|
argv[3], argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------*/
|
|
static void putCounter(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
pCounter cter = NULL;
|
|
float fVal;
|
|
long counts;
|
|
char buffer[256], newAlias[256], dummy[80];
|
|
int status, i, icounts;
|
|
CounterMode eMode;
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putcounter",
|
|
eLogError);
|
|
return;
|
|
}
|
|
memset(dummy, 0, 80 * sizeof(char));
|
|
|
|
/*
|
|
find counter
|
|
*/
|
|
cter = (pCounter) FindCommandData(pSics, argv[3], "SingleCounter");
|
|
if (!cter) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: counter %s not found!", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
do preset
|
|
*/
|
|
fVal = GetCounterPreset(cter);
|
|
strlcpy(newAlias, argv[2],255);
|
|
strlcat(newAlias, "_preset",255);
|
|
status =
|
|
NXDputalias(self->fileHandle, self->dictHandle, newAlias, &fVal);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,255, "ERROR: failed to write preset to %s", newAlias);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
|
|
/*
|
|
do countmode
|
|
*/
|
|
eMode = GetCounterMode(cter);
|
|
strcpy(newAlias, argv[2]);
|
|
strcat(newAlias, "_mode");
|
|
if (eMode == eTimer) {
|
|
strcpy(dummy, "timer");
|
|
} else {
|
|
strcpy(dummy, "monitor");
|
|
}
|
|
status =
|
|
NXDputalias(self->fileHandle, self->dictHandle, newAlias, dummy);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write counter mode to %s", newAlias);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
|
|
/*
|
|
do time
|
|
*/
|
|
fVal = GetCountTime(cter, pCon);
|
|
strlcpy(newAlias, argv[2],255);
|
|
strlcat(newAlias, "_time",255);
|
|
if (NXDdefget(self->dictHandle, newAlias, dummy, 79)) {
|
|
status =
|
|
NXDputalias(self->fileHandle, self->dictHandle, newAlias, &fVal);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write count time to %s", newAlias);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
do counter and monitors
|
|
*/
|
|
for (i = 0; i < 10; i++) {
|
|
snprintf(newAlias,255, "%s_%2.2d", argv[2], i);
|
|
if (NXDdefget(self->dictHandle, newAlias, dummy, 79)) {
|
|
counts = GetMonitor(cter, i, pCon);
|
|
icounts = (int) counts;
|
|
status = NXDputalias(self->fileHandle, self->dictHandle, newAlias,
|
|
&icounts);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putSicsData(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
|
|
pSICSData data = NULL;
|
|
int status;
|
|
char buffer[256];
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putSicsData",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
find data
|
|
*/
|
|
data = (pSICSData) FindCommandData(pSics, argv[3], "SICSData");
|
|
if (data == NULL) {
|
|
snprintf(buffer, 255, "ERROR: sicsdata %s not found!", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
status =
|
|
NXDputalias(self->fileHandle, self->dictHandle, argv[2], data->data);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write sicsdata to %s", argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putAttribute(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
int status, type = NX_CHAR;
|
|
char buffer[256];
|
|
|
|
if (argc < 5) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to putAttribute",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
status = NXDopenalias(self->fileHandle, self->dictHandle, argv[2]);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to open alias %s", argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
status = NXputattr(self->fileHandle, argv[3], (void *) argv[4],
|
|
strlen(argv[4]) + 1, type);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write attribute %s", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
NXopenpath(self->fileHandle, "/");
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putHdb(SConnection * pCon, SicsInterp * pSics, pNXScript self,
|
|
int argc, char *argv[])
|
|
{
|
|
pHdb node = NULL;
|
|
char alias[512];
|
|
hdbValue v;
|
|
float fVal, *floatAr = NULL;
|
|
int i;
|
|
int start[5], size[5];
|
|
|
|
if (argc < 3) {
|
|
SCWrite(pCon, "ERROR: putHdb needs at least node name", eLogError);
|
|
return;
|
|
}
|
|
node = FindHdbNode(NULL, argv[2], pCon);
|
|
if (node == NULL) {
|
|
SCPrintf(pCon, eLogError, "ERROR: node %s not found", argv[2]);
|
|
return;
|
|
}
|
|
memset(alias, 0, 512 * sizeof(char));
|
|
if (!GetHdbProperty(node, "nxalias", alias, 512)) {
|
|
if (argc < 4) {
|
|
SCPrintf(pCon, eLogError,
|
|
"ERROR: neither nxalias property nor alias on command line found for %s",
|
|
argv[2]);
|
|
return;
|
|
} else {
|
|
strlcpy(alias, argv[3], 512);
|
|
}
|
|
}
|
|
GetHipadabaPar(node, &v, pCon);
|
|
if (argc > 3 && strcmp(argv[3], "point") == 0) {
|
|
NXDopenalias(self->fileHandle, self->dictHandle, alias);
|
|
start[0] = atoi(argv[4]);
|
|
size[0] = 1;
|
|
switch (v.dataType) {
|
|
case HIPINT:
|
|
NXputslab(self->fileHandle, &v.v.intValue, start, size);
|
|
break;
|
|
case HIPFLOAT:
|
|
fVal = v.v.doubleValue;
|
|
NXputslab(self->fileHandle, &fVal, start, size);
|
|
break;
|
|
}
|
|
ReleaseHdbValue(&v);
|
|
NXopenpath(self->fileHandle, "/");
|
|
return;
|
|
}
|
|
switch (v.dataType) {
|
|
case HIPNONE:
|
|
return;
|
|
break;
|
|
case HIPINT:
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, &v.v.intValue);
|
|
break;
|
|
case HIPFLOAT:
|
|
fVal = v.v.doubleValue;
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, &fVal);
|
|
break;
|
|
case HIPTEXT:
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, v.v.text);
|
|
break;
|
|
case HIPINTAR:
|
|
case HIPINTVARAR:
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, v.v.intArray);
|
|
break;
|
|
case HIPFLOATAR:
|
|
case HIPFLOATVARAR:
|
|
floatAr = malloc(v.arrayLength * sizeof(float));
|
|
if (floatAr == NULL) {
|
|
SCPrintf(pCon, eLogError, "ERROR: out of memory writing %s",
|
|
node->name);
|
|
return;
|
|
}
|
|
for (i = 0; i < v.arrayLength; i++) {
|
|
floatAr[i] = (float)v.v.floatArray[i];
|
|
}
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, floatAr);
|
|
free(floatAr);
|
|
break;
|
|
}
|
|
ReleaseHdbValue(&v);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void putHdbOff(SConnection * pCon, SicsInterp * pSics, pNXScript self,
|
|
int argc, char *argv[])
|
|
{
|
|
pHdb node = NULL;
|
|
char alias[512];
|
|
hdbValue v;
|
|
float fVal, *floatAr = NULL;
|
|
int i, offset;
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: putHdbOff needs at least a node name and an offset", eLogError);
|
|
return;
|
|
}
|
|
node = FindHdbNode(NULL, argv[2], pCon);
|
|
if (node == NULL) {
|
|
SCPrintf(pCon, eLogError, "ERROR: node %s not found", argv[2]);
|
|
return;
|
|
}
|
|
memset(alias, 0, 512 * sizeof(char));
|
|
if (!GetHdbProperty(node, "nxalias", alias, 512)) {
|
|
if (argc < 5) {
|
|
SCPrintf(pCon, eLogError,
|
|
"ERROR: neither nxalias property nor alias on command line found for %s",
|
|
argv[2]);
|
|
return;
|
|
} else {
|
|
strlcpy(alias, argv[4], 512);
|
|
}
|
|
}
|
|
offset = atoi(argv[3]);
|
|
|
|
GetHipadabaPar(node, &v, pCon);
|
|
if(offset < 0 || offset > v.arrayLength){
|
|
SCPrintf(pCon,eLogError,"ERROR: invalid offset %d specified", offset );
|
|
return;
|
|
}
|
|
switch (v.dataType) {
|
|
case HIPNONE:
|
|
return;
|
|
break;
|
|
case HIPINTAR:
|
|
case HIPINTVARAR:
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, v.v.intArray+offset);
|
|
break;
|
|
case HIPFLOATAR:
|
|
case HIPFLOATVARAR:
|
|
floatAr = malloc(v.arrayLength * sizeof(float));
|
|
if (floatAr == NULL) {
|
|
SCPrintf(pCon, eLogError, "ERROR: out of memory writing %s",
|
|
node->name);
|
|
return;
|
|
}
|
|
for (i = 0; i < v.arrayLength; i++) {
|
|
floatAr[i] = v.v.floatArray[i];
|
|
}
|
|
NXDputalias(self->fileHandle, self->dictHandle, alias, floatAr+offset);
|
|
free(floatAr);
|
|
break;
|
|
default:
|
|
SCPrintf(pCon,eLogError,"ERROR: offsets can only be used with array data types");
|
|
return;
|
|
}
|
|
ReleaseHdbValue(&v);
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void putHdbSlab(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
pHdb node = NULL;
|
|
char alias[512];
|
|
hdbValue v;
|
|
float fVal, *floatAr = NULL;
|
|
int start[NX_MAXRANK], size[NX_MAXRANK];
|
|
int i, status;
|
|
|
|
if (argc < 5) {
|
|
SCWrite(pCon,
|
|
"ERROR: putHdbSlab needs at least node name start, size",
|
|
eLogError);
|
|
return;
|
|
}
|
|
node = FindHdbNode(NULL, argv[2], pCon);
|
|
if (node == NULL) {
|
|
SCPrintf(pCon, eLogError, "ERROR: node %s not found", argv[2]);
|
|
return;
|
|
}
|
|
memset(alias, 0, 512 * sizeof(char));
|
|
if (!GetHdbProperty(node, "nxalias", alias, 512)) {
|
|
SCPrintf(pCon, eLogError,
|
|
"ERROR: nxalias property not found for %s", argv[2]);
|
|
return;
|
|
}
|
|
status = NXDopenalias(self->fileHandle, self->dictHandle, alias);
|
|
if (status != NX_OK) {
|
|
SCPrintf(pCon, eLogError, "ERROR: failed to open alias for %s",
|
|
argv[2]);
|
|
return;
|
|
}
|
|
|
|
status = listToArray(pSics, argv[3], start);
|
|
if (status != TCL_OK) {
|
|
SCWrite(pCon, "ERROR: failed to convert start value list", eLogError);
|
|
return;
|
|
}
|
|
|
|
status = listToArray(pSics, argv[4], size);
|
|
if (status != TCL_OK) {
|
|
SCWrite(pCon, "ERROR: failed to convert size value list", eLogError);
|
|
return;
|
|
}
|
|
|
|
GetHipadabaPar(node, &v, pCon);
|
|
switch (v.dataType) {
|
|
case HIPNONE:
|
|
return;
|
|
break;
|
|
case HIPINT:
|
|
status = NXputslab(self->fileHandle, &v.v.intValue, start, size);
|
|
break;
|
|
case HIPFLOAT:
|
|
fVal = v.v.doubleValue;
|
|
status = NXputslab(self->fileHandle, &fVal, start, size);
|
|
break;
|
|
case HIPTEXT:
|
|
status = NXputslab(self->fileHandle, v.v.text, start, size);
|
|
break;
|
|
case HIPINTAR:
|
|
case HIPINTVARAR:
|
|
status = NXputslab(self->fileHandle, v.v.intArray, start, size);
|
|
break;
|
|
case HIPFLOATAR:
|
|
case HIPFLOATVARAR:
|
|
floatAr = malloc(v.arrayLength * sizeof(float));
|
|
if (floatAr == NULL) {
|
|
SCPrintf(pCon, eLogError, "ERROR: out of memory writing %s",
|
|
node->name);
|
|
return;
|
|
}
|
|
for (i = 0; i < v.arrayLength; i++) {
|
|
floatAr[i] = v.v.floatArray[i];
|
|
}
|
|
status = NXputslab(self->fileHandle, floatAr, start, size);
|
|
free(floatAr);
|
|
break;
|
|
}
|
|
if (status != NX_OK) {
|
|
SCPrintf(pCon, eLogError, "ERROR: failed to write slab for node %s",
|
|
argv[2]);
|
|
}
|
|
ReleaseHdbValue(&v);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
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++) {
|
|
snprintf(dummy,sizeof(dummy)-1, "dim%1.1d", i);
|
|
snprintf(value,sizeof(value)-1, "%d", iDim[i]);
|
|
status = NXDupdate(self->dictHandle, dummy, value);
|
|
if (status == 0) {
|
|
NXDadd(self->dictHandle, dummy, value);
|
|
}
|
|
}
|
|
timeBin = GetHistTimeBin(mem, &timeLength);
|
|
if (timeLength > 2) {
|
|
snprintf(dummy,sizeof(dummy)-1, "%d", timeLength);
|
|
} else {
|
|
snprintf(dummy,sizeof(dummy)-1, "%d", 1);
|
|
}
|
|
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.
|
|
Thus subsets can only be checked for after that. And then we can allocate
|
|
memory.
|
|
-------------------------------------------------------------------------*/
|
|
static void putHistogramMemory(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
pHistMem mem = NULL;
|
|
int status, start, length, i, subset = 0, bank = 0;
|
|
HistInt *iData = NULL;
|
|
char buffer[256];
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to puthm",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
find Histogram Memory
|
|
*/
|
|
mem = (pHistMem) FindCommandData(pSics, argv[3], "HistMem");
|
|
if (!mem) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: HistMem %s not found!", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
default: everything
|
|
*/
|
|
start = 0;
|
|
length = GetHistLength(mem);
|
|
updateHMDim(self, mem);
|
|
|
|
/*
|
|
check for further arguments specifying a subset
|
|
*/
|
|
if (argc > 5) {
|
|
subset = 1;
|
|
status = Tcl_GetInt(InterpGetTcl(pSics), argv[4], &start);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to integer", argv[4]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
status = Tcl_GetInt(InterpGetTcl(pSics), argv[5], &length);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to integer", argv[5]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* check for additional bank number
|
|
*/
|
|
if (argc > 6) {
|
|
status = Tcl_GetInt(InterpGetTcl(pSics), argv[6], &bank);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to integer", argv[6]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
read HM
|
|
*/
|
|
if (subset) {
|
|
iData = (HistInt *) malloc(length * sizeof(HistInt));
|
|
if (!iData) {
|
|
SCWrite(pCon, "ERROR: out of memory for reading histogram memory",
|
|
eLogError);
|
|
return;
|
|
}
|
|
memset(iData, 0, length * sizeof(HistInt));
|
|
status =
|
|
GetHistogramDirect(mem, pCon, bank, 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", eLogError);
|
|
if (subset) {
|
|
free(iData);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
finally: write
|
|
*/
|
|
status = NXDputalias(self->fileHandle, self->dictHandle, argv[2], iData);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write histogram memory data");
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
|
|
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 =0;
|
|
|
|
if (argc < 5) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to puthmchunked",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
find Histogram Memory
|
|
*/
|
|
mem = (pHistMem) FindCommandData(pSics, argv[3], "HistMem");
|
|
if (!mem) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: HistMem %s not found!", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
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) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to integer", argv[4]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
read HM
|
|
*/
|
|
if (subset) {
|
|
iData = (HistInt *) malloc(length * sizeof(HistInt));
|
|
if (!iData) {
|
|
SCWrite(pCon, "ERROR: out of memory for reading histogram memory",
|
|
eLogError);
|
|
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", eLogError);
|
|
if (subset) {
|
|
free(iData);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
finally: write
|
|
*/
|
|
status = NXDputalias(self->fileHandle, self->dictHandle, argv[2], iData);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write histogram memory data");
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
|
|
if (subset) {
|
|
free(iData);
|
|
}
|
|
SCSendOK(pCon);
|
|
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
#define HANUM 3
|
|
static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self,
|
|
int argc, char *argv[])
|
|
{
|
|
int start[NX_MAXRANK], size[NX_MAXRANK];
|
|
int status, written = 0;
|
|
pHistMem mem = NULL;
|
|
HistInt *histData = NULL;
|
|
pSICSData data = NULL;
|
|
pCounter memsec = NULL;
|
|
pHdb node = NULL;
|
|
char buffer[256];
|
|
enum histargs { haStart, haLength, haBank };
|
|
int i, haIndex, hpars[HANUM], haFirst = 6;
|
|
|
|
if (argc < 6) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putslab",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
status = NXDopenalias(self->fileHandle, self->dictHandle, argv[2]);
|
|
if (status != NX_OK) {
|
|
SCPrintf(pCon, eLogError, "ERROR: failed to open alias %s", argv[2]);
|
|
return;
|
|
}
|
|
|
|
status = listToArray(pSics, argv[3], start);
|
|
if (status != TCL_OK) {
|
|
SCWrite(pCon, "ERROR: failed to convert start value list", eLogError);
|
|
return;
|
|
}
|
|
|
|
status = listToArray(pSics, argv[4], size);
|
|
if (status != TCL_OK) {
|
|
SCWrite(pCon, "ERROR: failed to convert size value list", eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* try to write HM data
|
|
*/
|
|
mem = (pHistMem) FindCommandData(pSics, argv[5], "HistMem");
|
|
if (mem != NULL) {
|
|
if (argc == 6) {
|
|
histData = GetHistogramPointer(mem, pCon);
|
|
} else if (argc > 6) {
|
|
for (i = 0, haIndex = haFirst; i < HANUM; i++, haIndex++) {
|
|
status = Tcl_GetInt(InterpGetTcl(pSics), argv[haIndex], &hpars[i]);
|
|
if (status != TCL_OK) {
|
|
sprintf(buffer, "ERROR: failed to convert %s to integer",
|
|
argv[haIndex]);
|
|
SCWrite(pCon, buffer, eError);
|
|
return;
|
|
}
|
|
}
|
|
histData = (HistInt *) malloc(hpars[haLength] * sizeof(HistInt));
|
|
if (!histData) {
|
|
SCWrite(pCon, "ERROR: out of memory for reading histogram memory",
|
|
eError);
|
|
return;
|
|
}
|
|
memset(histData, 0, hpars[haLength] * sizeof(HistInt));
|
|
status = GetHistogramDirect(mem, pCon, hpars[haBank],
|
|
hpars[haStart],
|
|
hpars[haStart] + hpars[haLength],
|
|
histData,
|
|
hpars[haLength] * sizeof(HistInt));
|
|
}
|
|
if (histData) {
|
|
status = NXputslab(self->fileHandle, histData, start, size);
|
|
if (status == NX_OK) {
|
|
written = 1;
|
|
}
|
|
if (argc > 6)
|
|
free(histData);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* try to write second gen histogram data
|
|
*/
|
|
memsec = (pCounter) FindCommandData(pSics, argv[5], "HistMemSec");
|
|
if(memsec != NULL){
|
|
node = GetHipadabaNode(memsec->pDes->parNode,"data");
|
|
if(node == NULL){
|
|
SCWrite(pCon,"ERROR: ?? data node to second gen HM not found", eError);
|
|
return;
|
|
}
|
|
status = NXputslab(self->fileHandle, node->value.v.intArray, start, size);
|
|
if (status == NX_OK) {
|
|
written = 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* try to look for sicsdata
|
|
*/
|
|
data = (pSICSData) FindCommandData(pSics, argv[5], "SICSData");
|
|
if (data != NULL) {
|
|
status = NXputslab(self->fileHandle, data->data, start, size);
|
|
if (status == NX_OK) {
|
|
written = 1;
|
|
}
|
|
}
|
|
/*
|
|
* drop out of hierarchy
|
|
*/
|
|
NXopenpath(self->fileHandle, "/");
|
|
|
|
if (written == 0) {
|
|
SCWrite(pCon, "ERROR: failed to write data, data not recognised",
|
|
eLogError);
|
|
}
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static short *HistInt2Short(HistInt *data, int length)
|
|
{
|
|
int i;
|
|
|
|
int16_t *shdata = NULL;
|
|
shdata = malloc(length*sizeof(int16_t));
|
|
if(shdata == NULL){
|
|
return NULL;
|
|
}
|
|
memset(shdata,0,length*sizeof(int16_t));
|
|
for(i = 0; i < length; i++){
|
|
shdata[i] = (short)data[i];
|
|
}
|
|
return shdata;
|
|
}
|
|
/*----------------------------------------------------------------------*/
|
|
static void putSlab16(SConnection * pCon, SicsInterp * pSics, pNXScript self,
|
|
int argc, char *argv[])
|
|
{
|
|
int start[NX_MAXRANK], size[NX_MAXRANK], dim[MAXDIM];
|
|
int status, written = 0, rank, i;
|
|
pHistMem mem = NULL;
|
|
HistInt *histData = NULL;
|
|
int16_t *shortData = NULL;
|
|
pHdb node = NULL;
|
|
unsigned int length;
|
|
pCounter memsec = NULL;
|
|
|
|
if (argc < 6) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putslab",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
status = NXDopenalias(self->fileHandle, self->dictHandle, argv[2]);
|
|
if (status != NX_OK) {
|
|
SCPrintf(pCon, eLogError, "ERROR: failed to open alias %s", argv[2]);
|
|
return;
|
|
}
|
|
|
|
status = listToArray(pSics, argv[3], start);
|
|
if (status != TCL_OK) {
|
|
SCWrite(pCon, "ERROR: failed to convert start value list", eLogError);
|
|
return;
|
|
}
|
|
|
|
status = listToArray(pSics, argv[4], size);
|
|
if (status != TCL_OK) {
|
|
SCWrite(pCon, "ERROR: failed to convert size value list", eLogError);
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* try to write HM data
|
|
*/
|
|
mem = (pHistMem) FindCommandData(pSics, argv[5], "HistMem");
|
|
if (mem != NULL) {
|
|
histData = GetHistogramPointer(mem, pCon);
|
|
if (histData) {
|
|
GetHistDim(mem, dim,&rank);
|
|
for(i = 0, length = 1; i < rank; i++){
|
|
length *= dim[i];
|
|
}
|
|
shortData = HistInt2Short(histData,length);
|
|
if(shortData != NULL){
|
|
status = NXputslab(self->fileHandle, shortData, start, size);
|
|
free(shortData);
|
|
}
|
|
if (status == NX_OK) {
|
|
written = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* try to write second gen histogram data
|
|
*/
|
|
memsec = (pCounter) FindCommandData(pSics, argv[5], "HistMemSec");
|
|
if(memsec != NULL){
|
|
node = GetHipadabaNode(memsec->pDes->parNode,"data");
|
|
if(node == NULL){
|
|
SCWrite(pCon,"ERROR: ?? data node to second gen HM not found", eError);
|
|
return;
|
|
}
|
|
GetHistDim((pHistMem)memsec, dim,&rank);
|
|
for(i = 0, length = 1; i < rank; i++){
|
|
length *= dim[i];
|
|
}
|
|
shortData = HistInt2Short(node->value.v.intArray,length);
|
|
if(shortData != NULL){
|
|
status = NXputslab(self->fileHandle, shortData, start, size);
|
|
free(shortData);
|
|
}
|
|
if (status == NX_OK) {
|
|
written = 1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* drop out of hierarchy
|
|
*/
|
|
NXopenpath(self->fileHandle, "/");
|
|
|
|
if (written == 0) {
|
|
SCWrite(pCon, "ERROR: failed to write data, data not recognised",
|
|
eLogError);
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
static void putTimeBinning(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
pHistMem mem = NULL;
|
|
int i, status, timeLength;
|
|
char buffer[256], defString[512], dummy[40];
|
|
const float *timeBin;
|
|
float *timeCopy = NULL;
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to puttimebinning",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
find Histogram Memory
|
|
*/
|
|
mem = (pHistMem) FindCommandData(pSics, argv[3], "HistMem");
|
|
if (!mem) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: HistMem %s not found!", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
build definition string
|
|
*/
|
|
status = NXDdefget(self->dictHandle, argv[2], buffer, 254);
|
|
if (!status) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: alias %s for time binning not found", argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
timeBin = GetHistTimeBin(mem, &timeLength);
|
|
snprintf(defString,sizeof(defString)-1, "%s -dim {%d} ", buffer, timeLength);
|
|
|
|
/*
|
|
Divide the time binning when appropriate and write
|
|
*/
|
|
if (self->timeDivisor != 1) {
|
|
timeCopy = (float *) malloc(timeLength * sizeof(float));
|
|
if (timeCopy == NULL) {
|
|
SCWrite(pCon, "ERROR: out of memory writing time binning",
|
|
eLogError);
|
|
return;
|
|
}
|
|
for (i = 0; i < timeLength; i++) {
|
|
timeCopy[i] = timeBin[i] / self->timeDivisor;
|
|
}
|
|
status = NXDputdef(self->fileHandle, self->dictHandle,
|
|
defString, (void *) timeCopy);
|
|
free(timeCopy);
|
|
} else {
|
|
status = NXDputdef(self->fileHandle, self->dictHandle,
|
|
defString, (void *) timeBin);
|
|
}
|
|
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write time binning");
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
SCSendOK(pCon);
|
|
return;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putArray(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
float *data = NULL;
|
|
int length, i, status;
|
|
char num[20];
|
|
char buffer[256], defString[512], *varData;
|
|
Tcl_Interp *tcl = NULL;
|
|
double dVal;
|
|
|
|
if (argc < 5) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to array",
|
|
eLogError);
|
|
return;
|
|
}
|
|
tcl = InterpGetTcl(pSics);
|
|
assert(tcl != NULL);
|
|
|
|
/*
|
|
get array length
|
|
*/
|
|
status = Tcl_GetInt(tcl, argv[4], &length);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to integer in putarray",
|
|
argv[4]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
allocate
|
|
*/
|
|
if (length > 0) {
|
|
data = (float *) malloc(length * sizeof(float));
|
|
}
|
|
if (data == NULL) {
|
|
snprintf(buffer, 255,
|
|
"ERROR: out of memory or invalid length in putarray at %s, length = %s",
|
|
argv[2], argv[4]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
memset(data, 0, length * sizeof(float));
|
|
|
|
/*
|
|
try getting data
|
|
*/
|
|
for (i = 0; i < length; i++) {
|
|
snprintf(num,sizeof(num)-1, "%d", i);
|
|
varData = (char *) Tcl_GetVar2(tcl, argv[3], num, 0);
|
|
if (varData != NULL) {
|
|
status = Tcl_GetDouble(tcl, varData, &dVal);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1,
|
|
"ERROR: failed to convert %s to double in putarray",
|
|
varData);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
data[i] = (float) dVal;
|
|
} else {
|
|
snprintf(buffer, 254,
|
|
"WARNING: failed to find array element %d in putarray", i);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
}
|
|
|
|
/*
|
|
build definition string
|
|
*/
|
|
status = NXDdefget(self->dictHandle, argv[2], buffer, 254);
|
|
if (!status) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: alias %s for array not found in putarray",
|
|
argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
free(data);
|
|
return;
|
|
}
|
|
snprintf(defString, 511, "%s -dim {%d} ", buffer, length);
|
|
|
|
/*
|
|
write it!
|
|
*/
|
|
status = NXDputdef(self->fileHandle, self->dictHandle, defString, data);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write array in putarray");
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
free(data);
|
|
SCSendOK(pCon);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putIntArray(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
int *data = NULL;
|
|
int length, i, status;
|
|
char num[20];
|
|
char buffer[256], defString[512], *varData;
|
|
Tcl_Interp *tcl = NULL;
|
|
int iVal;
|
|
|
|
if (argc < 5) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to array",
|
|
eLogError);
|
|
return;
|
|
}
|
|
tcl = InterpGetTcl(pSics);
|
|
assert(tcl != NULL);
|
|
|
|
/*
|
|
get array length
|
|
*/
|
|
status = Tcl_GetInt(tcl, argv[4], &length);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to integer", argv[4]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
allocate
|
|
*/
|
|
if (length > 0) {
|
|
data = (int *) malloc(length * sizeof(int));
|
|
}
|
|
if (data == NULL) {
|
|
SCWrite(pCon, "ERROR: out of memory or invalid length", eLogError);
|
|
return;
|
|
}
|
|
memset(data, 0, length * sizeof(int));
|
|
|
|
/*
|
|
try getting data
|
|
*/
|
|
for (i = 0; i < length; i++) {
|
|
snprintf(num,sizeof(num)-1, "%d", i);
|
|
varData = (char *) Tcl_GetVar2(tcl, argv[3], num, 0);
|
|
if (varData != NULL) {
|
|
status = Tcl_GetInt(tcl, varData, &iVal);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to int", varData);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
data[i] = iVal;
|
|
} else {
|
|
snprintf(buffer, 254, "WARNING: failed to find array element %d", i);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
}
|
|
|
|
/*
|
|
build definition string
|
|
*/
|
|
status = NXDdefget(self->dictHandle, argv[2], buffer, 254);
|
|
if (!status) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: alias %s for array not found", argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
free(data);
|
|
return;
|
|
}
|
|
snprintf(defString, 511, "%s -dim {%d} ", buffer, length);
|
|
|
|
/*
|
|
write it!
|
|
*/
|
|
status = NXDputdef(self->fileHandle, self->dictHandle, defString, data);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write array");
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
free(data);
|
|
SCSendOK(pCon);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void putGlobal(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
char value[1024];
|
|
int status;
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putglobal",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
Arg2Text(argc - 3, &argv[3], value, 1023);
|
|
status = NXputattr(self->fileHandle, argv[2], value, strlen(value),
|
|
NX_CHAR);
|
|
if (status != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write attribute", eLogError);
|
|
}
|
|
SCSendOK(pCon);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------*/
|
|
static int handlePut(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
int status, iVal;
|
|
char buffer[1024], defString[1024], numBuf[25];
|
|
double dVal;
|
|
float fVal;
|
|
|
|
/*============ */
|
|
if (strcmp(argv[1], "putfloat") == 0) {
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putfloat",
|
|
eLogError);
|
|
return 1;
|
|
}
|
|
status = Tcl_GetDouble(InterpGetTcl(pSics), argv[3], &dVal);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to float", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return 1;
|
|
}
|
|
fVal = (float) dVal;
|
|
status = NXDputalias(self->fileHandle, self->dictHandle,
|
|
argv[2], &fVal);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write %f to alias %s",
|
|
fVal, argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
return 1;
|
|
} else if (strcmp(argv[1], "putint") == 0) {
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to putint",
|
|
eLogError);
|
|
return 1;
|
|
}
|
|
status = Tcl_GetInt(InterpGetTcl(pSics), argv[3], &iVal);
|
|
if (status != TCL_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to convert %s to int", argv[3]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return 1;
|
|
}
|
|
status = NXDputalias(self->fileHandle, self->dictHandle,
|
|
argv[2], &iVal);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write %d to alias %s",
|
|
iVal, argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
return 1;
|
|
} else if (strcmp(argv[1], "puttext") == 0) {
|
|
/*====================*/
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to puttext",
|
|
eLogError);
|
|
return 1;
|
|
}
|
|
Arg2Text(argc - 3, &argv[3], buffer, 1023);
|
|
trim(buffer);
|
|
status = NXDdefget(self->dictHandle, argv[2], defString, 1023);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: alias %s not found in puttext", argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
return 1;
|
|
}
|
|
if (strlen(defString) < 900) {
|
|
strlcat(defString, " -dim {",1024);
|
|
snprintf(numBuf,sizeof(numBuf)-1, "%d", (int) strlen(buffer) + 1);
|
|
strlcat(defString, numBuf,1024);
|
|
strlcat(defString, " }",1024);
|
|
} else {
|
|
SCWrite(pCon, "ERROR: out of definition string space in puttext",
|
|
eLogError);
|
|
return 1;
|
|
}
|
|
status = NXDputdef(self->fileHandle, self->dictHandle,
|
|
defString, buffer);
|
|
if (status != NX_OK) {
|
|
snprintf(buffer,sizeof(buffer)-1, "ERROR: failed to write alias %s", argv[2]);
|
|
SCWrite(pCon, buffer, eLogError);
|
|
}
|
|
return 1;
|
|
} else if (strcmp(argv[1], "putmot") == 0) {
|
|
/*=========== */
|
|
putMotor(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "putcounter") == 0) {
|
|
/* ================ */
|
|
putCounter(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "puthdb") == 0) {
|
|
/* ================ */
|
|
putHdb(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "puthdboff") == 0) {
|
|
/* ================ */
|
|
putHdbOff(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "puthdbslab") == 0) {
|
|
/* ================ */
|
|
putHdbSlab(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "puthm") == 0) {
|
|
/*=================*/
|
|
putHistogramMemory(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "puttimebinning") == 0) {
|
|
/*=================*/
|
|
putTimeBinning(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putarray") == 0) {
|
|
/*================*/
|
|
putArray(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putintarray") == 0) {
|
|
/*================*/
|
|
putIntArray(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putglobal") == 0) {
|
|
/*===============*/
|
|
putGlobal(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putsicsdata") == 0) {
|
|
/*===============*/
|
|
putSicsData(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putattribute") == 0) {
|
|
/*===============*/
|
|
putAttribute(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putslab") == 0) {
|
|
/*===============*/
|
|
putSlab(pCon, pSics, self, argc, argv);
|
|
} else if (strcmp(argv[1], "putslab16") == 0) {
|
|
/*===============*/
|
|
putSlab16(pCon, pSics, self, argc, argv);
|
|
} else {
|
|
SCPrintf(pCon, eLogError, "ERROR: put command %s not recognised", argv[1] );
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void makeLink(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
int status;
|
|
char pBueffel[256];
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to makelink",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
status = NXDaliaslink(self->fileHandle, self->dictHandle,
|
|
argv[2], argv[3]);
|
|
if (status != NX_OK) {
|
|
snprintf(pBueffel, 255, "ERROR: linking %s against %s failed",
|
|
argv[2], argv[3]);
|
|
SCWrite(pCon, pBueffel, eLogError);
|
|
return;
|
|
}
|
|
|
|
SCSendOK(pCon);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
static void makeNamedLink(SConnection * pCon, SicsInterp * pSics,
|
|
pNXScript self, int argc, char *argv[])
|
|
{
|
|
int status;
|
|
char pBueffel[256];
|
|
|
|
if (argc < 5) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to makenamedlink",
|
|
eLogError);
|
|
return;
|
|
}
|
|
|
|
status = NXDaliasnamedlink(self->fileHandle, self->dictHandle,
|
|
argv[2], argv[3], argv[4]);
|
|
if (status != NX_OK) {
|
|
snprintf(pBueffel, 255, "ERROR: linking %s against %s as %s failed",
|
|
argv[2], argv[3], argv[4]);
|
|
SCWrite(pCon, pBueffel, eLogError);
|
|
return;
|
|
}
|
|
|
|
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",
|
|
eLogError);
|
|
return;
|
|
}
|
|
if (argc < 4) {
|
|
SCWrite(pCon,
|
|
"ERROR: insufficient number of arguments to updateDictVar",
|
|
eLogError);
|
|
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;
|
|
int status;
|
|
char buffer[132];
|
|
|
|
/*
|
|
preliminary checks
|
|
*/
|
|
assert(self);
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 1;
|
|
}
|
|
if (argc < 2) {
|
|
SCWrite(pCon, "ERROR: no keyword found", eLogError);
|
|
return 1;
|
|
}
|
|
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;
|
|
}
|
|
} else if (strcmp(argv[1], "divisor") == 0) {
|
|
if (argc < 3) {
|
|
SCWrite(pCon, "ERROR: no divisor found", eLogError);
|
|
return 1;
|
|
}
|
|
if (!SCMatchRights(pCon, usMugger)) {
|
|
return 1;
|
|
}
|
|
self->timeDivisor = atoi(argv[2]);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
status = handleFileOperations(pCon, self, argc, argv);
|
|
if (status < 0) {
|
|
return 0;
|
|
} else if (status == 1) {
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
if we are here, we can only continue if files are open
|
|
*/
|
|
if (self->fileHandle == NULL || self->dictHandle == NULL) {
|
|
SCWrite(pCon, "ERROR: cannot write, files not open", eLogError);
|
|
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;
|
|
}
|
|
|
|
if (strcmp(argv[1], "isalias") == 0) {
|
|
if (argc < 3) {
|
|
SCWrite(pCon, "ERROR: need alias to test", eLogError);
|
|
return 1;
|
|
}
|
|
if (NXDget(self->dictHandle, argv[2], buffer, 131) == NX_OK) {
|
|
snprintf(buffer, 131, "%s = 1", argv[2]);
|
|
} else {
|
|
snprintf(buffer, 131, "%s = 0", argv[2]);
|
|
}
|
|
SCWrite(pCon, buffer, eValue);
|
|
return 1;
|
|
}
|
|
|
|
if (strcmp(argv[1], "makelink") == 0) {
|
|
makeLink(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
}
|
|
if (strcmp(argv[1], "makenamedlink") == 0) {
|
|
makeNamedLink(pCon, pSics, self, argc, argv);
|
|
return 1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*=============== make it ==============================================*/
|
|
static void KillNXScript(void *pData)
|
|
{
|
|
pNXScript self = (pNXScript) pData;
|
|
if (self == NULL) {
|
|
return;
|
|
}
|
|
if (self->pDes) {
|
|
DeleteDescriptor(self->pDes);
|
|
}
|
|
if (self->fileHandle) {
|
|
NXclose(&self->fileHandle);
|
|
}
|
|
if (self->dictHandle) {
|
|
NXDclose(self->dictHandle, NULL);
|
|
}
|
|
free(self);
|
|
}
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
int MakeNXScript(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pNXScript self = NULL;
|
|
int status;
|
|
|
|
self = (pNXScript) malloc(sizeof(NXScript));
|
|
if (self == NULL) {
|
|
SCWrite(pCon, "ERROR: no memory for NXscript creation", eError);
|
|
return 0;
|
|
}
|
|
memset(self, 0, sizeof(NXScript));
|
|
self->pDes = CreateDescriptor("NXScript");
|
|
if (self->pDes == NULL) {
|
|
SCWrite(pCon, "ERROR: no memory for NXscript creation", eError);
|
|
free(self);
|
|
return 0;
|
|
}
|
|
self->timeDivisor = 1;
|
|
|
|
/*
|
|
create with with a default name if none specified
|
|
*/
|
|
if (argc > 1) {
|
|
status =
|
|
AddCommand(pSics, argv[1], NXScriptAction, KillNXScript, self);
|
|
} else {
|
|
status =
|
|
AddCommand(pSics, "nxscript", NXScriptAction, KillNXScript, self);
|
|
}
|
|
if (!status) {
|
|
SCWrite(pCon, "ERROR: duplicate NXScript object not created", eError);
|
|
KillNXScript(self);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|