- Rearranged directory structure for forking out ANSTO
- Refactored site specific stuff into a site module - PSI specific stuff is now in the PSI directory. - The old version has been tagged with pre-ansto
This commit is contained in:
786
polterwrite.c
Normal file
786
polterwrite.c
Normal file
@ -0,0 +1,786 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
P O L T E R W R I T E
|
||||
|
||||
Polterwrite is an object for writing POLTI data files.
|
||||
|
||||
copyright: see copyright.h
|
||||
|
||||
Uwe Filges, November 2001
|
||||
----------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <tcl.h>
|
||||
#undef VOID
|
||||
#include "sics.h"
|
||||
#include "event.h"
|
||||
#include "counter.h"
|
||||
#include "HistMem.h"
|
||||
#include "nxdict.h"
|
||||
#include "nxutil.h"
|
||||
#include "motor.h"
|
||||
#include "sicsvar.h"
|
||||
#include "polterwrite.h"
|
||||
|
||||
/*
|
||||
diaphragm1 - chopper
|
||||
*/
|
||||
#define DIA1DIST 8000
|
||||
|
||||
/*
|
||||
histogram memory name
|
||||
*/
|
||||
#define HM "hm"
|
||||
|
||||
#define DETRADIUS 3000
|
||||
|
||||
typedef struct {
|
||||
pObjectDescriptor pDes;
|
||||
pHistMem pHist;
|
||||
int iNew;
|
||||
time_t tUpdate;
|
||||
int iInterval;
|
||||
int iEnd;
|
||||
SConnection *pCon;
|
||||
char *dictfile;
|
||||
char *pFile;
|
||||
}Polterdi, *pPolterdi;
|
||||
|
||||
/* ------------------- forward declaration of task function --------------*/
|
||||
static int PoldiTask(void *pData);
|
||||
static void PoldiUpdate(pPolterdi self, SConnection *pCon);
|
||||
|
||||
/*------------------ The Countstart Callback Function ----------------------*/
|
||||
static int Countstartcallback(int iEvent, void *pEventData, void *pUser)
|
||||
{
|
||||
pPolterdi self = NULL;
|
||||
|
||||
if(iEvent == COUNTSTART)
|
||||
{
|
||||
self = (pPolterdi)pUser;
|
||||
assert(self);
|
||||
self->iNew = 1;
|
||||
self->iEnd = 0;
|
||||
self->tUpdate = time(NULL);
|
||||
self->pCon = (SConnection *)pEventData;
|
||||
TaskRegister(pServ->pTasker,PoldiTask,NULL,NULL,self,1);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*------------------ The Countend Callback Function ----------------------*/
|
||||
static int Countendcallback(int iEvent, void *pEventData, void *pUser)
|
||||
{
|
||||
pPolterdi self = NULL;
|
||||
|
||||
if(iEvent == COUNTEND)
|
||||
{
|
||||
self = (pPolterdi)pUser;
|
||||
assert(self);
|
||||
self->tUpdate = time(NULL);
|
||||
self->iEnd = 1;
|
||||
PoldiUpdate(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 writePolterdiGlobal(NXhandle hfil, NXdict hdict,
|
||||
SConnection *pCon){
|
||||
char pBueffel[512];
|
||||
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"etitle","title");
|
||||
SNXFormatTime(pBueffel,511);
|
||||
|
||||
NXDputalias(hfil,hdict,"estart",pBueffel);
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"iname","instrument");
|
||||
sprintf(pBueffel,"%d",strlen("SINQ, PSI, Switzerland"));
|
||||
NXDupdate(hdict,"strdim",pBueffel);
|
||||
NXDputalias(hfil,hdict,"sname","SINQ, PSI, Switzerland");
|
||||
sprintf(pBueffel,"%d",strlen("continous spallation source"));
|
||||
NXDupdate(hdict,"strdim",pBueffel);
|
||||
NXDputalias(hfil,hdict,"stype","continous spallation source");
|
||||
NXDupdate(hdict,"strdim","132");
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static void writeChopper(NXhandle hfil, NXdict hdict, SConnection *pCon){
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"cname","choppername");
|
||||
SNXSPutDrivable(pServ->pSics,pCon,hfil,hdict,"chopperspeed","crot");
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
static void writeDiaphragm1(NXhandle hfil, NXdict hdict,
|
||||
SConnection *pCon){
|
||||
float dist;
|
||||
|
||||
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"dia1x","d1hl");
|
||||
SNXSPutMotorNull(pServ->pSics,pCon,hfil,hdict,"dia1x0","d1hl");
|
||||
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"dia1y","d1hr");
|
||||
SNXSPutMotorNull(pServ->pSics,pCon,hfil,hdict,"dia1y0","d1hr");
|
||||
dist = (float)DIA1DIST;
|
||||
NXDputalias(hfil,hdict,"dia1dist",&dist);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
||||
static void writeDiaphragm2(NXhandle hfil, NXdict hdict,
|
||||
SConnection *pCon){
|
||||
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2x_plus", "d2hl");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2xplus0", "d2hl");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2x_minus", "d2hr");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2xminus0", "d2hr");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2z_plus", "d2vu");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2zplus0", "d2vu");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "dia2z_minus", "d2vl");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "dia2zminus0", "d2vl");
|
||||
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"dia2dist","dia1_dia2");
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
static void writeSample(NXhandle hfil, NXdict hdict,
|
||||
SConnection *pCon)
|
||||
{
|
||||
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"sdist","dia2_sample");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"chopperdist","chopper_sample");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"saname","sample");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"senvir","environment");
|
||||
/*
|
||||
SNXSPutEVVar(hfil,hdict,"temperature",pCon,"stemp","stddev");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "srsu", "rsu");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "srsu0", "rsu");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "srsl", "rsl");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "srsl0", "rsl");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "srsa", "rsa");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "srsa0", "rsa");
|
||||
*/
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "sshu", "shu");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "sshu0", "shu");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "sshl", "shl");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "sshl0", "shl");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssgu", "sgu");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssgu0", "sgu");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssgl", "sgl");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssgl0", "sgl");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssv", "sv");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssv0", "sv");
|
||||
SNXSPutMotor(pServ->pSics, pCon, hfil, hdict, "ssa", "sa");
|
||||
SNXSPutMotorNull(pServ->pSics, pCon, hfil, hdict, "ssa0", "sa");
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
|
||||
static int PoldiStart(pPolterdi self, SConnection *pCon)
|
||||
{
|
||||
char pBueffel[256];
|
||||
NXhandle hfil = NULL;
|
||||
NXdict hdict= NULL;
|
||||
int status;
|
||||
const float *fTime = NULL;
|
||||
CounterMode eMode;
|
||||
float *fTime2 = NULL,fTheta0[801],fTheta[801], fVal;
|
||||
pSicsVariable pVar = NULL;
|
||||
float det_radius, det_size, x0det, y0det, twothet;
|
||||
float pi, alpha1, alphasamp, sms, phidetav, phim;
|
||||
float phi2det, val1, val2, nodet,scancheck;
|
||||
int iLength, i, nzell;
|
||||
pMotor sa;
|
||||
HistInt *lData = NULL;
|
||||
long lVal;
|
||||
|
||||
/* create filename */
|
||||
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,&hfil);
|
||||
if(!hfil)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: cannot create data file ",eError);
|
||||
return 0;
|
||||
}
|
||||
/* tell Uwe User what we are doing */
|
||||
pVar = NULL;
|
||||
pVar = FindVariable(pServ->pSics,"scancheck");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar, &scancheck);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
if (scancheck == 0) {
|
||||
sprintf(pBueffel,"Writing %s ......",self->pFile);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
}
|
||||
|
||||
|
||||
/* write globals */
|
||||
SNXSPutGlobals(hfil,self->pFile,"POLDI",pCon);
|
||||
|
||||
/* open nxdict */
|
||||
status = NXDinitfromfile(self->dictfile,&hdict);
|
||||
if(status != NX_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: failed to open dictionary file %s",
|
||||
self->dictfile);
|
||||
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(&hfil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
writePolterdiGlobal(hfil,hdict,pCon);
|
||||
|
||||
writeChopper(hfil,hdict,pCon);
|
||||
|
||||
writeDiaphragm1(hfil,hdict,pCon);
|
||||
|
||||
writeDiaphragm2(hfil,hdict,pCon);
|
||||
|
||||
writeSample(hfil,hdict,pCon);
|
||||
|
||||
/*
|
||||
write time binning
|
||||
*/
|
||||
|
||||
fTime = GetHistTimeBin(self->pHist,&iLength);
|
||||
fTime2 = (float *)malloc(iLength*sizeof(float));
|
||||
if(fTime2)
|
||||
{
|
||||
for(i = 0;i < iLength; i++)
|
||||
{
|
||||
fTime2[i] = fTime[i]/2.;
|
||||
}
|
||||
sprintf(pBueffel,"%d",iLength);
|
||||
NXDupdate(hdict,"timebin",pBueffel);
|
||||
NXDputalias(hfil,hdict,"dtime",fTime2);
|
||||
free(fTime2);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory while writing time binning",eError);
|
||||
}
|
||||
|
||||
/*
|
||||
theta calculation
|
||||
*/
|
||||
det_radius = (float)DETRADIUS;
|
||||
pVar = FindVariable(pServ->pSics,"det_size");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar,&det_size);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
pVar = NULL;
|
||||
pVar = FindVariable(pServ->pSics,"nodet");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar,&nodet);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
pVar = NULL;
|
||||
nzell = (int)nodet;
|
||||
|
||||
pVar = FindVariable(pServ->pSics,"x0_det");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar,&x0det);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
pVar = NULL;
|
||||
pVar = FindVariable(pServ->pSics,"y0_det");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar, &y0det);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
pVar = NULL;
|
||||
pVar = FindVariable(pServ->pSics,"twotheta");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar, &twothet);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
|
||||
pi = 3.1415926536;
|
||||
/* transformation to radient */
|
||||
twothet = twothet*pi/180;
|
||||
if (x0det < 0) {
|
||||
alpha1 = atan(y0det/x0det);
|
||||
}
|
||||
if (x0det > 0) {
|
||||
alpha1 = pi + atan(y0det/x0det);
|
||||
}
|
||||
alphasamp=pi + alpha1 - twothet;
|
||||
sms = sqrt(x0det*x0det + y0det*y0det);
|
||||
phidetav = pi - alphasamp - asin(sms/det_radius*sin(alphasamp)) + alpha1;
|
||||
phim = atan(y0det/x0det);
|
||||
if (phim < 0) {
|
||||
phim = pi + phim;
|
||||
}
|
||||
for(i = 0; i <= nzell; i++)
|
||||
{
|
||||
phi2det = phidetav+(i-0.5*(nzell-1.0))*det_size/(det_radius);
|
||||
val1 = det_radius*sin(phi2det) - sms*sin(phim);
|
||||
val2 = det_radius*cos(phi2det) - sms*cos(phim);
|
||||
fTheta0[i] = atan(val1/val2);
|
||||
if (fTheta0[i] < 0) {
|
||||
fTheta0[i] = pi + fTheta0[i];
|
||||
}
|
||||
/* transformation to degree */
|
||||
fTheta0[i] = fTheta0[i]*180/pi;
|
||||
}
|
||||
for (i=0;i<=nzell;i++)
|
||||
{
|
||||
fTheta[i]=fTheta0[nzell-i];
|
||||
}
|
||||
NXDputalias(hfil,hdict,"dtheta",fTheta);
|
||||
NXDputalias(hfil,hdict,"detector_radius",&det_radius);
|
||||
NXDputalias(hfil,hdict,"cell_size",&det_size);
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"ddist","detectordist");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"sangle","scatt_angle");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"detx0","x0_det");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"dety0","y0_det");
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil,hdict,"theta","twotheta");
|
||||
/*
|
||||
write Histogram
|
||||
*/
|
||||
lData = GetHistogramPointer(self->pHist,pCon);
|
||||
if(lData)
|
||||
{
|
||||
NXDputalias(hfil,hdict,"dcounts",lData);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to get histogram data",eError);
|
||||
}
|
||||
|
||||
/*
|
||||
write counting data
|
||||
*/
|
||||
fVal = GetHistCountTime(self->pHist,pCon);
|
||||
NXDputalias(hfil,hdict,"cntime",&fVal);
|
||||
lVal = GetHistMonitor(self->pHist,1,pCon);
|
||||
NXDputalias(hfil,hdict,"cnmon1",&lVal);
|
||||
eMode = GetHistCountMode(self->pHist);
|
||||
if(eMode == eTimer)
|
||||
{
|
||||
strcpy(pBueffel,"timer");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(pBueffel,"monitor");
|
||||
}
|
||||
NXDputalias(hfil,hdict,"cnmode",pBueffel);
|
||||
fVal = GetHistPreset(self->pHist);
|
||||
NXDputalias(hfil,hdict,"cnpreset",&fVal);
|
||||
|
||||
/* close everything */
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
self->iNew = 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void PoldiUpdate(pPolterdi self, SConnection *pCon)
|
||||
{
|
||||
char pBueffel[256];
|
||||
NXhandle hfil = NULL;
|
||||
NXdict hdict = NULL;
|
||||
int status;
|
||||
const float *fTime = NULL;
|
||||
CounterMode eMode;
|
||||
float *fTime2 = NULL, fTheta[801], fVal;
|
||||
pSicsVariable pVar = NULL;
|
||||
float det_radius, det_size, x0det, y0det, twothet;
|
||||
float pi, alpha1, alphasamp, sms, phidetav, phim;
|
||||
float phi2det, val1, val2, nodet, scancheck;
|
||||
int iLength, i, nzell;
|
||||
pMotor sa;
|
||||
HistInt *lData = NULL;
|
||||
long lVal;
|
||||
time_t zeit;
|
||||
|
||||
/* open everything again */
|
||||
status = NXopen(self->pFile,NXACC_RDWR,&hfil);
|
||||
if(status != NX_OK)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
|
||||
return;
|
||||
}
|
||||
status = NXDinitfromfile(self->dictfile,&hdict);
|
||||
if(status != NX_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: failed to open dictionary file %s",
|
||||
self->dictfile);
|
||||
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(&hfil);
|
||||
return;
|
||||
}
|
||||
|
||||
/* tell the user that something is happening */
|
||||
pVar = NULL;
|
||||
pVar = FindVariable(pServ->pSics,"scancheck");
|
||||
if(pVar)
|
||||
{
|
||||
VarGetFloat(pVar, &scancheck);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: Command not found!",eError);
|
||||
return;
|
||||
}
|
||||
if (scancheck == 0) {
|
||||
time(&zeit);
|
||||
sprintf(pBueffel,"Updating %s on %s ",self->pFile,asctime(localtime(&zeit)));
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
}
|
||||
/*
|
||||
write time binning
|
||||
*/
|
||||
|
||||
fTime = GetHistTimeBin(self->pHist,&iLength);
|
||||
fTime2 = (float *)malloc(iLength*sizeof(float));
|
||||
if(fTime2)
|
||||
{
|
||||
for(i = 0;i < iLength; i++) {
|
||||
fTime2[i] = fTime[i]/2.;
|
||||
}
|
||||
sprintf(pBueffel,"%d",iLength);
|
||||
NXDupdate(hdict,"timebin",pBueffel);
|
||||
NXDputalias(hfil,hdict,"dtime",fTime2);
|
||||
free(fTime2);
|
||||
} else {
|
||||
SCWrite(pCon,"ERROR: out of memory while writing time binning",eError);
|
||||
}
|
||||
|
||||
/*
|
||||
write Histogram
|
||||
*/
|
||||
|
||||
lData = GetHistogramPointer(self->pHist,pCon);
|
||||
if(lData)
|
||||
{
|
||||
NXDputalias(hfil,hdict,"dcounts",lData);
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to get histogram data",eError);
|
||||
}
|
||||
|
||||
/*
|
||||
write counting data
|
||||
*/
|
||||
fVal = GetHistCountTime(self->pHist,pCon);
|
||||
NXDputalias(hfil,hdict,"cntime",&fVal);
|
||||
lVal = GetHistMonitor(self->pHist,1,pCon);
|
||||
NXDputalias(hfil,hdict,"cnmon1",&lVal);
|
||||
eMode = GetHistCountMode(self->pHist);
|
||||
if(eMode == eTimer)
|
||||
{
|
||||
strcpy(pBueffel,"timer");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(pBueffel,"monitor");
|
||||
}
|
||||
NXDputalias(hfil,hdict,"cnmode",pBueffel);
|
||||
fVal = GetHistPreset(self->pHist);
|
||||
NXDputalias(hfil,hdict,"cnpreset",&fVal);
|
||||
|
||||
|
||||
/* close everything */
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,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 PoldiLink(pPolterdi self, SConnection *pCon)
|
||||
{
|
||||
NXhandle hfil = NULL;
|
||||
NXdict hdict = NULL;
|
||||
int status;
|
||||
char pBueffel[512];
|
||||
|
||||
/* open everything again */
|
||||
NXopen(self->pFile,NXACC_RDWR,&hfil);
|
||||
if(!self->pFile)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: cannot reopen data file ",eError);
|
||||
return;
|
||||
}
|
||||
status = NXDinitfromfile(self->dictfile,&hdict);
|
||||
if(status != NX_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: failed to open dictionary file %s",
|
||||
self->dictfile);
|
||||
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(&hfil);
|
||||
return;
|
||||
}
|
||||
|
||||
NXDaliaslink(hfil,hdict,"dana","dcounts");
|
||||
NXDaliaslink(hfil,hdict,"dana","dtheta");
|
||||
NXDaliaslink(hfil,hdict,"dana","dtime");
|
||||
|
||||
/* close everything */
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
This is the task function for updating the data file any now and then
|
||||
automatically
|
||||
--------------------------------------------------------------------------*/
|
||||
static int PoldiTask(void *pData)
|
||||
{
|
||||
pPolterdi self = NULL;
|
||||
int iWrite, iRet, ltask;
|
||||
|
||||
self = (pPolterdi)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)
|
||||
{
|
||||
ltask = GetDevexecID(pServ->pExecutor);
|
||||
if (ltask > 0)
|
||||
{
|
||||
self->tUpdate = time(NULL) + self->iInterval;
|
||||
iWrite = 1;
|
||||
iRet = 1;
|
||||
} else {
|
||||
self->iEnd = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(self->iEnd == 1)
|
||||
{
|
||||
self->tUpdate = 0;
|
||||
iWrite = 0;
|
||||
iRet = 0;
|
||||
}
|
||||
|
||||
if(iWrite)
|
||||
{
|
||||
if(self->iNew)
|
||||
{
|
||||
PoldiStart(self,self->pCon);
|
||||
PoldiUpdate(self,self->pCon);
|
||||
PoldiLink(self,self->pCon);
|
||||
}
|
||||
else
|
||||
{
|
||||
PoldiUpdate(self,self->pCon);
|
||||
}
|
||||
}
|
||||
return iRet;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static void KillPolterdi(void *pData){
|
||||
pPolterdi self = (pPolterdi)pData;
|
||||
if(!self)
|
||||
return;
|
||||
|
||||
if(self->pDes){
|
||||
DeleteDescriptor(self->pDes);
|
||||
}
|
||||
if(self->pFile){
|
||||
free(self->pFile);
|
||||
}
|
||||
if(self->dictfile){
|
||||
free(self->dictfile);
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
int PolterInstall(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
pPolterdi pNew = NULL;
|
||||
pICallBack pCall = NULL;
|
||||
pDummy pDum;
|
||||
pHistMem pHist = NULL;
|
||||
|
||||
/* configure fortify */
|
||||
/*
|
||||
iFortifyScope = Fortify_EnterScope();
|
||||
Fortify_CheckAllMemory();
|
||||
*/
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to PolterInstall",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
pHist = (pHistMem)FindCommandData(pSics,HM,"HistMem");
|
||||
|
||||
if (!pHist)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Histogram memory NOT found",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pNew = (pPolterdi)malloc(sizeof(Polterdi));
|
||||
if(!pNew){
|
||||
SCWrite(pCon,"ERROR: out of memory in PolterInstall",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pNew,0,sizeof(Polterdi));
|
||||
pNew->pDes = CreateDescriptor("PoldiWrite");
|
||||
pNew->pHist = pHist;
|
||||
pNew->dictfile = strdup(argv[1]);
|
||||
pNew->iInterval = 20*60;
|
||||
if(!pNew->pDes || !pNew->dictfile){
|
||||
SCWrite(pCon,"ERROR: out of memory in PolterInstall",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
/* 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);
|
||||
KillPolterdi(pNew);
|
||||
return 0;
|
||||
}
|
||||
RegisterCallback(pCall,COUNTSTART,Countstartcallback,pNew,NULL);
|
||||
RegisterCallback(pCall,COUNTEND,Countendcallback,pNew,NULL);
|
||||
|
||||
AddCommand(pSics,"storedata",PolterAction,KillPolterdi,pNew);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
int PolterAction(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
int iRet, iVal;
|
||||
pPolterdi self = NULL;
|
||||
char pBueffel[512];
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Insufficient number of arguments to StoreData",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
self = (pPolterdi)pData;
|
||||
assert(self);
|
||||
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"start") == 0)
|
||||
{
|
||||
PoldiStart(self,pCon);
|
||||
PoldiUpdate(self,pCon);
|
||||
PoldiLink(self,pCon);
|
||||
return 1;
|
||||
} else if(strcmp(argv[1],"update") == 0)
|
||||
{
|
||||
if((self->iNew) || (!self->pFile))
|
||||
{
|
||||
PoldiStart(self,pCon);
|
||||
PoldiUpdate(self,pCon);
|
||||
PoldiLink(self,pCon);
|
||||
}
|
||||
else
|
||||
{
|
||||
PoldiUpdate(self,pCon);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else if(strcmp(argv[1],"getfile") == 0)
|
||||
{
|
||||
sprintf(pBueffel,"StoreData.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,"storedata.interval = %d",self->iInterval/60);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SCWrite(pCon,"ERROR: subcommand to StoreData not recognized",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user