Files
sics/fowrite.c
cvs bde19bb973 - Fixes to HM code for AMOR TOF
- A couple of TAS fixes
- o2t was fixed to work with any drivable
- FOCUS was mended to include beam monitor in data file
2002-07-19 15:09:21 +00:00

1007 lines
30 KiB
C

/*---------------------------------------------------------------------------
F O W R I T E
FOCUS data writing object.
copyright: see copyright.h
Mark Koennecke, November 1998
Added code for three detector banks.
Mark Koennecke, March 2000
-----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <tcl.h>
/* avoid irritating compiler warning M.Z.08.2001 */
#undef VOID
#include "fortify.h"
#include "sics.h"
#include "event.h"
#include "counter.h"
#include "HistMem.h"
#include "nxdict.h"
#include "nxutil.h"
#include "motor.h"
#include "selector.h"
#include "fowrite.h"
#include "scan.h"
#include "sicsvar.h"
#include "fitcenter.h"
#include "fomerge.h"
/* the name of the SICS chopper controller object */
#define CHOPPERNAME "choco"
/*--------- the internal data structure ------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pHistMem pHist;
int iNew;
time_t tUpdate;
int iInterval;
int iEnd;
SConnection *pCon;
char *pFile;
char *pDictFile;
pFit pFitter;
float fElastic;
int iUpper, iMiddle, iLower;
/* detector availability flags */
} FoWrite, *pFoWrite;
/* ------------------- forward declaration of task function --------------*/
static int FoTask(void *pData);
static void FoUpdate(pFoWrite self, SConnection *pCon);
/*------------------ The Countstart Callback Function ----------------------*/
static int Countstartcallback(int iEvent, void *pEventData, void *pUser)
{
pFoWrite self = NULL;
if(iEvent == COUNTSTART)
{
self = (pFoWrite)pUser;
assert(self);
self->iNew = 1;
self->iEnd = 0;
self->tUpdate = time(NULL);
self->pCon = (SConnection *)pEventData;
TaskRegister(pServ->pTasker,FoTask,NULL,NULL,self,1);
return 1;
}
return 1;
}
/*------------------ The Countend Callback Function ----------------------*/
static int Countendcallback(int iEvent, void *pEventData, void *pUser)
{
pFoWrite self = NULL;
if(iEvent == COUNTEND)
{
self = (pFoWrite)pUser;
assert(self);
self->tUpdate = time(NULL);
self->iEnd = 1;
FoUpdate(self,self->pCon);
return 1;
}
return 1;
}
/*-----------------------------------------------------------------------*/
static void SNError(void *pData, char *text)
{
SConnection *pCon;
assert(pData);
pCon = (SConnection *)pData;
SCWrite(pCon,text,eError);
}
/*------------------------------------------------------------------------*/
static void WriteSelector(NXhandle pFile, NXdict pDict, SConnection *pCon)
{
pSicsSelector pSel = NULL;
char *pName = NULL;
CommandList *pCom = NULL;
pDummy pDum = NULL;
float fTh, fTTH, fB1, fB2;
int iRet;
pCom = FindCommand(pServ->pSics,"mono");
if(!pCom)
{
SCWrite(pCon,"ERROR: no monochromator found",eError);
return ;
}
pSel = (pSicsSelector)pCom->pData;
if(!pSel)
{
SCWrite(pCon,"ERROR: no monochromator found",eError);
return ;
}
pDum = (pDummy)pSel;
if(strcmp(pDum->pDescriptor->name,"CrystalSelector") != 0)
{
SCWrite(pCon,"ERROR: monochromator is invalid",eError);
return ;
}
NXDputalias(pFile,pDict,"mname",MonoGetType(pSel));
iRet = GetMonoPositions(pSel,pCon,&fTh, &fTTH, &fB1, &fB2);
if(!iRet)
{
SCWrite(pCon,"ERROR: Problem reading monochromator positions",eError);
SCWrite(pCon,"ERROR: monochromator data missing in file",eError);
return;
}
NXDputalias(pFile,pDict,"mtheta",&fTh);
NXDputalias(pFile,pDict,"mttheta",&fTTH);
SNXSPutDrivable(pServ->pSics,pCon, pFile,pDict,"lambda","mlambda");
SNXSPutDrivable(pServ->pSics,pCon, pFile,pDict,"qi","menergy");
}
/*----------------------------------------------------------------------*/
static float CalculateElastic(pFoWrite self, SConnection *pCon)
{
pIDrivable pDriv;
pSicsVariable pVar;
CommandList *pCom = NULL;
float fLambda, fDist, fResult;
pCom = FindCommand(pServ->pSics,"lambda");
if(!pCom)
return 0.;
pDriv = GetDrivableInterface(pCom->pData);
if(!pDriv)
return 0.;
fLambda = pDriv->GetValue(pCom->pData,pCon);
pVar = FindVariable(pServ->pSics,"sampledist");
if(!pVar)
return 0.;
fDist = pVar->fVal;
pVar = FindVariable(pServ->pSics,"detectordist");
if(!pVar)
return 0.;
fDist += pVar->fVal;
fResult = 252.78*fLambda*(fDist/1000.);
return fResult;
}
/*-------------------------------------------------------------------------
FoStart writes all the fixed data items, creates a new file etc.
A complete file is obtained after FoStart plus a call to FoUpdate
*/
static int FoStart(pFoWrite self, SConnection *pCon)
{
NXhandle pFile = NULL;
NXdict pDict = NULL;
int iStat, iLength, i;
char pBueffel[512];
CounterMode eMode;
float fVal, *fArray;
const float *fTime;
float *fTime2 = NULL;
char pBuffer[50];
/* get a filename */
if(self->pFile)
free(self->pFile);
self->pFile = SNXMakeFileName(pServ->pSics,pCon);
if(!self->pFile)
{
SCWrite(pCon,"ERROR: Extra severe: failed to create data file name",
eError);
return 0;
}
/* create a Nexus file */
NXopen(self->pFile,NXACC_CREATE,&pFile);
if(!pFile)
{
SCWrite(pCon,"ERROR: cannot create data file ",eError);
return 0;
}
/* tell Uwe User what we are doing */
sprintf(pBueffel,"Writing %s ......",self->pFile);
SCWrite(pCon,pBueffel,eWarning);
/* write globals */
SNXSPutGlobals(pFile,self->pFile,"FOCUS",pCon);
/* open nxdict and configure nxdict parameters */
iStat = NXDinitfromfile(self->pDictFile,&pDict);
if(iStat != NX_OK)
{
sprintf(pBueffel,"ERROR: failed to open dictionary file %s",
self->pDictFile);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,"ERROR: Aborting data file writing",eError);
SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError);
SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError);
NXclose(&pFile);
return 0;
}
/* put permanent data */
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"etitle","title");
SNXFormatTime(pBueffel,511);
/* entry & instrument stuff */
NXDputalias(pFile,pDict,"estart",pBueffel);
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"iname","instrument");
NXDputalias(pFile,pDict,"sname","SINQ, PSI, Switzerland");
NXDputalias(pFile,pDict,"stype","continous spallation source");
/* disk chopper */
NXDputalias(pFile,pDict,"cname","Dornier disk chopper");
/* be-filter */
NXDputalias(pFile,pDict,"bname","BE-filter");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"bstatus","bestatus");
/* flight path */
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fltype","flightpath");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fllength","flightpathlength");
/* monochromator */
WriteSelector(pFile,pDict,pCon);
/* fermi chupper */
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fcname","ferminame");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fcdist","fermidist");
/* counting data */
eMode = GetHistCountMode(self->pHist);
if(eMode == eTimer)
{
strcpy(pBueffel,"timer");
}
else
{
strcpy(pBueffel,"monitor");
}
NXDputalias(pFile,pDict,"cnmode",pBueffel);
fVal = GetHistPreset(self->pHist);
NXDputalias(pFile,pDict,"cnpreset",&fVal);
/* detector banks */
fTime = GetHistTimeBin(self->pHist,&iLength);
fTime2 = (float *)malloc(iLength*sizeof(float));
if(fTime2)
{
for(i = 0; i < iLength; i++)
{
fTime2[i] = fTime[i]/10.;
}
sprintf(pBueffel,"%d",iLength);
NXDupdate(pDict,"timebin",pBueffel);
if(self->iMiddle)
{
NXDupdate(pDict,"bank","bank1");
NXDputalias(pFile,pDict,"dtime",fTime2);
}
if(self->iUpper)
{
NXDupdate(pDict,"bank","upperbank");
NXDputalias(pFile,pDict,"dtime",fTime2);
}
if(self->iLower)
{
NXDupdate(pDict,"bank","lowerbank");
NXDputalias(pFile,pDict,"dtime",fTime2);
}
if( (self->iLower || self->iUpper) && self->iMiddle)
{
NXDupdate(pDict,"bank","merged");
NXDputalias(pFile,pDict,"dtime",fTime2);
}
NXDupdate(pDict,"bank","bank1");
/* calculate theoretical position of elastic peak */
fVal = CalculateElastic(self,pCon);
self->fElastic = (fVal - fTime2[0]) / (fTime2[1] - fTime2[0]);
free(fTime2);
fTime2 = NULL;
}
else
{
SCWrite(pCon,"ERROR: out of memory while writing time binning",
eError);
}
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"ddist","detectordist");
/* theta arrays */
if(self->iMiddle)
{
NXDupdate(pDict,"bank","bank1");
iLength = getFMdim(MIDDLE);
sprintf(pBuffer,"%d",iLength);
NXDupdate(pDict,"noofdetectors",pBuffer);
fArray = getFMBankTheta(MIDDLE);
NXDputalias(pFile,pDict,"dtheta",fArray);
}
if(self->iLower)
{
NXDupdate(pDict,"bank","lowerbank");
iLength = getFMdim(LOWER);
sprintf(pBuffer,"%d",iLength);
NXDupdate(pDict,"noofdetectors",pBuffer);
fArray = getFMBankTheta(LOWER);
NXDputalias(pFile,pDict,"dtheta",fArray);
}
if(self->iUpper)
{
NXDupdate(pDict,"bank","upperbank");
iLength = getFMdim(UPPER);
sprintf(pBuffer,"%d",iLength);
NXDupdate(pDict,"noofdetectors",pBuffer);
fArray = getFMBankTheta(UPPER);
NXDputalias(pFile,pDict,"dtheta",fArray);
}
if(self->iMiddle && ( self->iLower || self->iUpper) )
{
NXDupdate(pDict,"bank","merged");
iLength = getFMdim(MERGED);
sprintf(pBuffer,"%d",iLength);
NXDupdate(pDict,"noofdetectors",pBuffer);
fArray = getFMBankTheta(MERGED);
NXDputalias(pFile,pDict,"dtheta",fArray);
}
NXDupdate(pDict,"bank","bank1");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"ddelay","delay");
/* sample info */
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"saname","sample");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"senvir","environment");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"sdist","sampledist");
SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"saangle","sampleangle");
/* close everything */
NXclose(&pFile);
NXDclose(pDict,NULL);
}
/*---------------------------------------------------------------------------*/
static void FoUpdate(pFoWrite self, SConnection *pCon)
{
char pBueffel[512];
int iInt, iStat, iTime, i, j, iDet, iIndex;
long lVal;
float fVal;
const float *fTime;
NXhandle pFile = NULL;
NXdict pDict;
HistInt *lData = NULL;
int *iSum = NULL;
float *fAxis = NULL;
long *lSum = NULL;
float fCenter, fStdDev, fFWHM;
/* open everything again */
NXopen(self->pFile,NXACC_RDWR,&pFile);
if(!pFile)
{
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
return;
}
iStat = NXDinitfromfile(self->pDictFile,&pDict);
if(iStat != NX_OK)
{
sprintf(pBueffel,"ERROR: failed to open dictionary file %s",
self->pDictFile);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,"ERROR: Aborting data file writing",eError);
SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError);
SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError);
NXclose(&pFile);
return;
}
/* tell the user that something is happening */
sprintf(pBueffel,"Updating %s",self->pFile);
SCWrite(pCon,pBueffel,eWarning);
/* do the end time */
SNXFormatTime(pBueffel,511);
NXDputalias(pFile,pDict,"eend",pBueffel);
/* chopper speeds */
SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"diskspeed","crot");
SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"fermispeed","fcrot");
SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"phase","fcphase");
SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"ratio","cratio");
/* counter data */
fVal = GetHistCountTime(self->pHist,pCon);
NXDputalias(pFile,pDict,"cntime",&fVal);
lVal = GetHistMonitor(self->pHist,1,pCon);
NXDputalias(pFile,pDict,"cnmon1",&lVal);
lVal = GetHistMonitor(self->pHist,0,pCon);
NXDputalias(pFile,pDict,"cnmon2",&lVal);
lVal = GetHistMonitor(self->pHist,4,pCon);
NXDputalias(pFile,pDict,"cnmon3",&lVal);
/* histogram with three detector banks */
fTime = GetHistTimeBin(self->pHist,&iInt);
iTime = iInt;
sprintf(pBueffel,"%d",iInt);
NXDupdate(pDict,"timebin",pBueffel);
lData = GetHistogramPointer(self->pHist,pCon);
if(!lData)
{
SCWrite(pCon,"ERROR: failed to find Histogram Memory Data",eError);
NXclose(&pFile);
NXDclose(pDict,NULL);
return;
}
setFMDataPointer(lData,iTime);
if(self->iUpper)
{
NXDupdate(pDict,"bank","upperbank");
iDet = getFMdim(UPPER);
sprintf(pBueffel,"%d",iDet);
NXDupdate(pDict,"noofdetectors",pBueffel);
lData = getFMBankPointer(UPPER);
NXDputalias(pFile,pDict,"dcounts",lData);
/* summed counts for each detector */
iSum = (int *)malloc(iDet*sizeof(int));
if(iSum)
{
memset(iSum,0,iDet*sizeof(int));
for(i = 0; i < iDet; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
{
iSum[i] += lData[iIndex+j];
}
}
NXDputalias(pFile,pDict,"dsums",iSum);
free(iSum);
}
else
{
SCWrite(pCon,"WARNING: out of memory, failed to do sums",
eWarning);
}
}
/* middle bank */
if(self->iMiddle)
{
NXDupdate(pDict,"bank","bank1");
iDet = getFMdim(MIDDLE);
sprintf(pBueffel,"%d",iDet);
NXDupdate(pDict,"noofdetectors",pBueffel);
lData = getFMBankPointer(MIDDLE);
NXDputalias(pFile,pDict,"dcounts",lData);
/* summed counts for each detector */
iSum = (int *)malloc(iDet*sizeof(int));
if(iSum)
{
memset(iSum,0,iDet*sizeof(int));
for(i = 0; i < iDet; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
{
iSum[i] += lData[iIndex+j];
}
}
NXDputalias(pFile,pDict,"dsums",iSum);
free(iSum);
}
else
{
SCWrite(pCon,"WARNING: out of memory, failed to do sums",
eWarning);
}
}
if(self->iLower)
{
NXDupdate(pDict,"bank","lowerbank");
iDet = getFMdim(LOWER);
sprintf(pBueffel,"%d",iDet);
NXDupdate(pDict,"noofdetectors",pBueffel);
lData = getFMBankPointer(LOWER);
NXDputalias(pFile,pDict,"dcounts",lData);
/* summed counts for each detector */
iSum = (int *)malloc(iDet*sizeof(int));
if(iSum)
{
memset(iSum,0,iDet*sizeof(int));
for(i = 0; i < iDet; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
{
iSum[i] += lData[iIndex+j];
}
}
NXDputalias(pFile,pDict,"dsums",iSum);
free(iSum);
}
else
{
SCWrite(pCon,"WARNING: out of memory, failed to do sums",
eWarning);
}
}
/* merged data */
if( (self->iUpper || self->iLower) && self->iMiddle)
{
NXDupdate(pDict,"bank","merged");
iDet = getFMdim(MERGED);
sprintf(pBueffel,"%d",iDet);
NXDupdate(pDict,"noofdetectors",pBueffel);
lData = getFMBankPointer(MERGED);
NXDputalias(pFile,pDict,"dcounts",lData);
/* summed counts for each detector */
iSum = (int *)malloc(iDet*sizeof(int));
if(iSum)
{
memset(iSum,0,iDet*sizeof(int));
for(i = 0; i < iDet; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
{
iSum[i] += lData[iIndex+j];
}
}
NXDputalias(pFile,pDict,"dsums",iSum);
free(iSum);
}
else
{
SCWrite(pCon,"WARNING: out of memory, failed to do sums",
eWarning);
}
}
/* calculate elastic peak position */
NXDupdate(pDict,"bank","bank1");
lData = getFMBankPointer(MIDDLE);
if(lData)
{
lSum = (long *)malloc(iTime *sizeof(long));
fAxis = (float *)malloc(iTime *sizeof(float));
if( lSum && fAxis)
{
memset(lSum,0,iTime*sizeof(long));
memset(fAxis,0,iTime*sizeof(float));
for(i = 5; i < iDet - 5; i++)
{
iIndex = i * iTime;
for(j = 0; j < iTime; j++)
{
lSum[j] += lData[iIndex+j];
}
}
for(i = 0; i < iTime; i++)
{
fAxis[i] = (float)i;
}
iStat = CalculateFitFromData(self->pFitter,fAxis,lSum,iTime);
if(iStat != 1)
{
SCWrite(pCon,"WARNING: problem locating elastic peak",eWarning);
}
GetFitResults(self->pFitter,&fCenter,&fStdDev,&fFWHM,&fVal);
fVal = fCenter - self->fElastic;
if(fVal < 0.)
fVal = - fVal;
/* bad value, leave at theoretical value */
if(fVal > 10.)
{
SCWrite(pCon,
"WARNING: bad fit result, using theoretical elastic peak position",
eWarning);
}
else
{
self->fElastic = fCenter;
}
free(lSum);
free(fAxis);
}
else
{
SCWrite(pCon,"WARNING: out of memory, failed to do sums",eWarning);
}
}
sprintf(pBueffel,"Elastic peak found at detector: %f",self->fElastic);
SCWrite(pCon,pBueffel,eWarning);
NXDputalias(pFile,pDict,"delastic",&self->fElastic);
/* sample temperature */
SNXSPutEVVar(pFile,pDict,"temperature",pCon,"stemp",NULL);
/* close everything */
NXclose(&pFile);
NXDclose(pDict,NULL);
}
/*-------------------------------------------------------------------------
FoLink sets all the links for the NXdata vGroup. Had to be separate because
at least one update is necessary before this can be done.
*/
static void FoLink(pFoWrite self, SConnection *pCon)
{
NXhandle pFile;
NXdict pDict;
int iStat;
char pBueffel[512];
/* open everything again */
NXopen(self->pFile,NXACC_RDWR,&pFile);
if(!pFile)
{
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
return;
}
iStat = NXDinitfromfile(self->pDictFile,&pDict);
if(iStat != NX_OK)
{
sprintf(pBueffel,"ERROR: failed to open dictionary file %s",
self->pDictFile);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,"ERROR: Aborting data file writing",eError);
SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError);
SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError);
NXclose(&pFile);
return;
}
if( (self->iUpper || self->iLower) && self->iMiddle)
{
NXDupdate(pDict,"bank","merged");
NXDaliaslink(pFile,pDict,"dana","dcounts");
NXDaliaslink(pFile,pDict,"dana","dtime");
NXDaliaslink(pFile,pDict,"dana","dtheta");
NXDaliaslink(pFile,pDict,"dana","cnmon1");
}
if(self->iUpper)
{
NXDupdate(pDict,"bank","upperbank");
NXDaliaslink(pFile,pDict,"dana","dcounts");
NXDaliaslink(pFile,pDict,"dana","dtime");
NXDaliaslink(pFile,pDict,"dana","dtheta");
NXDaliaslink(pFile,pDict,"dana","cnmon1");
}
if(self->iMiddle)
{
NXDupdate(pDict,"bank","bank1");
NXDaliaslink(pFile,pDict,"dana","dcounts");
NXDaliaslink(pFile,pDict,"dana","dtime");
NXDaliaslink(pFile,pDict,"dana","dtheta");
NXDaliaslink(pFile,pDict,"dana","cnmon1");
}
if(self->iLower)
{
NXDupdate(pDict,"bank","lowerbank");
NXDaliaslink(pFile,pDict,"dana","dcounts");
NXDaliaslink(pFile,pDict,"dana","dtime");
NXDaliaslink(pFile,pDict,"dana","dtheta");
NXDaliaslink(pFile,pDict,"dana","cnmon1");
}
/* close everything */
NXclose(&pFile);
NXDclose(pDict,NULL);
self->iNew = 0;
}
/*---------------------------------------------------------------------------
This is the task function for updating the data file any now and then
automatically
*/
static int FoTask(void *pData)
{
pFoWrite self = NULL;
int iWrite, iRet;
self = (pFoWrite)pData;
if(!self)
return 0;
/* figure out if we need to write */
iWrite = 0;
iRet = 1;
/* first case: update intervall */
if(time(NULL) >= self->tUpdate)
{
self->tUpdate = time(NULL) + self->iInterval;
iWrite = 1;
iRet = 1;
}
if(self->iEnd)
{
self->tUpdate = 0;
iWrite = 0;
iRet = 0;
}
if(iWrite)
{
if(self->iNew)
{
FoStart(self,self->pCon);
FoUpdate(self,self->pCon);
FoLink(self,self->pCon);
}
else
{
FoUpdate(self,self->pCon);
}
}
return iRet;
}
/*------------------------------------------------------------------------*/
static void KillFoWrite(void *pData)
{
pFoWrite self = NULL;
self = (pFoWrite)pData;
if(!self)
return;
if(self->pDes)
DeleteDescriptor(self->pDes);
if(self->pDictFile)
free(self->pDictFile);
if(self->pFile)
free(self->pFile);
if(self->pFitter)
DeleteFitCenter(self->pFitter);
/* free fomerge */
killFM();
free(self);
}
/*-----------------------------------------------------------------------*/
int FoInstall(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pHistMem pHist= NULL;
char pBueffel[512];
pFoWrite pNew = NULL;
pICallBack pCall = NULL;
pDummy pDum;
/* check arguments */
if(argc < 4 )
{
SCWrite(pCon,"ERROR: Insufficient number of arguments to FoInstall",
eError);
return 0;
}
pHist = (pHistMem)FindCommandData(pSics,argv[1],"HistMem");
if(!pHist)
{
SCWrite(pCon,"ERROR: Histogram memory NOT found",eError);
return 0;
}
if(!initializeFM(argv[3]))
{
SCWrite(pCon,"ERROR: bad merge data file",eError);
return 0;
}
/* allocate data structure */
pNew = (pFoWrite)malloc(sizeof(FoWrite));
if(!pNew)
{
SCWrite(pCon,"ERROR: out of memory in FoInstall",eError);
return 0;
}
memset(pNew,0,sizeof(FoWrite));
pNew->pDes = CreateDescriptor("FocusWrite");
pNew->pFitter = CreateFitCenter(NULL);
if( (!pNew->pDes) || (!pNew->pFitter) )
{
SCWrite(pCon,"ERROR: out of memory in FoInstall",eError);
return 0;
}
pNew->pHist = pHist;
pNew->pDictFile = strdup(argv[2]);
pNew->iInterval = 20*60;
pNew->iMiddle =1;
/* install callbacks */
pDum = (pDummy)pHist;
pCall = (pICallBack)pDum->pDescriptor->GetInterface(pHist,
CALLBACKINTERFACE);
if(!pCall)
{
SCWrite(pCon,
"ERROR: no callback interface found at your histogram memory",
eError);
KillFoWrite(pNew);
return 0;
}
RegisterCallback(pCall,COUNTSTART,Countstartcallback,pNew,NULL);
RegisterCallback(pCall,COUNTEND,Countendcallback,pNew,NULL);
/* install command */
AddCommand(pSics,"StoreFocus",FoAction,KillFoWrite,pNew);
return 1;
}
/*-------------------------------------------------------------------------*/
int FoAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
int iRet, iVal;
pFoWrite self = NULL;
char pBueffel[512];
if(argc < 1)
{
SCWrite(pCon,"ERROR: Insufficient number of arguments to StoreFocus",
eError);
return 0;
}
self = (pFoWrite)pData;
assert(self);
strtolower(argv[1]);
if(strcmp(argv[1],"start") == 0)
{
FoStart(self,pCon);
FoUpdate(self,pCon);
FoLink(self,pCon);
return 1;
}
else if(strcmp(argv[1],"update") == 0)
{
if((self->iNew) || (!self->pFile))
{
FoStart(self,pCon);
FoUpdate(self,pCon);
FoLink(self,pCon);
}
else
{
FoUpdate(self,pCon);
}
return 1;
}
else if(strcmp(argv[1],"getfile") == 0)
{
sprintf(pBueffel,"storefocus.file = %s",self->pFile);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
else if(strcmp(argv[1],"interval") == 0)
{
if(argc > 2) /* set value */
{
if(!SCMatchRights(pCon,usUser))
{
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ",argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
self->iInterval = iVal*60; /* go to seconds from minutes*/
SCSendOK(pCon);
return 1;
}
else /* read the value */
{
sprintf(pBueffel,"storefocus.interval = %d",self->iInterval/60);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
else if(strcmp(argv[1],"middle") == 0)
{
if(argc > 2) /* set value */
{
if(!SCMatchRights(pCon,usMugger))
{
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(iVal < 0) iVal = 0;
self->iMiddle = iVal;
setFMconfiguration(self->iUpper,self->iMiddle,self->iLower);
SCSendOK(pCon);
return 1;
}
else /* read the value */
{
sprintf(pBueffel,"storefocus.middle = %d",self->iMiddle);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
else if(strcmp(argv[1],"lower") == 0)
{
if(argc > 2) /* set value */
{
if(!SCMatchRights(pCon,usMugger))
{
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(iVal < 0) iVal = 0;
self->iLower = iVal;
setFMconfiguration(self->iUpper,self->iMiddle,self->iLower);
SCSendOK(pCon);
return 1;
}
else /* read the value */
{
sprintf(pBueffel,"storefocus.lower = %d",self->iLower);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
else if(strcmp(argv[1],"upper") == 0)
{
if(argc > 2) /* set value */
{
if(!SCMatchRights(pCon,usMugger))
{
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(iVal < 0) iVal = 0;
self->iUpper = iVal;
setFMconfiguration(self->iUpper,self->iMiddle,self->iLower);
SCSendOK(pCon);
return 1;
}
else /* read the value */
{
sprintf(pBueffel,"storefocus.upper = %d",self->iUpper);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
SCWrite(pCon,"ERROR: subcommand to storefocus not recognized",eError);
return 0;
}