Files
sicspsi/fowrite.c
koennecke eb72d5c486 - Adapted indenation to new agreed upon system
- Fixed bad status in poldi zug driver
2009-02-13 09:01:03 +00:00

1077 lines
31 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 "hmcontrol.h"
#include "fomerge.h"
/* histogram memory names */
#define HM1 "hm1"
#define HM2 "hm2"
#define HM3 "hm3"
/* the name of the SICS chopper controller object */
#define CHOPPERNAME "choco"
/*--------- the internal data structure ------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pHistMem pHistogram1, pHistogram2, pHistogram3;
int iNew;
time_t tUpdate;
int iInterval;
int iEnd;
SConnection *pCon;
pCounter pCount;
char *pFile;
char *pDictFile;
pFit pFitter;
float fElastic;
pICallBack pCall;
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;
pSicsVariable var1 = NULL;
pSicsVariable var2 = NULL;
int lbank, mbank;
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 */
var2 = FindVariable(pServ->pSics, "mbank");
if (var2) {
VarGetInt(var2, &mbank);
} else {
SCWrite(pCon, "ERROR: mbank value not found!", eError);
}
if (var2) {
eMode = GetHistCountMode(self->pHistogram2);
fTime = GetHistTimeBin(self->pHistogram2, &iLength);
fVal = GetHistPreset(self->pHistogram2);
} else {
var1 = FindVariable(pServ->pSics, "lbank");
if (var1) {
VarGetInt(var1, &lbank);
} else {
SCWrite(pCon, "ERROR: lbank value not found!", eError);
}
if (var1) {
eMode = GetHistCountMode(self->pHistogram1);
fTime = GetHistTimeBin(self->pHistogram1, &iLength);
fVal = GetHistPreset(self->pHistogram1);
} else {
eMode = GetHistCountMode(self->pHistogram3);
fTime = GetHistTimeBin(self->pHistogram3, &iLength);
fVal = GetHistPreset(self->pHistogram3);
}
}
if (eMode == eTimer) {
strcpy(pBueffel, "timer");
} else {
strcpy(pBueffel, "monitor");
}
NXDputalias(pFile, pDict, "cnmode", pBueffel);
NXDputalias(pFile, pDict, "cnpreset", &fVal);
/* detector banks */
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 = 150;
sprintf(pBuffer, "%d", iLength);
NXDupdate(pDict, "noofdetectors", pBuffer);
fArray = getFMBankTheta(MIDDLE);
NXDputalias(pFile, pDict, "dtheta", fArray);
}
if (self->iLower) {
NXDupdate(pDict, "bank", "lowerbank");
iLength = 115;
sprintf(pBuffer, "%d", iLength);
NXDupdate(pDict, "noofdetectors", pBuffer);
fArray = getFMBankTheta(LOWER);
NXDputalias(pFile, pDict, "dtheta", fArray);
}
if (self->iUpper) {
NXDupdate(pDict, "bank", "upperbank");
iLength = 110;
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 = 375;
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);
return 0;
}
/*---------------------------------------------------------------------------*/
static void FoUpdate(pFoWrite self, SConnection * pCon)
{
char pBueffel[512];
int iInt, iStat, iTime, i, ii, j, iDet, iIndex;
pSicsVariable var1 = NULL;
pSicsVariable var2 = NULL;
pSicsVariable var3 = NULL;
int lbank, mbank, ubank;
long lVal;
float fVal;
const float *fTime;
NXhandle pFile = NULL;
NXdict pDict;
HistInt *lData = NULL;
HistInt *mData = NULL;
HistInt *uData = 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 */
var2 = FindVariable(pServ->pSics, "mbank");
if (var2) {
VarGetInt(var2, &mbank);
} else {
SCWrite(pCon, "ERROR: mbank value not found!", eError);
}
if (var2) {
fVal = GetHistCountTime(self->pHistogram2, pCon);
NXDputalias(pFile, pDict, "cntime", &fVal);
lVal = GetHistMonitor(self->pHistogram2, 1, pCon);
NXDputalias(pFile, pDict, "cnmon1", &lVal);
lVal = GetHistMonitor(self->pHistogram2, 0, pCon);
NXDputalias(pFile, pDict, "cnmon2", &lVal);
lVal = GetHistMonitor(self->pHistogram2, 4, pCon);
NXDputalias(pFile, pDict, "cnmon3", &lVal);
fTime = GetHistTimeBin(self->pHistogram2, &iInt);
} else {
var1 = FindVariable(pServ->pSics, "lbank");
if (var1) {
VarGetInt(var1, &lbank);
} else {
SCWrite(pCon, "ERROR: lbank value not found!", eError);
}
if (var1) {
fVal = GetHistCountTime(self->pHistogram1, pCon);
NXDputalias(pFile, pDict, "cntime", &fVal);
lVal = GetHistMonitor(self->pHistogram1, 1, pCon);
NXDputalias(pFile, pDict, "cnmon1", &lVal);
lVal = GetHistMonitor(self->pHistogram1, 0, pCon);
NXDputalias(pFile, pDict, "cnmon2", &lVal);
lVal = GetHistMonitor(self->pHistogram1, 4, pCon);
NXDputalias(pFile, pDict, "cnmon3", &lVal);
fTime = GetHistTimeBin(self->pHistogram1, &iInt);
} else {
fVal = GetHistCountTime(self->pHistogram3, pCon);
NXDputalias(pFile, pDict, "cntime", &fVal);
lVal = GetHistMonitor(self->pHistogram3, 1, pCon);
NXDputalias(pFile, pDict, "cnmon1", &lVal);
lVal = GetHistMonitor(self->pHistogram3, 0, pCon);
NXDputalias(pFile, pDict, "cnmon2", &lVal);
lVal = GetHistMonitor(self->pHistogram3, 4, pCon);
NXDputalias(pFile, pDict, "cnmon3", &lVal);
fTime = GetHistTimeBin(self->pHistogram3, &iInt);
}
}
/* histogram with three detector banks */
iTime = iInt;
sprintf(pBueffel, "%d", iInt);
NXDupdate(pDict, "timebin", pBueffel);
var1 = FindVariable(pServ->pSics, "lbank");
if (var1) {
VarGetInt(var1, &lbank);
} else {
SCWrite(pCon, "ERROR: lbank value not found!", eError);
}
if (lbank == 1) {
lData = GetHistogramPointer(self->pHistogram1, pCon);
if (!lData) {
SCWrite(pCon,
"ERROR: failed to find Histogram Memory Data (lower bank)",
eError);
NXclose(&pFile);
NXDclose(pDict, NULL);
return;
}
}
if (mbank == 1) {
mData = GetHistogramPointer(self->pHistogram2, pCon);
if (!mData) {
SCWrite(pCon,
"ERROR: failed to find Histogram Memory Data (middle bank)",
eError);
NXclose(&pFile);
NXDclose(pDict, NULL);
return;
}
}
var3 = FindVariable(pServ->pSics, "ubank");
if (var3) {
VarGetInt(var3, &ubank);
} else {
SCWrite(pCon, "ERROR: ubank value not found!", eError);
}
if (ubank == 1) {
uData = GetHistogramPointer(self->pHistogram3, pCon);
if (!uData) {
SCWrite(pCon,
"ERROR: failed to find Histogram Memory Data (upper bank)",
eError);
NXclose(&pFile);
NXDclose(pDict, NULL);
return;
}
}
setFMDataPointer(lData, iTime, LOWER);
setFMDataPointer(mData, iTime, MIDDLE);
setFMDataPointer(uData, iTime, UPPER);
/* middle bank */
if (self->iMiddle) {
NXDupdate(pDict, "bank", "bank1");
iDet = 150;
sprintf(pBueffel, "%d", iDet);
NXDupdate(pDict, "noofdetectors", pBueffel);
mData = getFMBankPointer(MIDDLE);
NXDputalias(pFile, pDict, "dcounts", mData);
/* 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] += mData[iIndex + j];
}
}
NXDputalias(pFile, pDict, "dsums", iSum);
free(iSum);
} else {
SCWrite(pCon, "WARNING: out of memory, failed to do sums", eWarning);
}
}
if (self->iUpper) {
NXDupdate(pDict, "bank", "upperbank");
iDet = 110;
sprintf(pBueffel, "%d", iDet);
NXDupdate(pDict, "noofdetectors", pBueffel);
uData = getFMBankPointer(UPPER);
NXDputalias(pFile, pDict, "dcounts", uData);
/* 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] += uData[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 = 115;
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);
}
/*
now get and write tof_monitor
*/
lData = (HistInt *) malloc(iTime * sizeof(HistInt));
if (!lData) {
SCWrite(pCon, "ERROR: out of memory while writing tof-monitor",
eError);
} else {
memset(lData, 0, iTime * sizeof(HistInt));
GetHistogramDirect(self->pHistogram1, pCon, 0, 115 * iTime,
116 * iTime, lData, iTime * sizeof(HistInt));
NXDputalias(pFile, pDict, "tofmon", lData);
}
}
/* merged data */
if ((self->iUpper || self->iLower) && self->iMiddle) {
NXDupdate(pDict, "bank", "merged");
iDet = 375;
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");
mData = getFMBankPointer(MIDDLE);
iDet = getFMdim(MIDDLE);
if (mData) {
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] += mData[iIndex + j];
}
}
for (i = 0; i < iTime; i++) {
fAxis[i] = (float) i;
}
iStat = CalculateFitFromData(self->pFitter, fAxis, lSum, iTime);
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.) {
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;
FoUpdate(self, self->pCon);
}
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[])
{
CommandList *pCom = NULL;
char pBueffel[512];
pFoWrite pNew = NULL;
pICallBack pCall = NULL;
pDummy pDum;
pHMcontrol pHMC = NULL;
commandContext comCon;
/* check arguments */
if (argc < 4) {
SCWrite(pCon, "ERROR: Insufficient number of arguments to FoInstall",
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->pCall = CreateCallBackInterface();
pNew->pFitter = CreateFitCenter(NULL);
if ((!pNew->pDes) || (!pNew->pFitter)) {
SCWrite(pCon, "ERROR: out of memory in FoInstall", eError);
free(pNew);
return 0;
}
pNew->pDictFile = strdup(argv[2]);
pNew->iInterval = 20 * 60;
pHMC = FindCommandData(pSics, argv[1], "HMcontrol");
if (!pHMC) {
SCWrite(pCon, "ERROR: no histogram memory control found!", eError);
free(pNew);
return 0;
}
/* find things in interpreter */
pCom = FindCommand(pSics, "hm1");
if (!pCom) {
SCWrite(pCon,
"ERROR: Histogram memory for lower detector bank NOT found",
eError);
pNew->pHistogram1 = NULL;
} else {
pNew->pHistogram1 = (pHistMem) pCom->pData;
pNew->iLower = 1;
}
pCom = FindCommand(pSics, HM2);
if (pCom) {
pNew->pHistogram2 = (pHistMem) pCom->pData;
pNew->iMiddle = 1;
} else {
SCWrite(pCon,
"ERROR: Histogram memory for middle detector bank NOT found",
eError);
pNew->pHistogram2 = NULL;
}
pCom = FindCommand(pSics, HM3);
if (pCom) {
pNew->pHistogram3 = (pHistMem) pCom->pData;
pNew->iUpper = 1;
} else {
SCWrite(pCon,
"ERROR: Histogram memory for upper detector bank NOT found",
eError);
pNew->pHistogram3 = NULL;
}
if (!initializeFM(argv[3])) {
SCWrite(pCon, "ERROR: bad merge data file", eError);
return 0;
}
pCom = FindCommand(pSics, "counter");
if (pCom) {
pNew->pCount = (pCounter) pCom->pData;
}
comCon.transID = 0;
strncpy(comCon.deviceID, "internal", SCDEVIDLEN);
RegisterCallback(pHMC->pCall, COUNTSTART, Countstartcallback, pNew,
NULL);
RegisterCallback(pHMC->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;
}