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