- fixed a little bug with hkl: phi limits were not properly tested
- updated powder file writing to properly work with mean and stddev
This commit is contained in:
290
varlog.c
290
varlog.c
@@ -6,6 +6,12 @@
|
||||
|
||||
Mark Koennecke, September 1997
|
||||
|
||||
Substantially revised to calculate running measn and standard deviations
|
||||
instead of storing data ain a list. The module now supports running
|
||||
averages and logging to file.
|
||||
|
||||
Mark Koennecke, April 2000
|
||||
|
||||
Copyright:
|
||||
|
||||
Labor fuer Neutronenstreuung
|
||||
@@ -48,15 +54,14 @@
|
||||
#include "varlog.h"
|
||||
#include "commandlog.h"
|
||||
|
||||
/* maximum number of log entries, limit memory usage */
|
||||
#define MAXLOG 2000
|
||||
/*------------------------------------------------------------------------*/
|
||||
typedef struct __VarLog
|
||||
{
|
||||
int iList;
|
||||
time_t tFrequency;
|
||||
time_t tNext;
|
||||
int iCount;
|
||||
double dSum;
|
||||
double dDeviation;
|
||||
FILE *fd;
|
||||
}VarLog;
|
||||
|
||||
@@ -79,19 +84,12 @@
|
||||
pNew->tFrequency = 300; /* 5 minutes */
|
||||
pNew->tNext = 0;
|
||||
pNew->iCount = 0;
|
||||
pNew->dSum = 0.;
|
||||
pNew->dDeviation = 0.;
|
||||
pNew->fd = NULL;
|
||||
|
||||
i = LLDcreate(sizeof(LogItem));
|
||||
if(i < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pNew->iList = i;
|
||||
*self = pNew;
|
||||
return 1;
|
||||
}
|
||||
*self = pNew;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int VarlogDelete(pVarLog self)
|
||||
@@ -100,7 +98,6 @@
|
||||
{
|
||||
fclose(self->fd);
|
||||
}
|
||||
LLDdelete(self->iList);
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@@ -108,18 +105,10 @@
|
||||
{
|
||||
int iRet, iList;
|
||||
|
||||
iList = self->iList;
|
||||
assert(iList >= 0);
|
||||
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
LLDnodeDelete(iList);
|
||||
iRet = LLDnodePtr2Prev(iList);
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
self->tNext = 0;
|
||||
self->iCount = 0;
|
||||
self->dSum = 0.;
|
||||
self->dDeviation = 0.;
|
||||
self->tNext = 0;
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
@@ -139,6 +128,7 @@
|
||||
time_t tCurrent;
|
||||
int iFile = 0;
|
||||
char pBuffer[80];
|
||||
double dMean, dTmp;
|
||||
|
||||
assert(self);
|
||||
|
||||
@@ -147,61 +137,38 @@
|
||||
/* check if we are logging to file */
|
||||
if(self->fd != NULL)
|
||||
{
|
||||
iFile = 1;
|
||||
iFile = 1;
|
||||
}
|
||||
|
||||
/* limit size of log */
|
||||
if(self->iCount > MAXLOG)
|
||||
{
|
||||
|
||||
VarlogClear(self);
|
||||
WriteToCommandLog("SYS>","WARNING: variable log cleared in order to prevent memory overflow");
|
||||
}
|
||||
|
||||
/* log always if tFrequncy is 0 */
|
||||
if(self->tFrequency == 0)
|
||||
{
|
||||
sItem.tTime = tCurrent;
|
||||
sItem.fVal = fVal;
|
||||
LLDnodeAppendFrom(self->iList, &sItem);
|
||||
self->iCount++;
|
||||
}
|
||||
/* update the running mean */
|
||||
self->dSum += fVal;
|
||||
self->iCount++;
|
||||
dMean = self->dSum/self->iCount;
|
||||
dTmp = fVal - dMean;
|
||||
self->dDeviation += dTmp*dTmp;
|
||||
|
||||
|
||||
/* if not initialised, do it */
|
||||
if(self->tNext < 1)
|
||||
{
|
||||
sItem.tTime = tCurrent;
|
||||
sItem.fVal = fVal;
|
||||
if(iFile)
|
||||
{
|
||||
VLFormatTime(tCurrent,pBuffer,79);
|
||||
fprintf(self->fd," %s %f \n", pBuffer,fVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLDnodeAppendFrom(self->iList, &sItem);
|
||||
self->iCount++;
|
||||
}
|
||||
self->tNext = tCurrent + self->tFrequency;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if, log time passed, do it */
|
||||
/* if, log time passed, write to file */
|
||||
if(tCurrent > self->tNext)
|
||||
{
|
||||
sItem.tTime = tCurrent;
|
||||
sItem.fVal = fVal;
|
||||
if(iFile)
|
||||
{
|
||||
VLFormatTime(tCurrent,pBuffer,79);
|
||||
fprintf(self->fd," %s %f \n", pBuffer,fVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLDnodeAppendFrom(self->iList, &sItem);
|
||||
self->iCount++;
|
||||
}
|
||||
self->tNext = tCurrent + self->tFrequency;
|
||||
return 1;
|
||||
}
|
||||
@@ -210,115 +177,31 @@
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int VarlogLength(pVarLog self, int *iLength)
|
||||
{
|
||||
int iLang, iRet, iList;
|
||||
|
||||
iList = self->iList;
|
||||
assert(iList >= 0);
|
||||
|
||||
iLang = 0;
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
iLang++;
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
*iLength = iLang;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int VarlogGetTime(pVarLog self, time_t *tTime)
|
||||
{
|
||||
int iRet, i, iList;
|
||||
LogItem sItem;
|
||||
|
||||
iList = self->iList;
|
||||
assert(iList >= 0);
|
||||
|
||||
i = 0;
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
LLDnodeDataTo(iList,&sItem);
|
||||
tTime[i] = sItem.tTime;
|
||||
i++;
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int VarlogGetVal(pVarLog self, float *fValue)
|
||||
{
|
||||
int iRet, i, iList;
|
||||
LogItem sItem;
|
||||
|
||||
iList = self->iList;
|
||||
assert(iList >= 0);
|
||||
|
||||
i = 0;
|
||||
iRet = LLDnodePtr2First(iList);
|
||||
while(iRet != 0)
|
||||
{
|
||||
LLDnodeDataTo(iList,&sItem);
|
||||
fValue[i] = sItem.fVal;
|
||||
i++;
|
||||
iRet = LLDnodePtr2Next(iList);
|
||||
}
|
||||
*iLength = self->iCount;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int VarlogGetMean(pVarLog self, float *fMean, float *fStdDev)
|
||||
{
|
||||
int i, iLength = 0, iList;
|
||||
float fM, fStd, fSum,fD, *fVal = NULL;
|
||||
double dMean, dStdDev;
|
||||
|
||||
iList = self->iList;
|
||||
assert(iList >= 0);
|
||||
|
||||
VarlogLength(self,&iLength);
|
||||
if(iLength < 1) /* nothing to do */
|
||||
if(self->iCount > 0)
|
||||
{
|
||||
*fMean = 0.;
|
||||
*fStdDev = 0.;
|
||||
return 0;
|
||||
dMean = self->dSum/(double)self->iCount;
|
||||
dStdDev = sqrt(self->dDeviation/(double)self->iCount);
|
||||
}
|
||||
|
||||
/* get some memory for values */
|
||||
fVal = (float *)malloc(iLength*sizeof(float));
|
||||
if(!fVal)
|
||||
else
|
||||
{
|
||||
*fMean = 0.;
|
||||
*fStdDev = 0.;
|
||||
return 0;
|
||||
dMean = .0;
|
||||
dStdDev = .0;
|
||||
}
|
||||
|
||||
/* get values */
|
||||
VarlogGetVal(self, fVal);
|
||||
|
||||
/* calculate mean first */
|
||||
fSum = 0.;
|
||||
for(i = 0; i < iLength; i++)
|
||||
{
|
||||
fSum += fVal[i];
|
||||
}
|
||||
fM = fSum/(float)iLength;
|
||||
|
||||
/* do standard deviation */
|
||||
fSum = 0.;
|
||||
for(i = 0; i < iLength; i++)
|
||||
{
|
||||
fD = fM - fVal[i];
|
||||
fSum += fD*fD;
|
||||
}
|
||||
fStd = sqrt(fSum/(float)iLength);
|
||||
|
||||
*fMean = fM;
|
||||
*fStdDev = fStd;
|
||||
free(fVal);
|
||||
|
||||
*fMean = (float)dMean;
|
||||
*fStdDev = (float)dStdDev;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
int VarlogWrapper(pVarLog self, int *iSwitch, SConnection *pCon,
|
||||
int VarlogWrapper(pVarLog self, SConnection *pCon,
|
||||
char *subcommand, char *sub2, char *pVarName)
|
||||
{
|
||||
float fMean, fStdDev, *fData = NULL;
|
||||
@@ -329,22 +212,9 @@
|
||||
long lNew;
|
||||
|
||||
|
||||
iList = self->iList;
|
||||
strtolower(subcommand);
|
||||
/*------------ on */
|
||||
if(strcmp(subcommand,"on") == 0)
|
||||
{
|
||||
*iSwitch = 1;
|
||||
return 1;
|
||||
}
|
||||
/*----------- off */
|
||||
else if(strcmp(subcommand,"off") == 0)
|
||||
{
|
||||
*iSwitch = 0;
|
||||
return 1;
|
||||
}
|
||||
/*--------- file */
|
||||
else if(strcmp(subcommand,"file") == 0)
|
||||
if(strcmp(subcommand,"file") == 0)
|
||||
{
|
||||
if(self->fd != NULL)
|
||||
{
|
||||
@@ -363,10 +233,19 @@
|
||||
{
|
||||
self->tFrequency = 300;
|
||||
}
|
||||
*iSwitch = 1;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*----- flush */
|
||||
else if(strcmp(subcommand,"flush") == 0)
|
||||
{
|
||||
if(self->fd != NULL)
|
||||
{
|
||||
fflush(self->fd);
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*----- close */
|
||||
else if(strcmp(subcommand,"close") == 0)
|
||||
{
|
||||
@@ -375,82 +254,20 @@
|
||||
fclose(self->fd);
|
||||
self->fd = NULL;
|
||||
}
|
||||
*iSwitch = 0;
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/* ------------ gettime */
|
||||
else if(strcmp(subcommand,"gettime") == 0)
|
||||
/*----- status */
|
||||
else if(strcmp(subcommand,"status") == 0)
|
||||
{
|
||||
iRet = VarlogLength(self, &iLength);
|
||||
if(!iRet)
|
||||
if(self->fd != NULL)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Invalid logging list",eError);
|
||||
return 0;
|
||||
SCWrite(pCon,"Logging to file on",eValue);
|
||||
}
|
||||
pTArray = (time_t *)malloc(iLength * sizeof(time_t));
|
||||
if(!pTArray)
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in varlog",eError);
|
||||
return 0;
|
||||
SCWrite(pCon,"No Logging to file",eValue);
|
||||
}
|
||||
VarlogGetTime(self,pTArray);
|
||||
/* format into a string */
|
||||
pData = (char *)malloc((iLength*35+100)*sizeof(char));
|
||||
if(!pData)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in varlog",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pData,0,(iLength*35+100)*sizeof(char));
|
||||
sprintf(pData,"%s.TimeStaamps = {",pVarName);
|
||||
for(i = 0; i < iLength; i++)
|
||||
{
|
||||
strcat(pData,",");
|
||||
VLFormatTime(pTArray[i],pBueffel,80);
|
||||
strcat(pData,pBueffel);
|
||||
}
|
||||
strcat(pData,"}");
|
||||
SCWrite(pCon,pData,eValue);
|
||||
free(pTArray);
|
||||
free(pData);
|
||||
return 1;
|
||||
}
|
||||
/*------------ getval */
|
||||
else if(strcmp(subcommand,"getval") == 0)
|
||||
{
|
||||
iRet = VarlogLength(self, &iLength);
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: Invalid logging list",eError);
|
||||
return 0;
|
||||
}
|
||||
fData = (float *)malloc(iLength * sizeof(float));
|
||||
if(!fData)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in varlog",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(fData,0,iLength *sizeof(float));
|
||||
VarlogGetVal(self,fData);
|
||||
/* format a reply */
|
||||
pData = (char *)malloc((iLength*11+50)*sizeof(char));
|
||||
if(!pData)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in varlog",eError);
|
||||
return 0;
|
||||
}
|
||||
memset(pData,0,(iLength*11+50)*sizeof(char));
|
||||
sprintf(pData,"%s.Values = {",pVarName);
|
||||
for(i = 0; i < iLength; i++)
|
||||
{
|
||||
strcat(pData,",");
|
||||
sprintf(pBueffel,"%8.2f",fData[i]);
|
||||
strcat(pData,pBueffel);
|
||||
}
|
||||
SCWrite(pCon,pData,eValue);
|
||||
free(fData);
|
||||
free(pData);
|
||||
return 1;
|
||||
}
|
||||
/*--------- getmean */
|
||||
@@ -470,7 +287,6 @@
|
||||
/*------------ clear */
|
||||
else if(strcmp(subcommand,"clear") == 0)
|
||||
{
|
||||
*iSwitch = 0;
|
||||
return VarlogClear(self);
|
||||
}
|
||||
/*------------- frequency */
|
||||
|
||||
Reference in New Issue
Block a user