/*--------------------------------------------------------------------- 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 #include #include #include #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; }