- Refactored histogram memory code a little
- motor driver for ECB now fully working - Fixed an anticollider bug - Untested version of a driver for the Risoe TDC histogram memory
This commit is contained in:
23
HistDriv.i
23
HistDriv.i
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 478 "histogram.w"
|
#line 461 "histogram.w"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
H I S T D R I V
|
H I S T D R I V
|
||||||
@ -10,22 +10,13 @@
|
|||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#ifndef SICSHISTDRIV
|
#ifndef SICSHISTDRIV
|
||||||
#define SICSHISTDRIV
|
#define SICSHISTDRIV
|
||||||
#define MAXCHAN 16834
|
#include "hmdata.h"
|
||||||
|
|
||||||
|
|
||||||
#line 83 "histogram.w"
|
#line 89 "histogram.w"
|
||||||
|
|
||||||
typedef struct __HistDriver {
|
typedef struct __HistDriver {
|
||||||
/* configuration data */
|
pHMdata data;
|
||||||
HistMode eHistMode;
|
|
||||||
OverFlowMode eFlow;
|
|
||||||
int iRank;
|
|
||||||
int iDims[MAXDIM];
|
|
||||||
int nDim;
|
|
||||||
int iLength;
|
|
||||||
int iBinWidth;
|
|
||||||
float fTime[MAXCHAN];
|
|
||||||
int iTimeChan;
|
|
||||||
/* counting operations data */
|
/* counting operations data */
|
||||||
CounterMode eCount;
|
CounterMode eCount;
|
||||||
float fCountPreset;
|
float fCountPreset;
|
||||||
@ -77,17 +68,17 @@
|
|||||||
void *pPriv;
|
void *pPriv;
|
||||||
} HistDriver;
|
} HistDriver;
|
||||||
|
|
||||||
#line 490 "histogram.w"
|
#line 473 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#line 240 "histogram.w"
|
#line 228 "histogram.w"
|
||||||
|
|
||||||
pHistDriver CreateHistDriver(pStringDict pDict);
|
pHistDriver CreateHistDriver(pStringDict pDict);
|
||||||
void DeleteHistDriver(pHistDriver self);
|
void DeleteHistDriver(pHistDriver self);
|
||||||
int HistDriverConfig(pHistDriver self, pStringDict pOpt,
|
int HistDriverConfig(pHistDriver self, pStringDict pOpt,
|
||||||
SConnection *pCon);
|
SConnection *pCon);
|
||||||
|
|
||||||
#line 491 "histogram.w"
|
#line 474 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
18
HistMem.h
18
HistMem.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 451 "histogram.w"
|
#line 434 "histogram.w"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
H I S T M E M
|
H I S T M E M
|
||||||
@ -33,7 +33,7 @@
|
|||||||
eSANSTOF
|
eSANSTOF
|
||||||
} HistMode;
|
} HistMode;
|
||||||
|
|
||||||
#line 35 "histogram.w"
|
#line 36 "histogram.w"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
eOIgnore,
|
eOIgnore,
|
||||||
@ -42,22 +42,22 @@
|
|||||||
eReflect
|
eReflect
|
||||||
} OverFlowMode;
|
} OverFlowMode;
|
||||||
|
|
||||||
#line 471 "histogram.w"
|
#line 454 "histogram.w"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#line 304 "histogram.w"
|
#line 287 "histogram.w"
|
||||||
|
|
||||||
pHistMem CreateHistMemory(char *drivername);
|
pHistMem CreateHistMemory(char *drivername);
|
||||||
void DeleteHistMemory(void *self);
|
void DeleteHistMemory(void *self);
|
||||||
|
|
||||||
#line 320 "histogram.w"
|
#line 303 "histogram.w"
|
||||||
|
|
||||||
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
|
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
|
||||||
int HistSetOption(pHistMem self, char *name, char *value);
|
int HistSetOption(pHistMem self, char *name, char *value);
|
||||||
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
|
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
|
||||||
|
|
||||||
#line 348 "histogram.w"
|
#line 331 "histogram.w"
|
||||||
|
|
||||||
float GetHistPreset(pHistMem self);
|
float GetHistPreset(pHistMem self);
|
||||||
int SetHistPreset(pHistMem self, float fVal);
|
int SetHistPreset(pHistMem self, float fVal);
|
||||||
@ -72,7 +72,7 @@
|
|||||||
int HistBlockCount(pHistMem self, SConnection *pCon);
|
int HistBlockCount(pHistMem self, SConnection *pCon);
|
||||||
|
|
||||||
|
|
||||||
#line 377 "histogram.w"
|
#line 360 "histogram.w"
|
||||||
|
|
||||||
int SetHistogram(pHistMem self, SConnection *pCon,
|
int SetHistogram(pHistMem self, SConnection *pCon,
|
||||||
int i,int iStart, int iEnd, HistInt *lData);
|
int i,int iStart, int iEnd, HistInt *lData);
|
||||||
@ -84,7 +84,7 @@
|
|||||||
HistInt *lData, int iDataLen);
|
HistInt *lData, int iDataLen);
|
||||||
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);
|
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal);
|
||||||
|
|
||||||
#line 420 "histogram.w"
|
#line 403 "histogram.w"
|
||||||
|
|
||||||
int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
@ -93,7 +93,7 @@
|
|||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
#line 473 "histogram.w"
|
#line 456 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
11
HistMem.i
11
HistMem.i
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 496 "histogram.w"
|
#line 479 "histogram.w"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
H I S T M E M -- Internal
|
H I S T M E M -- Internal
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#ifndef SICSHISTMEMINT
|
#ifndef SICSHISTMEMINT
|
||||||
#define SICSHISTMEMINT
|
#define SICSHISTMEMINT
|
||||||
|
|
||||||
#line 262 "histogram.w"
|
#line 250 "histogram.w"
|
||||||
|
|
||||||
typedef struct __HistMem {
|
typedef struct __HistMem {
|
||||||
pObjectDescriptor pDes;
|
pObjectDescriptor pDes;
|
||||||
@ -22,14 +22,9 @@
|
|||||||
pICountable pCountInt;
|
pICountable pCountInt;
|
||||||
pICallBack pCall;
|
pICallBack pCall;
|
||||||
pStringDict pOption;
|
pStringDict pOption;
|
||||||
HistInt *iLocalData;
|
|
||||||
int iLocalLength;
|
|
||||||
int iLocalUpdate;
|
|
||||||
time_t tLocal;
|
|
||||||
int iUpdateIntervall;
|
|
||||||
} HistMem;
|
} HistMem;
|
||||||
|
|
||||||
#line 506 "histogram.w"
|
#line 489 "histogram.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
2
Makefile
2
Makefile
@ -59,7 +59,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \
|
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \
|
||||||
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \
|
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \
|
||||||
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) ecb.o ecbdriv.o \
|
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) ecb.o ecbdriv.o \
|
||||||
ecbcounter.o
|
ecbcounter.o hmdata.o tdchm.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
@ -105,7 +105,7 @@ static long ColliderSetValue(void *pData, SConnection *pCon, float fTarget){
|
|||||||
*/
|
*/
|
||||||
LLDdelete(self->sequenceList);
|
LLDdelete(self->sequenceList);
|
||||||
self->sequenceList = LLDcreate(sizeof(Sequence));
|
self->sequenceList = LLDcreate(sizeof(Sequence));
|
||||||
self->level = 0;
|
self->level = -1; /* otherwise level 0 will not be started */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
evaluate colliderScript
|
evaluate colliderScript
|
||||||
|
@ -86,4 +86,3 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
36
ecb.c
36
ecb.c
@ -20,8 +20,9 @@
|
|||||||
#include "ecb.i"
|
#include "ecb.i"
|
||||||
/*------------- private defines and error codes ------------------------*/
|
/*------------- private defines and error codes ------------------------*/
|
||||||
#define ACKN ('\6') /* Acknowledge character */
|
#define ACKN ('\6') /* Acknowledge character */
|
||||||
#define READ_BYTES 3
|
#define READ_BYTES 3
|
||||||
#define WRITE_BYTES 4
|
#define WRITE_BYTES 4
|
||||||
|
#define DMAREAD 5
|
||||||
#define ECB_BYTES 65536L
|
#define ECB_BYTES 65536L
|
||||||
|
|
||||||
typedef union /* Used to swap bytes in 'address' and 'byte_count' */
|
typedef union /* Used to swap bytes in 'address' and 'byte_count' */
|
||||||
@ -179,6 +180,33 @@ int ecbRead(pECB self, unsigned short address,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
int ecbDMARead(pECB self, unsigned short address, void *buffer,
|
||||||
|
unsigned short byteCount){
|
||||||
|
int status, count;
|
||||||
|
|
||||||
|
assert(self != NULL);
|
||||||
|
assert(self->gpib != NULL);
|
||||||
|
self->lastError = 0;
|
||||||
|
|
||||||
|
status = ecbPrepareIO(self,DMAREAD,address,(unsigned short)byteCount);
|
||||||
|
if(status <= 0){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
usleep(20*1000);
|
||||||
|
|
||||||
|
/*
|
||||||
|
actual read
|
||||||
|
*/
|
||||||
|
status = GPIBread(self->gpib,self->ecbDeviceID, buffer, byteCount);
|
||||||
|
if(status < 0){
|
||||||
|
self->lastError = status;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
int ecbWrite(pECB self, unsigned short address,
|
int ecbWrite(pECB self, unsigned short address,
|
||||||
void *buffer, int byteCount){
|
void *buffer, int byteCount){
|
||||||
|
|
||||||
@ -317,9 +345,13 @@ int ECBAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
sprintf(pBuffer,"%x %x %x %x",
|
sprintf(pBuffer,"%x %x %x %x",
|
||||||
out.d, out.e, out.c, out.c);
|
out.d, out.e, out.b, out.c);
|
||||||
SCWrite(pCon,pBuffer,eValue);
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if(strcmp(argv[1],"clear") == 0){
|
||||||
|
ecbClear(self);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
SCWrite(pCon,"ERROR: ECB does not understand keyword", eError);
|
SCWrite(pCon,"ERROR: ECB does not understand keyword", eError);
|
||||||
return 0;
|
return 0;
|
||||||
|
2
ecb.h
2
ecb.h
@ -32,6 +32,8 @@ typedef struct {
|
|||||||
void *buffer, int byteCount);
|
void *buffer, int byteCount);
|
||||||
int ecbWrite(pECB self, unsigned short address,
|
int ecbWrite(pECB self, unsigned short address,
|
||||||
void *buffer, int byteCount);
|
void *buffer, int byteCount);
|
||||||
|
int ecbDMARead(pECB self, unsigned short address, void *buffer,
|
||||||
|
unsigned short byteCount);
|
||||||
void ecbClear(pECB self);
|
void ecbClear(pECB self);
|
||||||
int fixECBError(pECB self);
|
int fixECBError(pECB self);
|
||||||
void ecbErrorDescription(pECB self, char *buffer,
|
void ecbErrorDescription(pECB self, char *buffer,
|
||||||
|
7
ecb.w
7
ecb.w
@ -72,6 +72,8 @@ The function interface then looks like:
|
|||||||
void *buffer, int byteCount);
|
void *buffer, int byteCount);
|
||||||
int ecbWrite(pECB self, unsigned short address,
|
int ecbWrite(pECB self, unsigned short address,
|
||||||
void *buffer, int byteCount);
|
void *buffer, int byteCount);
|
||||||
|
int ecbDMARead(pECB self, unsigned short address, void *buffer,
|
||||||
|
unsigned short byteCount);
|
||||||
void ecbClear(pECB self);
|
void ecbClear(pECB self);
|
||||||
int fixECBError(pECB self);
|
int fixECBError(pECB self);
|
||||||
void ecbErrorDescription(pECB self, char *buffer,
|
void ecbErrorDescription(pECB self, char *buffer,
|
||||||
@ -89,6 +91,9 @@ content is in in, on success the outpt registers are stored in out.
|
|||||||
\item[ecbRead] reads byteCount bytes from the ECB address address into
|
\item[ecbRead] reads byteCount bytes from the ECB address address into
|
||||||
buffer. Please note that address in this contest is an address in the
|
buffer. Please note that address in this contest is an address in the
|
||||||
ECB's memory space and not the GPIB address.
|
ECB's memory space and not the GPIB address.
|
||||||
|
\item[ecbDMARead] reads byteCount bytes from the ECB DMA address address into
|
||||||
|
buffer. Please note that address in this contest is an address in the
|
||||||
|
ECB's memory space and not the GPIB address.
|
||||||
\item[ecbWrite] writes byteCount bytes from buffer to the ECB address
|
\item[ecbWrite] writes byteCount bytes from buffer to the ECB address
|
||||||
address. Please note that address in this contest is an address in the
|
address. Please note that address in this contest is an address in the
|
||||||
ECB's memory space and not the GPIB address.
|
ECB's memory space and not the GPIB address.
|
||||||
@ -102,7 +107,7 @@ ECB problem. Max maxBytes of description are copied into buffer.
|
|||||||
|
|
||||||
|
|
||||||
There is also an interface to the SICS interpreter for the ECB. This
|
There is also an interface to the SICS interpreter for the ECB. This
|
||||||
can be useful for debugging and testing and as a tool for scripting
|
can be useful for debugging and testing and as a tool for scriptingy
|
||||||
auxiliary equipment controlled through the ECB. The interface to the
|
auxiliary equipment controlled through the ECB. The interface to the
|
||||||
SICS interpreter for the ECB is represented through the ECB Factory
|
SICS interpreter for the ECB is represented through the ECB Factory
|
||||||
function:
|
function:
|
||||||
|
12
ecbdriv.c
12
ecbdriv.c
@ -67,8 +67,9 @@ Parameter indexes in ObPar array and meanings
|
|||||||
#define STEPS2DEG 13 /* conversion factor motor steps to Degree */
|
#define STEPS2DEG 13 /* conversion factor motor steps to Degree */
|
||||||
#define DEG2STEP 14 /* conversion factor from degree to encoder digits */
|
#define DEG2STEP 14 /* conversion factor from degree to encoder digits */
|
||||||
#define BACKLASH 15 /* motor backlash */
|
#define BACKLASH 15 /* motor backlash */
|
||||||
|
#define PORT 17 /* ECB port when multiplexed */
|
||||||
|
|
||||||
#define MAXPAR 18 /* 1 extra for the sentinel, do not forget to initialize! */
|
#define MAXPAR 19 /* 1 extra for the sentinel, do not forget to initialize! */
|
||||||
|
|
||||||
/*------------------------------ ECB defines -------------------------*/
|
/*------------------------------ ECB defines -------------------------*/
|
||||||
#define MAX_ENCODER 40
|
#define MAX_ENCODER 40
|
||||||
@ -411,7 +412,8 @@ static int loadMulti(pECBMotDriv self){
|
|||||||
mult_chan = (unsigned char)rint(ObVal(self->driverPar,MULTCHAN));
|
mult_chan = (unsigned char)rint(ObVal(self->driverPar,MULTCHAN));
|
||||||
in.b = -1; /* SET_PORT */
|
in.b = -1; /* SET_PORT */
|
||||||
in.d = (unsigned char)(multi + (mult_chan << 4));
|
in.d = (unsigned char)(multi + (mult_chan << 4));
|
||||||
in.e = self->ecbIndex;
|
in.e = (unsigned char)rint(ObVal(self->driverPar,PORT));
|
||||||
|
in.c = self->ecbIndex;
|
||||||
status = ecbExecute(self->ecb,MOPARA,in,&out);
|
status = ecbExecute(self->ecb,MOPARA,in,&out);
|
||||||
if(status != 1){
|
if(status != 1){
|
||||||
self->errorCode = COMMERROR;
|
self->errorCode = COMMERROR;
|
||||||
@ -557,7 +559,7 @@ static int controlMotor(pECBMotDriv self, int enable){
|
|||||||
*/
|
*/
|
||||||
in.e = 8;
|
in.e = 8;
|
||||||
in.b = 11; /* set control signal */
|
in.b = 11; /* set control signal */
|
||||||
in.c = -self->ecbIndex;
|
in.c = self->ecbIndex;
|
||||||
status = ecbExecute(self->ecb,MOPARA,in,&out);
|
status = ecbExecute(self->ecb,MOPARA,in,&out);
|
||||||
if(status != 1){
|
if(status != 1){
|
||||||
self->errorCode = COMMERROR;
|
self->errorCode = COMMERROR;
|
||||||
@ -698,9 +700,6 @@ static int checkStatusResponse(pECBMotDriv self, Z80_reg out){
|
|||||||
return HWFault;
|
return HWFault;
|
||||||
} else if(out.b & 32){
|
} else if(out.b & 32){
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
} else if(out.b & 64){
|
|
||||||
self->errorCode = ECBINHIBIT;
|
|
||||||
return HWFault;
|
|
||||||
} else if(out.b & 16){
|
} else if(out.b & 16){
|
||||||
self->errorCode = ECBLIMIT;
|
self->errorCode = ECBLIMIT;
|
||||||
return HWFault;
|
return HWFault;
|
||||||
@ -1142,6 +1141,7 @@ static void initializeParameters(pECBMotDriv self){
|
|||||||
ObParInit(self->driverPar,STEPS2DEG,"step2deg",1,usMugger);
|
ObParInit(self->driverPar,STEPS2DEG,"step2deg",1,usMugger);
|
||||||
ObParInit(self->driverPar,DEG2STEP,"step2dig",0,usMugger);
|
ObParInit(self->driverPar,DEG2STEP,"step2dig",0,usMugger);
|
||||||
ObParInit(self->driverPar,BACKLASH,"backlash",0,usMugger);
|
ObParInit(self->driverPar,BACKLASH,"backlash",0,usMugger);
|
||||||
|
ObParInit(self->driverPar,PORT,"port",0,usMugger);
|
||||||
ObParInit(self->driverPar,MAXPAR-1,"tueet",-100,-100); /* sentinel! */
|
ObParInit(self->driverPar,MAXPAR-1,"tueet",-100,-100); /* sentinel! */
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
208
histdriv.c
208
histdriv.c
@ -64,17 +64,15 @@
|
|||||||
}
|
}
|
||||||
memset(pNew,0,sizeof(HistDriver));
|
memset(pNew,0,sizeof(HistDriver));
|
||||||
|
|
||||||
|
pNew->data = makeHMData();
|
||||||
|
if(!pNew->data)
|
||||||
|
{
|
||||||
|
free(pNew);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* initialise defaults */
|
/* initialise defaults */
|
||||||
pNew->eHistMode = eHNormal;
|
|
||||||
StringDictAddPair(pOption,"histmode","normal");
|
|
||||||
pNew->eFlow = eOCeil;
|
|
||||||
StringDictAddPair(pOption,"overflowmode","ceil");
|
|
||||||
pNew->iRank = 1;
|
|
||||||
StringDictAddPair(pOption,"rank","1");
|
StringDictAddPair(pOption,"rank","1");
|
||||||
pNew->iLength = 412;
|
|
||||||
StringDictAddPair(pOption,"length","412");
|
|
||||||
pNew->iBinWidth = 16;
|
|
||||||
StringDictAddPair(pOption,"binwidth","16");
|
|
||||||
for(i = 0; i < MAXDIM; i++)
|
for(i = 0; i < MAXDIM; i++)
|
||||||
{
|
{
|
||||||
sprintf(pDim,"dim%1.1d",i);
|
sprintf(pDim,"dim%1.1d",i);
|
||||||
@ -84,8 +82,6 @@
|
|||||||
pNew->eCount = eTimer;
|
pNew->eCount = eTimer;
|
||||||
pNew->iReconfig = 1;
|
pNew->iReconfig = 1;
|
||||||
pNew->iUpdate = 0;
|
pNew->iUpdate = 0;
|
||||||
pNew->iTimeChan = 1;
|
|
||||||
|
|
||||||
|
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
@ -98,59 +94,12 @@
|
|||||||
{
|
{
|
||||||
self->FreePrivate(self);
|
self->FreePrivate(self);
|
||||||
}
|
}
|
||||||
|
if(self->data)
|
||||||
|
{
|
||||||
|
killHMData(self->data);
|
||||||
|
}
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
static char *pHistMode[] = {
|
|
||||||
"transparent",
|
|
||||||
"normal",
|
|
||||||
"tof",
|
|
||||||
"strobo",
|
|
||||||
"hrpt",
|
|
||||||
"psd",
|
|
||||||
"sanstof",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static HistMode Text2Mode(char *text)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while(pHistMode[i] != NULL)
|
|
||||||
{
|
|
||||||
if(strcmp(pHistMode[i],text) == 0)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
/* not found */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
static char *pFlowMode[] = {
|
|
||||||
"ignore",
|
|
||||||
"ceil",
|
|
||||||
"count",
|
|
||||||
"reflect",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
static OverFlowMode Text2Flow(char *text)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while(pFlowMode[i] != NULL)
|
|
||||||
{
|
|
||||||
if(strcmp(pFlowMode[i],text) == 0)
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
/* not found */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int HistDriverConfig(pHistDriver self, pStringDict pOpt, SConnection *pCon)
|
int HistDriverConfig(pHistDriver self, pStringDict pOpt, SConnection *pCon)
|
||||||
{
|
{
|
||||||
@ -166,138 +115,5 @@
|
|||||||
assert(pOpt);
|
assert(pOpt);
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
|
|
||||||
/* enter histmode */
|
return configureHMdata(self->data,pOpt,pCon);
|
||||||
iRet = StringDictGet(pOpt,"histmode",pValue,79);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
strtolower(pValue);
|
|
||||||
iRet = Text2Mode(pValue);
|
|
||||||
if(iRet < 0)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: Invalid parameter %s to HistMode",pValue);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
self->eHistMode = iRet;
|
|
||||||
|
|
||||||
/* handle overflowmode */
|
|
||||||
iRet = StringDictGet(pOpt,"overflowmode",pValue,79);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
strtolower(pValue);
|
|
||||||
iRet = Text2Flow(pValue);
|
|
||||||
if(iRet < 0)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: Invalid parameter %s to OverflowMode",pValue);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
self->eFlow = iRet;
|
|
||||||
|
|
||||||
/* no of hist */
|
|
||||||
iRet = StringDictGetAsNumber(pOpt,"rank",&fVal);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
iRet = StringDictGet(pOpt,"rank",pValue,79);
|
|
||||||
if(iRet)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %s not valid for Rank ",pValue);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fVal < 0)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %f is invalid for rank",fVal);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
self->iRank = (int)fVal;
|
|
||||||
|
|
||||||
/* length */
|
|
||||||
iRet = StringDictGetAsNumber(pOpt,"length",&fVal);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
iRet = StringDictGet(pOpt,"length",pValue,79);
|
|
||||||
if(iRet)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %s not valid for Length ",pValue);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fVal < 1)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %f is invalid for Length",fVal);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
self->iLength = (int)fVal;
|
|
||||||
|
|
||||||
/* BinWidth */
|
|
||||||
iRet = StringDictGetAsNumber(pOpt,"binwidth",&fVal);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
iRet = StringDictGet(pOpt,"binwidth",pValue,79);
|
|
||||||
if(iRet)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %s not valid for BinWidth ",pValue);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fVal < 1)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %f is invalid for BinWidth",fVal);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
self->iBinWidth = (int)fVal;
|
|
||||||
|
|
||||||
/* dimensions */
|
|
||||||
self->nDim = 0;
|
|
||||||
for(i = 0; i < MAXDIM; i++)
|
|
||||||
{
|
|
||||||
sprintf(pValue,"dim%1.1d",i);
|
|
||||||
iRet = StringDictGetAsNumber(pOpt,pValue,&fVal);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
if(i < self->iRank)
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"WARNING: dimension %s NOT found",pValue);
|
|
||||||
SCWrite(pCon,pBueffel,eWarning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(fVal > 0.)
|
|
||||||
{
|
|
||||||
self->nDim++;
|
|
||||||
self->iDims[i] = (int)fVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
498
histmem.c
498
histmem.c
@ -62,6 +62,7 @@
|
|||||||
#include "dynstring.h"
|
#include "dynstring.h"
|
||||||
#include "event.h"
|
#include "event.h"
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
|
#include "tdchm.h"
|
||||||
/*
|
/*
|
||||||
#define LOADDEBUG 1
|
#define LOADDEBUG 1
|
||||||
*/
|
*/
|
||||||
@ -106,12 +107,13 @@
|
|||||||
fprintf(fd,"%s preset %f\n",name,fVal);
|
fprintf(fd,"%s preset %f\n",name,fVal);
|
||||||
|
|
||||||
/* time binning if TOF */
|
/* time binning if TOF */
|
||||||
if(self->pDriv->eHistMode == eHTOF)
|
if(isInTOFMode(self->pDriv->data))
|
||||||
{
|
{
|
||||||
fprintf(fd,"%s genbin %f %f %d\n",
|
fprintf(fd,"%s genbin %f %f %d\n",
|
||||||
name, self->pDriv->fTime[0],
|
name, self->pDriv->data->timeBinning[0],
|
||||||
self->pDriv->fTime[1] - self->pDriv->fTime[0],
|
self->pDriv->data->timeBinning[1] -
|
||||||
self->pDriv->iTimeChan);
|
self->pDriv->data->timeBinning[0],
|
||||||
|
self->pDriv->data->nTimeChan);
|
||||||
fprintf(fd,"%s init\n",name);
|
fprintf(fd,"%s init\n",name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,9 +169,7 @@
|
|||||||
iRet = self->pDriv->Start(self->pDriv, pCon);
|
iRet = self->pDriv->Start(self->pDriv, pCon);
|
||||||
if(iRet == OKOK)
|
if(iRet == OKOK)
|
||||||
{
|
{
|
||||||
self->pDriv->iUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
self->iLocalUpdate = 1;
|
|
||||||
self->tLocal = time(NULL) + self->iUpdateIntervall;
|
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -214,7 +214,7 @@
|
|||||||
iRet = self->pDriv->Pause(self->pDriv, pCon);
|
iRet = self->pDriv->Pause(self->pDriv, pCon);
|
||||||
if(iRet == OKOK)
|
if(iRet == OKOK)
|
||||||
{
|
{
|
||||||
self->pDriv->iUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -259,7 +259,7 @@
|
|||||||
iRet = self->pDriv->Continue(self->pDriv, pCon);
|
iRet = self->pDriv->Continue(self->pDriv, pCon);
|
||||||
if(iRet == OKOK)
|
if(iRet == OKOK)
|
||||||
{
|
{
|
||||||
self->pDriv->iUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
return iRet;
|
return iRet;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -312,20 +312,19 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self->iLocalUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
return HWBusy;
|
return HWBusy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(eCt == HWBusy)
|
if(eCt == HWBusy)
|
||||||
self->iLocalUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
|
|
||||||
if(eCt == HWIdle)
|
if(eCt == HWIdle)
|
||||||
{
|
{
|
||||||
/* force an update of local histogram data with next
|
/* force an update of local histogram data with next
|
||||||
GetHistogram
|
GetHistogram
|
||||||
*/
|
*/
|
||||||
self->iLocalUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
self->tLocal = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return eCt;
|
return eCt;
|
||||||
@ -426,11 +425,6 @@
|
|||||||
pNew->pCountInt->Halt = HistHalt;
|
pNew->pCountInt->Halt = HistHalt;
|
||||||
pNew->pCountInt->Pause = HistPause;
|
pNew->pCountInt->Pause = HistPause;
|
||||||
pNew->pCountInt->Continue = HistContinue;
|
pNew->pCountInt->Continue = HistContinue;
|
||||||
pNew->iLocalData = NULL;
|
|
||||||
pNew->iLocalLength = 0;
|
|
||||||
pNew->iUpdateIntervall = 0;
|
|
||||||
pNew->iLocalUpdate = 1;
|
|
||||||
pNew->tLocal = 0;
|
|
||||||
|
|
||||||
/* initialise options dictionary */
|
/* initialise options dictionary */
|
||||||
pNew->pOption = CreateStringDict();
|
pNew->pOption = CreateStringDict();
|
||||||
@ -451,6 +445,10 @@
|
|||||||
{
|
{
|
||||||
pNew->pDriv = CreateSINQDriver(pNew->pOption);
|
pNew->pDriv = CreateSINQDriver(pNew->pOption);
|
||||||
}
|
}
|
||||||
|
else if(strcmp(driver,"tdc") == 0)
|
||||||
|
{
|
||||||
|
pNew->pDriv = MakeTDCHM(pNew->pOption);
|
||||||
|
}
|
||||||
else /* no driver found */
|
else /* no driver found */
|
||||||
{
|
{
|
||||||
DeleteDescriptor(pNew->pDes);
|
DeleteDescriptor(pNew->pDes);
|
||||||
@ -494,10 +492,6 @@
|
|||||||
{
|
{
|
||||||
DeleteStringDict(self->pOption);
|
DeleteStringDict(self->pOption);
|
||||||
}
|
}
|
||||||
if(self->iLocalData)
|
|
||||||
{
|
|
||||||
free(self->iLocalData);
|
|
||||||
}
|
|
||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
@ -568,22 +562,6 @@
|
|||||||
assert(self);
|
assert(self);
|
||||||
assert(pCon);
|
assert(pCon);
|
||||||
|
|
||||||
/* handle update intervall */
|
|
||||||
iRet = StringDictGet(self->pOption,"update",pValue,79);
|
|
||||||
assert(iRet); /* this is a programming error, we added it
|
|
||||||
when creating the histogram memory object
|
|
||||||
*/
|
|
||||||
iRet = Tcl_GetInt(pSics->pTcl,pValue,&iVal);
|
|
||||||
if(iRet != TCL_OK)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"WARNING: invalid value for update ignored",
|
|
||||||
eWarning);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->iUpdateIntervall = iVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
iRet = HistDriverConfig(self->pDriv,self->pOption,pCon);
|
iRet = HistDriverConfig(self->pDriv,self->pOption,pCon);
|
||||||
if(!iRet)
|
if(!iRet)
|
||||||
{
|
{
|
||||||
@ -596,8 +574,6 @@
|
|||||||
SCWrite(pCon,"ERROR: failed to configure histogram memory",eError);
|
SCWrite(pCon,"ERROR: failed to configure histogram memory",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
self->iLocalUpdate = 1;
|
|
||||||
self->tLocal = 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@ -642,124 +618,23 @@
|
|||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim)
|
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim)
|
||||||
{
|
{
|
||||||
int i, myDim;
|
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
for(i = 0, myDim = 0; i < self->pDriv->nDim; i++)
|
getHMDataDim(self->pDriv->data,iDim,nDim);
|
||||||
|
if(isInTOFMode(self->pDriv->data))
|
||||||
{
|
{
|
||||||
if(self->pDriv->iDims[i] > 0)
|
iDim[*nDim] = getNoOfTimebins(self->pDriv->data);
|
||||||
{
|
*nDim ++;
|
||||||
iDim[i] = self->pDriv->iDims[i];
|
|
||||||
myDim++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(self->pDriv->eHistMode == eHTOF
|
|
||||||
|| self->pDriv->eHistMode == ePSD
|
|
||||||
|| self->pDriv->eHistMode == eSANSTOF)
|
|
||||||
{
|
|
||||||
iDim[myDim] = self->pDriv->iTimeChan;
|
|
||||||
myDim++;
|
|
||||||
}
|
|
||||||
*nDim = myDim;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
static long SumRow(int *iData, int iDataLength, int iStart, int iEnd)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
long lSum;
|
|
||||||
|
|
||||||
if(iEnd > iDataLength)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
lSum = 0;
|
|
||||||
for(i = iStart; i < iEnd; i++)
|
|
||||||
{
|
|
||||||
lSum += iData[i];
|
|
||||||
}
|
|
||||||
return lSum;
|
|
||||||
}
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
long HistSum(pHistMem self, SConnection *pCon,
|
long HistSum(pHistMem self, SConnection *pCon,
|
||||||
int iStart[MAXDIM], int iEnd[MAXDIM])
|
int iStart[MAXDIM], int iEnd[MAXDIM])
|
||||||
{
|
{
|
||||||
int i, iDataDim[MAXDIM], nDim, iIndex;
|
|
||||||
long lSum;
|
|
||||||
char pBueffel[132];
|
|
||||||
HistInt *iData = NULL;
|
|
||||||
int iHistLength, iRet;
|
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
|
return sumHMDataRectangle(self,pCon,iStart,iEnd);
|
||||||
/* do some serious error checking */
|
|
||||||
GetHistDim(self,iDataDim,&nDim);
|
|
||||||
if(nDim <= 0)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: Now data dimensions specified, cannot sum",eError);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for(i = 0; i < nDim; i++)
|
|
||||||
{
|
|
||||||
if( (iStart[i] < 0) || (iStart[i] > iDataDim[i]) )
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %d is out of data dimension range",
|
|
||||||
iStart[i]);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if( (iEnd[i] < 0) || (iEnd[i] > iDataDim[i]) )
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: %d is out of data dimension range",
|
|
||||||
iEnd[i]);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get histogram data */
|
|
||||||
iHistLength = GetHistLength(self);
|
|
||||||
iData = (HistInt *)malloc(iHistLength*sizeof(HistInt));
|
|
||||||
if(!iData)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: Failed to allocate data in sum", eError);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
iRet = GetHistogram(self,pCon,0,0,iHistLength,iData,
|
|
||||||
iHistLength*sizeof(HistInt));
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: could not get hold of data to sum",eError);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* actually sum */
|
|
||||||
switch(nDim)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
lSum = SumRow(iData, iHistLength, iStart[0], iEnd[0]);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
lSum = 0;
|
|
||||||
for(i = iStart[0]; i < iEnd[0]; i++)
|
|
||||||
{
|
|
||||||
iIndex = i*iDataDim[1];
|
|
||||||
lSum += SumRow(iData,iHistLength,
|
|
||||||
iIndex+iStart[1], iIndex+iEnd[1]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
sprintf(pBueffel,
|
|
||||||
"ERROR: summing in %d dimensions not yet implemented",
|
|
||||||
nDim);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
lSum = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(iData);
|
|
||||||
return lSum;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
CounterMode GetHistCountMode(pHistMem self)
|
CounterMode GetHistCountMode(pHistMem self)
|
||||||
@ -806,15 +681,15 @@
|
|||||||
const float *GetHistTimeBin(pHistMem self, int *iLength)
|
const float *GetHistTimeBin(pHistMem self, int *iLength)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
*iLength = self->pDriv->iTimeChan;
|
*iLength = getNoOfTimebins(self->pDriv->data);
|
||||||
return self->pDriv->fTime;
|
return getTimeBinning(self->pDriv->data);
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int GetHistLength(pHistMem self)
|
int GetHistLength(pHistMem self)
|
||||||
{
|
{
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
return self->pDriv->iRank*self->pDriv->iLength;
|
return getHMDataLength(self->pDriv->data);
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
float GetHistCountTime(pHistMem self, SConnection *pCon)
|
float GetHistCountTime(pHistMem self, SConnection *pCon)
|
||||||
@ -898,9 +773,7 @@
|
|||||||
i,iStart,iEnd,lData);
|
i,iStart,iEnd,lData);
|
||||||
if(iRet == OKOK)
|
if(iRet == OKOK)
|
||||||
{
|
{
|
||||||
self->iLocalUpdate = 1;
|
updateHMData(self->pDriv->data);
|
||||||
self->tLocal = 0;
|
|
||||||
self->pDriv->iUpdate = 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -921,87 +794,20 @@
|
|||||||
int GetHistogram(pHistMem self, SConnection *pCon,
|
int GetHistogram(pHistMem self, SConnection *pCon,
|
||||||
int i, int iStart, int iEnd, HistInt *lData, int iDataLen)
|
int i, int iStart, int iEnd, HistInt *lData, int iDataLen)
|
||||||
{
|
{
|
||||||
int ii, iErr, iRet, iCopy;
|
|
||||||
char pBueffel[512], pError[80];
|
|
||||||
HistInt *lHist = NULL;
|
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
if(!self->iInit)
|
if(!self->iInit)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: histogram memory not initialised",eError);
|
SCWrite(pCon,"ERROR: histogram memory not initialised",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the full histogram if an update is needed */
|
if(iEnd > iDataLen/sizeof(HistInt))
|
||||||
if( (self->iLocalUpdate) && (time(NULL) > self->tLocal) )
|
{
|
||||||
{
|
SCWrite(pCon,"WARNING: truncating request to fit data space",eWarning);
|
||||||
#ifdef LOADDEBUG
|
iEnd = (iDataLen/sizeof(HistInt)) - 1;
|
||||||
fprintf(stdout,"Getting new histogram from HM\n");
|
}
|
||||||
#endif
|
return getHMDataHistogram(self,pCon,i,iStart,iEnd,lData);
|
||||||
/* check data allocation */
|
|
||||||
if(self->iLocalLength != self->pDriv->iLength)
|
|
||||||
{
|
|
||||||
if(self->iLocalData)
|
|
||||||
{
|
|
||||||
free(self->iLocalData);
|
|
||||||
self->iLocalData = NULL;
|
|
||||||
}
|
|
||||||
self->iLocalData = (HistInt *)malloc(
|
|
||||||
self->pDriv->iLength*sizeof(HistInt));
|
|
||||||
if(!self->iLocalData)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: failed to allocate data in GetHistogram",
|
|
||||||
eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
self->iLocalLength = self->pDriv->iLength;
|
|
||||||
memset(self->iLocalData,0,self->iLocalLength*sizeof(HistInt));
|
|
||||||
}
|
|
||||||
/* try at least three times */
|
|
||||||
for(ii = 0; ii < 3; ii++)
|
|
||||||
{
|
|
||||||
iRet = self->pDriv->GetHistogram(self->pDriv,pCon,
|
|
||||||
i,0,self->iLocalLength,
|
|
||||||
self->iLocalData);
|
|
||||||
if(iRet == OKOK)
|
|
||||||
{
|
|
||||||
self->iLocalUpdate = 0;
|
|
||||||
self->tLocal = time(NULL) + self->iUpdateIntervall;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iRet = self->pDriv->GetError(self->pDriv,&iErr,pError,79);
|
|
||||||
sprintf(pBueffel,"ERROR: %s ",pError);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
iRet = self->pDriv->TryAndFixIt(self->pDriv,iErr);
|
|
||||||
if(iRet == COTERM)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy from buffer if there and updated */
|
|
||||||
if(self->iLocalData)
|
|
||||||
{
|
|
||||||
#ifdef LOADDEBUG
|
|
||||||
fprintf(stdout,"Copying histogram data from memory\n");
|
|
||||||
#endif
|
|
||||||
lHist = self->iLocalData + iStart;
|
|
||||||
if(iEnd*sizeof(HistInt) < iDataLen)
|
|
||||||
{
|
|
||||||
iCopy = iEnd;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iCopy = iDataLen/sizeof(HistInt);
|
|
||||||
}
|
|
||||||
memcpy(lData,lHist,iCopy*sizeof(HistInt));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int GetHistogramDirect(pHistMem self, SConnection *pCon,
|
int GetHistogramDirect(pHistMem self, SConnection *pCon,
|
||||||
@ -1048,10 +854,6 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
HistInt *GetHistogramPointer(pHistMem self, SConnection *pCon)
|
HistInt *GetHistogramPointer(pHistMem self, SConnection *pCon)
|
||||||
{
|
{
|
||||||
int ii, iErr, iRet, iCopy;
|
|
||||||
char pBueffel[512], pError[80];
|
|
||||||
HistInt *lHist = NULL;
|
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
|
|
||||||
if(!self->iInit)
|
if(!self->iInit)
|
||||||
@ -1060,67 +862,7 @@
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self->iLocalData == NULL)
|
return getHMDataBufferPointer(self,pCon);
|
||||||
{
|
|
||||||
self->iLocalUpdate = 1;
|
|
||||||
self->tLocal = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get the full histogram if an update is needed */
|
|
||||||
if( (self->iLocalUpdate) && (time(NULL) > self->tLocal) )
|
|
||||||
{
|
|
||||||
#ifdef LOADDEBUG
|
|
||||||
fprintf(stdout,"Getting new histogram from HM\n");
|
|
||||||
#endif
|
|
||||||
/* check data allocation */
|
|
||||||
if(self->iLocalLength != self->pDriv->iLength)
|
|
||||||
{
|
|
||||||
if(self->iLocalData)
|
|
||||||
{
|
|
||||||
free(self->iLocalData);
|
|
||||||
self->iLocalData = NULL;
|
|
||||||
}
|
|
||||||
self->iLocalData = (HistInt *)malloc(
|
|
||||||
self->pDriv->iLength*sizeof(HistInt));
|
|
||||||
if(!self->iLocalData)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: failed to allocate data in GetHistogram",
|
|
||||||
eError);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
self->iLocalLength = self->pDriv->iLength;
|
|
||||||
memset(self->iLocalData,0,self->iLocalLength*sizeof(HistInt));
|
|
||||||
}
|
|
||||||
/* try at least three times */
|
|
||||||
for(ii = 0; ii < 3; ii++)
|
|
||||||
{
|
|
||||||
iRet = self->pDriv->GetHistogram(self->pDriv,pCon,
|
|
||||||
0,0,self->iLocalLength,
|
|
||||||
self->iLocalData);
|
|
||||||
if(iRet == OKOK)
|
|
||||||
{
|
|
||||||
self->iLocalUpdate = 0;
|
|
||||||
self->tLocal = time(NULL) + self->iUpdateIntervall;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iRet = self->pDriv->GetError(self->pDriv,&iErr,pError,79);
|
|
||||||
sprintf(pBueffel,"ERROR: %s ",pError);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
iRet = self->pDriv->TryAndFixIt(self->pDriv,iErr);
|
|
||||||
if(iRet == COTERM)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef LOADDEBUG
|
|
||||||
fprintf(stdout,"Copying histogram data from memory\n");
|
|
||||||
#endif
|
|
||||||
return self->iLocalData;
|
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal)
|
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal)
|
||||||
@ -1142,9 +884,7 @@
|
|||||||
iRet = self->pDriv->Preset(self->pDriv,pCon,lVal);
|
iRet = self->pDriv->Preset(self->pDriv,pCon,lVal);
|
||||||
if(iRet == OKOK)
|
if(iRet == OKOK)
|
||||||
{
|
{
|
||||||
self->pDriv->iUpdate = 0;
|
updateHMData(self->pDriv->data);
|
||||||
self->iLocalUpdate = 1;
|
|
||||||
self->tLocal = 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1161,6 +901,7 @@
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
|
static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
|
||||||
{
|
{
|
||||||
@ -1183,6 +924,22 @@
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int checkHMEnd(pHistMem self, char *text){
|
||||||
|
int iTest, iEnd;
|
||||||
|
|
||||||
|
iEnd = getHMDataLength(self->pDriv->data);
|
||||||
|
if(text == NULL){
|
||||||
|
return iEnd;
|
||||||
|
} else {
|
||||||
|
iTest = atoi(text);
|
||||||
|
if(iTest > iEnd){
|
||||||
|
return iEnd;
|
||||||
|
} else {
|
||||||
|
return iTest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int HistAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -1276,7 +1033,8 @@
|
|||||||
/* authorise */
|
/* authorise */
|
||||||
if(!SCMatchRights(pCon,usMugger))
|
if(!SCMatchRights(pCon,usMugger))
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,"ERROR: you need to be manager in order to configure %s",
|
sprintf(pBueffel,
|
||||||
|
"ERROR: you need to be manager in order to configure %s",
|
||||||
argv[0]);
|
argv[0]);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1304,7 +1062,6 @@
|
|||||||
fVal = atof(argv[2]);
|
fVal = atof(argv[2]);
|
||||||
if(!SCMatchRights(pCon,self->iAccess))
|
if(!SCMatchRights(pCon,self->iAccess))
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: you are not priviledged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
iRet = SetHistPreset(self,fVal);
|
iRet = SetHistPreset(self,fVal);
|
||||||
@ -1324,7 +1081,6 @@
|
|||||||
{
|
{
|
||||||
if(!SCMatchRights(pCon,self->iAccess))
|
if(!SCMatchRights(pCon,self->iAccess))
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: you are not priviledged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
self->iExponent = atoi(argv[2]);
|
self->iExponent = atoi(argv[2]);
|
||||||
@ -1346,7 +1102,6 @@
|
|||||||
strtolower(argv[2]);
|
strtolower(argv[2]);
|
||||||
if(!SCMatchRights(pCon,self->iAccess))
|
if(!SCMatchRights(pCon,self->iAccess))
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: you are not priviledged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(strcmp(argv[2],"timer") == 0)
|
if(strcmp(argv[2],"timer") == 0)
|
||||||
@ -1386,8 +1141,6 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCWrite(pCon,
|
|
||||||
"ERROR: you are not privileged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1410,8 +1163,6 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCWrite(pCon,
|
|
||||||
"ERROR: you are not privileged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1429,8 +1180,6 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCWrite(pCon,
|
|
||||||
"ERROR: you are not privileged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1448,8 +1197,6 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SCWrite(pCon,
|
|
||||||
"ERROR: you are not privileged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1458,8 +1205,6 @@
|
|||||||
/* check user rights */
|
/* check user rights */
|
||||||
if(!SCMatchRights(pCon,self->iAccess))
|
if(!SCMatchRights(pCon,self->iAccess))
|
||||||
{
|
{
|
||||||
SCWrite(pCon,
|
|
||||||
"ERROR: you are not priviledged for attempted operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1491,15 +1236,6 @@
|
|||||||
}
|
}
|
||||||
iNum = atoi(argv[2]);
|
iNum = atoi(argv[2]);
|
||||||
|
|
||||||
/* check iNum */
|
|
||||||
if( (iNum < 0) || (iNum > self->pDriv->iRank))
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: requested histogram no %d out of range",
|
|
||||||
iNum);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* optional iStart, default 0 */
|
/* optional iStart, default 0 */
|
||||||
iStart = 0;
|
iStart = 0;
|
||||||
if(argc > 3 )
|
if(argc > 3 )
|
||||||
@ -1514,20 +1250,11 @@
|
|||||||
iStart = 0;
|
iStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* optional iEnd, default to maximum */
|
if(argc > 4){
|
||||||
iEnd = self->pDriv->iLength;
|
iEnd = checkHMEnd(self,argv[4]);
|
||||||
if(argc > 4)
|
} else {
|
||||||
{
|
iEnd = checkHMEnd(self,NULL);
|
||||||
iEnd = atoi(argv[4]);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check iEnd */
|
|
||||||
if(iEnd > self->pDriv->iLength)
|
|
||||||
{
|
|
||||||
iEnd = self->pDriv->iLength;
|
|
||||||
SCWrite(pCon,
|
|
||||||
"WARNING: invalid end parameter reset to max ",eWarning);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate data storage and get it */
|
/* allocate data storage and get it */
|
||||||
lData = (HistInt *)malloc(iEnd*sizeof(HistInt));
|
lData = (HistInt *)malloc(iEnd*sizeof(HistInt));
|
||||||
@ -1577,15 +1304,6 @@
|
|||||||
}
|
}
|
||||||
iNum = atoi(argv[2]);
|
iNum = atoi(argv[2]);
|
||||||
|
|
||||||
/* check iNum */
|
|
||||||
if( (iNum < 0) || (iNum > self->pDriv->iRank))
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: requested histogram no %d out of range",
|
|
||||||
iNum);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* optional iStart, default 0 */
|
/* optional iStart, default 0 */
|
||||||
iStart = 0;
|
iStart = 0;
|
||||||
if(argc > 3 )
|
if(argc > 3 )
|
||||||
@ -1600,20 +1318,11 @@
|
|||||||
iStart = 0;
|
iStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* optional iEnd, default to maximum */
|
if(argc > 4){
|
||||||
iEnd = self->pDriv->iLength;
|
iEnd = checkHMEnd(self,argv[4]);
|
||||||
if(argc > 4)
|
} else {
|
||||||
{
|
iEnd = checkHMEnd(self,NULL);
|
||||||
iEnd = atoi(argv[4]);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check iEnd */
|
|
||||||
if(iEnd > self->pDriv->iLength)
|
|
||||||
{
|
|
||||||
iEnd = self->pDriv->iLength;
|
|
||||||
SCWrite(pCon,
|
|
||||||
"WARNING: invalid end parameter reset to max ",eWarning);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate data storage and get it */
|
/* allocate data storage and get it */
|
||||||
lData = (HistInt *)malloc((iEnd+1)*sizeof(HistInt));
|
lData = (HistInt *)malloc((iEnd+1)*sizeof(HistInt));
|
||||||
@ -1659,15 +1368,6 @@
|
|||||||
}
|
}
|
||||||
iNum = atoi(argv[2]);
|
iNum = atoi(argv[2]);
|
||||||
|
|
||||||
/* check iNum */
|
|
||||||
if( (iNum < 0) || (iNum > self->pDriv->iRank))
|
|
||||||
{
|
|
||||||
sprintf(pBueffel,"ERROR: requested histogram no %d out of range",
|
|
||||||
iNum);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* optional iStart, default 0 */
|
/* optional iStart, default 0 */
|
||||||
iStart = 0;
|
iStart = 0;
|
||||||
if(argc > 3 )
|
if(argc > 3 )
|
||||||
@ -1678,24 +1378,16 @@
|
|||||||
/* check iStart */
|
/* check iStart */
|
||||||
if(iStart < 0)
|
if(iStart < 0)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"WARNING: Invalid start position defaulted to 0",eWarning);
|
SCWrite(pCon,"WARNING: Invalid start position defaulted to 0",
|
||||||
|
eWarning);
|
||||||
iStart = 0;
|
iStart = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* optional iEnd, default to maximum */
|
if(argc > 4){
|
||||||
iEnd = self->pDriv->iLength;
|
iEnd = checkHMEnd(self,argv[4]);
|
||||||
if(argc > 4)
|
} else {
|
||||||
{
|
iEnd = checkHMEnd(self,NULL);
|
||||||
iEnd = atoi(argv[4]);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* check iEnd */
|
|
||||||
if(iEnd > self->pDriv->iLength)
|
|
||||||
{
|
|
||||||
iEnd = self->pDriv->iLength;
|
|
||||||
SCWrite(pCon,
|
|
||||||
"WARNING: invalid end parameter reset to max ",eWarning);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate data storage and get it */
|
/* allocate data storage and get it */
|
||||||
lData = (HistInt *)malloc((iEnd+1)*sizeof(HistInt));
|
lData = (HistInt *)malloc((iEnd+1)*sizeof(HistInt));
|
||||||
@ -1731,7 +1423,8 @@
|
|||||||
else if(strcmp(argv[1],"notimebin") == 0)
|
else if(strcmp(argv[1],"notimebin") == 0)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel,
|
sprintf(pBueffel,
|
||||||
"%s.notimebin = %d",argv[0], self->pDriv->iTimeChan);
|
"%s.notimebin = %d",argv[0],
|
||||||
|
getNoOfTimebins(self->pDriv->data));
|
||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1740,9 +1433,9 @@
|
|||||||
{
|
{
|
||||||
Tcl_DStringInit(&tResult);
|
Tcl_DStringInit(&tResult);
|
||||||
Tcl_DStringAppend(&tResult,"histogram.timebins = ",-1);
|
Tcl_DStringAppend(&tResult,"histogram.timebins = ",-1);
|
||||||
for(i = 0; i < self->pDriv->iTimeChan; i++)
|
for(i = 0; i < self->pDriv->data->nTimeChan; i++)
|
||||||
{
|
{
|
||||||
sprintf(pBueffel," %8.2f", self->pDriv->fTime[i]);
|
sprintf(pBueffel," %8.2f", self->pDriv->data->timeBinning[i]);
|
||||||
Tcl_DStringAppend(&tResult,pBueffel,-1);
|
Tcl_DStringAppend(&tResult,pBueffel,-1);
|
||||||
}
|
}
|
||||||
/* Write it */
|
/* Write it */
|
||||||
@ -1757,7 +1450,6 @@
|
|||||||
{
|
{
|
||||||
if(!SCMatchRights(pCon,usMugger))
|
if(!SCMatchRights(pCon,usMugger))
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: you are not authorised for this operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(GetStatus() == eCounting)
|
if(GetStatus() == eCounting)
|
||||||
@ -1795,22 +1487,13 @@
|
|||||||
/* do it */
|
/* do it */
|
||||||
if(iNum >= MAXCHAN)
|
if(iNum >= MAXCHAN)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: number of requested time bins exceeds maximum permissible number",
|
SCWrite(pCon,
|
||||||
|
"ERROR: number of requested time bins exceeds maximum permissible number",
|
||||||
eError);
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
for(i = 0; i < iNum; i++)
|
genTimeBinning(self->pDriv->data,
|
||||||
{
|
(float)dStart,(float)dStep,iNum);
|
||||||
self->pDriv->fTime[i] = dStart + i* dStep;
|
|
||||||
}
|
|
||||||
self->pDriv->iTimeChan = iNum;
|
|
||||||
self->iInit = 0;
|
|
||||||
self->pDriv->iLength = 1;
|
|
||||||
for(i = 0; i < self->pDriv->iRank; i++)
|
|
||||||
{
|
|
||||||
self->pDriv->iLength *= self->pDriv->iDims[i];
|
|
||||||
}
|
|
||||||
self->pDriv->iLength *= self->pDriv->iTimeChan;
|
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1819,7 +1502,6 @@
|
|||||||
{
|
{
|
||||||
if(!SCMatchRights(pCon,usMugger))
|
if(!SCMatchRights(pCon,usMugger))
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: yoy are not authorised for this operation",eError);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(argc < 4)
|
if(argc < 4)
|
||||||
@ -1843,20 +1525,11 @@
|
|||||||
}
|
}
|
||||||
if( (iNum < 0) || (iNum > MAXCHAN) )
|
if( (iNum < 0) || (iNum > MAXCHAN) )
|
||||||
{
|
{
|
||||||
SCWrite(pCon,"ERROR: requested time bin out or permissible range",eError);
|
SCWrite(pCon,"ERROR: requested time bin out or permissible range",
|
||||||
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
self->pDriv->fTime[iNum] = dStep;
|
setTimeBin(self->pDriv->data,iNum, (float)dStep);
|
||||||
if(iNum > self->pDriv->iTimeChan)
|
|
||||||
{
|
|
||||||
self->pDriv->iTimeChan = iNum;
|
|
||||||
self->pDriv->iLength = 1;
|
|
||||||
for(i = 0; i < self->pDriv->iRank; i++)
|
|
||||||
{
|
|
||||||
self->pDriv->iLength *= self->pDriv->iDims[i];
|
|
||||||
}
|
|
||||||
self->pDriv->iLength *= self->pDriv->iTimeChan;
|
|
||||||
}
|
|
||||||
self->iInit = 0;
|
self->iInit = 0;
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1864,8 +1537,7 @@
|
|||||||
/* clear time bin info */
|
/* clear time bin info */
|
||||||
else if(strcmp(argv[1],"clearbin") == 0)
|
else if(strcmp(argv[1],"clearbin") == 0)
|
||||||
{
|
{
|
||||||
self->pDriv->iTimeChan = 0;
|
clearTimeBinning(self->pDriv->data);
|
||||||
self->iInit = 1;
|
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
}
|
}
|
||||||
/*-------- sum */
|
/*-------- sum */
|
||||||
@ -1924,5 +1596,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ $\langle$Modes {\footnotesize ?}$\rangle\equiv$
|
|||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
|
These modes are specific to the SINQ histogram memory.
|
||||||
A histogram memory can be operated in transparent mode. It has not yet been
|
A histogram memory can be operated in transparent mode. It has not yet been
|
||||||
defined what this means but it is sort of storing raw data from the detector
|
defined what this means but it is sort of storing raw data from the detector
|
||||||
without any summing or processing. Normal mode is better defined, this is
|
without any summing or processing. Normal mode is better defined, this is
|
||||||
@ -101,6 +102,11 @@ command. Then on initialisation first the logical histogram memory
|
|||||||
evaluates the general options and then the driver in its Config
|
evaluates the general options and then the driver in its Config
|
||||||
function evaluates the driver specific options.
|
function evaluates the driver specific options.
|
||||||
|
|
||||||
|
The histogram memory supports several dimensions, a time binning
|
||||||
|
option and optional buffering of histogram memory data read from the
|
||||||
|
actual HM. All this data management stuff is handled in a separate
|
||||||
|
class, HMdata. See the documentation for HMdata for more details.
|
||||||
|
|
||||||
|
|
||||||
\subsubsection{The Histogram memory driver}
|
\subsubsection{The Histogram memory driver}
|
||||||
Adhering to the Sics paradigm of dividing any device into a logical device
|
Adhering to the Sics paradigm of dividing any device into a logical device
|
||||||
@ -115,16 +121,7 @@ $\langle$HistType {\footnotesize ?}$\rangle\equiv$
|
|||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ typedef struct __HistDriver {@\\
|
\mbox{}\verb@ typedef struct __HistDriver {@\\
|
||||||
\mbox{}\verb@ /* configuration data */@\\
|
\mbox{}\verb@ pHMdata data;@\\
|
||||||
\mbox{}\verb@ HistMode eHistMode;@\\
|
|
||||||
\mbox{}\verb@ OverFlowMode eFlow;@\\
|
|
||||||
\mbox{}\verb@ int iRank;@\\
|
|
||||||
\mbox{}\verb@ int iDims[MAXDIM];@\\
|
|
||||||
\mbox{}\verb@ int nDim;@\\
|
|
||||||
\mbox{}\verb@ int iLength;@\\
|
|
||||||
\mbox{}\verb@ int iBinWidth;@\\
|
|
||||||
\mbox{}\verb@ float fTime[MAXCHAN];@\\
|
|
||||||
\mbox{}\verb@ int iTimeChan;@\\
|
|
||||||
\mbox{}\verb@ /* counting operations data */@\\
|
\mbox{}\verb@ /* counting operations data */@\\
|
||||||
\mbox{}\verb@ CounterMode eCount;@\\
|
\mbox{}\verb@ CounterMode eCount;@\\
|
||||||
\mbox{}\verb@ float fCountPreset;@\\
|
\mbox{}\verb@ float fCountPreset;@\\
|
||||||
@ -185,15 +182,6 @@ $\langle$HistType {\footnotesize ?}$\rangle\equiv$
|
|||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
Quite a lot, but a histogram memory is quite a complex piece of equipment.
|
Quite a lot, but a histogram memory is quite a complex piece of equipment.
|
||||||
The configuration information is in the elements EhistMode, eOverFlowMode,
|
|
||||||
iRank, iDims and iBinWidth fields. iDim and nDim desribe the logical
|
|
||||||
dimensions of the histogram memory. These may be different from the
|
|
||||||
dimensions used for data transfer. For instance the SANS detector is
|
|
||||||
handled internally as 1600+ numbers where it really is a filed o
|
|
||||||
128*128.
|
|
||||||
Additionally there is an array of
|
|
||||||
floating point values which denote the time binning for time-o-flight
|
|
||||||
operation or the stroboscopic binning axis in stroboscopic mode.
|
|
||||||
|
|
||||||
The fields fPreset and CounterMode hold the counting parameter data.
|
The fields fPreset and CounterMode hold the counting parameter data.
|
||||||
|
|
||||||
@ -326,11 +314,6 @@ $\langle$HistST {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ pICountable pCountInt;@\\
|
\mbox{}\verb@ pICountable pCountInt;@\\
|
||||||
\mbox{}\verb@ pICallBack pCall;@\\
|
\mbox{}\verb@ pICallBack pCall;@\\
|
||||||
\mbox{}\verb@ pStringDict pOption;@\\
|
\mbox{}\verb@ pStringDict pOption;@\\
|
||||||
\mbox{}\verb@ HistInt *iLocalData;@\\
|
|
||||||
\mbox{}\verb@ int iLocalLength;@\\
|
|
||||||
\mbox{}\verb@ int iLocalUpdate;@\\
|
|
||||||
\mbox{}\verb@ time_t tLocal;@\\
|
|
||||||
\mbox{}\verb@ int iUpdateIntervall;@\\
|
|
||||||
\mbox{}\verb@ } HistMem;@\\
|
\mbox{}\verb@ } HistMem;@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@$\diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
@ -630,7 +613,7 @@ following.
|
|||||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||||
\mbox{}\verb@#ifndef SICSHISTDRIV@\\
|
\mbox{}\verb@#ifndef SICSHISTDRIV@\\
|
||||||
\mbox{}\verb@#define SICSHISTDRIV@\\
|
\mbox{}\verb@#define SICSHISTDRIV@\\
|
||||||
\mbox{}\verb@#define MAXCHAN 16834 @\\
|
\mbox{}\verb@#include "hmdata.h"@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@@$\langle$HistType {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@$\langle$HistType {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
\mbox{}\verb@@$\langle$HistDrivProt {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@$\langle$HistDrivProt {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
33
histogram.w
33
histogram.w
@ -17,6 +17,7 @@ histograms. Let's discuss these different modes first.
|
|||||||
eSANSTOF
|
eSANSTOF
|
||||||
} HistMode;
|
} HistMode;
|
||||||
@}
|
@}
|
||||||
|
These modes are specific to the SINQ histogram memory.
|
||||||
A histogram memory can be operated in transparent mode. It has not yet been
|
A histogram memory can be operated in transparent mode. It has not yet been
|
||||||
defined what this means but it is sort of storing raw data from the detector
|
defined what this means but it is sort of storing raw data from the detector
|
||||||
without any summing or processing. Normal mode is better defined, this is
|
without any summing or processing. Normal mode is better defined, this is
|
||||||
@ -73,6 +74,11 @@ command. Then on initialisation first the logical histogram memory
|
|||||||
evaluates the general options and then the driver in its Config
|
evaluates the general options and then the driver in its Config
|
||||||
function evaluates the driver specific options.
|
function evaluates the driver specific options.
|
||||||
|
|
||||||
|
The histogram memory supports several dimensions, a time binning
|
||||||
|
option and optional buffering of histogram memory data read from the
|
||||||
|
actual HM. All this data management stuff is handled in a separate
|
||||||
|
class, HMdata. See the documentation for HMdata for more details.
|
||||||
|
|
||||||
|
|
||||||
\subsubsection{The Histogram memory driver}
|
\subsubsection{The Histogram memory driver}
|
||||||
Adhering to the Sics paradigm of dividing any device into a logical device
|
Adhering to the Sics paradigm of dividing any device into a logical device
|
||||||
@ -82,16 +88,7 @@ definition:
|
|||||||
|
|
||||||
@d HistType @{
|
@d HistType @{
|
||||||
typedef struct __HistDriver {
|
typedef struct __HistDriver {
|
||||||
/* configuration data */
|
pHMdata data;
|
||||||
HistMode eHistMode;
|
|
||||||
OverFlowMode eFlow;
|
|
||||||
int iRank;
|
|
||||||
int iDims[MAXDIM];
|
|
||||||
int nDim;
|
|
||||||
int iLength;
|
|
||||||
int iBinWidth;
|
|
||||||
float fTime[MAXCHAN];
|
|
||||||
int iTimeChan;
|
|
||||||
/* counting operations data */
|
/* counting operations data */
|
||||||
CounterMode eCount;
|
CounterMode eCount;
|
||||||
float fCountPreset;
|
float fCountPreset;
|
||||||
@ -145,15 +142,6 @@ definition:
|
|||||||
@}
|
@}
|
||||||
|
|
||||||
Quite a lot, but a histogram memory is quite a complex piece of equipment.
|
Quite a lot, but a histogram memory is quite a complex piece of equipment.
|
||||||
The configuration information is in the elements EhistMode, eOverFlowMode,
|
|
||||||
iRank, iDims and iBinWidth fields. iDim and nDim desribe the logical
|
|
||||||
dimensions of the histogram memory. These may be different from the
|
|
||||||
dimensions used for data transfer. For instance the SANS detector is
|
|
||||||
handled internally as 1600+ numbers where it really is a filed o
|
|
||||||
128*128.
|
|
||||||
Additionally there is an array of
|
|
||||||
floating point values which denote the time binning for time-o-flight
|
|
||||||
operation or the stroboscopic binning axis in stroboscopic mode.
|
|
||||||
|
|
||||||
The fields fPreset and CounterMode hold the counting parameter data.
|
The fields fPreset and CounterMode hold the counting parameter data.
|
||||||
|
|
||||||
@ -269,11 +257,6 @@ histogram memory object is fairly simple:
|
|||||||
pICountable pCountInt;
|
pICountable pCountInt;
|
||||||
pICallBack pCall;
|
pICallBack pCall;
|
||||||
pStringDict pOption;
|
pStringDict pOption;
|
||||||
HistInt *iLocalData;
|
|
||||||
int iLocalLength;
|
|
||||||
int iLocalUpdate;
|
|
||||||
time_t tLocal;
|
|
||||||
int iUpdateIntervall;
|
|
||||||
} HistMem;
|
} HistMem;
|
||||||
@}
|
@}
|
||||||
According to the general Sics object interface the first field is the object
|
According to the general Sics object interface the first field is the object
|
||||||
@ -485,7 +468,7 @@ following.
|
|||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#ifndef SICSHISTDRIV
|
#ifndef SICSHISTDRIV
|
||||||
#define SICSHISTDRIV
|
#define SICSHISTDRIV
|
||||||
#define MAXCHAN 16834
|
#include "hmdata.h"
|
||||||
|
|
||||||
@< HistType@>
|
@< HistType@>
|
||||||
@< HistDrivProt @>
|
@< HistDrivProt @>
|
||||||
|
11
histsim.c
11
histsim.c
@ -58,7 +58,7 @@
|
|||||||
*/
|
*/
|
||||||
static int iSet = 0;
|
static int iSet = 0;
|
||||||
static HistInt iSetVal = 0;
|
static HistInt iSetVal = 0;
|
||||||
|
static HistMode eHistMode;
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
static int SimConfig(pHistDriver self, SConnection *pCon,
|
static int SimConfig(pHistDriver self, SConnection *pCon,
|
||||||
pStringDict pOption, SicsInterp *pSics)
|
pStringDict pOption, SicsInterp *pSics)
|
||||||
@ -67,14 +67,13 @@
|
|||||||
char pData[132];
|
char pData[132];
|
||||||
float fFail;
|
float fFail;
|
||||||
|
|
||||||
if(self->eHistMode == eHTOF)
|
if(eHistMode == eHTOF)
|
||||||
{
|
{
|
||||||
for(i = 0; i < self->nDim; i++)
|
for(i = 0; i < self->data->rank; i++)
|
||||||
{
|
{
|
||||||
iLength *= self->iDims[i];
|
iLength *= self->data->iDim[i];
|
||||||
}
|
}
|
||||||
iLength *= self->iTimeChan;
|
iLength *= self->data->nTimeChan;
|
||||||
self->iLength = iLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
361
hmdata.c
Normal file
361
hmdata.c
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
This is a data handling class for histogram memory data.
|
||||||
|
For more information see hmdata.tex.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, January 2003
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "hmdata.h"
|
||||||
|
#include "HistMem.h"
|
||||||
|
#include "HistMem.i"
|
||||||
|
#include "HistDriv.i"
|
||||||
|
#include "countdriv.h"
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
pHMdata makeHMData(void) {
|
||||||
|
pHMdata self = NULL;
|
||||||
|
|
||||||
|
self = (pHMdata)malloc(sizeof(HMdata));
|
||||||
|
if(self == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(self,0,sizeof(HMdata));
|
||||||
|
self->nTimeChan = 1;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
void killHMData(pHMdata self){
|
||||||
|
if(self->localBuffer != NULL){
|
||||||
|
free(self->localBuffer);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int resizeBuffer(pHMdata self){
|
||||||
|
long size;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
size = 1;
|
||||||
|
for(i = 0; i < self->rank; i++){
|
||||||
|
size *= self->iDim[i];
|
||||||
|
}
|
||||||
|
if(self->tofMode){
|
||||||
|
size *= self->nTimeChan;
|
||||||
|
}
|
||||||
|
if(self->localBuffer != NULL){
|
||||||
|
free(self->localBuffer);
|
||||||
|
self->localBuffer = NULL;
|
||||||
|
}
|
||||||
|
self->localBuffer = (HistInt *)malloc(size*sizeof(HistInt));
|
||||||
|
if(!self->localBuffer){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(self->localBuffer,0,size*sizeof(HistInt));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
int configureHMdata(pHMdata self, pStringDict pOpt,
|
||||||
|
SConnection *pCon){
|
||||||
|
int status, i;
|
||||||
|
float fVal;
|
||||||
|
char pValue[80];
|
||||||
|
|
||||||
|
self->tofMode = 0;
|
||||||
|
status = StringDictGetAsNumber(pOpt,"rank",&fVal);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: critical configuration problem: no rank found",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->rank = (int)rint(fVal);
|
||||||
|
|
||||||
|
for(i = 0; i < self->rank; i++){
|
||||||
|
sprintf(pValue,"dim%1.1d",i);
|
||||||
|
status = StringDictGetAsNumber(pOpt,pValue,&fVal);
|
||||||
|
if(!status){
|
||||||
|
sprintf(pValue,"ERROR dimension %d not found!!", i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->iDim[i] = (int)rint(fVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGetAsNumber(pOpt,"update",&fVal);
|
||||||
|
if(!status){
|
||||||
|
self->updateIntervall = 0; /* no buffering */
|
||||||
|
} else {
|
||||||
|
self->updateIntervall = (int)rint(fVal);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
note: remove update request in histmem.c
|
||||||
|
*/
|
||||||
|
if(self->updateIntervall > 0){
|
||||||
|
/*
|
||||||
|
we do buffer
|
||||||
|
*/
|
||||||
|
status = resizeBuffer(self);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: failed to resize buffer",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int genTimeBinning(pHMdata self, float start, float step, int noSteps){
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(noSteps >= MAXCHAN){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i < noSteps; i++){
|
||||||
|
self->timeBinning[i] = start + i*step;
|
||||||
|
}
|
||||||
|
self->tofMode = 1;
|
||||||
|
self->nTimeChan = noSteps;
|
||||||
|
return resizeBuffer(self);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int setTimeBin(pHMdata self, int index, float value){
|
||||||
|
if(index > 0 || index < MAXCHAN){
|
||||||
|
self->timeBinning[index] = value;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->tofMode = 1;
|
||||||
|
if(index > self->nTimeChan){
|
||||||
|
self->nTimeChan = index;
|
||||||
|
return resizeBuffer(self);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
int isInTOFMode(pHMdata self){
|
||||||
|
return self->tofMode;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
int getNoOfTimebins(pHMdata self){
|
||||||
|
return self->nTimeChan;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
float *getTimeBinning(pHMdata self){
|
||||||
|
return self->timeBinning;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
void clearTimeBinning(pHMdata self){
|
||||||
|
self->nTimeChan = 1;
|
||||||
|
self->tofMode = 0;
|
||||||
|
resizeBuffer(self);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
void getHMDataDim(pHMdata self, int iDim[MAXDIM], int *rank){
|
||||||
|
memcpy(iDim,self->iDim,self->rank*sizeof(int));
|
||||||
|
*rank = self->rank;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
long getHMDataLength(pHMdata self){
|
||||||
|
long length = 1;
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < self->rank; i++){
|
||||||
|
length *= self->iDim[i];
|
||||||
|
}
|
||||||
|
if(self->tofMode){
|
||||||
|
length *= self->nTimeChan;
|
||||||
|
}
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
void updateHMData(pHMdata self){
|
||||||
|
self->updateFlag = 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------
|
||||||
|
The idea here is that upper level code sets the updateFlag through
|
||||||
|
updateHMData (above) whenever the HM changes (counts). If this flag is set
|
||||||
|
the next call to get getHMDataHistogram will read a new copy from the HM.
|
||||||
|
After reading nextUpdate is set to time + updateIntervall. In order to
|
||||||
|
prevent clients hammering the HM nextUpdate is checked as well.
|
||||||
|
updateIntervall can be set to a reasonable time intervall between updates in seconds. If updateIntervall is 0, a direct read is always perfomed.
|
||||||
|
If this system needs to be bypassed altogether (because there is no memory
|
||||||
|
to buffer all HM) use GetHistogramDirect (histogram.c) instead which acts
|
||||||
|
on the driver level.
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
static int mustUpdate(pHMdata self){
|
||||||
|
if(self->updateFlag == 1 && time(NULL) >= self->nextUpdate){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
static int updateHMbuffer(pHistMem hist, int bank, SConnection *pCon){
|
||||||
|
int status, iErr, i;
|
||||||
|
char pError[80], pBueffel[256];
|
||||||
|
pHMdata self = hist->pDriv->data;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++){
|
||||||
|
status = hist->pDriv->GetHistogram(hist->pDriv,pCon,
|
||||||
|
bank,0,getHMDataLength(self),
|
||||||
|
self->localBuffer);
|
||||||
|
if(status == OKOK){
|
||||||
|
self->nextUpdate = time(NULL) + self->updateIntervall;
|
||||||
|
self->updateFlag = 0;
|
||||||
|
break;
|
||||||
|
} else{
|
||||||
|
status = hist->pDriv->GetError(hist->pDriv,&iErr,pError,79);
|
||||||
|
sprintf(pBueffel,"ERROR: %s ",pError);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
status = hist->pDriv->TryAndFixIt(hist->pDriv,iErr);
|
||||||
|
if(status == COTERM) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(status == OKOK){
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int getHMDataHistogram(pHistMem hist, SConnection *pCon,
|
||||||
|
int bank, int start, int length,
|
||||||
|
HistInt *lData){
|
||||||
|
int status;
|
||||||
|
pHMdata self = hist->pDriv->data;
|
||||||
|
HistInt *lStart;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
if(self->localBuffer == NULL){
|
||||||
|
resizeBuffer(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
update buffer if necessary
|
||||||
|
*/
|
||||||
|
if(mustUpdate(self)){
|
||||||
|
status = updateHMbuffer(hist,bank,pCon);
|
||||||
|
if(status != OKOK){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
copy buffered data to lData
|
||||||
|
*/
|
||||||
|
lStart = self->localBuffer + start;
|
||||||
|
if(start + length > getHMDataLength(self)){
|
||||||
|
length = getHMDataLength(self) - start - 1;
|
||||||
|
}
|
||||||
|
memcpy(lData,lStart,length*sizeof(HistInt));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
HistInt *getHMDataBufferPointer(pHistMem hist,SConnection *pCon){
|
||||||
|
int status;
|
||||||
|
pHMdata self = hist->pDriv->data;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
if(self->localBuffer == NULL){
|
||||||
|
resizeBuffer(self);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
update buffer if necessary
|
||||||
|
*/
|
||||||
|
if(mustUpdate(self)){
|
||||||
|
status = updateHMbuffer(hist,0,pCon);
|
||||||
|
if(status != OKOK){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self->localBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static long SumRow(HistInt *iData, int iDataLength, int iStart, int iEnd){
|
||||||
|
int i;
|
||||||
|
long lSum;
|
||||||
|
|
||||||
|
if(iEnd > iDataLength){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lSum = 0;
|
||||||
|
for(i = iStart; i < iEnd; i++){
|
||||||
|
lSum += iData[i];
|
||||||
|
}
|
||||||
|
return lSum;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
long sumHMDataRectangle(pHistMem hist, SConnection *pCon,
|
||||||
|
int iStart[MAXDIM], int iEnd[MAXDIM]) {
|
||||||
|
HistInt *iData;
|
||||||
|
pHMdata self = hist->pDriv->data;
|
||||||
|
int i, iHistLength, status, iIndex;
|
||||||
|
char pBueffel[256];
|
||||||
|
long lSum;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
/*
|
||||||
|
error checking
|
||||||
|
*/
|
||||||
|
for(i = 0; i < self->rank; i++){
|
||||||
|
if( (iStart[i] < 0) || (iStart[i] > self->iDim[i]) ) {
|
||||||
|
sprintf(pBueffel,"ERROR: %d is out of data dimension range",
|
||||||
|
iStart[i]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if( (iEnd[i] < 0) || (iEnd[i] > self->iDim[i]) ){
|
||||||
|
sprintf(pBueffel,"ERROR: %d is out of data dimension range",
|
||||||
|
iEnd[i]);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
get an update of the HM if necessary
|
||||||
|
*/
|
||||||
|
if(mustUpdate(self)){
|
||||||
|
status = updateHMbuffer(hist,0,pCon);
|
||||||
|
if(status != OKOK){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iHistLength = getHMDataLength(self);
|
||||||
|
/* actually sum */
|
||||||
|
switch(self->rank)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
lSum = SumRow(self->localBuffer, iHistLength,
|
||||||
|
iStart[0], iEnd[0]);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
lSum = 0;
|
||||||
|
for(i = iStart[0]; i < iEnd[0]; i++){
|
||||||
|
iIndex = i*self->iDim[1];
|
||||||
|
lSum += SumRow(self->localBuffer,iHistLength,
|
||||||
|
iIndex+iStart[1], iIndex+iEnd[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"ERROR: summing in %d dimensions not yet implemented",
|
||||||
|
self->rank);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
lSum = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return lSum;
|
||||||
|
}
|
61
hmdata.h
Normal file
61
hmdata.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
This is a data handling class for histogram memory data.
|
||||||
|
For more information see hmdata.tex.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, January 2003
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSHMDATA
|
||||||
|
#define SICSHMDATA
|
||||||
|
#include "sics.h"
|
||||||
|
#include "HistMem.h"
|
||||||
|
#include "stringdict.h"
|
||||||
|
#define MAXCHAN 16834
|
||||||
|
#define MAXDIM 3
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int rank;
|
||||||
|
int iDim[MAXDIM];
|
||||||
|
int nTimeChan;
|
||||||
|
float timeBinning[MAXCHAN];
|
||||||
|
int tofMode;
|
||||||
|
time_t nextUpdate;
|
||||||
|
int updateIntervall;
|
||||||
|
int updateFlag;
|
||||||
|
HistInt *localBuffer;
|
||||||
|
} HMdata, *pHMdata;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pHMdata makeHMData(void);
|
||||||
|
void killHMData(pHMdata self);
|
||||||
|
|
||||||
|
int configureHMdata(pHMdata self, pStringDict pOpt,
|
||||||
|
SConnection *pCon);
|
||||||
|
int genTimeBinning(pHMdata self, float start, float step,
|
||||||
|
int noSteps);
|
||||||
|
int setTimeBin(pHMdata self, int index, float value);
|
||||||
|
|
||||||
|
int getNoOfTimebins(pHMdata self);
|
||||||
|
float *getTimeBinning(pHMdata self);
|
||||||
|
int isInTOFMode(pHMdata self);
|
||||||
|
void clearTimeBinning(pHMdata self);
|
||||||
|
|
||||||
|
void getHMDataDim(pHMdata self, int iDIM[MAXDIM], int *rank);
|
||||||
|
long getHMDataLength(pHMdata self);
|
||||||
|
|
||||||
|
int getHMDataHistogram(pHistMem hist, SConnection *pCon,
|
||||||
|
int bank, int start, int length,
|
||||||
|
HistInt *lData);
|
||||||
|
void updateHMData(pHMdata self);
|
||||||
|
HistInt *getHMDataBufferPointer(pHistMem hist, SConnection *pCon);
|
||||||
|
|
||||||
|
long sumHMDataRectangle(pHistMem self, SConnection *pCon,
|
||||||
|
int start[MAXDIM], int end[MAXDIM]);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
111
hmdata.w
Normal file
111
hmdata.w
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
\subsubsection{HMdata}
|
||||||
|
This is a data class for histogram memories. This class has the
|
||||||
|
following tasks:
|
||||||
|
\begin{itemize}
|
||||||
|
\item Maintain the dimensions of the histogram memory.
|
||||||
|
\item Keep track of the time binning, when appropriate.
|
||||||
|
\item In many cases the histogram memory data is buffered in order to
|
||||||
|
prevent excessive access to the histogram memory through status
|
||||||
|
display clients gone mad. This task is also handled through this class.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
In order to do this, the following data structure is needed:
|
||||||
|
@d hmdatadat @{
|
||||||
|
typedef struct {
|
||||||
|
int rank;
|
||||||
|
int iDim[MAXDIM];
|
||||||
|
int nTimeChan;
|
||||||
|
float timeBinning[MAXCHAN];
|
||||||
|
int tofMode;
|
||||||
|
time_t nextUpdate;
|
||||||
|
int updateIntervall;
|
||||||
|
int updateFlag;
|
||||||
|
HistInt *localBuffer;
|
||||||
|
} HMdata, *pHMdata;
|
||||||
|
@}
|
||||||
|
|
||||||
|
The following functions work on this data structure:
|
||||||
|
@d hmdatfunc @{
|
||||||
|
pHMdata makeHMData(void);
|
||||||
|
void killHMData(pHMdata self);
|
||||||
|
|
||||||
|
int configureHMdata(pHMdata self, pStringDict pOpt,
|
||||||
|
SConnection *pCon);
|
||||||
|
int genTimeBinning(pHMdata self, float start, float step,
|
||||||
|
int noSteps);
|
||||||
|
int setTimeBin(pHMdata self, int index, float value);
|
||||||
|
|
||||||
|
int getNoOfTimebins(pHMdata self);
|
||||||
|
float *getTimeBinning(pHMdata self);
|
||||||
|
int isInTOFMode(pHMdata self);
|
||||||
|
void clearTimeBinning(pHMdata self);
|
||||||
|
|
||||||
|
void getHMDataDim(pHMdata self, int iDIM[MAXDIM], int *rank);
|
||||||
|
long getHMDataLength(pHMdata self);
|
||||||
|
|
||||||
|
int getHMDataHistogram(pHistMem hist, SConnection *pCon,
|
||||||
|
int bank, int start, int length,
|
||||||
|
HistInt *lData);
|
||||||
|
void updateHMData(pHMdata self);
|
||||||
|
HistInt *getHMDataBufferPointer(pHistMem hist, SConnection *pCon);
|
||||||
|
|
||||||
|
long sumHMDataRectangle(pHistMem self, SConnection *pCon,
|
||||||
|
int start[MAXDIM], int end[MAXDIM]);
|
||||||
|
@}
|
||||||
|
|
||||||
|
\begin{description}
|
||||||
|
\item[makeHMData] allocate a new HMdata structure.
|
||||||
|
\item[killHMData] properly release all memory used by the HMdata
|
||||||
|
structure.
|
||||||
|
\item[configureHMdata] configures the HMdata from the configuration
|
||||||
|
options in pOpt.
|
||||||
|
\item[getTimeBinning] generate a equidistant time binning starting at
|
||||||
|
start. Create noSteps time bins of size step.
|
||||||
|
\item[isInTOFMode] returns true if we are in TOF mode, 0 else.
|
||||||
|
\item[setTimeBin] sets a single time bin at index to value. Used for
|
||||||
|
irregular time binnings.
|
||||||
|
\item[clearTimeBinning] removes all time binnings.
|
||||||
|
\item[getNoOfTimeBins] returns the number of time bins.
|
||||||
|
\item[getTimeBinning] returns a pointer to the time binning array. Do
|
||||||
|
not free or modify in any other form.
|
||||||
|
\item[getHMDataDim] retrieves the rank and dimensions of histogram
|
||||||
|
memory data.
|
||||||
|
\item[getHMDataLength] gets the size of the histogram memory array.
|
||||||
|
\item[getHMDataHistogram] copies histogram memory data to
|
||||||
|
lData. Dependent on the status, data is copied either from a local
|
||||||
|
buffer or retrieved from the histogram memory. lData must have been
|
||||||
|
allocated large enough to cope with all the data before this works
|
||||||
|
properly.
|
||||||
|
\item[forceHMDataUpdate] makes sure that the histogram is read from
|
||||||
|
the histogram memory and not from the buffer the next time round.
|
||||||
|
\item[getHMDataBufferPointer] returns a pointer to the internal buffer
|
||||||
|
pointer of HMdata. Use with extra care!
|
||||||
|
\item[sumHMDataRectangle] sums a rectangular box delimted by start and end
|
||||||
|
from the histogram memory.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
|
||||||
|
@o hmdata.h @{
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
This is a data handling class for histogram memory data.
|
||||||
|
For more information see hmdata.tex.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, January 2003
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSHMDATA
|
||||||
|
#define SICSHMDATA
|
||||||
|
#include "sics.h"
|
||||||
|
#include "HistMem.h"
|
||||||
|
#include "stringdict.h"
|
||||||
|
#define MAXCHAN 16834
|
||||||
|
#define MAXDIM 3
|
||||||
|
|
||||||
|
@<hmdatadat@>
|
||||||
|
|
||||||
|
@<hmdatfunc@>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@}
|
4
motreg.c
4
motreg.c
@ -95,6 +95,7 @@ int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
|
|||||||
int ret;
|
int ret;
|
||||||
long (*oldSet)(void *pmotorData, SConnection *pCon, float fValue);
|
long (*oldSet)(void *pmotorData, SConnection *pCon, float fValue);
|
||||||
pIDrivable pDriv = NULL;
|
pIDrivable pDriv = NULL;
|
||||||
|
char pBueffel[132];
|
||||||
|
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
@ -107,6 +108,9 @@ int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
|
|||||||
self->motorData,
|
self->motorData,
|
||||||
pCon,
|
pCon,
|
||||||
fValue);
|
fValue);
|
||||||
|
sprintf(pBueffel,"anticollision started %s to %f",self->motorName,
|
||||||
|
fValue);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
|
||||||
pDriv->SetValue = oldSet;
|
pDriv->SetValue = oldSet;
|
||||||
self->iActive = 1;
|
self->iActive = 1;
|
||||||
|
155
sicsstat.tcl
155
sicsstat.tcl
@ -1,22 +1,139 @@
|
|||||||
# Counter counter
|
# Motor atz
|
||||||
counter SetPreset 60.000000
|
atz sign 1.000000
|
||||||
counter SetMode Timer
|
atz SoftZero 0.000000
|
||||||
# Motor a77
|
atz SoftLowerLim -3900.000000
|
||||||
a77 sign 1.000000
|
atz SoftUpperLim 0.000000
|
||||||
a77 SoftZero 0.000000
|
atz Fixed -1.000000
|
||||||
a77 SoftLowerLim -30.000000
|
atz InterruptMode 0.000000
|
||||||
a77 SoftUpperLim 30.000000
|
atz AccessCode 2.000000
|
||||||
a77 Fixed -1.000000
|
# Motor az1
|
||||||
a77 InterruptMode 0.000000
|
az1 sign 1.000000
|
||||||
a77 AccessCode 2.000000
|
az1 SoftZero 0.000000
|
||||||
# Motor 2t
|
az1 SoftLowerLim -3900.000000
|
||||||
2t sign 1.000000
|
az1 SoftUpperLim 0.000000
|
||||||
2t SoftZero 0.000000
|
az1 Fixed -1.000000
|
||||||
2t SoftLowerLim -120.000000
|
az1 InterruptMode 0.000000
|
||||||
2t SoftUpperLim 120.000000
|
az1 AccessCode 2.000000
|
||||||
2t Fixed -1.000000
|
# Motor dv
|
||||||
2t InterruptMode 0.000000
|
dv sign 1.000000
|
||||||
2t AccessCode 2.000000
|
dv SoftZero 0.000000
|
||||||
|
dv SoftLowerLim -14000.000000
|
||||||
|
dv SoftUpperLim 25000.000000
|
||||||
|
dv Fixed -1.000000
|
||||||
|
dv InterruptMode 0.000000
|
||||||
|
dv AccessCode 2.000000
|
||||||
|
# Motor dh
|
||||||
|
dh sign 1.000000
|
||||||
|
dh SoftZero 0.000000
|
||||||
|
dh SoftLowerLim -14000.000000
|
||||||
|
dh SoftUpperLim 16000.000000
|
||||||
|
dh Fixed -1.000000
|
||||||
|
dh InterruptMode 0.000000
|
||||||
|
dh AccessCode 2.000000
|
||||||
|
# Motor dz
|
||||||
|
dz sign 1.000000
|
||||||
|
dz SoftZero 0.000000
|
||||||
|
dz SoftLowerLim 1.050000
|
||||||
|
dz SoftUpperLim 6.000000
|
||||||
|
dz Fixed -1.000000
|
||||||
|
dz InterruptMode 0.000000
|
||||||
|
dz AccessCode 2.000000
|
||||||
|
# Motor sy
|
||||||
|
sy sign 1.000000
|
||||||
|
sy SoftZero 0.000000
|
||||||
|
sy SoftLowerLim -10000.000000
|
||||||
|
sy SoftUpperLim 10000.000000
|
||||||
|
sy Fixed -1.000000
|
||||||
|
sy InterruptMode 0.000000
|
||||||
|
sy AccessCode 2.000000
|
||||||
|
# Motor sx
|
||||||
|
sx sign 1.000000
|
||||||
|
sx SoftZero 0.000000
|
||||||
|
sx SoftLowerLim -10000.000000
|
||||||
|
sx SoftUpperLim 10000.000000
|
||||||
|
sx Fixed -1.000000
|
||||||
|
sx InterruptMode 0.000000
|
||||||
|
sx AccessCode 2.000000
|
||||||
|
# Motor sz
|
||||||
|
sz sign 1.000000
|
||||||
|
sz SoftZero 0.000000
|
||||||
|
sz SoftLowerLim -10000.000000
|
||||||
|
sz SoftUpperLim 10000.000000
|
||||||
|
sz Fixed -1.000000
|
||||||
|
sz InterruptMode 0.000000
|
||||||
|
sz AccessCode 2.000000
|
||||||
|
# Motor om
|
||||||
|
om sign 1.000000
|
||||||
|
om SoftZero 0.000000
|
||||||
|
om SoftLowerLim -10000.000000
|
||||||
|
om SoftUpperLim 10000.000000
|
||||||
|
om Fixed -1.000000
|
||||||
|
om InterruptMode 0.000000
|
||||||
|
om AccessCode 2.000000
|
||||||
|
# Motor tl
|
||||||
|
tl sign 1.000000
|
||||||
|
tl SoftZero 0.000000
|
||||||
|
tl SoftLowerLim -10000.000000
|
||||||
|
tl SoftUpperLim 10000.000000
|
||||||
|
tl Fixed -1.000000
|
||||||
|
tl InterruptMode 0.000000
|
||||||
|
tl AccessCode 2.000000
|
||||||
|
# Motor tu
|
||||||
|
tu sign 1.000000
|
||||||
|
tu SoftZero 0.000000
|
||||||
|
tu SoftLowerLim -10000.000000
|
||||||
|
tu SoftUpperLim 10000.000000
|
||||||
|
tu Fixed -1.000000
|
||||||
|
tu InterruptMode 0.000000
|
||||||
|
tu AccessCode 2.000000
|
||||||
|
# Motor gl
|
||||||
|
gl sign 1.000000
|
||||||
|
gl SoftZero 0.000000
|
||||||
|
gl SoftLowerLim -10000.000000
|
||||||
|
gl SoftUpperLim 10000.000000
|
||||||
|
gl Fixed -1.000000
|
||||||
|
gl InterruptMode 0.000000
|
||||||
|
gl AccessCode 2.000000
|
||||||
|
# Motor gu
|
||||||
|
gu sign 1.000000
|
||||||
|
gu SoftZero 0.000000
|
||||||
|
gu SoftLowerLim -10000.000000
|
||||||
|
gu SoftUpperLim 10000.000000
|
||||||
|
gu Fixed -1.000000
|
||||||
|
gu InterruptMode 0.000000
|
||||||
|
gu AccessCode 2.000000
|
||||||
|
# Motor sc
|
||||||
|
sc sign 1.000000
|
||||||
|
sc SoftZero 0.000000
|
||||||
|
sc SoftLowerLim -2000.000000
|
||||||
|
sc SoftUpperLim 70000.000000
|
||||||
|
sc Fixed -1.000000
|
||||||
|
sc InterruptMode 0.000000
|
||||||
|
sc AccessCode 2.000000
|
||||||
|
# Motor stz
|
||||||
|
stz sign 1.000000
|
||||||
|
stz SoftZero 0.000000
|
||||||
|
stz SoftLowerLim 6500.000000
|
||||||
|
stz SoftUpperLim 20000.000000
|
||||||
|
stz Fixed -1.000000
|
||||||
|
stz InterruptMode 0.000000
|
||||||
|
stz AccessCode 2.000000
|
||||||
|
# Motor stx
|
||||||
|
stx sign 1.000000
|
||||||
|
stx SoftZero 0.000000
|
||||||
|
stx SoftLowerLim -16000.000000
|
||||||
|
stx SoftUpperLim 16000.000000
|
||||||
|
stx Fixed -1.000000
|
||||||
|
stx InterruptMode 0.000000
|
||||||
|
stx AccessCode 2.000000
|
||||||
|
# Motor sr
|
||||||
|
sr sign 1.000000
|
||||||
|
sr SoftZero 0.000000
|
||||||
|
sr SoftLowerLim -10000.000000
|
||||||
|
sr SoftUpperLim 10000.000000
|
||||||
|
sr Fixed -1.000000
|
||||||
|
sr InterruptMode 0.000000
|
||||||
|
sr AccessCode 2.000000
|
||||||
samplename KohlSulfid
|
samplename KohlSulfid
|
||||||
samplename setAccess 2
|
samplename setAccess 2
|
||||||
comment UNKNOWN
|
comment UNKNOWN
|
||||||
|
212
sinqhmdriv.c
212
sinqhmdriv.c
@ -68,6 +68,57 @@
|
|||||||
self->iLastHMError = 0;
|
self->iLastHMError = 0;
|
||||||
self->iLastCTError = 0;
|
self->iLastCTError = 0;
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static char *pHistMode[] = {
|
||||||
|
"transparent",
|
||||||
|
"normal",
|
||||||
|
"tof",
|
||||||
|
"strobo",
|
||||||
|
"hrpt",
|
||||||
|
"psd",
|
||||||
|
"sanstof",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static HistMode Text2Mode(char *text)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while(pHistMode[i] != NULL)
|
||||||
|
{
|
||||||
|
if(strcmp(pHistMode[i],text) == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
/* not found */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static char *pFlowMode[] = {
|
||||||
|
"ignore",
|
||||||
|
"ceil",
|
||||||
|
"count",
|
||||||
|
"reflect",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static OverFlowMode Text2Flow(char *text)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while(pFlowMode[i] != NULL)
|
||||||
|
{
|
||||||
|
if(strcmp(pFlowMode[i],text) == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
/* not found */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
Configure deconfigures first, in order to have a clean state. Than the HM
|
Configure deconfigures first, in order to have a clean state. Than the HM
|
||||||
is configured and a client connection will be built. Configure requires,
|
is configured and a client connection will be built. Configure requires,
|
||||||
@ -80,14 +131,14 @@
|
|||||||
SinqHMDriv *pInternal;
|
SinqHMDriv *pInternal;
|
||||||
int status, iMode;
|
int status, iMode;
|
||||||
char pError[132];
|
char pError[132];
|
||||||
char pHMComputer[256];
|
char pHMComputer[256], pValue[80], pBueffel[256];
|
||||||
float fVal;
|
float fVal;
|
||||||
char pcCounter[256];
|
char pcCounter[256];
|
||||||
CommandList *pCom = NULL;
|
CommandList *pCom = NULL;
|
||||||
int iStart = 0;
|
int iStart = 0;
|
||||||
int iInit = 0, i;
|
int iInit = 0, i, iRet;
|
||||||
int xOff, xFac, yOff, yFac;
|
int xOff, xFac, yOff, yFac;
|
||||||
int iPort;
|
int iPort, iLength;
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
assert(self->pPriv);
|
assert(self->pPriv);
|
||||||
@ -97,9 +148,70 @@
|
|||||||
pInternal = (SinqHMDriv *)self->pPriv;
|
pInternal = (SinqHMDriv *)self->pPriv;
|
||||||
ErrInit(pInternal);
|
ErrInit(pInternal);
|
||||||
|
|
||||||
|
|
||||||
|
/* enter histmode */
|
||||||
|
iRet = StringDictGet(pOpt,"histmode",pValue,79);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strtolower(pValue);
|
||||||
|
iRet = Text2Mode(pValue);
|
||||||
|
if(iRet < 0)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: Invalid parameter %s to HistMode",pValue);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pInternal->eHistMode = iRet;
|
||||||
|
|
||||||
|
/* handle overflowmode */
|
||||||
|
iRet = StringDictGet(pOpt,"overflowmode",pValue,79);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strtolower(pValue);
|
||||||
|
iRet = Text2Flow(pValue);
|
||||||
|
if(iRet < 0)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: Invalid parameter %s to OverflowMode",pValue);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pInternal->eFlow = iRet;
|
||||||
|
|
||||||
|
/* BinWidth */
|
||||||
|
iRet = StringDictGetAsNumber(pOpt,"binwidth",&fVal);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
iRet = StringDictGet(pOpt,"binwidth",pValue,79);
|
||||||
|
if(iRet)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: %s not valid for BinWidth ",pValue);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: internal Value not found!",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(fVal < 1)
|
||||||
|
{
|
||||||
|
sprintf(pBueffel,"ERROR: %f is invalid for BinWidth",fVal);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pInternal->iBinWidth = (int)fVal;
|
||||||
|
|
||||||
|
|
||||||
/* check BinWidth */
|
/* check BinWidth */
|
||||||
if( (self->iBinWidth != 1) && (self->iBinWidth != 2)
|
if( (pInternal->iBinWidth != 1) && (pInternal->iBinWidth != 2)
|
||||||
&& (self->iBinWidth != 4))
|
&& (pInternal->iBinWidth != 4))
|
||||||
{
|
{
|
||||||
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",pCon);
|
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",pCon);
|
||||||
return 0;
|
return 0;
|
||||||
@ -137,7 +249,7 @@
|
|||||||
pCom = FindCommand(pSics,pcCounter);
|
pCom = FindCommand(pSics,pcCounter);
|
||||||
if(!pCom)
|
if(!pCom)
|
||||||
{
|
{
|
||||||
PrintHMError("WARNING: no EL737 counter for HM found! ",
|
PrintHMError("WARNING: no counter for HM found! ",
|
||||||
pCon);
|
pCon);
|
||||||
pInternal->pCounter = NULL;
|
pInternal->pCounter = NULL;
|
||||||
}
|
}
|
||||||
@ -147,7 +259,7 @@
|
|||||||
if(!pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
if(!pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||||
COUNTID))
|
COUNTID))
|
||||||
{
|
{
|
||||||
PrintHMError("EL737 counter for histogram memory is invalid",
|
PrintHMError("Counter for histogram memory is invalid",
|
||||||
pCon);
|
pCon);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -170,8 +282,10 @@
|
|||||||
/* in any case let us propagate the state of affairs to
|
/* in any case let us propagate the state of affairs to
|
||||||
SINQHM
|
SINQHM
|
||||||
*/
|
*/
|
||||||
SINQHMSetPar(pInternal->pMaster,self->iRank, self->iLength,
|
|
||||||
self->iBinWidth);
|
SINQHMSetPar(pInternal->pMaster,self->data->rank,
|
||||||
|
getHMDataLength(self->data),
|
||||||
|
pInternal->iBinWidth);
|
||||||
|
|
||||||
|
|
||||||
/* actual configuration. On first call, check for flag INIt in
|
/* actual configuration. On first call, check for flag INIt in
|
||||||
@ -205,8 +319,8 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (self->iBinWidth != 1) && (self->iBinWidth != 2)
|
if( (pInternal->iBinWidth != 1) && (pInternal->iBinWidth != 2)
|
||||||
&& (self->iBinWidth != 4))
|
&& (pInternal->iBinWidth != 4))
|
||||||
{
|
{
|
||||||
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",
|
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",
|
||||||
pCon);
|
pCon);
|
||||||
@ -215,7 +329,7 @@ pCon);
|
|||||||
|
|
||||||
|
|
||||||
/* configure */
|
/* configure */
|
||||||
switch(self->eHistMode)
|
switch(pInternal->eHistMode)
|
||||||
{
|
{
|
||||||
case eHTransparent:
|
case eHTransparent:
|
||||||
iMode = SQHM__TRANS;
|
iMode = SQHM__TRANS;
|
||||||
@ -226,22 +340,25 @@ pCon);
|
|||||||
case eHTOF:
|
case eHTOF:
|
||||||
iMode = SQHM__TOF;
|
iMode = SQHM__TOF;
|
||||||
/* recalculate some parameters */
|
/* recalculate some parameters */
|
||||||
self->iLength = 1;
|
iLength = 1;
|
||||||
for(i = 0; i < self->iRank; i++)
|
for(i = 0; i < self->data->rank; i++)
|
||||||
{
|
{
|
||||||
self->iLength *= self->iDims[i];
|
iLength *= self->data->iDim[i];
|
||||||
}
|
}
|
||||||
self->iLength *= self->iTimeChan;
|
iLength *= self->data->nTimeChan;
|
||||||
SINQHMDefineBank(pInternal->pMaster,0,0,self->iDims[0],
|
SINQHMDefineBank(pInternal->pMaster,0,0,self->data->iDim[0],
|
||||||
self->fTime,self->iTimeChan);
|
self->data->timeBinning,
|
||||||
|
self->data->nTimeChan);
|
||||||
break;
|
break;
|
||||||
case eSANSTOF:
|
case eSANSTOF:
|
||||||
iMode = SQHM__TOF;
|
iMode = SQHM__TOF;
|
||||||
self->iLength = self->iDims[0]*self->iDims[1];
|
iLength = self->data->iDim[0]*self->data->iDim[1];
|
||||||
self->iLength *= self->iTimeChan;
|
iLength *= self->data->nTimeChan;
|
||||||
SINQHMDefineBank(pInternal->pMaster,0,0,
|
SINQHMDefineBank(pInternal->pMaster,0,0,
|
||||||
(self->iDims[0]*self->iDims[1]) + 3,
|
(self->data->iDim[0]*self->data->iDim[1])
|
||||||
self->fTime,self->iTimeChan);
|
+ 3,
|
||||||
|
self->data->timeBinning,
|
||||||
|
self->data->nTimeChan);
|
||||||
break;
|
break;
|
||||||
case eHStrobo:
|
case eHStrobo:
|
||||||
iMode = SQHM__HM_PSD | SQHM__STROBO;
|
iMode = SQHM__HM_PSD | SQHM__STROBO;
|
||||||
@ -256,7 +373,7 @@ pCon);
|
|||||||
PrintHMError("Unsupported mode requested",pCon);
|
PrintHMError("Unsupported mode requested",pCon);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
switch(self->eFlow)
|
switch(pInternal->eFlow)
|
||||||
{
|
{
|
||||||
case eOIgnore:
|
case eOIgnore:
|
||||||
iMode = iMode | SQHM__BO_IGN;
|
iMode = iMode | SQHM__BO_IGN;
|
||||||
@ -274,13 +391,13 @@ pCon);
|
|||||||
PrintHMError("Unsupported overflowmode requested",pCon);
|
PrintHMError("Unsupported overflowmode requested",pCon);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(self->eHistMode != ePSD)
|
if(pInternal->eHistMode != ePSD)
|
||||||
{
|
{
|
||||||
status = SINQHMConfigure(pInternal->pMaster,
|
status = SINQHMConfigure(pInternal->pMaster,
|
||||||
iMode,
|
iMode,
|
||||||
self->iRank,
|
self->data->rank,
|
||||||
self->iLength,
|
getHMDataLength(self->data),
|
||||||
self->iBinWidth,
|
pInternal->iBinWidth,
|
||||||
0,0);
|
0,0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -320,15 +437,15 @@ pCon);
|
|||||||
/* xSize and ySize are supposed to be in dim */
|
/* xSize and ySize are supposed to be in dim */
|
||||||
status = SINQHMConfigurePSD(pInternal->pMaster,
|
status = SINQHMConfigurePSD(pInternal->pMaster,
|
||||||
iMode,
|
iMode,
|
||||||
self->iDims[0],
|
self->data->iDim[0],
|
||||||
xOff,
|
xOff,
|
||||||
xFac,
|
xFac,
|
||||||
self->iDims[1],
|
self->data->iDim[1],
|
||||||
yOff,
|
yOff,
|
||||||
yFac,
|
yFac,
|
||||||
self->iBinWidth,
|
pInternal->iBinWidth,
|
||||||
self->fTime,
|
self->data->timeBinning,
|
||||||
self->iTimeChan);
|
self->data->nTimeChan);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(status < 0)
|
if(status < 0)
|
||||||
@ -380,15 +497,17 @@ pCon);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* first zero the HM */
|
/* first zero the HM */
|
||||||
if(self->eHistMode == ePSD && self->iTimeChan > 2){
|
if(pInternal->eHistMode == ePSD && self->data->nTimeChan > 2){
|
||||||
/*
|
/*
|
||||||
this is special for AMOR and should be replaced by -1, -1, -1
|
this is special for AMOR and should be replaced by -1, -1, -1
|
||||||
logic ASAP
|
logic ASAP
|
||||||
*/
|
*/
|
||||||
nHist = (self->iDims[0]*self->iDims[1] + 2) *self->iTimeChan;
|
nHist = (self->data->iDim[0]*self->data->iDim[1] + 2) *
|
||||||
|
self->data->nTimeChan;
|
||||||
status = SINQHMZero(pInternal->pMaster,-1,-1,-1);
|
status = SINQHMZero(pInternal->pMaster,-1,-1,-1);
|
||||||
}else{
|
}else{
|
||||||
status = SINQHMZero(pInternal->pMaster,-1,0,self->iRank*self->iLength);
|
status = SINQHMZero(pInternal->pMaster,-1,0,
|
||||||
|
self->data->rank*getHMDataLength(self->data));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
status = SINQHMZero(pInternal->pMaster,-1,-1,-1);
|
status = SINQHMZero(pInternal->pMaster,-1,-1,-1);
|
||||||
@ -745,8 +864,8 @@ pCon);
|
|||||||
pInternal = self->pPriv;
|
pInternal = self->pPriv;
|
||||||
|
|
||||||
/* we do not need to do a lot of copying when datasizes match! */
|
/* we do not need to do a lot of copying when datasizes match! */
|
||||||
iByte = (iEnd - iStart) * self->iBinWidth;
|
iByte = (iEnd - iStart) * pInternal->iBinWidth;
|
||||||
if(self->iBinWidth == sizeof(HistInt))
|
if(pInternal->iBinWidth == sizeof(HistInt))
|
||||||
{
|
{
|
||||||
/* read HM */
|
/* read HM */
|
||||||
status = SINQHMRead(pInternal->pMaster,
|
status = SINQHMRead(pInternal->pMaster,
|
||||||
@ -779,7 +898,7 @@ pCon);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* convert to correct datasize */
|
/* convert to correct datasize */
|
||||||
switch(self->iBinWidth)
|
switch(pInternal->iBinWidth)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
pPtr = (char *)pData;
|
pPtr = (char *)pData;
|
||||||
@ -831,7 +950,7 @@ pCon);
|
|||||||
pInternal = self->pPriv;
|
pInternal = self->pPriv;
|
||||||
|
|
||||||
/* allocate storage */
|
/* allocate storage */
|
||||||
iByte = iEnd * self->iBinWidth;
|
iByte = iEnd * pInternal->iBinWidth;
|
||||||
pData = (void *)malloc(iByte*sizeof(char));
|
pData = (void *)malloc(iByte*sizeof(char));
|
||||||
if(!pData)
|
if(!pData)
|
||||||
{
|
{
|
||||||
@ -841,7 +960,7 @@ pCon);
|
|||||||
memset(pData,0,iByte);
|
memset(pData,0,iByte);
|
||||||
|
|
||||||
/* convert from long to supported binwidth */
|
/* convert from long to supported binwidth */
|
||||||
switch(self->iBinWidth)
|
switch(pInternal->iBinWidth)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
pPtr = (char *)pData;
|
pPtr = (char *)pData;
|
||||||
@ -926,10 +1045,10 @@ pCon);
|
|||||||
pInternal = self->pPriv;
|
pInternal = self->pPriv;
|
||||||
|
|
||||||
/* get memory */
|
/* get memory */
|
||||||
if(self->eHistMode == ePSD && self->iTimeChan > 2){
|
if(pInternal->eHistMode == ePSD && self->data->nTimeChan > 2){
|
||||||
nHist = self->iDims[0]*self->iDims[1]*self->iTimeChan;
|
nHist = self->data->iDim[0]*self->data->iDim[1]*self->data->nTimeChan;
|
||||||
} else {
|
} else {
|
||||||
nHist = self->iRank*self->iLength;
|
nHist = getHMDataLength(self->data);
|
||||||
}
|
}
|
||||||
plData = (HistInt *)malloc(nHist*sizeof(HistInt));
|
plData = (HistInt *)malloc(nHist*sizeof(HistInt));
|
||||||
if(!plData)
|
if(!plData)
|
||||||
@ -989,6 +1108,9 @@ pCon);
|
|||||||
StringDictAddPair(pOption,"yoff","100");
|
StringDictAddPair(pOption,"yoff","100");
|
||||||
StringDictAddPair(pOption,"yfac","10");
|
StringDictAddPair(pOption,"yfac","10");
|
||||||
StringDictAddPair(pOption,"init","1");
|
StringDictAddPair(pOption,"init","1");
|
||||||
|
StringDictAddPair(pOption,"histmode","normal");
|
||||||
|
StringDictAddPair(pOption,"overflowmode","ceil");
|
||||||
|
StringDictAddPair(pOption,"binwidth","4");
|
||||||
|
|
||||||
/* initialise our private data structure */
|
/* initialise our private data structure */
|
||||||
pInternal = (SinqHMDriv *)malloc(sizeof(SinqHMDriv));
|
pInternal = (SinqHMDriv *)malloc(sizeof(SinqHMDriv));
|
||||||
@ -999,6 +1121,10 @@ pCon);
|
|||||||
}
|
}
|
||||||
memset(pInternal,0,sizeof(SinqHMDriv));
|
memset(pInternal,0,sizeof(SinqHMDriv));
|
||||||
pNew->pPriv = pInternal;
|
pNew->pPriv = pInternal;
|
||||||
|
pInternal->eHistMode = eHNormal;
|
||||||
|
pInternal->eFlow = eOCeil;
|
||||||
|
pInternal->iBinWidth = 4;
|
||||||
|
|
||||||
|
|
||||||
/* configure all those functions */
|
/* configure all those functions */
|
||||||
pNew->Configure = SQConfigure;
|
pNew->Configure = SQConfigure;
|
||||||
|
11
sinqhmdriv.i
11
sinqhmdriv.i
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 60 "sinqhmdriv.w"
|
#line 63 "sinqhmdriv.w"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
/*--------------------------------------------------------------------------
|
||||||
S I N Q H M
|
S I N Q H M
|
||||||
@ -21,18 +21,21 @@
|
|||||||
pSINQHM pMaster;
|
pSINQHM pMaster;
|
||||||
int iLastHMError;
|
int iLastHMError;
|
||||||
int iLastCTError;
|
int iLastCTError;
|
||||||
|
HistMode eHistMode;
|
||||||
|
int iBinWidth;
|
||||||
|
OverFlowMode eFlow;
|
||||||
} SinqHMDriv;
|
} SinqHMDriv;
|
||||||
|
|
||||||
#line 73 "sinqhmdriv.w"
|
#line 76 "sinqhmdriv.w"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#line 55 "sinqhmdriv.w"
|
#line 58 "sinqhmdriv.w"
|
||||||
|
|
||||||
pHistDriver CreateSINQDriver(pStringDict pOption);
|
pHistDriver CreateSINQDriver(pStringDict pOption);
|
||||||
int isSINQHMDriv(pHistDriver test);
|
int isSINQHMDriv(pHistDriver test);
|
||||||
|
|
||||||
#line 75 "sinqhmdriv.w"
|
#line 78 "sinqhmdriv.w"
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,6 +30,9 @@ $\langle$SQType {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ pSINQHM pMaster;@\\
|
\mbox{}\verb@ pSINQHM pMaster;@\\
|
||||||
\mbox{}\verb@ int iLastHMError;@\\
|
\mbox{}\verb@ int iLastHMError;@\\
|
||||||
\mbox{}\verb@ int iLastCTError;@\\
|
\mbox{}\verb@ int iLastCTError;@\\
|
||||||
|
\mbox{}\verb@ HistMode eHistMode;@\\
|
||||||
|
\mbox{}\verb@ int iBinWidth;@\\
|
||||||
|
\mbox{}\verb@ OverFlowMode eFlow;@\\
|
||||||
\mbox{}\verb@ } SinqHMDriv;@\\
|
\mbox{}\verb@ } SinqHMDriv;@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@$\diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
|
@ -25,6 +25,9 @@ already reflected by the driver private data structure:
|
|||||||
pSINQHM pMaster;
|
pSINQHM pMaster;
|
||||||
int iLastHMError;
|
int iLastHMError;
|
||||||
int iLastCTError;
|
int iLastCTError;
|
||||||
|
HistMode eHistMode;
|
||||||
|
int iBinWidth;
|
||||||
|
OverFlowMode eFlow;
|
||||||
} SinqHMDriv;
|
} SinqHMDriv;
|
||||||
@}
|
@}
|
||||||
|
|
||||||
|
539
tdchm.c
Normal file
539
tdchm.c
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
This is a driver for the TDC histogram memory as supplied with the
|
||||||
|
Risoe instruments. This system uses a Z80 processor internally.
|
||||||
|
Communication is via a GPIB interface. For more information on this
|
||||||
|
device consult documentation available from Risoe.
|
||||||
|
|
||||||
|
The TDC needs a separate counter for controlling the count operation.
|
||||||
|
The counter is connected to the TDC and inhibits histogramming when the
|
||||||
|
counter is not ready. This is alos why many of the functions in this
|
||||||
|
file chain down to a counter.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, February 2003
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "sics.h"
|
||||||
|
#include "countdriv.h"
|
||||||
|
#include "counter.h"
|
||||||
|
#include "HistMem.h"
|
||||||
|
#include "stringdict.h"
|
||||||
|
#include "HistDriv.i"
|
||||||
|
#include "ecb.h"
|
||||||
|
|
||||||
|
/*-------------------------- private definitions -----------------------*/
|
||||||
|
typedef enum {HMX, HMY, HMXY} TDCModes;
|
||||||
|
|
||||||
|
#define MAXTDCCHANNELS (128*128)
|
||||||
|
|
||||||
|
#define COMMERROR -301
|
||||||
|
#define MAXEXCEEDED -302
|
||||||
|
|
||||||
|
/*------------------------- private data structure ---------------------*/
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
TDCModes mode;
|
||||||
|
int map;
|
||||||
|
int bank;
|
||||||
|
unsigned char fillByte;
|
||||||
|
int range;
|
||||||
|
int n;
|
||||||
|
int errorCode;
|
||||||
|
pCounter counter;
|
||||||
|
pECB tdc;
|
||||||
|
} Tdc, *pTdc;
|
||||||
|
|
||||||
|
/*=======================================================================*/
|
||||||
|
static int downloadConfiguration(pTdc self){
|
||||||
|
int status;
|
||||||
|
Z80_reg in, out;
|
||||||
|
int function;
|
||||||
|
|
||||||
|
/*
|
||||||
|
map
|
||||||
|
*/
|
||||||
|
in.d = (unsigned char)self->map;
|
||||||
|
status = ecbExecute(self->tdc,134,in,&out);
|
||||||
|
if(status != 1){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
mode
|
||||||
|
*/
|
||||||
|
switch(self->mode){
|
||||||
|
case HMX:
|
||||||
|
function = 129;
|
||||||
|
break;
|
||||||
|
case HMY:
|
||||||
|
function = 130;
|
||||||
|
break;
|
||||||
|
caseHMXY:
|
||||||
|
function = 128;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
status = ecbExecute(self->tdc,function,in,&out);
|
||||||
|
if(status != 1){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
static int TDCConfigure(pHistDriver self, SConnection *pCon,
|
||||||
|
pStringDict pOpt, SicsInterp *pSics){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
char pValue[80];
|
||||||
|
float value;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
status = StringDictGet(pOpt,"mode",pValue,79);
|
||||||
|
assert(status); /* defaults should have been set in driver creation*/
|
||||||
|
if(strcmp(pValue,"HMX") == 0){
|
||||||
|
tdc->mode = HMX;
|
||||||
|
}else if(strcmp(pValue,"HMY") == 0){
|
||||||
|
tdc->mode = HMY;
|
||||||
|
}else if(strcmp(pValue,"HMXY") == 0){
|
||||||
|
tdc->mode = HMXY;
|
||||||
|
} else {
|
||||||
|
SCWrite(pCon,"ERROR: invalid HM mode defaulted to HMXY",eError);
|
||||||
|
tdc->mode = HMXY;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGetAsNumber(pOpt,"map",&value);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: invalid map value",eError);
|
||||||
|
} else {
|
||||||
|
tdc->map = (int)rint(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGetAsNumber(pOpt,"bank",&value);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: invalid bank value",eError);
|
||||||
|
} else {
|
||||||
|
tdc->bank = (int)rint(value);
|
||||||
|
if(tdc->bank != 0 && tdc->bank != 1){
|
||||||
|
SCWrite(pCon,"ERROR: invalid bank value defaulted to 0",eError);
|
||||||
|
tdc->bank = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGetAsNumber(pOpt,"range",&value);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: invalid range value",eError);
|
||||||
|
} else {
|
||||||
|
tdc->range = (int)rint(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGetAsNumber(pOpt,"n",&value);
|
||||||
|
if(!status){
|
||||||
|
SCWrite(pCon,"ERROR: invalid n value",eError);
|
||||||
|
} else {
|
||||||
|
tdc->n = (int)rint(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGet(pOpt,"counter",pValue,79);
|
||||||
|
/*
|
||||||
|
ignore errors here, in order to support operations without counter
|
||||||
|
*/
|
||||||
|
if(!status){
|
||||||
|
tdc->counter = NULL;
|
||||||
|
}
|
||||||
|
tdc->counter = FindCommandData(pSics,pValue,"SingleCounter");
|
||||||
|
|
||||||
|
tdc->fillByte = 0;
|
||||||
|
|
||||||
|
status = downloadConfiguration(tdc);
|
||||||
|
if(!status){
|
||||||
|
tdc->errorCode = status;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = StringDictGet(pOpt,"ecb",pValue,79);
|
||||||
|
assert(status);
|
||||||
|
tdc->tdc = FindCommandData(pSics,pValue,"ECB");
|
||||||
|
if(tdc->tdc == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: failed to locate ECB system, critical!",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->iReconfig = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=======================================================================*/
|
||||||
|
static int clearTdc(pTdc self, unsigned char fill){
|
||||||
|
Z80_reg in, out;
|
||||||
|
|
||||||
|
in.b = self->bank;
|
||||||
|
in.c = fill;
|
||||||
|
in.d = 0;
|
||||||
|
return ecbExecute(self->tdc,133,in,&out);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
static int enableTdc(pTdc self){
|
||||||
|
Z80_reg in, out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
range and n are obscure parameters
|
||||||
|
*/
|
||||||
|
in.c = 0;
|
||||||
|
in.b = self->range;
|
||||||
|
in.d = (char) ((self->n >>8) && 255);
|
||||||
|
in.e = (char)(self->n && 255);
|
||||||
|
|
||||||
|
return ecbExecute(self->tdc,131,in,&out);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static int TDCStart(pHistDriver self, SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
tdc->errorCode = 0;
|
||||||
|
|
||||||
|
status = clearTdc(tdc,0);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = enableTdc(tdc);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
start the counter if available
|
||||||
|
*/
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
tdc->counter->pDriv->fPreset = self->fCountPreset;
|
||||||
|
tdc->counter->pDriv->eMode = self->eCount;
|
||||||
|
return tdc->counter->pDriv->Start(tdc->counter->pDriv);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int disableTdc(pTdc self){
|
||||||
|
Z80_reg in, out;
|
||||||
|
|
||||||
|
return ecbExecute(self->tdc,132,in,&out);
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
|
static int TDCHalt(pHistDriver self){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
tdc->errorCode = 0;
|
||||||
|
|
||||||
|
status = disableTdc(tdc);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
tdc->counter->pDriv->Halt(tdc->counter->pDriv);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int TDCCountStatus(pHistDriver self, SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
float fControl;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
return tdc->counter->pDriv->GetStatus(tdc->counter->pDriv,&fControl);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
The TDC does not seem to have a means to figure if it is counting or not
|
||||||
|
or to do some sort of progress report.
|
||||||
|
*/
|
||||||
|
return HWIdle;
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int TDCGetError(pHistDriver self, int *iCode, char *perror,
|
||||||
|
int iErrlen){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
*iCode = tdc->errorCode;
|
||||||
|
switch(tdc->errorCode){
|
||||||
|
case COMMERROR:
|
||||||
|
strncpy(perror,"Communication problem with TDC",iErrlen);
|
||||||
|
break;
|
||||||
|
case MAXEXCEEDED:
|
||||||
|
strncpy(perror,"Requested to many channels for read",iErrlen);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
tdc->counter->pDriv->GetError(tdc->counter->pDriv,
|
||||||
|
iCode,perror,iErrlen);
|
||||||
|
} else{
|
||||||
|
strncpy(perror,"Undefined error code",iErrlen);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int TDCFixIt(pHistDriver self, int iCode){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
switch(iCode){
|
||||||
|
case COMMERROR:
|
||||||
|
ecbClear(tdc->tdc);
|
||||||
|
result = COREDO;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
result = tdc->counter->pDriv->TryAndFixIt(tdc->counter->pDriv,
|
||||||
|
iCode);
|
||||||
|
} else{
|
||||||
|
result = COTERM;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int TDCGetData(pHistDriver self, SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
return tdc->counter->pDriv->ReadValues(tdc->counter->pDriv);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*======================================================================*/
|
||||||
|
static long TDCGetMonitor(pHistDriver self, int i, SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
return GetMonitor(tdc->counter,i,pCon);
|
||||||
|
}
|
||||||
|
return -9999; /* no monitor available */
|
||||||
|
}
|
||||||
|
/*======================================================================*/
|
||||||
|
static float TDCGetTime(pHistDriver self,SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
return GetCountTime(tdc->counter,pCon);
|
||||||
|
}
|
||||||
|
return -9999.99; /* no time available */
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int TDCPause(pHistDriver self, SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
status = disableTdc(tdc);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
return tdc->counter->pDriv->Pause(tdc->counter->pDriv);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=====================================================================*/
|
||||||
|
static int TDCContinue(pHistDriver self, SConnection *pCon){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
status = enableTdc(tdc);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(tdc->counter != NULL){
|
||||||
|
return tdc->counter->pDriv->Continue(tdc->counter->pDriv);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*=======================================================================*/
|
||||||
|
static int TDCFree(pHistDriver self){
|
||||||
|
free(self->pPriv);
|
||||||
|
}
|
||||||
|
/*======================================================================*/
|
||||||
|
static int TDCSetHistogram(pHistDriver self, SConnection *pCon,
|
||||||
|
int i, int iStart, int iEnd, HistInt *pData){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
char pBueffel[256];
|
||||||
|
Ecb_pack data;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"WARNING: SetHistogram can only fill HM with a fill byte %s",
|
||||||
|
"\n using firts value for that");
|
||||||
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
|
||||||
|
data.result = pData[0];
|
||||||
|
status = clearTdc(tdc,data.b.byt0);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*======================================================================*/
|
||||||
|
static int TDCPreset(pHistDriver self, SConnection *pCon, HistInt iVal){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
char pBueffel[256];
|
||||||
|
Ecb_pack data;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
sprintf(pBueffel,
|
||||||
|
"WARNING: Preset can only fill HM with a fill byte %s",
|
||||||
|
"\n using first value for that");
|
||||||
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
|
||||||
|
data.result = iVal;
|
||||||
|
status = clearTdc(tdc,data.b.byt0);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*======================================================================*/
|
||||||
|
static int TDCGetHistogram(pHistDriver self, SConnection *pCon,
|
||||||
|
int bank, int iStart, int length,
|
||||||
|
HistInt *pData){
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
int status;
|
||||||
|
unsigned short address, byteCount;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
tdc = (pTdc)self->pPriv;
|
||||||
|
assert(tdc);
|
||||||
|
|
||||||
|
if(length >= MAXTDCCHANNELS){
|
||||||
|
tdc->errorCode = MAXEXCEEDED;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
|
||||||
|
address = 0;
|
||||||
|
byteCount = length *4;
|
||||||
|
status = ecbDMARead(tdc->tdc,address,pData,byteCount);
|
||||||
|
if(status != 1){
|
||||||
|
tdc->errorCode = COMMERROR;
|
||||||
|
return HWFault;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*====================================================================*/
|
||||||
|
pHistDriver MakeTDCHM(pStringDict pOption){
|
||||||
|
pHistDriver pNew = NULL;
|
||||||
|
pTdc tdc = NULL;
|
||||||
|
|
||||||
|
/* create the general driver */
|
||||||
|
pNew = CreateHistDriver(pOption);
|
||||||
|
if(!pNew)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add our options */
|
||||||
|
StringDictAddPair(pOption,"ecb","blub");
|
||||||
|
StringDictAddPair(pOption,"range","0");
|
||||||
|
StringDictAddPair(pOption,"n","0");
|
||||||
|
StringDictAddPair(pOption,"bank","0");
|
||||||
|
StringDictAddPair(pOption,"mode","HMXY");
|
||||||
|
StringDictAddPair(pOption,"counter","Gwendolin");
|
||||||
|
StringDictAddPair(pOption,"map","9");
|
||||||
|
|
||||||
|
/* initialise our private data structure */
|
||||||
|
tdc = (pTdc)malloc(sizeof(Tdc));
|
||||||
|
if(tdc == NULL){
|
||||||
|
free(pNew);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(tdc,0,sizeof(Tdc));
|
||||||
|
tdc->map = 9;
|
||||||
|
tdc->mode = HMXY;
|
||||||
|
pNew->pPriv = tdc;
|
||||||
|
|
||||||
|
/* configure all those functions */
|
||||||
|
pNew->Configure = TDCConfigure;
|
||||||
|
pNew->Start = TDCStart;
|
||||||
|
pNew->Halt = TDCHalt;
|
||||||
|
pNew->GetCountStatus = TDCCountStatus;
|
||||||
|
pNew->GetError = TDCGetError;
|
||||||
|
pNew->TryAndFixIt = TDCFixIt;
|
||||||
|
pNew->GetData = TDCGetData;
|
||||||
|
pNew->GetHistogram = TDCGetHistogram;
|
||||||
|
pNew->SetHistogram = TDCSetHistogram;
|
||||||
|
pNew->GetMonitor = TDCGetMonitor;
|
||||||
|
pNew->GetTime = TDCGetTime;
|
||||||
|
pNew->Preset = TDCPreset;
|
||||||
|
pNew->FreePrivate = TDCFree;
|
||||||
|
pNew->Pause = TDCPause;
|
||||||
|
pNew->Continue = TDCContinue;
|
||||||
|
|
||||||
|
return pNew;
|
||||||
|
}
|
15
tdchm.h
Normal file
15
tdchm.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
This is a driver for the TDC histogram memory as supplied with the
|
||||||
|
Risoe instruments. This system uses a Z80 processor internally.
|
||||||
|
Communication is via a GPIB interface. For more information on this
|
||||||
|
device consult documentation available from Risoe.
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, February 2003
|
||||||
|
--------------------------------------------------------------------------*/
|
||||||
|
#ifndef TDCHM
|
||||||
|
#define TDCHM
|
||||||
|
|
||||||
|
pHistDriver MakeTDCHM(pStringDict pOption);
|
||||||
|
#endif
|
Reference in New Issue
Block a user