Files
sics/sicsdata.c

1161 lines
33 KiB
C

/*---------------------------------------------------------------------
S I C S D A T A
An attempt to a generic interface to SICS data for all sorts of SICS
clients.
WARNING: this code only works when ints and floats are of the same size!
copyright: see file COPYRIGHT
Mark Koennecke, June 2003
added addto. Mark Koennecke, August 2009
Make Hipadaba compatible, Mark Koennecke, November 2012
----------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
#include <tcl.h>
#include <math.h>
#include "fortify.h"
#include "sics.h"
#include "splitter.h"
#include "scan.h"
#include "HistMem.h"
#include "sicsdata.h"
#include "sicshipadaba.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*--------------------------------------------------------------------*/
static void KillSICSData(void *pData)
{
pSICSData self = NULL;
self = (pSICSData) pData;
if (!self) {
return;
}
if (self->data != NULL) {
free(self->data);
}
if (self->dataType != NULL) {
free(self->dataType);
}
if (self->pDes != NULL) {
DeleteDescriptor(self->pDes);
}
free(self);
}
/*---------------------------------------------------------------------*/
pSICSData createSICSData(char *name)
{
pSICSData pNew = NULL;
pNew = (pSICSData) malloc(sizeof(SICSData));
if (!pNew) {
return NULL;
}
memset(pNew, 0, sizeof(SICSData));
pNew->pDes = CreateDescriptor("SICSData");
pNew->data = (int *) malloc(1024 * sizeof(int));
pNew->dataType = (char *) malloc(1024 * sizeof(char));
if (pNew->pDes == NULL || pNew->data == NULL || pNew->dataType == NULL) {
KillSICSData(pNew);
return NULL;
}
/* pNew->pDes->parNode = MakeHipadabaNode(name,HIPINTVARAR, 1); */
/* if(pNew->pDes->parNode == NULL){ */
/* KillSICSData(pNew); */
/* return NULL; */
/* } */
/* pNew->pDes->parNode->value.doNotFree = 1; */
/* pNew->pDes->parNode->value.v.intArray = pNew->data; */
memset(pNew->data, 0, 1024 * sizeof(int));
memset(pNew->dataType, 0, 1024 * sizeof(char));
pNew->currentDataSize = 1024;
pNew->dataUsed = 0;
return pNew;
}
/*---------------------------------------------------------------------------*/
int getSICSDataInt(pSICSData self, int pos, int *value)
{
if (pos >= self->dataUsed || self->dataType[pos] != INTTYPE) {
return 0;
}
*value = self->data[pos];
return 1;
}
/*---------------------------------------------------------------------------*/
int getSICSDataFloat(pSICSData self, int pos, float *value)
{
if (pos >= self->dataUsed || self->dataType[pos] != FLOATTYPE) {
return 0;
}
memcpy(value, &self->data[pos], sizeof(float));
return 1;
}
/*---------------------------------------------------------------------------*/
int setSICSDataInt(pSICSData self, int pos, int value)
{
int *idata = NULL;
idata = getSICSDataPointer(self, 0, pos + 1);
if (idata == NULL) {
return 0;
}
idata[pos] = value;
self->dataType[pos] = INTTYPE;
return 1;
}
/*----------------------------------------------------------------------------*/
int setSICSDataFloat(pSICSData self, int pos, float value)
{
int *idata = NULL;
idata = getSICSDataPointer(self, 0, pos + 1);
if (idata == NULL) {
return 0;
}
memcpy(&idata[pos], &value, sizeof(float));
self->dataType[pos] = FLOATTYPE;
return 1;
}
/*-------------------------------------------------------------------*/
int *getSICSDataPointer(pSICSData self, int start, int end)
{
int newSize;
int *newData = NULL;
char *newType = NULL;
assert(self);
if (end >= self->currentDataSize) {
/* we have to resize */
if (self->currentDataSize * 2 > end) {
newSize = self->currentDataSize * 2.;
} else {
newSize = end + self->dataUsed;
}
newData = (int *) malloc(newSize * sizeof(int));
newType = (char *) malloc(newSize * sizeof(char));
if (newData == NULL || newType == NULL) {
return NULL;
}
memset(newData, 0, newSize * sizeof(int));
memset(newType, 0, newSize * sizeof(char));
memcpy(newData, self->data, self->dataUsed * sizeof(int));
memcpy(newType, self->dataType, self->dataUsed * sizeof(char));
free(self->data);
free(self->dataType);
self->data = newData;
self->dataType = newType;
self->currentDataSize = newSize;
}
if (end > self->dataUsed) {
self->dataUsed = end;
}
return &self->data[start];
}
/*------------------------------------------------------------------------
assign a type to a couple of data values
--------------------------------------------------------------------------*/
static void assignType(pSICSData self, int start, int end, int type)
{
int i;
assert(self);
assert(end <= self->currentDataSize);
assert(type == INTTYPE || type == FLOATTYPE);
for (i = start; i < end; i++) {
self->dataType[i] = type;
}
}
/*-----------------------------------------------------------------------*/
void assignSICSType(pSICSData self, int start, int end, int type)
{
assignType(self, start, end, type);
}
/*------------------------------------------------------------------------
netEncode transforms the data in the array into network format.
- int become ints in network byte order
- floats become fixed point and thus ints in network byte order as well
-------------------------------------------------------------------------*/
static void netEncode(pSICSData self)
{
int i;
float fVal;
assert(self);
for (i = 0; i < self->dataUsed; i++) {
if (self->dataType[i] == INTTYPE) {
self->data[i] = htonl(self->data[i]);
}
if (self->dataType[i] == FLOATTYPE) {
memcpy(&fVal, self->data + i, sizeof(float));
fVal *= 65536.;
self->data[i] = htonl((int) fVal);
}
}
}
/*---------------------------------------------------------------------*/
void clearSICSData(pSICSData self)
{
assert(self);
int clearSize = 8192;
self->dataUsed = 0;
if (self->currentDataSize > clearSize) {
free(self->data);
free(self->dataType);
self->data = (int *) malloc(clearSize * sizeof(int));
self->dataType = (char *) malloc(clearSize * sizeof(char));
self->currentDataSize = clearSize;
}
memset(self->data, 0, self->currentDataSize * sizeof(int));
memset(self->dataType, 0, self->currentDataSize * sizeof(char));
}
/*--------------------------------------------------------------------*/
static int dumpSICSDataXY(pSICSData self, char *filename,
SConnection * pCon)
{
FILE *fd = NULL;
char pBueffel[132];
int i;
float fVal;
fd = fopen(filename, "w");
if (fd == NULL) {
snprintf(pBueffel, 131, "ERROR: cannot open %s", filename);
SCWrite(pCon, pBueffel, eError);
return 0;
}
for (i = 0; i < self->dataUsed; i++) {
if (self->dataType[i] == INTTYPE) {
fprintf(fd, "%10d %25d\n", i, self->data[i]);
}
if (self->dataType[i] == FLOATTYPE) {
memcpy(&fVal, self->data + i, sizeof(float));
fprintf(fd, "%10d %25.5f\n", i, fVal);
}
}
fclose(fd);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int dumpSICSData(pSICSData self, char *filename, SConnection * pCon)
{
FILE *fd = NULL;
char pBueffel[132];
int i;
float fVal;
fd = fopen(filename, "w");
if (fd == NULL) {
snprintf(pBueffel, 131, "ERROR: cannot open %s", filename);
SCWrite(pCon, pBueffel, eError);
return 0;
}
for (i = 0; i < self->dataUsed; i++) {
if (self->dataType[i] == INTTYPE) {
fprintf(fd, " %d", self->data[i]);
}
if (self->dataType[i] == FLOATTYPE) {
memcpy(&fVal, self->data + i, sizeof(float));
fprintf(fd, " %.5f", fVal);
}
}
fclose(fd);
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------*/
static int putInt(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, iVal, pos, *iData = NULL;
assert(self);
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData putint",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon, "ERROR: failed to convert putint position to integer",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[1], &iVal);
if (status != TCL_OK) {
SCWrite(pCon, "ERROR: failed to convert putint value to integer",
eError);
return 0;
}
iData = getSICSDataPointer(self, pos, pos + 1);
if (!iData) {
SCWrite(pCon, "ERROR: out of memory in putint", eError);
return 0;
}
*iData = iVal;
SCSendOK(pCon);
self->dataType[pos] = INTTYPE;
return 1;
}
/*-------------------------------------------------------------------*/
static int putFloat(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, *iData = NULL;
float fVal;
double dVal;
char buffer[256];
assert(self);
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData putfloat",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon, "ERROR: failed to convert putfloat position to integer",
eError);
return 0;
}
status = Tcl_GetDouble(InterpGetTcl(pSics), argv[1], &dVal);
if (status != TCL_OK) {
snprintf(buffer, 255,
"ERROR: faild to convert putfloat value %s to float",
argv[1]);
SCWrite(pCon, buffer, eError);
return 0;
}
iData = getSICSDataPointer(self, pos, pos + 1);
if (!iData) {
SCWrite(pCon, "ERROR: out of memory in putfloat", eError);
return 0;
}
fVal = (float) dVal;
memcpy(iData, &fVal, sizeof(float));
self->dataType[pos] = FLOATTYPE;
SCSendOK(pCon);
return 1;
}
/*------------------------------------------------------------------*/
static int getPos(pSICSData self, char *name, SConnection * pCon, int pos)
{
char pBueffel[512];
float value;
if (pos >= self->dataUsed) {
SCWrite(pCon, "ERROR: requested position out of range", eError);
return 0;
}
if (self->dataType[pos] == FLOATTYPE) {
memcpy(&value, &self->data[pos], sizeof(float));
snprintf(pBueffel, 511, "%s = %f", name, value);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
if (self->dataType[pos] == INTTYPE) {
snprintf(pBueffel, 511, "%s = %d", name, self->data[pos]);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
return 0;
}
/*------------------------------------------------------------------*/
static float getDataPos(pSICSData self, int pos)
{
float value;
assert(pos < self->dataUsed);
if (self->dataType[pos] == FLOATTYPE) {
memcpy(&value, &self->data[pos], sizeof(float));
} else {
value = (float) self->data[pos];
}
return value;
}
/*------------------------------------------------------------------*/
static int divideSicsData(pSICSData self, SicsInterp * pSics,
SConnection * pCon, char *name)
{
int i;
pSICSData other = NULL;
float val, div;
other = (pSICSData) FindCommandData(pSics, name, "SICSData");
if (other == NULL) {
SCWrite(pCon, "ERROR: requested SICSData object to divide not found",
eError);
return 0;
}
if (other->dataUsed < self->dataUsed) {
SCWrite(pCon, "ERROR: not enough data in SICSData for division",
eError);
return 0;
}
for (i = 0; i < self->dataUsed; i++) {
div = getDataPos(other, i);
if (ABS(div) > .00001) {
val = getDataPos(self, i) / div;
} else {
val = .0;
}
if (self->dataType[i] == INTTYPE) {
self->data[i] = (int) val;
} else {
memcpy(&self->data[i], &val, sizeof(float));
}
}
return 1;
}
/*------------------------------------------------------------------*/
static int scaleSicsData(pSICSData self, SicsInterp * pSics,
SConnection * pCon, float scale)
{
int i;
float div;
for (i = 0; i < self->dataUsed; i++) {
div = getDataPos(self, i);
div *= scale;
if (self->dataType[i] == INTTYPE) {
self->data[i] = (int) fabsf(div);
} else {
memcpy(&self->data[i], &div, sizeof(float));
}
}
return 1;
}
/*------------------------------------------------------------------*/
static int addToSicsData(pSICSData self, SicsInterp * pSics,
SConnection *pCon, float val)
{
int i;
float div;
for (i = 0; i < self->dataUsed; i++) {
div = getDataPos(self, i);
div += val;
if (self->dataType[i] == INTTYPE) {
self->data[i] = (int) fabsf(div);
} else {
memcpy(&self->data[i], &div, sizeof(float));
}
}
return 1;
}
/*-------------------------------------------------------------------*/
static int copyScanCounts(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, np, i;
pScanData pScan = NULL;
int *iData = NULL;
long *lData = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copyscancounts",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyscancounts position to integer",
eError);
return 0;
}
pScan = FindCommandData(pSics, argv[1], "ScanObject");
if (!pScan) {
SCWrite(pCon, "ERROR: scan object not found in copyscancounts",
eError);
return 0;
}
np = GetScanNP(pScan);
iData = getSICSDataPointer(self, pos, pos + np);
lData = (long *) malloc(np * sizeof(long));
if (!iData || !lData) {
SCWrite(pCon, "ERROR: out of memory in copyscancounts", eError);
return 0;
}
memset(lData, 0, np * sizeof(long));
GetScanCounts(pScan, lData, np);
for (i = 0; i < np; i++) {
self->data[pos + i] = (int) lData[i];
self->dataType[pos + i] = INTTYPE;
}
free(lData);
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------*/
static int copyScanMonitor(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, np, i, monitor;
pScanData pScan = NULL;
int *iData = NULL;
long *lData = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copyscanmon",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyscancounts position to integer",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &monitor);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyscancounts monitor to integer",
eError);
return 0;
}
pScan = FindCommandData(pSics, argv[1], "ScanObject");
if (!pScan) {
SCWrite(pCon, "ERROR: scan object not found in copyscanmonitor",
eError);
return 0;
}
np = GetScanNP(pScan);
iData = getSICSDataPointer(self, pos, pos + np);
lData = (long *) malloc(np * sizeof(long));
if (!iData || !lData) {
SCWrite(pCon, "ERROR: out of memory in copyscanmonitor", eError);
return 0;
}
memset(lData, 0, np * sizeof(long));
GetScanMonitor(pScan, monitor, lData, np);
for (i = 0; i < np; i++) {
self->data[pos + i] = (int) lData[i];
self->dataType[pos + i] = INTTYPE;
}
free(lData);
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------*/
static int copyScanVar(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, np, i, var;
pScanData pScan = NULL;
int *iData = NULL;
float *fData = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copyscanvar",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyscanvar position to integer",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &var);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyscanvar varID to integer",
eError);
return 0;
}
pScan = FindCommandData(pSics, argv[1], "ScanObject");
if (!pScan) {
SCWrite(pCon, "ERROR: scan object not found in copyscanvar", eError);
return 0;
}
np = GetScanNP(pScan);
iData = getSICSDataPointer(self, pos, pos + np);
fData = (float *) malloc(np * sizeof(float));
if (!iData || !fData) {
SCWrite(pCon, "ERROR: out of memory in copyscanvar", eError);
return 0;
}
memset(fData, 0, np * sizeof(float));
GetSoftScanVar(pScan, var, fData, np);
for (i = 0; i < np; i++) {
memcpy(self->data + pos + i, fData + i, sizeof(float));
self->dataType[pos + i] = FLOATTYPE;
}
free(fData);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int copyTimeBin(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, noTimeBin, pos, i;
pHistMem pHist = NULL;
const float *fTimeBin = NULL;
int *iData = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copytimebin",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copytimebin position to integer",
eError);
return 0;
}
pHist = (pHistMem) FindCommandData(pSics, argv[1], "HistMem");
if (!pHist) {
SCWrite(pCon, "ERROR: histogram memory not found in copytimebin",
eError);
return 0;
}
fTimeBin = GetHistTimeBin(pHist, &noTimeBin);
iData = getSICSDataPointer(self, pos, pos + noTimeBin);
if (!fTimeBin || !iData) {
SCWrite(pCon, "ERROR: out of memory in SICSData copytimebin", eError);
return 0;
}
for (i = 0; i < noTimeBin; i++) {
setSICSDataInt(self, pos + i, (int) (fTimeBin[i]));
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int copyHM(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, i, subset = 0, start, end;
pHistMem pHist = NULL;
const float *fTimeBin = NULL;
int *iData = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copyhm",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyhm position to integer", eError);
return 0;
}
pHist = (pHistMem) FindCommandData(pSics, argv[1], "HistMem");
if (!pHist) {
SCWrite(pCon, "ERROR: histogram memory not found in copyhm",
eError);
return 0;
}
start = 0;
end = GetHistLength(pHist);
if (argc > 3) {
subset = 1;
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &start);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyhm start to integer", eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[3], &end);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyhm end to integer", eError);
return 0;
}
}
iData = getSICSDataPointer(self, pos, pos + (end - start));
if (!iData) {
SCWrite(pCon, "ERROR: out of memory in SICSData copyhm", eError);
return 0;
}
if(end > GetHistLength(pHist)){
GetHistogramDirect(pHist, pCon, 0, start, end, iData,
(end - start) * sizeof(int));
} else {
GetHistogram(pHist, pCon, 0, start, end, iData,
(end - start) * sizeof(int));
}
assignType(self, pos, pos + (end - start), INTTYPE);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int copyHMBank(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, i, bank, dataLength;
pHistMem pHist = NULL;
const float *fTimeBin = NULL;
int *iData = NULL;
if (argc < 4) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copyhm",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyhmbank position to integer",
eError);
return 0;
}
pHist = (pHistMem) FindCommandData(pSics, argv[1], "HistMem");
if (!pHist) {
SCWrite(pCon, "ERROR: histogram memory not found in copyhmbank",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &bank);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyhmbank bank to integer", eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[3], &dataLength);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copyhmbank dataLength to integer",
eError);
return 0;
}
iData = getSICSDataPointer(self, pos, pos + dataLength);
if (!iData) {
SCWrite(pCon, "ERROR: out of memory in SICSData copyhmbank", eError);
return 0;
}
GetHistogramDirect(pHist, pCon, bank, 0, dataLength, iData,
dataLength * sizeof(int));
assignType(self, pos, pos + dataLength, INTTYPE);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------*/
static int copyData(pSICSData self, SicsInterp * pSics,
SConnection * pCon, int argc, char *argv[])
{
pSICSData other = NULL;
int pos, start, end, i;
if (argc < 6) {
SCWrite(pCon, "ERROR: Insufficient number of arguments to copydata",
eError);
return 0;
}
pos = atoi(argv[2]);
start = atoi(argv[4]);
end = atoi(argv[5]);
if ((other = FindCommandData(pSics, argv[3], "SICSData")) == NULL) {
SCWrite(pCon, "ERROR: invalid SICSData requested", eError);
return 0;
}
if (start > end || end > other->dataUsed) {
SCWrite(pCon, "ERROR: invalid copy range specified", eError);
return 0;
}
getSICSDataPointer(self, pos, pos + (end - start));
memcpy(&self->data[pos], &other->data[start],
(end - start) * sizeof(int));
memcpy(&self->dataType[pos], &other->dataType[start],
(end - start) * sizeof(char));
return 1;
}
/*--------------------------------------------------------------------*/
static int copyNode(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, pos, length, *iData, i;
pHdb node = NULL;
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copynode",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[0], &pos);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copynode position to integer", eError);
return 0;
}
node = FindHdbNode(NULL,argv[1], pCon);
if(node == NULL){
SCPrintf(pCon,eError,"ERROR: node %s not found", argv[1]);
return 0;
}
if(argc > 2){
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &length);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copynode length to integer", eError);
return 0;
} else {
length = node->value.arrayLength;
}
} else {
length = node->value.arrayLength;
}
if(length < 1) {
length = 1;
}
if(length > node->value.arrayLength){
length = node->value.arrayLength;
}
iData = getSICSDataPointer(self, pos, pos + length);
if (!iData) {
SCWrite(pCon, "ERROR: out of memory in SICSData copynode", eError);
return 0;
}
switch(node->value.dataType){
case HIPINT:
setSICSDataInt(self,pos,node->value.v.intValue);
break;
case HIPFLOAT:
setSICSDataFloat(self,pos,(float)node->value.v.doubleValue);
break;
case HIPINTAR:
case HIPINTVARAR:
memcpy(iData, node->value.v.intArray, length*sizeof(int));
assignType(self, pos, pos + length, INTTYPE);
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
for(i = 0; i < length; i++){
setSICSDataFloat(self,pos+i, (float)node->value.v.floatArray[i]);
}
break;
default:
SCWrite(pCon,"ERROR: cannot copy non numeric data into a SICSData", eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int intify(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int i;
float fval;
for(i = 0; i < self->dataUsed; i++){
if(self->dataType[i] == FLOATTYPE){
memcpy(&fval,self->data+i,sizeof(float));
self->data[i] = (int)fval;
self->dataType[i] = INTTYPE;
}
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------*/
static int copyToNode(pSICSData self, int argc, char *argv[],
SConnection * pCon, SicsInterp * pSics)
{
int status, start, length,i, j, ival;
float fval;
pHdb node = NULL;
if (argc < 3) {
SCWrite(pCon, "ERROR: not enough arguments to SICSData copytonode",
eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[1], &start);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copytonode start to integer", eError);
return 0;
}
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &length);
if (status != TCL_OK) {
SCWrite(pCon,
"ERROR: failed to convert copytonode length to integer", eError);
return 0;
}
node = FindHdbNode(NULL,argv[0], pCon);
if(node == NULL){
SCPrintf(pCon,eError,"ERROR: node %s not found", argv[1]);
return 0;
}
switch(node->value.dataType){
case HIPINT:
getSICSDataInt(self,start,&ival);
node->value.v.intValue = ival;
break;
case HIPFLOAT:
getSICSDataFloat(self,start,&fval);
node->value.v.doubleValue = (double) fval;
break;
case HIPINTAR:
case HIPINTVARAR:
if(node->value.arrayLength != length){
if(node->value.v.intArray != NULL){
free(node->value.v.intArray);
}
node->value.v.intArray = malloc(length*sizeof(int));
if(node->value.v.intArray == NULL){
SCWrite(pCon,"ERROR: out of memory in copytonode",eError);
return 0;
}
node->value.arrayLength = length;
}
memcpy(node->value.v.intArray, self->data + start, length*sizeof(int));
break;
case HIPFLOATAR:
case HIPFLOATVARAR:
if(node->value.arrayLength != length){
if(node->value.v.floatArray != NULL){
free(node->value.v.floatArray);
}
node->value.v.floatArray = malloc(length*sizeof(double));
if(node->value.v.floatArray == NULL){
SCWrite(pCon,"ERROR: out of memory in copytonode",eError);
return 0;
}
node->value.arrayLength = length;
}
for(i = start, j = 0; i < length; i++, j++){
getSICSDataFloat(self,i,&fval);
node->value.v.floatArray[j] = (double)fval;
}
break;
default:
SCWrite(pCon,"ERROR: cannot copy non numeric data into a SICSData", eError);
return 0;
}
NotifyHipadabaPar(node,pCon);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------
Look here in order to find out about commands understood
----------------------------------------------------------------------*/
int SICSDataAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pSICSData self = NULL;
char pBueffel[132];
int pos;
float scale, val;
self = (pSICSData) pData;
assert(self);
if (argc < 2) {
SCWrite(pCon, "ERROR: not enough arguments to act upon data", eError);
return 0;
}
strtolower(argv[1]);
/*------ clear*/
if (strcmp(argv[1], "clear") == 0) {
clearSICSData(self);
SCSendOK(pCon);
return 1;
} else if (strcmp(argv[1], "used") == 0) {
/*--------- used */
snprintf(pBueffel, 131, "%s = %d", argv[0], self->dataUsed);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else if (strcmp(argv[1], "dumpxy") == 0) {
/* --------- dump */
if (argc < 3) {
SCWrite(pCon, "ERROR: need a file name to dump to", eError);
return 0;
}
return dumpSICSDataXY(self, argv[2], pCon);
} else if (strcmp(argv[1], "dump") == 0) {
/* --------- dump */
if (argc < 3) {
SCWrite(pCon, "ERROR: need a file name to dump to", eError);
return 0;
}
return dumpSICSData(self, argv[2], pCon);
} else if (strcmp(argv[1], "get") == 0) {
if (argc < 3) {
SCWrite(pCon, "ERROR: need a position to read", eError);
return 0;
}
pos = atoi(argv[2]);
return getPos(self, argv[0], pCon, pos);
} else if (strcmp(argv[1], "divideby") == 0) {
if (argc < 3) {
SCWrite(pCon, "ERROR: need a SICSdata to divide by", eError);
return 0;
}
return divideSicsData(self, pSics, pCon, argv[2]);
} else if (strcmp(argv[1], "scale") == 0) {
if (argc < 3) {
SCWrite(pCon, "ERROR: need a scale factor to apply", eError);
return 0;
}
return scaleSicsData(self, pSics, pCon, atof(argv[2]));
} else if (strcmp(argv[1], "addto") == 0) {
if (argc < 3) {
SCWrite(pCon, "ERROR: need a value to add", eError);
return 0;
}
return addToSicsData(self, pSics, pCon, atof(argv[2]));
} else if (strcmp(argv[1], "copydata") == 0) {
return copyData(self, pSics, pCon, argc, argv);
} else if (strcmp(argv[1], "putint") == 0) {
/*---------- putint */
return putInt(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "putfloat") == 0) {
/*---------- putfloat */
return putFloat(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copyscancounts") == 0) {
/*-------- copyscancounts*/
return copyScanCounts(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copyscanmon") == 0) {
/*-------- copyscanmon*/
return copyScanMonitor(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copyscanvar") == 0) {
/*--------- copyscanvar */
return copyScanVar(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copytimebin") == 0) {
/*--------- copytimebin */
return copyTimeBin(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copyhm") == 0) {
/*--------- copyhm */
return copyHM(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copyhmbank") == 0) {
/*--------- copyhmbank */
return copyHMBank(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copynode") == 0) {
/*--------- copynode */
return copyNode(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "copytonode") == 0) {
/*--------- copyTonode */
return copyToNode(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "intify") == 0) {
/*--------- copyTonode */
return intify(self, argc - 2, &argv[2], pCon, pSics);
} else if (strcmp(argv[1], "writezipped") == 0) {
/*--------- writezipped */
if (argc < 3) {
SCWrite(pCon, "ERROR: need a name for writezipped", eError);
return 0;
}
netEncode(self);
SCWriteZipped(pCon, argv[2], self->data, self->dataUsed * sizeof(int));
return 1;
} else if (strcmp(argv[1], "writeuu") == 0) {
/*--------- writeuu */
if (argc < 3) {
SCWrite(pCon, "ERROR: need a name for writeuu", eError);
return 0;
}
netEncode(self);
SCWriteUUencoded(pCon, argv[2], self->data,
self->dataUsed * sizeof(int));
return 1;
}
SCWrite(pCon, "ERROR: object command to SICSData not recognized",
eError);
return 0;
}
/*----------------------------------------------------------------------*/
int SICSDataFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pSICSData self = NULL;
int iRet;
if (argc < 3) {
SCWrite(pCon, "ERROR: not enough arguments to SICSDataFactory",
eError);
return 0;
}
strtolower(argv[1]);
strtolower(argv[2]);
if (strcmp(argv[1], "new") == 0) {
self = createSICSData(argv[2]);
if (self == NULL) {
SCWrite(pCon, "ERROR: not enough memory to create SICSData", eError);
return 0;
}
iRet = AddCommand(pSics, argv[2], SICSDataAction, KillSICSData, self);
if (!iRet) {
SCWrite(pCon,
"ERROR: new SICSData not created due to name collision",
eError);
KillSICSData(self);
return 0;
}
SCSendOK(pCon);
return 1;
} else if (strcmp(argv[1], "del") == 0) {
self = (pSICSData) FindCommandData(pSics, argv[2], "SICSData");
if (self == NULL) {
SCWrite(pCon, "ERROR: SICSData to kill not found!", eError);
return 0;
}
RemoveCommand(pSics, argv[2]);
SCSendOK(pCon);
return 1;
}
SCWrite(pCon, "ERROR: object command to SICSData not recognized",
eError);
return 0;
}