- Added a a general data handling object

- Extended the callback interface to register scipts on callbacks
- Fixed a stop bug in the anticollision object
- Modified the HM code to do zero through a client connection
This commit is contained in:
cvs
2003-06-13 11:35:35 +00:00
parent f3853c20f0
commit 6819991e85
26 changed files with 1649 additions and 98 deletions

598
sicsdata.c Normal file
View File

@ -0,0 +1,598 @@
/*---------------------------------------------------------------------
S I C S D A T A
An attempt to a generic interface to SICS data for all sorts of SICS
clients.
copyright: see file COPYRIGHT
Mark Koennecke, June 2003
----------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
#include <tcl.h>
#include "fortify.h"
#include "sics.h"
#include "splitter.h"
#include "scan.h"
#include "HistMem.h"
#include "sicsdata.h"
#define INTTYPE 0
#define FLOATTYPE 1
/*--------------------------------------------------------------------*/
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(void){
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;
}
memset(pNew->data,0,1024*sizeof(int));
memset(pNew->dataType,0,1024*sizeof(char));
pNew->currentDataSize = 1024;
pNew->dataUsed = 0;
return pNew;
}
/*-------------------------------------------------------------------*/
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;
}
}
/*------------------------------------------------------------------------
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);
}
}
}
/*---------------------------------------------------------------------*/
static void clearSICSData(pSICSData self){
assert(self);
self->dataUsed = 0;
memset(self->data,0,self->currentDataSize*sizeof(int));
memset(self->dataType,0,self->currentDataSize*sizeof(char));
}
/*--------------------------------------------------------------------*/
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,"%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 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;
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){
SCWrite(pCon,"ERROR: failed to convert putint value to float",
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 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++){
memcpy(iData + pos + i, fTimeBin + i, sizeof(float));
self->dataType[pos+i] = FLOATTYPE;
}
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 copytimebin",
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;
}
GetHistogramDirect(pHist,pCon,0,start,end,iData,(end-start)*sizeof(int));
assignType(self,pos,pos+(end-start),INTTYPE);
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];
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],"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],"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){
/*--------- copytimebin */
return copyHM(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();
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;
}