Files
sics/faverage.c
cvs db6c355f44 - Enhanced and debugged histogram memory for AMOR
* added PROJECT both in HM and driver code
  * added single detector support.
- Removed several bugs in the AMOR data bit.
- Updated documentation
2001-08-17 14:33:05 +00:00

378 lines
10 KiB
C

/*---------------------------------------------------------------------------
F o c u s A v e r a g e r
A little averager for FOCUS data. Used by the FOCUS status display.
copyright: see copyright.h
Mark Koennecke, October 1998
Updated for additional detector banks
Mark Koennecke, March 2000
Added focusraw command for retrieving single detector banks in support
of the colour mapping part of the FOCUS status display.
Mark Koennecke, July 2001
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <tcl.h>
#include <time.h>
#include "fortify.h"
#include "sics.h"
#include "counter.h"
#include "HistMem.h"
#include "fomerge.h"
#include "faverage.h"
/*
#define DEB 1
*/
/*-------------------------------------------------------------------------*/
typedef struct __FocusAverager {
pObjectDescriptor pDes;
pHistMem pHist;
} FocusAverager, *pFocusAverager;
/*------------------------------------------------------------------------*/
static void KillFA(void *pData)
{
pFocusAverager self = NULL;
self = (pFocusAverager)pData;
if(!self)
return;
if(self->pDes)
DeleteDescriptor(self->pDes);
free(self);
}
/*-------------------------------------------------------------------------*/
int FocusAverageDo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pFocusAverager self = NULL;
int *iData = NULL;
const float *fTimeBin = NULL;
float fVal;
int iLength, iStart, iEnd, iNum, i,ii, iTest, iBufLen, iRet, iVal;
char pBueffel[256];
HistInt *hiData = NULL, *hiPtr;
time_t tStart, tEnd;
int iBank = MIDDLE;
self = (pFocusAverager)pData;
assert(self);
assert(pCon);
assert(pSics);
/* we need two parameters: start and end of averaging */
if(argc < 3)
{
SCWrite(pCon,
"ERROR: insufficient number of parameters for FocusAverage",
eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[1],&iStart);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert %d to integer",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iEnd);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert %d to integer",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* another parameter, if available describes the detector bank
*/
if(argc > 3)
{
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iBank);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert %d to integer",argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
/* how much to do: correct parameters? */
iNum = iEnd - iStart;
if(iNum < 0)
{
SCWrite(pCon,"ERROR: invalid parameters given to FocusAverage",
eError);
return 0;
}
/* may be only one histogram requested */
if(iNum == 0)
iNum = 1;
if(iStart < 0)
{
SCWrite(pCon,"ERROR: invalid parameters given to FocusAverage",
eError);
return 0;
}
#ifdef DEB
printf("Starting averaging ...\n");
fflush(stdout);
tStart = time(NULL);
#endif
/* do work! first retrieve time binning data */
fTimeBin = GetHistTimeBin(self->pHist,&iLength);
assert(fTimeBin);
if(iLength <= 0)
{
SCWrite(pCon,"ERROR: histogram memory inproperly configured",eError);
return 0;
}
/* allocate result data */
iBufLen = (iLength *2 +1)*sizeof(int);
iData = (int *)malloc(iBufLen);
memset(iData,0,iBufLen);
/* get histogram length */
i = getFMdim(iBank);
/* correct iEnd to maximum allowed */
iTest = i;
if(iEnd > iTest -1)
{
iEnd = iTest - 1;
iNum = iEnd - iStart;
if(iNum <= 0)
iNum = 1;
}
#ifdef DEB
printf("Getting histogram....\n");
fflush(stdout);
#endif
hiData = GetHistogramPointer(self->pHist,pCon);
if(hiData == NULL)
{
SCWrite(pCon,"ERROR: failed to read histogram memory data",eError);
free(iData);
return 0;
}
setFMDataPointer(hiData, iLength);
hiData = getFMBankPointer(iBank);
#ifdef DEB
tEnd = time(NULL);
printf("Histogram received in %d seconds\n", tStart - tEnd);
fflush(stdout);
#endif
if(hiData == NULL)
{
SCWrite(pCon,"ERROR: BAD Configuration",eError);
return 0;
}
/* first int: length of things to come */
iData[0] = htonl(iLength);
/* sum up */
for(i = iStart; i < iEnd; i++)
{
hiPtr = hiData + i*iLength;
for(ii = 0; ii < iLength; ii++)
{
iData[ii+1] += hiPtr[ii];
}
}
/* average */
for(i = 1; i < iLength + 1; i++)
{
fVal = (float)iData[i]/(float)iNum;
fVal *= 65536.;
iData[i] = htonl((int)fVal);
}
/* make time binning fixed point */
for(i = 0; i < iLength; i++)
{
fVal = fTimeBin[i]/10.;
fVal *= 65536.;
iData[iLength+1+i] = htonl((int)fVal);
}
#ifdef DEB
printf("Sending averaged data....\n");
fflush(stdout);
#endif
/* finally send out uuencoded */
SCWriteUUencoded(pCon,"FocusAverage",iData,iBufLen);
if(iData)
free(iData);
#ifdef DEB
printf("Averaging finished\n");
fflush(stdout);
#endif
return 1;
}
/*-------------------------------------------------------------------------*/
static int FocusRaw(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pFocusAverager self = NULL;
int *iData = NULL;
int iLength, noTimebin, iRet, i;
char pBueffel[256];
const float *timeBin;
HistInt *hiData = NULL, *hiPtr;
int iBank = MIDDLE;
self = (pFocusAverager)pData;
assert(self);
assert(pCon);
assert(pSics);
/* we need one parameter, the bank to read */
if(argc < 2)
{
SCWrite(pCon,
"ERROR: insufficient number of parameters for FocusRaw",
eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[1],&iBank);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert %d to integer",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
timeBin = GetHistTimeBin(self->pHist,&iLength);
assert(timeBin);
hiData = GetHistogramPointer(self->pHist,pCon);
if(hiData == NULL)
{
SCWrite(pCon,"ERROR: failed to read histogram memory data",eError);
return 0;
}
setFMDataPointer(hiData, iLength);
hiData = getFMBankPointer(iBank);
if(hiData == NULL)
{
SCWrite(pCon,"ERROR: BAD Configuration",eError);
return 0;
}
/* get histogram length */
iLength = getFMdim(iBank);
noTimebin = getFMdim(TIMEBIN);
/* write dimension info*/
sprintf(pBueffel,"focusrawdim = %d = %d", iLength, noTimebin);
SCWrite(pCon,pBueffel,eValue);
/* allocate space */
iData = (int *)malloc((iLength*noTimebin+1)*sizeof(int));
if(iData == NULL)
{
SCWrite(pCon,"ERROR: out of memory in FocusRaw",eError);
return 0;
}
memset(iData,0,noTimebin*iLength*sizeof(int));
/* first int: length of things to come */
iData[0] = htonl(iLength*noTimebin);
/* network byte order for everything */
for(i = 0; i < noTimebin*iLength; i++)
{
iData[i+1] = htonl(hiData[i]);
}
/* send away, zipped */
SCWriteZipped(pCon,"focusraw",iData,(iLength*noTimebin+1)*sizeof(int));
free(iData);
return 1;
}
/*-------------------------------------------------------------------------*/
int MakeFA(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pFocusAverager pNew = NULL;
CommandList *pCom = NULL;
pDummy pDum = NULL;
char pBueffel[256];
int iRet;
assert(pCon);
assert(pSics);
/* we need two parameters: the name for the averager and the histogram
memory
*/
if(argc < 3)
{
SCWrite(pCon,"ERROR: Insufficient number of parameters to MakeFA",
eError);
return 0;
}
/* find histogram memory */
pCom = FindCommand(pSics,argv[2]);
if(!pCom)
{
sprintf(pBueffel,"ERROR: histogram memory %s NOT found!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pDum = (pDummy)pCom->pData;
if(!pDum)
{
sprintf(pBueffel,"ERROR: histogram memory %s INVALID!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(strcmp(pDum->pDescriptor->name,"HistMem") != 0)
{
sprintf(pBueffel,"ERROR: %s is NO histogram memory object!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* we got what we need: set things up */
pNew = (pFocusAverager)malloc(sizeof(FocusAverager));
if(!pNew)
{
SCWrite(pCon,"ERROR: out of memory in MakeFA",eError);
return 0;
}
memset(pNew,0,sizeof(FocusAverager));
pNew->pDes = CreateDescriptor("FocusAverager");
if(!pNew->pDes)
{
SCWrite(pCon,"ERROR: out of memory in MakeFA",eError);
return 0;
}
pNew->pHist = (pHistMem)pDum;
iRet = AddCommand(pSics,argv[1],FocusAverageDo, KillFA, pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon,pBueffel,eError);
KillFA(pNew);
return 0;
}
iRet = AddCommand(pSics,"focusraw",FocusRaw, NULL, pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command focusraw not created");
SCWrite(pCon,pBueffel,eError);
return 0;
}
return 1;
}