1161 lines
33 KiB
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;
|
|
}
|