- 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
|
||||
@ -10,22 +10,13 @@
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef SICSHISTDRIV
|
||||
#define SICSHISTDRIV
|
||||
#define MAXCHAN 16834
|
||||
#include "hmdata.h"
|
||||
|
||||
|
||||
#line 83 "histogram.w"
|
||||
#line 89 "histogram.w"
|
||||
|
||||
typedef struct __HistDriver {
|
||||
/* configuration data */
|
||||
HistMode eHistMode;
|
||||
OverFlowMode eFlow;
|
||||
int iRank;
|
||||
int iDims[MAXDIM];
|
||||
int nDim;
|
||||
int iLength;
|
||||
int iBinWidth;
|
||||
float fTime[MAXCHAN];
|
||||
int iTimeChan;
|
||||
pHMdata data;
|
||||
/* counting operations data */
|
||||
CounterMode eCount;
|
||||
float fCountPreset;
|
||||
@ -77,17 +68,17 @@
|
||||
void *pPriv;
|
||||
} HistDriver;
|
||||
|
||||
#line 490 "histogram.w"
|
||||
#line 473 "histogram.w"
|
||||
|
||||
|
||||
#line 240 "histogram.w"
|
||||
#line 228 "histogram.w"
|
||||
|
||||
pHistDriver CreateHistDriver(pStringDict pDict);
|
||||
void DeleteHistDriver(pHistDriver self);
|
||||
int HistDriverConfig(pHistDriver self, pStringDict pOpt,
|
||||
SConnection *pCon);
|
||||
|
||||
#line 491 "histogram.w"
|
||||
#line 474 "histogram.w"
|
||||
|
||||
|
||||
#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
|
||||
@ -33,7 +33,7 @@
|
||||
eSANSTOF
|
||||
} HistMode;
|
||||
|
||||
#line 35 "histogram.w"
|
||||
#line 36 "histogram.w"
|
||||
|
||||
typedef enum {
|
||||
eOIgnore,
|
||||
@ -42,22 +42,22 @@
|
||||
eReflect
|
||||
} OverFlowMode;
|
||||
|
||||
#line 471 "histogram.w"
|
||||
#line 454 "histogram.w"
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#line 304 "histogram.w"
|
||||
#line 287 "histogram.w"
|
||||
|
||||
pHistMem CreateHistMemory(char *drivername);
|
||||
void DeleteHistMemory(void *self);
|
||||
|
||||
#line 320 "histogram.w"
|
||||
#line 303 "histogram.w"
|
||||
|
||||
int HistGetOption(pHistMem self, char *name, char *result, int iResultLen);
|
||||
int HistSetOption(pHistMem self, char *name, char *value);
|
||||
int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics);
|
||||
|
||||
#line 348 "histogram.w"
|
||||
#line 331 "histogram.w"
|
||||
|
||||
float GetHistPreset(pHistMem self);
|
||||
int SetHistPreset(pHistMem self, float fVal);
|
||||
@ -72,7 +72,7 @@
|
||||
int HistBlockCount(pHistMem self, SConnection *pCon);
|
||||
|
||||
|
||||
#line 377 "histogram.w"
|
||||
#line 360 "histogram.w"
|
||||
|
||||
int SetHistogram(pHistMem self, SConnection *pCon,
|
||||
int i,int iStart, int iEnd, HistInt *lData);
|
||||
@ -84,7 +84,7 @@
|
||||
HistInt *lData, int iDataLen);
|
||||
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 argc, char *argv[]);
|
||||
@ -93,7 +93,7 @@
|
||||
int argc, char *argv[]);
|
||||
|
||||
|
||||
#line 473 "histogram.w"
|
||||
#line 456 "histogram.w"
|
||||
|
||||
|
||||
#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
|
||||
@ -11,7 +11,7 @@
|
||||
#ifndef SICSHISTMEMINT
|
||||
#define SICSHISTMEMINT
|
||||
|
||||
#line 262 "histogram.w"
|
||||
#line 250 "histogram.w"
|
||||
|
||||
typedef struct __HistMem {
|
||||
pObjectDescriptor pDes;
|
||||
@ -22,14 +22,9 @@
|
||||
pICountable pCountInt;
|
||||
pICallBack pCall;
|
||||
pStringDict pOption;
|
||||
HistInt *iLocalData;
|
||||
int iLocalLength;
|
||||
int iLocalUpdate;
|
||||
time_t tLocal;
|
||||
int iUpdateIntervall;
|
||||
} HistMem;
|
||||
|
||||
#line 506 "histogram.w"
|
||||
#line 489 "histogram.w"
|
||||
|
||||
|
||||
#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 \
|
||||
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.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
|
||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||
|
@ -105,7 +105,7 @@ static long ColliderSetValue(void *pData, SConnection *pCon, float fTarget){
|
||||
*/
|
||||
LLDdelete(self->sequenceList);
|
||||
self->sequenceList = LLDcreate(sizeof(Sequence));
|
||||
self->level = 0;
|
||||
self->level = -1; /* otherwise level 0 will not be started */
|
||||
|
||||
/*
|
||||
evaluate colliderScript
|
||||
|
@ -86,4 +86,3 @@
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
34
ecb.c
34
ecb.c
@ -22,6 +22,7 @@
|
||||
#define ACKN ('\6') /* Acknowledge character */
|
||||
#define READ_BYTES 3
|
||||
#define WRITE_BYTES 4
|
||||
#define DMAREAD 5
|
||||
#define ECB_BYTES 65536L
|
||||
|
||||
typedef union /* Used to swap bytes in 'address' and 'byte_count' */
|
||||
@ -179,6 +180,33 @@ int ecbRead(pECB self, unsigned short address,
|
||||
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,
|
||||
void *buffer, int byteCount){
|
||||
|
||||
@ -317,9 +345,13 @@ int ECBAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
return 0;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"clear") == 0){
|
||||
ecbClear(self);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: ECB does not understand keyword", eError);
|
||||
return 0;
|
||||
|
2
ecb.h
2
ecb.h
@ -32,6 +32,8 @@ typedef struct {
|
||||
void *buffer, int byteCount);
|
||||
int ecbWrite(pECB self, unsigned short address,
|
||||
void *buffer, int byteCount);
|
||||
int ecbDMARead(pECB self, unsigned short address, void *buffer,
|
||||
unsigned short byteCount);
|
||||
void ecbClear(pECB self);
|
||||
int fixECBError(pECB self);
|
||||
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);
|
||||
int ecbWrite(pECB self, unsigned short address,
|
||||
void *buffer, int byteCount);
|
||||
int ecbDMARead(pECB self, unsigned short address, void *buffer,
|
||||
unsigned short byteCount);
|
||||
void ecbClear(pECB self);
|
||||
int fixECBError(pECB self);
|
||||
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
|
||||
buffer. Please note that address in this contest is an address in the
|
||||
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
|
||||
address. Please note that address in this contest is an address in the
|
||||
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
|
||||
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
|
||||
SICS interpreter for the ECB is represented through the ECB Factory
|
||||
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 DEG2STEP 14 /* conversion factor from degree to encoder digits */
|
||||
#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 -------------------------*/
|
||||
#define MAX_ENCODER 40
|
||||
@ -411,7 +412,8 @@ static int loadMulti(pECBMotDriv self){
|
||||
mult_chan = (unsigned char)rint(ObVal(self->driverPar,MULTCHAN));
|
||||
in.b = -1; /* SET_PORT */
|
||||
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);
|
||||
if(status != 1){
|
||||
self->errorCode = COMMERROR;
|
||||
@ -557,7 +559,7 @@ static int controlMotor(pECBMotDriv self, int enable){
|
||||
*/
|
||||
in.e = 8;
|
||||
in.b = 11; /* set control signal */
|
||||
in.c = -self->ecbIndex;
|
||||
in.c = self->ecbIndex;
|
||||
status = ecbExecute(self->ecb,MOPARA,in,&out);
|
||||
if(status != 1){
|
||||
self->errorCode = COMMERROR;
|
||||
@ -698,9 +700,6 @@ static int checkStatusResponse(pECBMotDriv self, Z80_reg out){
|
||||
return HWFault;
|
||||
} else if(out.b & 32){
|
||||
return HWBusy;
|
||||
} else if(out.b & 64){
|
||||
self->errorCode = ECBINHIBIT;
|
||||
return HWFault;
|
||||
} else if(out.b & 16){
|
||||
self->errorCode = ECBLIMIT;
|
||||
return HWFault;
|
||||
@ -1142,6 +1141,7 @@ static void initializeParameters(pECBMotDriv self){
|
||||
ObParInit(self->driverPar,STEPS2DEG,"step2deg",1,usMugger);
|
||||
ObParInit(self->driverPar,DEG2STEP,"step2dig",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! */
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
208
histdriv.c
208
histdriv.c
@ -64,17 +64,15 @@
|
||||
}
|
||||
memset(pNew,0,sizeof(HistDriver));
|
||||
|
||||
pNew->data = makeHMData();
|
||||
if(!pNew->data)
|
||||
{
|
||||
free(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialise defaults */
|
||||
pNew->eHistMode = eHNormal;
|
||||
StringDictAddPair(pOption,"histmode","normal");
|
||||
pNew->eFlow = eOCeil;
|
||||
StringDictAddPair(pOption,"overflowmode","ceil");
|
||||
pNew->iRank = 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++)
|
||||
{
|
||||
sprintf(pDim,"dim%1.1d",i);
|
||||
@ -84,8 +82,6 @@
|
||||
pNew->eCount = eTimer;
|
||||
pNew->iReconfig = 1;
|
||||
pNew->iUpdate = 0;
|
||||
pNew->iTimeChan = 1;
|
||||
|
||||
|
||||
return pNew;
|
||||
}
|
||||
@ -98,59 +94,12 @@
|
||||
{
|
||||
self->FreePrivate(self);
|
||||
}
|
||||
if(self->data)
|
||||
{
|
||||
killHMData(self->data);
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -166,138 +115,5 @@
|
||||
assert(pOpt);
|
||||
assert(pCon);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
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;
|
||||
return configureHMdata(self->data,pOpt,pCon);
|
||||
}
|
||||
|
482
histmem.c
482
histmem.c
@ -62,6 +62,7 @@
|
||||
#include "dynstring.h"
|
||||
#include "event.h"
|
||||
#include "status.h"
|
||||
#include "tdchm.h"
|
||||
/*
|
||||
#define LOADDEBUG 1
|
||||
*/
|
||||
@ -106,12 +107,13 @@
|
||||
fprintf(fd,"%s preset %f\n",name,fVal);
|
||||
|
||||
/* time binning if TOF */
|
||||
if(self->pDriv->eHistMode == eHTOF)
|
||||
if(isInTOFMode(self->pDriv->data))
|
||||
{
|
||||
fprintf(fd,"%s genbin %f %f %d\n",
|
||||
name, self->pDriv->fTime[0],
|
||||
self->pDriv->fTime[1] - self->pDriv->fTime[0],
|
||||
self->pDriv->iTimeChan);
|
||||
name, self->pDriv->data->timeBinning[0],
|
||||
self->pDriv->data->timeBinning[1] -
|
||||
self->pDriv->data->timeBinning[0],
|
||||
self->pDriv->data->nTimeChan);
|
||||
fprintf(fd,"%s init\n",name);
|
||||
}
|
||||
|
||||
@ -167,9 +169,7 @@
|
||||
iRet = self->pDriv->Start(self->pDriv, pCon);
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
self->pDriv->iUpdate = 1;
|
||||
self->iLocalUpdate = 1;
|
||||
self->tLocal = time(NULL) + self->iUpdateIntervall;
|
||||
updateHMData(self->pDriv->data);
|
||||
return iRet;
|
||||
}
|
||||
else
|
||||
@ -214,7 +214,7 @@
|
||||
iRet = self->pDriv->Pause(self->pDriv, pCon);
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
self->pDriv->iUpdate = 1;
|
||||
updateHMData(self->pDriv->data);
|
||||
return iRet;
|
||||
}
|
||||
else
|
||||
@ -259,7 +259,7 @@
|
||||
iRet = self->pDriv->Continue(self->pDriv, pCon);
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
self->pDriv->iUpdate = 1;
|
||||
updateHMData(self->pDriv->data);
|
||||
return iRet;
|
||||
}
|
||||
else
|
||||
@ -312,20 +312,19 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
self->iLocalUpdate = 1;
|
||||
updateHMData(self->pDriv->data);
|
||||
return HWBusy;
|
||||
}
|
||||
}
|
||||
if(eCt == HWBusy)
|
||||
self->iLocalUpdate = 1;
|
||||
updateHMData(self->pDriv->data);
|
||||
|
||||
if(eCt == HWIdle)
|
||||
{
|
||||
/* force an update of local histogram data with next
|
||||
GetHistogram
|
||||
*/
|
||||
self->iLocalUpdate = 1;
|
||||
self->tLocal = 0;
|
||||
updateHMData(self->pDriv->data);
|
||||
}
|
||||
|
||||
return eCt;
|
||||
@ -426,11 +425,6 @@
|
||||
pNew->pCountInt->Halt = HistHalt;
|
||||
pNew->pCountInt->Pause = HistPause;
|
||||
pNew->pCountInt->Continue = HistContinue;
|
||||
pNew->iLocalData = NULL;
|
||||
pNew->iLocalLength = 0;
|
||||
pNew->iUpdateIntervall = 0;
|
||||
pNew->iLocalUpdate = 1;
|
||||
pNew->tLocal = 0;
|
||||
|
||||
/* initialise options dictionary */
|
||||
pNew->pOption = CreateStringDict();
|
||||
@ -451,6 +445,10 @@
|
||||
{
|
||||
pNew->pDriv = CreateSINQDriver(pNew->pOption);
|
||||
}
|
||||
else if(strcmp(driver,"tdc") == 0)
|
||||
{
|
||||
pNew->pDriv = MakeTDCHM(pNew->pOption);
|
||||
}
|
||||
else /* no driver found */
|
||||
{
|
||||
DeleteDescriptor(pNew->pDes);
|
||||
@ -494,10 +492,6 @@
|
||||
{
|
||||
DeleteStringDict(self->pOption);
|
||||
}
|
||||
if(self->iLocalData)
|
||||
{
|
||||
free(self->iLocalData);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@ -568,22 +562,6 @@
|
||||
assert(self);
|
||||
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);
|
||||
if(!iRet)
|
||||
{
|
||||
@ -596,8 +574,6 @@
|
||||
SCWrite(pCon,"ERROR: failed to configure histogram memory",eError);
|
||||
return 0;
|
||||
}
|
||||
self->iLocalUpdate = 1;
|
||||
self->tLocal = 0;
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -642,124 +618,23 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim)
|
||||
{
|
||||
int i, myDim;
|
||||
|
||||
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[i] = self->pDriv->iDims[i];
|
||||
myDim++;
|
||||
iDim[*nDim] = getNoOfTimebins(self->pDriv->data);
|
||||
*nDim ++;
|
||||
}
|
||||
}
|
||||
if(self->pDriv->eHistMode == eHTOF
|
||||
|| self->pDriv->eHistMode == ePSD
|
||||
|| self->pDriv->eHistMode == eSANSTOF)
|
||||
{
|
||||
iDim[myDim] = self->pDriv->iTimeChan;
|
||||
myDim++;
|
||||
}
|
||||
*nDim = myDim;
|
||||
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,
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
return sumHMDataRectangle(self,pCon,iStart,iEnd);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CounterMode GetHistCountMode(pHistMem self)
|
||||
@ -806,15 +681,15 @@
|
||||
const float *GetHistTimeBin(pHistMem self, int *iLength)
|
||||
{
|
||||
assert(self);
|
||||
*iLength = self->pDriv->iTimeChan;
|
||||
return self->pDriv->fTime;
|
||||
*iLength = getNoOfTimebins(self->pDriv->data);
|
||||
return getTimeBinning(self->pDriv->data);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int GetHistLength(pHistMem self)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
return self->pDriv->iRank*self->pDriv->iLength;
|
||||
return getHMDataLength(self->pDriv->data);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
float GetHistCountTime(pHistMem self, SConnection *pCon)
|
||||
@ -898,9 +773,7 @@
|
||||
i,iStart,iEnd,lData);
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
self->iLocalUpdate = 1;
|
||||
self->tLocal = 0;
|
||||
self->pDriv->iUpdate = 0;
|
||||
updateHMData(self->pDriv->data);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -921,10 +794,6 @@
|
||||
int GetHistogram(pHistMem self, SConnection *pCon,
|
||||
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);
|
||||
|
||||
if(!self->iInit)
|
||||
@ -933,75 +802,12 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the full histogram if an update is needed */
|
||||
if( (self->iLocalUpdate) && (time(NULL) > self->tLocal) )
|
||||
if(iEnd > iDataLen/sizeof(HistInt))
|
||||
{
|
||||
#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;
|
||||
SCWrite(pCon,"WARNING: truncating request to fit data space",eWarning);
|
||||
iEnd = (iDataLen/sizeof(HistInt)) - 1;
|
||||
}
|
||||
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;
|
||||
return getHMDataHistogram(self,pCon,i,iStart,iEnd,lData);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
int GetHistogramDirect(pHistMem self, SConnection *pCon,
|
||||
@ -1048,10 +854,6 @@
|
||||
/*-----------------------------------------------------------------------*/
|
||||
HistInt *GetHistogramPointer(pHistMem self, SConnection *pCon)
|
||||
{
|
||||
int ii, iErr, iRet, iCopy;
|
||||
char pBueffel[512], pError[80];
|
||||
HistInt *lHist = NULL;
|
||||
|
||||
assert(self);
|
||||
|
||||
if(!self->iInit)
|
||||
@ -1060,67 +862,7 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(self->iLocalData == NULL)
|
||||
{
|
||||
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;
|
||||
return getHMDataBufferPointer(self,pCon);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal)
|
||||
@ -1142,9 +884,7 @@
|
||||
iRet = self->pDriv->Preset(self->pDriv,pCon,lVal);
|
||||
if(iRet == OKOK)
|
||||
{
|
||||
self->pDriv->iUpdate = 0;
|
||||
self->iLocalUpdate = 1;
|
||||
self->tLocal = 0;
|
||||
updateHMData(self->pDriv->data);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -1161,6 +901,7 @@
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
|
||||
{
|
||||
@ -1183,6 +924,22 @@
|
||||
}
|
||||
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 argc, char *argv[])
|
||||
@ -1276,7 +1033,8 @@
|
||||
/* authorise */
|
||||
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]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
@ -1304,7 +1062,6 @@
|
||||
fVal = atof(argv[2]);
|
||||
if(!SCMatchRights(pCon,self->iAccess))
|
||||
{
|
||||
SCWrite(pCon,"ERROR: you are not priviledged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = SetHistPreset(self,fVal);
|
||||
@ -1324,7 +1081,6 @@
|
||||
{
|
||||
if(!SCMatchRights(pCon,self->iAccess))
|
||||
{
|
||||
SCWrite(pCon,"ERROR: you are not priviledged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
self->iExponent = atoi(argv[2]);
|
||||
@ -1346,7 +1102,6 @@
|
||||
strtolower(argv[2]);
|
||||
if(!SCMatchRights(pCon,self->iAccess))
|
||||
{
|
||||
SCWrite(pCon,"ERROR: you are not priviledged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
if(strcmp(argv[2],"timer") == 0)
|
||||
@ -1386,8 +1141,6 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: you are not privileged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1410,8 +1163,6 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: you are not privileged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1429,8 +1180,6 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: you are not privileged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1448,8 +1197,6 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: you are not privileged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -1458,8 +1205,6 @@
|
||||
/* check user rights */
|
||||
if(!SCMatchRights(pCon,self->iAccess))
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: you are not priviledged for attempted operation",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1491,15 +1236,6 @@
|
||||
}
|
||||
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 */
|
||||
iStart = 0;
|
||||
if(argc > 3 )
|
||||
@ -1514,19 +1250,10 @@
|
||||
iStart = 0;
|
||||
}
|
||||
|
||||
/* optional iEnd, default to maximum */
|
||||
iEnd = self->pDriv->iLength;
|
||||
if(argc > 4)
|
||||
{
|
||||
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);
|
||||
if(argc > 4){
|
||||
iEnd = checkHMEnd(self,argv[4]);
|
||||
} else {
|
||||
iEnd = checkHMEnd(self,NULL);
|
||||
}
|
||||
|
||||
/* allocate data storage and get it */
|
||||
@ -1577,15 +1304,6 @@
|
||||
}
|
||||
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 */
|
||||
iStart = 0;
|
||||
if(argc > 3 )
|
||||
@ -1600,19 +1318,10 @@
|
||||
iStart = 0;
|
||||
}
|
||||
|
||||
/* optional iEnd, default to maximum */
|
||||
iEnd = self->pDriv->iLength;
|
||||
if(argc > 4)
|
||||
{
|
||||
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);
|
||||
if(argc > 4){
|
||||
iEnd = checkHMEnd(self,argv[4]);
|
||||
} else {
|
||||
iEnd = checkHMEnd(self,NULL);
|
||||
}
|
||||
|
||||
/* allocate data storage and get it */
|
||||
@ -1659,15 +1368,6 @@
|
||||
}
|
||||
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 */
|
||||
iStart = 0;
|
||||
if(argc > 3 )
|
||||
@ -1678,23 +1378,15 @@
|
||||
/* check iStart */
|
||||
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;
|
||||
}
|
||||
|
||||
/* optional iEnd, default to maximum */
|
||||
iEnd = self->pDriv->iLength;
|
||||
if(argc > 4)
|
||||
{
|
||||
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);
|
||||
if(argc > 4){
|
||||
iEnd = checkHMEnd(self,argv[4]);
|
||||
} else {
|
||||
iEnd = checkHMEnd(self,NULL);
|
||||
}
|
||||
|
||||
/* allocate data storage and get it */
|
||||
@ -1731,7 +1423,8 @@
|
||||
else if(strcmp(argv[1],"notimebin") == 0)
|
||||
{
|
||||
sprintf(pBueffel,
|
||||
"%s.notimebin = %d",argv[0], self->pDriv->iTimeChan);
|
||||
"%s.notimebin = %d",argv[0],
|
||||
getNoOfTimebins(self->pDriv->data));
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
@ -1740,9 +1433,9 @@
|
||||
{
|
||||
Tcl_DStringInit(&tResult);
|
||||
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);
|
||||
}
|
||||
/* Write it */
|
||||
@ -1757,7 +1450,6 @@
|
||||
{
|
||||
if(!SCMatchRights(pCon,usMugger))
|
||||
{
|
||||
SCWrite(pCon,"ERROR: you are not authorised for this operation",eError);
|
||||
return 0;
|
||||
}
|
||||
if(GetStatus() == eCounting)
|
||||
@ -1795,22 +1487,13 @@
|
||||
/* do it */
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < iNum; i++)
|
||||
{
|
||||
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;
|
||||
genTimeBinning(self->pDriv->data,
|
||||
(float)dStart,(float)dStep,iNum);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
@ -1819,7 +1502,6 @@
|
||||
{
|
||||
if(!SCMatchRights(pCon,usMugger))
|
||||
{
|
||||
SCWrite(pCon,"ERROR: yoy are not authorised for this operation",eError);
|
||||
return 0;
|
||||
}
|
||||
if(argc < 4)
|
||||
@ -1843,20 +1525,11 @@
|
||||
}
|
||||
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;
|
||||
}
|
||||
self->pDriv->fTime[iNum] = 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;
|
||||
}
|
||||
setTimeBin(self->pDriv->data,iNum, (float)dStep);
|
||||
self->iInit = 0;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
@ -1864,8 +1537,7 @@
|
||||
/* clear time bin info */
|
||||
else if(strcmp(argv[1],"clearbin") == 0)
|
||||
{
|
||||
self->pDriv->iTimeChan = 0;
|
||||
self->iInit = 1;
|
||||
clearTimeBinning(self->pDriv->data);
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
/*-------- sum */
|
||||
@ -1924,5 +1596,3 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ $\langle$Modes {\footnotesize ?}$\rangle\equiv$
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\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
|
||||
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
|
||||
@ -101,6 +102,11 @@ command. Then on initialisation first the logical histogram memory
|
||||
evaluates the general options and then the driver in its Config
|
||||
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}
|
||||
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
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct __HistDriver {@\\
|
||||
\mbox{}\verb@ /* configuration 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@ pHMdata data;@\\
|
||||
\mbox{}\verb@ /* counting operations data */@\\
|
||||
\mbox{}\verb@ CounterMode eCount;@\\
|
||||
\mbox{}\verb@ float fCountPreset;@\\
|
||||
@ -185,15 +182,6 @@ $\langle$HistType {\footnotesize ?}$\rangle\equiv$
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
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.
|
||||
|
||||
@ -326,11 +314,6 @@ $\langle$HistST {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ pICountable pCountInt;@\\
|
||||
\mbox{}\verb@ pICallBack pCall;@\\
|
||||
\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@@$\diamond$
|
||||
\end{list}
|
||||
@ -630,7 +613,7 @@ following.
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSHISTDRIV@\\
|
||||
\mbox{}\verb@#define SICSHISTDRIV@\\
|
||||
\mbox{}\verb@#define MAXCHAN 16834 @\\
|
||||
\mbox{}\verb@#include "hmdata.h"@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\langle$HistType {\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
|
||||
} HistMode;
|
||||
@}
|
||||
These modes are specific to the SINQ histogram memory.
|
||||
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
|
||||
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
|
||||
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}
|
||||
Adhering to the Sics paradigm of dividing any device into a logical device
|
||||
@ -82,16 +88,7 @@ definition:
|
||||
|
||||
@d HistType @{
|
||||
typedef struct __HistDriver {
|
||||
/* configuration data */
|
||||
HistMode eHistMode;
|
||||
OverFlowMode eFlow;
|
||||
int iRank;
|
||||
int iDims[MAXDIM];
|
||||
int nDim;
|
||||
int iLength;
|
||||
int iBinWidth;
|
||||
float fTime[MAXCHAN];
|
||||
int iTimeChan;
|
||||
pHMdata data;
|
||||
/* counting operations data */
|
||||
CounterMode eCount;
|
||||
float fCountPreset;
|
||||
@ -145,15 +142,6 @@ definition:
|
||||
@}
|
||||
|
||||
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.
|
||||
|
||||
@ -269,11 +257,6 @@ histogram memory object is fairly simple:
|
||||
pICountable pCountInt;
|
||||
pICallBack pCall;
|
||||
pStringDict pOption;
|
||||
HistInt *iLocalData;
|
||||
int iLocalLength;
|
||||
int iLocalUpdate;
|
||||
time_t tLocal;
|
||||
int iUpdateIntervall;
|
||||
} HistMem;
|
||||
@}
|
||||
According to the general Sics object interface the first field is the object
|
||||
@ -485,7 +468,7 @@ following.
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifndef SICSHISTDRIV
|
||||
#define SICSHISTDRIV
|
||||
#define MAXCHAN 16834
|
||||
#include "hmdata.h"
|
||||
|
||||
@< HistType@>
|
||||
@< HistDrivProt @>
|
||||
|
11
histsim.c
11
histsim.c
@ -58,7 +58,7 @@
|
||||
*/
|
||||
static int iSet = 0;
|
||||
static HistInt iSetVal = 0;
|
||||
|
||||
static HistMode eHistMode;
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static int SimConfig(pHistDriver self, SConnection *pCon,
|
||||
pStringDict pOption, SicsInterp *pSics)
|
||||
@ -67,14 +67,13 @@
|
||||
char pData[132];
|
||||
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;
|
||||
self->iLength = iLength;
|
||||
iLength *= self->data->nTimeChan;
|
||||
}
|
||||
|
||||
/*
|
||||
|
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;
|
||||
long (*oldSet)(void *pmotorData, SConnection *pCon, float fValue);
|
||||
pIDrivable pDriv = NULL;
|
||||
char pBueffel[132];
|
||||
|
||||
|
||||
assert(self);
|
||||
@ -107,6 +108,9 @@ int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
|
||||
self->motorData,
|
||||
pCon,
|
||||
fValue);
|
||||
sprintf(pBueffel,"anticollision started %s to %f",self->motorName,
|
||||
fValue);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
|
||||
pDriv->SetValue = oldSet;
|
||||
self->iActive = 1;
|
||||
|
155
sicsstat.tcl
155
sicsstat.tcl
@ -1,22 +1,139 @@
|
||||
# Counter counter
|
||||
counter SetPreset 60.000000
|
||||
counter SetMode Timer
|
||||
# Motor a77
|
||||
a77 sign 1.000000
|
||||
a77 SoftZero 0.000000
|
||||
a77 SoftLowerLim -30.000000
|
||||
a77 SoftUpperLim 30.000000
|
||||
a77 Fixed -1.000000
|
||||
a77 InterruptMode 0.000000
|
||||
a77 AccessCode 2.000000
|
||||
# Motor 2t
|
||||
2t sign 1.000000
|
||||
2t SoftZero 0.000000
|
||||
2t SoftLowerLim -120.000000
|
||||
2t SoftUpperLim 120.000000
|
||||
2t Fixed -1.000000
|
||||
2t InterruptMode 0.000000
|
||||
2t AccessCode 2.000000
|
||||
# Motor atz
|
||||
atz sign 1.000000
|
||||
atz SoftZero 0.000000
|
||||
atz SoftLowerLim -3900.000000
|
||||
atz SoftUpperLim 0.000000
|
||||
atz Fixed -1.000000
|
||||
atz InterruptMode 0.000000
|
||||
atz AccessCode 2.000000
|
||||
# Motor az1
|
||||
az1 sign 1.000000
|
||||
az1 SoftZero 0.000000
|
||||
az1 SoftLowerLim -3900.000000
|
||||
az1 SoftUpperLim 0.000000
|
||||
az1 Fixed -1.000000
|
||||
az1 InterruptMode 0.000000
|
||||
az1 AccessCode 2.000000
|
||||
# Motor dv
|
||||
dv sign 1.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 setAccess 2
|
||||
comment UNKNOWN
|
||||
|
212
sinqhmdriv.c
212
sinqhmdriv.c
@ -68,6 +68,57 @@
|
||||
self->iLastHMError = 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
|
||||
is configured and a client connection will be built. Configure requires,
|
||||
@ -80,14 +131,14 @@
|
||||
SinqHMDriv *pInternal;
|
||||
int status, iMode;
|
||||
char pError[132];
|
||||
char pHMComputer[256];
|
||||
char pHMComputer[256], pValue[80], pBueffel[256];
|
||||
float fVal;
|
||||
char pcCounter[256];
|
||||
CommandList *pCom = NULL;
|
||||
int iStart = 0;
|
||||
int iInit = 0, i;
|
||||
int iInit = 0, i, iRet;
|
||||
int xOff, xFac, yOff, yFac;
|
||||
int iPort;
|
||||
int iPort, iLength;
|
||||
|
||||
assert(self);
|
||||
assert(self->pPriv);
|
||||
@ -97,9 +148,70 @@
|
||||
pInternal = (SinqHMDriv *)self->pPriv;
|
||||
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 */
|
||||
if( (self->iBinWidth != 1) && (self->iBinWidth != 2)
|
||||
&& (self->iBinWidth != 4))
|
||||
if( (pInternal->iBinWidth != 1) && (pInternal->iBinWidth != 2)
|
||||
&& (pInternal->iBinWidth != 4))
|
||||
{
|
||||
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",pCon);
|
||||
return 0;
|
||||
@ -137,7 +249,7 @@
|
||||
pCom = FindCommand(pSics,pcCounter);
|
||||
if(!pCom)
|
||||
{
|
||||
PrintHMError("WARNING: no EL737 counter for HM found! ",
|
||||
PrintHMError("WARNING: no counter for HM found! ",
|
||||
pCon);
|
||||
pInternal->pCounter = NULL;
|
||||
}
|
||||
@ -147,7 +259,7 @@
|
||||
if(!pInternal->pCounter->pDes->GetInterface(pInternal->pCounter,
|
||||
COUNTID))
|
||||
{
|
||||
PrintHMError("EL737 counter for histogram memory is invalid",
|
||||
PrintHMError("Counter for histogram memory is invalid",
|
||||
pCon);
|
||||
return 0;
|
||||
}
|
||||
@ -170,8 +282,10 @@
|
||||
/* in any case let us propagate the state of affairs to
|
||||
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
|
||||
@ -205,8 +319,8 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( (self->iBinWidth != 1) && (self->iBinWidth != 2)
|
||||
&& (self->iBinWidth != 4))
|
||||
if( (pInternal->iBinWidth != 1) && (pInternal->iBinWidth != 2)
|
||||
&& (pInternal->iBinWidth != 4))
|
||||
{
|
||||
PrintHMError("Unsuported BinWidth specified, 1,2,4 are permissable",
|
||||
pCon);
|
||||
@ -215,7 +329,7 @@ pCon);
|
||||
|
||||
|
||||
/* configure */
|
||||
switch(self->eHistMode)
|
||||
switch(pInternal->eHistMode)
|
||||
{
|
||||
case eHTransparent:
|
||||
iMode = SQHM__TRANS;
|
||||
@ -226,22 +340,25 @@ pCon);
|
||||
case eHTOF:
|
||||
iMode = SQHM__TOF;
|
||||
/* recalculate some parameters */
|
||||
self->iLength = 1;
|
||||
for(i = 0; i < self->iRank; i++)
|
||||
iLength = 1;
|
||||
for(i = 0; i < self->data->rank; i++)
|
||||
{
|
||||
self->iLength *= self->iDims[i];
|
||||
iLength *= self->data->iDim[i];
|
||||
}
|
||||
self->iLength *= self->iTimeChan;
|
||||
SINQHMDefineBank(pInternal->pMaster,0,0,self->iDims[0],
|
||||
self->fTime,self->iTimeChan);
|
||||
iLength *= self->data->nTimeChan;
|
||||
SINQHMDefineBank(pInternal->pMaster,0,0,self->data->iDim[0],
|
||||
self->data->timeBinning,
|
||||
self->data->nTimeChan);
|
||||
break;
|
||||
case eSANSTOF:
|
||||
iMode = SQHM__TOF;
|
||||
self->iLength = self->iDims[0]*self->iDims[1];
|
||||
self->iLength *= self->iTimeChan;
|
||||
iLength = self->data->iDim[0]*self->data->iDim[1];
|
||||
iLength *= self->data->nTimeChan;
|
||||
SINQHMDefineBank(pInternal->pMaster,0,0,
|
||||
(self->iDims[0]*self->iDims[1]) + 3,
|
||||
self->fTime,self->iTimeChan);
|
||||
(self->data->iDim[0]*self->data->iDim[1])
|
||||
+ 3,
|
||||
self->data->timeBinning,
|
||||
self->data->nTimeChan);
|
||||
break;
|
||||
case eHStrobo:
|
||||
iMode = SQHM__HM_PSD | SQHM__STROBO;
|
||||
@ -256,7 +373,7 @@ pCon);
|
||||
PrintHMError("Unsupported mode requested",pCon);
|
||||
return 0;
|
||||
}
|
||||
switch(self->eFlow)
|
||||
switch(pInternal->eFlow)
|
||||
{
|
||||
case eOIgnore:
|
||||
iMode = iMode | SQHM__BO_IGN;
|
||||
@ -274,13 +391,13 @@ pCon);
|
||||
PrintHMError("Unsupported overflowmode requested",pCon);
|
||||
return 0;
|
||||
}
|
||||
if(self->eHistMode != ePSD)
|
||||
if(pInternal->eHistMode != ePSD)
|
||||
{
|
||||
status = SINQHMConfigure(pInternal->pMaster,
|
||||
iMode,
|
||||
self->iRank,
|
||||
self->iLength,
|
||||
self->iBinWidth,
|
||||
self->data->rank,
|
||||
getHMDataLength(self->data),
|
||||
pInternal->iBinWidth,
|
||||
0,0);
|
||||
}
|
||||
else
|
||||
@ -320,15 +437,15 @@ pCon);
|
||||
/* xSize and ySize are supposed to be in dim */
|
||||
status = SINQHMConfigurePSD(pInternal->pMaster,
|
||||
iMode,
|
||||
self->iDims[0],
|
||||
self->data->iDim[0],
|
||||
xOff,
|
||||
xFac,
|
||||
self->iDims[1],
|
||||
self->data->iDim[1],
|
||||
yOff,
|
||||
yFac,
|
||||
self->iBinWidth,
|
||||
self->fTime,
|
||||
self->iTimeChan);
|
||||
pInternal->iBinWidth,
|
||||
self->data->timeBinning,
|
||||
self->data->nTimeChan);
|
||||
}
|
||||
|
||||
if(status < 0)
|
||||
@ -380,15 +497,17 @@ pCon);
|
||||
}
|
||||
|
||||
/* 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
|
||||
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);
|
||||
}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);
|
||||
@ -745,8 +864,8 @@ pCon);
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* we do not need to do a lot of copying when datasizes match! */
|
||||
iByte = (iEnd - iStart) * self->iBinWidth;
|
||||
if(self->iBinWidth == sizeof(HistInt))
|
||||
iByte = (iEnd - iStart) * pInternal->iBinWidth;
|
||||
if(pInternal->iBinWidth == sizeof(HistInt))
|
||||
{
|
||||
/* read HM */
|
||||
status = SINQHMRead(pInternal->pMaster,
|
||||
@ -779,7 +898,7 @@ pCon);
|
||||
}
|
||||
|
||||
/* convert to correct datasize */
|
||||
switch(self->iBinWidth)
|
||||
switch(pInternal->iBinWidth)
|
||||
{
|
||||
case 1:
|
||||
pPtr = (char *)pData;
|
||||
@ -831,7 +950,7 @@ pCon);
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* allocate storage */
|
||||
iByte = iEnd * self->iBinWidth;
|
||||
iByte = iEnd * pInternal->iBinWidth;
|
||||
pData = (void *)malloc(iByte*sizeof(char));
|
||||
if(!pData)
|
||||
{
|
||||
@ -841,7 +960,7 @@ pCon);
|
||||
memset(pData,0,iByte);
|
||||
|
||||
/* convert from long to supported binwidth */
|
||||
switch(self->iBinWidth)
|
||||
switch(pInternal->iBinWidth)
|
||||
{
|
||||
case 1:
|
||||
pPtr = (char *)pData;
|
||||
@ -926,10 +1045,10 @@ pCon);
|
||||
pInternal = self->pPriv;
|
||||
|
||||
/* get memory */
|
||||
if(self->eHistMode == ePSD && self->iTimeChan > 2){
|
||||
nHist = self->iDims[0]*self->iDims[1]*self->iTimeChan;
|
||||
if(pInternal->eHistMode == ePSD && self->data->nTimeChan > 2){
|
||||
nHist = self->data->iDim[0]*self->data->iDim[1]*self->data->nTimeChan;
|
||||
} else {
|
||||
nHist = self->iRank*self->iLength;
|
||||
nHist = getHMDataLength(self->data);
|
||||
}
|
||||
plData = (HistInt *)malloc(nHist*sizeof(HistInt));
|
||||
if(!plData)
|
||||
@ -989,6 +1108,9 @@ pCon);
|
||||
StringDictAddPair(pOption,"yoff","100");
|
||||
StringDictAddPair(pOption,"yfac","10");
|
||||
StringDictAddPair(pOption,"init","1");
|
||||
StringDictAddPair(pOption,"histmode","normal");
|
||||
StringDictAddPair(pOption,"overflowmode","ceil");
|
||||
StringDictAddPair(pOption,"binwidth","4");
|
||||
|
||||
/* initialise our private data structure */
|
||||
pInternal = (SinqHMDriv *)malloc(sizeof(SinqHMDriv));
|
||||
@ -999,6 +1121,10 @@ pCon);
|
||||
}
|
||||
memset(pInternal,0,sizeof(SinqHMDriv));
|
||||
pNew->pPriv = pInternal;
|
||||
pInternal->eHistMode = eHNormal;
|
||||
pInternal->eFlow = eOCeil;
|
||||
pInternal->iBinWidth = 4;
|
||||
|
||||
|
||||
/* configure all those functions */
|
||||
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
|
||||
@ -21,18 +21,21 @@
|
||||
pSINQHM pMaster;
|
||||
int iLastHMError;
|
||||
int iLastCTError;
|
||||
HistMode eHistMode;
|
||||
int iBinWidth;
|
||||
OverFlowMode eFlow;
|
||||
} SinqHMDriv;
|
||||
|
||||
#line 73 "sinqhmdriv.w"
|
||||
#line 76 "sinqhmdriv.w"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#line 55 "sinqhmdriv.w"
|
||||
#line 58 "sinqhmdriv.w"
|
||||
|
||||
pHistDriver CreateSINQDriver(pStringDict pOption);
|
||||
int isSINQHMDriv(pHistDriver test);
|
||||
|
||||
#line 75 "sinqhmdriv.w"
|
||||
#line 78 "sinqhmdriv.w"
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -30,6 +30,9 @@ $\langle$SQType {\footnotesize ?}$\rangle\equiv$
|
||||
\mbox{}\verb@ pSINQHM pMaster;@\\
|
||||
\mbox{}\verb@ int iLastHMError;@\\
|
||||
\mbox{}\verb@ int iLastCTError;@\\
|
||||
\mbox{}\verb@ HistMode eHistMode;@\\
|
||||
\mbox{}\verb@ int iBinWidth;@\\
|
||||
\mbox{}\verb@ OverFlowMode eFlow;@\\
|
||||
\mbox{}\verb@ } SinqHMDriv;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
|
@ -25,6 +25,9 @@ already reflected by the driver private data structure:
|
||||
pSINQHM pMaster;
|
||||
int iLastHMError;
|
||||
int iLastCTError;
|
||||
HistMode eHistMode;
|
||||
int iBinWidth;
|
||||
OverFlowMode eFlow;
|
||||
} 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