Files
sics/histmem.c
Koennecke Mark 66466c1c0f This is the first working version of the new logging system. Some work
in fine tuning still needs to be done. But is reasonably OK now.
2016-02-11 13:40:31 +01:00

1842 lines
50 KiB
C

/*--------------------------------------------------------------------------
H I S T M E M
The SICS histogram memory object.
Mark Koennecke, April 1996
revised: Mark Koennecke, June 1997
added getzip: Mark Koennecke, October 2000
Refactored data handling into separater HMdata class.
Mark Koennecke, January 2003
Added function to retrieve time delay and to format TOF bin array in order
to speed up TOF configuration for new http based HM's
Mark Koennecke, March 2009
Added an error field in the options stringdict
Mark Koennecke, June 2013
Copyright:
Labor fuer Neutronenstreuung
Paul Scherrer Institut
CH-5423 Villigen-PSI
The authors hereby grant permission to use, copy, modify, distribute,
and license this software and its documentation for any purpose, provided
that existing copyright notices are retained in all copies and that this
notice is included verbatim in any distributions. No written agreement,
license, or royalty fee is required for any of the authorized uses.
Modifications to this software may be copyrighted by their authors
and need not follow the licensing terms described here, provided that
the new terms are clearly indicated on the first page of each file where
they apply.
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
MODIFICATIONS.
----------------------------------------------------------------------------*/
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <tcl.h>
#include <time.h>
#include "sics.h"
#include "fortify.h"
#include "countdriv.h"
#include "counter.h"
#include "stringdict.h"
#include "splitter.h"
#include "HistMem.h"
#include "HistDriv.i"
#include "HistMem.i"
#include "histsim.h"
#include "mcstashm.h"
#include "dynstring.h"
#include "event.h"
#include "status.h"
#include "site.h"
#include "histmemsec.h"
#define ABS(x) (x < 0 ? -(x) : (x))
/*
#define LOADDEBUG 1
*/
/*
* from histregress.c
*/
extern pHistDriver CreateRegressHM(pStringDict pOpt);
/*
* from slavehm.c
*/
extern pHistDriver MakeHMSlaveHM(pStringDict pOpt);
/*------------------------------------------------------------------------*/
int isSecondGen(pHistMem self)
{
pDummy test = (pDummy)self;
if(strcmp(test->pDescriptor->name,"HistMemSec") == 0) {
return 1;
} else {
return 0;
}
}
/*-----------------------------------------------------------------------*/
pHistMem FindHM(SicsInterp *pSics, char *name)
{
pHistMem result = NULL;
result = (pHistMem)FindCommandData(pSics,name,"HistMem");
if(result == NULL){
result = (pHistMem)FindCommandData(pSics,name,"HistMemSec");
}
return result;
}
/*------------------------------------------------------------------------*/
static int HistHalt(void *pData)
{
pHistMem self = NULL;
self = (pHistMem) pData;
assert(self);
if (!self->iInit) {
return 0;
}
return self->pDriv->Halt(self->pDriv);
}
/*------------------------------------------------------------------------*/
static int HistSave(void *pData, char *name, FILE * fd)
{
pHistMem self = NULL;
char *pMode[] = {
"timer",
"monitor",
NULL
};
CounterMode eCount;
float fVal;
self = (pHistMem) pData;
assert(self);
if (!self->iInit) {
return 0;
}
/* counting modes */
eCount = GetHistCountMode(self);
fprintf(fd, "%s CountMode %s\n", name, pMode[eCount]);
fVal = GetHistPreset(self);
fprintf(fd, "%s preset %f\n", name, fVal);
/* time binning if TOF */
if (isInTOFMode(self->pDriv->data)) {
fprintf(fd, "%s genbin %f %f %d\n",
name, self->pDriv->data->timeBinning[0],
self->pDriv->data->timeBinning[1] -
self->pDriv->data->timeBinning[0],
self->pDriv->data->nTimeChan);
fprintf(fd, "%s init\n", name);
}
return 1;
}
/*------------------------------------------------------------------------*/
static void *GetHistInterface(void *pData, int iID)
{
pHistMem self = NULL;
self = (pHistMem) pData;
if (iID == COUNTID) {
return self->pCountInt;
} else if (iID == CALLBACKINTERFACE) {
return self->pCall;
}
return NULL;
}
/*------------------------------------------------------------------------*/
static void HistSetParameter(void *pData, float fPreset, CounterMode eMode)
{
pHistMem self = NULL;
self = (pHistMem) pData;
assert(self);
self->pDriv->eCount = eMode;
self->pDriv->fCountPreset = fPreset;
}
/*-------------------------------------------------------------------------*/
static int HistStartCount(void *pData, SConnection * pCon)
{
pHistMem self = NULL;
char pBueffel[512];
char pError[80];
int iErr, iRet, i;
self = (pHistMem) pData;
assert(self);
if (!GetCountLock(self->pCountInt, pCon)) {
return HWFault;
}
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eLogError);
return 0;
}
/* try at least three times to do it */
StringDictUpdate(self->pDriv->pOption, "error", "None");
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Start(self->pDriv, pCon);
if (iRet == OKOK) {
/* send a COUNTSTART event */
clearHMData(self->pDriv->data);
InvokeCallBack(self->pCall, COUNTSTART, pCon);
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eLogError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
eLogError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
StringDictUpdate(self->pDriv->pOption, "error", pError);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
/*-------------------------------------------------------------------------*/
static int HistPause(void *pData, SConnection * pCon)
{
pHistMem self = NULL;
char pBueffel[512];
char pError[80];
int iErr, iRet, i;
self = (pHistMem) pData;
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
}
/* try at least three times to do it */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Pause(self->pDriv, pCon);
if (iRet == OKOK) {
updateHMData(self->pDriv->data);
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
/*-------------------------------------------------------------------------*/
static int HistContinue(void *pData, SConnection * pCon)
{
pHistMem self = NULL;
char pBueffel[512];
char pError[80];
int iErr, iRet, i;
self = (pHistMem) pData;
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
}
/* try at least three times to do it */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->Continue(self->pDriv, pCon);
if (iRet == OKOK) {
updateHMData(self->pDriv->data);
return iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
eError);
SCSetInterrupt(pCon, eAbortBatch);
ReleaseCountLock(self->pCountInt);
return HWFault;
}
}
}
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
ReleaseCountLock(self->pCountInt);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
/*-------------------------------------------------------------------------*/
static int HistCountStatus(void *pData, SConnection * pCon)
{
pHistMem self = NULL;
int eCt, iRet, iErr;
char pBueffel[512], pError[90];
self = (pHistMem) pData;
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
return COTERM;
}
eCt = self->pDriv->GetCountStatus(self->pDriv, pCon);
if (eCt == HWFault) {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
eError);
SCSetInterrupt(pCon, eAbortBatch);
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
StringDictUpdate(self->pDriv->pOption, "error", pError);
return eCt;
} else {
updateHMData(self->pDriv->data);
return HWBusy;
}
}
/* if (eCt == HWBusy){ */
/* updateHMData(self->pDriv->data); */
/* } */
if (eCt == HWIdle) {
/* force an update of local histogram data with next
GetHistogram
*/
updateHMData(self->pDriv->data);
InvokeCallBack(self->pCall, COUNTEND, NULL);
ReleaseCountLock(self->pCountInt);
}
return eCt;
}
/*-------------------------------------------------------------------------
The question arises if the histograms shall be duplicated on the host
computer or not. They need to be in order to be written to file!
*/
static int HistTransfer(void *pData, SConnection * pCon)
{
pHistMem self = NULL;
int i, iErr, iRet, iStatus;
char pBueffel[512], pError[80];
self = (pHistMem) pData;
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return COTERM;
}
/* try at least three times */
for (i = 0; i < 3; i++) {
iRet = self->pDriv->GetData(self->pDriv, pCon);
if (iRet == OKOK) {
self->pDriv->iUpdate = 0;
iStatus = iRet;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "WARNING: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
SCWrite(pCon, "ERROR: failed to fix histogram memory problem",
eError);
SCSetInterrupt(pCon, eAbortBatch);
StringDictUpdate(self->pDriv->pOption, "error", pError);
iStatus = HWFault;
}
}
}
if (iRet == OKOK) {
return iStatus;
}
SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError);
SCSetInterrupt(pCon, eAbortBatch);
return HWFault;
}
/*-------------------------------------------------------------------------*/
pHistMem CreateHistMemory(char *driver)
{
pHistMem pNew = NULL;
pSite site = NULL;
pStringDict pOption;
/* make memory */
pNew = (pHistMem) malloc(sizeof(HistMem));
if (!pNew) {
return NULL;
}
memset(pNew, 0, sizeof(HistMem));
/* make object descriptor */
pNew->pDes = CreateDescriptor("HistMem");
if (!pNew->pDes) {
free(pNew);
return NULL;
}
pNew->pDes->SaveStatus = HistSave;
pNew->pDes->GetInterface = GetHistInterface;
/* initialise countable interface */
pNew->pCountInt = CreateCountableInterface();
if (!pNew->pCountInt) {
DeleteDescriptor(pNew->pDes);
free(pNew);
return NULL;
}
/* initialise callback interface */
pNew->pCall = CreateCallBackInterface();
if (!pNew->pCall) {
DeleteDescriptor(pNew->pDes);
free(pNew);
return NULL;
}
pNew->pCountInt->SetCountParameters = HistSetParameter;
pNew->pCountInt->StartCount = HistStartCount;
pNew->pCountInt->CheckCountStatus = HistCountStatus;
pNew->pCountInt->TransferData = HistTransfer;
pNew->pCountInt->Halt = HistHalt;
pNew->pCountInt->Pause = HistPause;
pNew->pCountInt->Continue = HistContinue;
/* initialise options dictionary */
pOption = CreateStringDict();
if (!pOption) {
DeleteDescriptor(pNew->pDes);
free(pNew);
return NULL;
}
StringDictAddPair(pOption, "driver", driver);
StringDictAddPair(pOption, "update", "0");
StringDictAddPair(pOption, "error", "None");
/* initialise driver */
if (strcmp(driver, "sim") == 0) {
pNew->pDriv = CreateSIMHM(pOption);
} else if (strcmp(driver, "mcstas") == 0) {
pNew->pDriv = NewMcStasHM(pOption);
} else if (strcmp(driver, "regress") == 0) {
pNew->pDriv = CreateRegressHM(pOption);
}
/*
else if(strcmp(driver,"slave") == 0)
{
pNew->pDriv = MakeHMSlaveHM(pOption);
}
*/
else {
site = getSite();
if (site != NULL) {
pNew->pDriv = site->CreateHistogramMemoryDriver(driver, pOption);
}
}
if (pNew->pDriv == NULL) {
DeleteDescriptor(pNew->pDes);
DeleteStringDict(pOption);
free(pNew);
return NULL;
}
pNew->iAccess = usUser;
pNew->iExponent = 0;
pNew->iInit = 0;
pNew->pDriv->pOption = pOption;
return pNew;
}
/*-----------------------------------------------------------------------*/
void DeleteHistMemory(void *pData)
{
pHistMem self;
self = (pHistMem) pData;
assert(self);
if (self->pDriv) {
DeleteHistDriver(self->pDriv);
}
if (self->pDes) {
DeleteDescriptor(self->pDes);
}
(void)Fortify_CheckAllMemory();
if (self->pCountInt) {
free(self->pCountInt);
}
if (self->pCall) {
DeleteCallBackInterface(self->pCall);
}
free(self);
}
/*-------------------------------------------------------------------------*/
int MakeHistMemory(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pHistMem pNew = NULL;
char pBueffel[512];
int iRet;
/* check no of arguments */
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: insufficient no of arguments to %s",
argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* make new HM */
strtolower(argv[2]);
pNew = CreateHistMemory(argv[2]);
if (!pNew) {
snprintf(pBueffel,sizeof(pBueffel)-1,
"ERROR: failed to create Histogram Memory %s, driver %s may be invalid or no memory",
argv[1], argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
StringDictAddPair(pNew->pDriv->pOption, "name", argv[1]);
/* install HM as command */
iRet =
AddCommand(pSics, argv[1], HistAction, DeleteHistMemory,
(void *) pNew);
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon, pBueffel, eError);
DeleteHistMemory((void *) pNew);
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
int HistGetOption(pHistMem self, char *name, char *result, int iLen)
{
assert(self);
strtolower(name);
return StringDictGet(self->pDriv->pOption, name, result, iLen);
}
/*-----------------------------------------------------------------------*/
int HistSetOption(pHistMem self, char *name, char *value)
{
int status;
assert(self);
self->iInit = 1;
strtolower(name);
status = StringDictUpdate(self->pDriv->pOption, name, value);
if (status == 0) {
return StringDictAddPair(self->pDriv->pOption, name, value);
}
return 1;
}
/*-----------------------------------------------------------------------*/
int HistConfigure(pHistMem self, SConnection * pCon, SicsInterp * pSics)
{
int iRet, iVal;
char pValue[80];
assert(self);
assert(pCon);
if (isRunning(self->pCountInt)) {
SCWrite(pCon,
"ERROR: cannot configure histogram memory while counting",
eError);
return 0;
}
iRet = HistDriverConfig(self->pDriv, self->pDriv->pOption, pCon);
if (!iRet) {
SCWrite(pCon, "ERROR: failed to configure histogram memory", eError);
return 0;
}
iRet =
self->pDriv->Configure(self->pDriv, pCon, self->pDriv->pOption,
pSics);
if (!iRet) {
SCWrite(pCon, "ERROR: failed to configure histogram memory", eError);
return 0;
}
tracePar(self->pDes->name,"initialized");
return 1;
}
/*--------------------------------------------------------------------------*/
float GetHistPreset(pHistMem self)
{
int i;
float fVal;
assert(self);
fVal = self->pDriv->fCountPreset;
if (self->pDriv->eCount == ePreset) {
for (i = 0; i < self->iExponent; i++) {
fVal /= 10.;
}
}
return fVal;
}
/*--------------------------------------------------------------------------*/
int SetHistPreset(pHistMem self, float fVal)
{
int i;
assert(self);
if (fVal < .0) {
return 0;
}
if (GetHistCountMode(self) == ePreset) {
for (i = 0; i < self->iExponent; i++) {
fVal *= 10.;
}
}
self->pDriv->fCountPreset = fVal;
return 1;
}
/*--------------------------------------------------------------------------*/
int GetHistDim(pHistMem self, int iDim[MAXDIM], int *nDim)
{
assert(self);
pDummy pDum;
hdbValue v;
pHdb node;
pDum = (pDummy)self;
if(strcmp(pDum->pDescriptor->name,"HistMemSec") == 0){
node = GetHipadabaNode(pDum->pDescriptor->parNode,"dim");
assert(node != NULL);
GetHipadabaPar(node,&v,NULL);
*nDim = v.arrayLength;
memcpy(iDim,v.v.intArray, *nDim*sizeof(int));
return 1;
}
getHMDataDim(self->pDriv->data, iDim, nDim);
if (isInTOFMode(self->pDriv->data)) {
iDim[*nDim] = getNoOfTimebins(self->pDriv->data);
*nDim = *nDim + 1;
}
return 1;
}
/*--------------------------------------------------------------------------*/
long HistSum(pHistMem self, SConnection * pCon,
int iStart[MAXDIM], int iEnd[MAXDIM])
{
assert(self);
return sumHMDataRectangle(self, pCon, iStart, iEnd);
}
/*---------------------------------------------------------------------------*/
CounterMode GetHistCountMode(pHistMem self)
{
assert(self);
return self->pDriv->eCount;
}
/*--------------------------------------------------------------------------*/
int SetHistCountMode(pHistMem self, CounterMode eNew)
{
int i;
assert(self);
if (eNew == self->pDriv->eCount) {
return 1;
}
if (eNew == eTimer) {
for (i = 0; i < self->iExponent; i++) {
self->pDriv->fCountPreset /= 10.;
}
}
if (eNew == ePreset) {
for (i = 0; i < self->iExponent; i++) {
self->pDriv->fCountPreset *= 10.;
}
}
self->pDriv->eCount = eNew;
return 1;
}
/*--------------------------------------------------------------------------*/
long GetHistMonitor(pHistMem self, int i, SConnection * pCon)
{
assert(self);
return self->pDriv->GetMonitor(self->pDriv, i, pCon);
}
/*-----------------------------------------------------------------------*/
void HistDirty(pHistMem self)
{
assert(self);
if(isSecondGen(self)){
SecHistDirty(self);
return;
}
if(self->pDriv != NULL){
updateHMData(self->pDriv->data);
}
}
/*-------------------------------------------------------------------------*/
const float *GetHistTimeBin(pHistMem self, int *iLength)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistTimeBin(self,iLength);
}
*iLength = getNoOfTimebins(self->pDriv->data);
return getTimeBinning(self->pDriv->data);
}
/*-------------------------------------------------------------------------*/
int GetHistLength(pHistMem self)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistLength(self);
}
return getHMDataLength(self->pDriv->data);
}
/*--------------------------------------------------------------------------*/
float GetHistCountTime(pHistMem self, SConnection * pCon)
{
assert(self);
return self->pDriv->GetTime(self->pDriv, pCon);
}
/*-------------------------------------------------------------------------*/
int HistDoCount(pHistMem self, SConnection * pCon)
{
assert(self);
/* start */
return StartDevice(GetExecutor(), "HistogramMemory", self->pDes, self,
pCon, RUNRUN, self->pDriv->fCountPreset);
}
/*-----------------------------------------------------------------------*/
int HistBlockCount(pHistMem self, SConnection * pCon)
{
int iRet;
assert(self);
/* start counting */
iRet = StartDevice(GetExecutor(), "HistogramMemory", self->pDes, self,
pCon, RUNDRIVE, self->pDriv->fCountPreset);
if (!iRet) {
/* error has already been reported */
return 0;
}
/* wait till end */
iRet = Wait4Success(GetExecutor());
if (iRet == DEVINT) {
SCWrite(pCon, "Counting aborted due to Interrupt", eError);
} else if (iRet == DEVERROR) {
SCWrite(pCon, "Counting finished with Problems", eValue);
iRet = 1;
} else {
SCWrite(pCon, "Counting finished", eValue);
iRet = 1;
}
return iRet;
}
/*-------------------------------------------------------------------------*/
int SetHistogram(pHistMem self, SConnection * pCon,
int i, int iStart, int iEnd, HistInt * lData)
{
int ii, iErr, iRet;
char pBueffel[512], pError[80];
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
}
/* try at least three times */
for (ii = 0; ii < 3; ii++) {
iRet = self->pDriv->SetHistogram(self->pDriv, pCon,
i, iStart, iEnd, lData);
if (iRet == OKOK) {
updateHMData(self->pDriv->data);
return 1;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
return 0;
}
}
}
return 0;
}
/*-------------------------------------------------------------------------*/
int GetHistogram(pHistMem self, SConnection * pCon,
int i, int iStart, int iEnd, HistInt * lData,
int iDataLen)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistogram(self,pCon,i,iStart,iEnd,lData,iDataLen);
}
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
}
if ((iEnd - iStart) > iDataLen / sizeof(HistInt)) {
SCWrite(pCon, "WARNING: truncating request to fit data space",
eWarning);
iEnd = (iDataLen / sizeof(HistInt)) - 1;
}
return getHMDataHistogram(self, pCon, i, iStart, iEnd-iStart, lData);
}
/*-------------------------------------------------------------------------*/
int GetHistogramDirect(pHistMem self, SConnection * pCon,
int i, int iStart, int iEnd, HistInt * lData,
int iDataLen)
{
int ii, iErr, iRet, iCopy;
char pBueffel[512], pError[80];
HistInt *lHist = NULL;
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
}
/* try at least three times */
for (ii = 0; ii < 3; ii++) {
iRet = self->pDriv->GetHistogram(self->pDriv, pCon,
i, iStart, iEnd, lData);
if (iRet == OKOK) {
tracePar(self->pDes->name,"!!datachange!!");
break;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
StringDictUpdate(self->pDriv->pOption, "error", pError);
return 0;
}
}
}
return 1;
}
/*-----------------------------------------------------------------------*/
HistInt *GetHistogramPointer(pHistMem self, SConnection * pCon)
{
assert(self);
if(isSecondGen(self)){
return GetSecHistogramPointer(self,pCon);
}
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return NULL;
}
return getHMDataBufferPointer(self, pCon);
}
/*--------------------------------------------------------------------------*/
int PresetHistogram(pHistMem self, SConnection * pCon, HistInt lVal)
{
int ii, iErr, iRet;
char pBueffel[512], pError[80];
assert(self);
if (!self->iInit) {
SCWrite(pCon, "ERROR: histogram memory not initialised", eError);
return 0;
}
/* try at least three times */
for (ii = 0; ii < 3; ii++) {
iRet = self->pDriv->Preset(self->pDriv, pCon, lVal);
if (iRet == OKOK) {
updateHMData(self->pDriv->data);
return 1;
} else {
iRet = self->pDriv->GetError(self->pDriv, &iErr, pError, 79);
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s ", pError);
SCWrite(pCon, pBueffel, eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr);
if (iRet == COTERM) {
StringDictUpdate(self->pDriv->pOption, "error", pError);
return 0;
}
}
}
return 0;
}
/*----------------------------------------------------------------------*/
static int HMCountInterest(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
char pBueffel[512];
pCon = (SConnection *) pUser;
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
if (iEvent == COUNTSTART && pUser != NULL) {
pCon = (SConnection *) pUser;
assert(pCon);
SCWrite(pCon, "HMCOUNTSTART", eEvent);
return 1;
} else if (iEvent == COUNTEND) {
assert(pCon);
SCWrite(pCon, "HMCOUNTEND", eEvent);
return 1;
}
return 0;
}
/*----------------------------------------------------------------------*/
static int checkHMEnd(pHistMem self, char *text)
{
int iTest, iEnd;
iEnd = getHMDataLength(self->pDriv->data);
if (text == NULL) {
return iEnd;
} else {
iTest = atoi(text);
if (iTest > iEnd) {
return iEnd;
} else {
return iTest;
}
}
}
/*--------------------------------------------------------------------------*/
void HMListOption(pHistMem self, SConnection * pCon)
{
char pBuffer[512];
char name[20];
char pValue[128];
const char *pKey;
int i, iRet, iLen, iRank, iDiscard, tofMode;
float fVal;
char *pMode[] = { "timer", "monitor", NULL };
pDynString buf = NULL;
memset(pBuffer, 0, sizeof(pBuffer));
memset(pValue, 0, sizeof(pValue));
memset(name, 0, sizeof(name));
buf = CreateDynString(256,256);
if(buf == NULL){
SCWrite(pCon,"ERROR: out of memory listing HM Options",eError);
return;
}
iRet = StringDictGet(self->pDriv->pOption, "name", name, 19);
if (0 == iRet) {
strcpy(name, "*");
}
iRet =
StringDictGet(self->pDriv->pOption, "driver", pValue,
sizeof(pValue) - 1);
if (0 < iRet) {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.driver = %s", name, pValue);
DynStringConcatLine(buf,pBuffer);
}
iRet = StringDictGetAsNumber(self->pDriv->pOption, "update", &fVal);
if (0 < iRet) {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.update = %d", name, (int) rint(fVal));
} else {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.update = 0 (no buffering)", name);
}
DynStringConcatLine(buf,pBuffer);
iRet = StringDictGetAsNumber(self->pDriv->pOption, "rank", &fVal);
if (0 < iRet) {
iRank = (int) rint(fVal);
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.rank = %d", name, iRank);
DynStringConcatLine(buf,pBuffer);
} else {
iRank = 0;
}
for (i = 0; i < iRank; i++) {
snprintf(pValue,sizeof(pValue)-1, "dim%1.1d", i);
iRet = StringDictGetAsNumber(self->pDriv->pOption, pValue, &fVal);
if (0 < iRet) {
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.dim%1.1d = %d", name, i, (int) rint(fVal));
DynStringConcatLine(buf,pBuffer);
}
}
pKey =
StringDictGetNext(self->pDriv->pOption, pValue, sizeof(pValue) - 1);
while (pKey != NULL) {
iDiscard = 0;
if (0 == strcmp("name", pKey))
iDiscard = 1;
if (0 == strcmp("driver", pKey))
iDiscard = 1;
if (0 == strcmp("update", pKey))
iDiscard = 1;
if (0 == strcmp("rank", pKey))
iDiscard = 1;
if (NULL != strstr(pKey, "dim"))
iDiscard = 1;
if (0 == iDiscard) {
snprintf(pBuffer, 511, "%s.%s = %s", name, pKey, pValue);
DynStringConcatLine(buf,pBuffer);
}
pKey =
StringDictGetNext(self->pDriv->pOption, pValue,
sizeof(pValue) - 1);
}
/* Display Count Mode */
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.CountMode = %s", name, pMode[self->pDriv->eCount]);
DynStringConcatLine(buf,pBuffer);
SCWrite(pCon, pBuffer, eValue);
/* Display Preset */
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.preset = %f", name, self->pDriv->fCountPreset);
DynStringConcatLine(buf,pBuffer);
if (self->pDriv->data->nTimeChan > 2) {
tofMode = 1;
} else {
tofMode = 0;
}
snprintf(pBuffer,sizeof(pBuffer)-1, "%s.tofMode = %d", name, tofMode);
DynStringConcatLine(buf,pBuffer);
SCWrite(pCon, GetCharArray(buf), eValue);
DeleteDynString(buf);
}
/*--------------------------------------------------------------------------*/
static pDynString formatTOF(pHistMem self)
{
const float *timebin;
int iLength, i, delay, delta = .0;
char number[20];
pDynString result = NULL;
timebin = GetHistTimeBin(self, &iLength);
if(timebin != NULL){
delay = timebin[0];
result = CreateDynString(512,512);
if(result == NULL){
return NULL;
}
for(i = 0; i < iLength; i++){
snprintf(number,20," %12d", (int)(timebin[i] - delay));
DynStringConcat(result,number);
if(i % 5 == 0 && i != 0){
DynStringConcatChar(result,'\n');
}
}
/*
* add the extra one
*/
if(iLength > 3){
delta = ABS(timebin[iLength -2] - timebin[iLength -1]);
}
snprintf(number,20," %12d", (int)(timebin[iLength -1] + delta - delay ));
DynStringConcat(result,number);
return result;
} else {
return NULL;
}
}
/*--------------------------------------------------------------------------*/
int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pHistMem self = NULL;
char pBueffel[512], pNumber[20];
int iaStart[MAXDIM], iaEnd[MAXDIM];
Tcl_DString tResult;
int iRet, iVal;
char *pBuf = NULL, *pPtr;
float fVal;
long lVal;
HistInt *lData = NULL;
int iStart, iEnd, iNum, i;
pDynString tofres = NULL;
CounterMode eCount;
char *pMode[] = {
"timer",
"monitor",
NULL
};
double dStart, dStep;
int nDim, iSwitch;
long lID;
assert(pCon);
assert(pSics);
assert(pData);
self = (pHistMem) pData;
/* check arguments */
if (argc < 2) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: no arguments specified to %s", argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* interest command */
strtolower(argv[1]);
if (strcmp(argv[1], "interest") == 0) {
lID = RegisterCallback(self->pCall,
COUNTSTART, HMCountInterest,
SCCopyConnection(pCon), SCDeleteConnection);
lID = RegisterCallback(self->pCall,
COUNTEND, HMCountInterest,
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
} else if (strcmp(argv[1], "configure") == 0) {
/* enough arguments ? */
if (argc < 4) {
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: not enough arguments to %s configure",
argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
} else { /* get value case */
strtolower(argv[2]);
iRet = HistGetOption(self, argv[2], NULL, 0);
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: option %s not known", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
pBuf = (char *) malloc((iRet + 60) * sizeof(char));
if (!pBuf) {
SCWrite(pCon, "ERROR: no memory in HistAction", eError);
return 0;
}
memset(pBuf, 0, iRet + 60);
HistGetOption(self, argv[2], pBuf, iRet + 60);
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.%s = %s", argv[0], argv[2], pBuf);
SCWrite(pCon, pBueffel, eValue);
free(pBuf);
return 1;
}
}
/* do it */
Arg2Text(argc - 3, &argv[3], pBueffel, 511);
/* authorise */
if (!SCMatchRights(pCon, usMugger)) {
snprintf(pBueffel,sizeof(pBueffel)-1,
"ERROR: you need to be manager in order to configure %s",
argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
strtolower(argv[2]);
iRet = HistSetOption(self, argv[2], pBueffel);
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: option %s not known", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
SCSendOK(pCon);
return 1;
} else if (strcmp(argv[1], "preset") == 0) { /* preset */
if (argc < 3) { /* get value */
fVal = GetHistPreset(self);
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.preset = %f", argv[0], fVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else { /* set case */
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change preset while counting",
eError);
return 0;
}
fVal = atof(argv[2]);
if (!SCMatchRights(pCon, self->iAccess)) {
return 0;
}
iRet = SetHistPreset(self, fVal);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
} else if (strcmp(argv[1], "exponent") == 0) { /* preset */
if (argc < 3) { /* get value */
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.exponent = %d", argv[0], self->iExponent);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else { /* set case */
if (!SCMatchRights(pCon, self->iAccess)) {
return 0;
}
self->iExponent = atoi(argv[2]);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
} else if (strcmp(argv[1], "countmode") == 0) { /* countmode */
if (argc < 3) { /* get value */
eCount = GetHistCountMode(self);
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.CountMode = %s", argv[0], pMode[eCount]);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else { /* set case */
strtolower(argv[2]);
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change countmode while counting",
eError);
return 0;
}
if (!SCMatchRights(pCon, self->iAccess)) {
return 0;
}
if (strcmp(argv[2], "timer") == 0) {
eCount = eTimer;
} else if (strcmp(argv[2], "monitor") == 0) {
eCount = ePreset;
} else {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s invalid as CountMode", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iRet = SetHistCountMode(self, eCount);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
} else if (strcmp(argv[1], "init") == 0) {
if (SCMatchRights(pCon, usMugger)) {
iRet = HistConfigure(self, pCon, pSics);
if (iRet) {
self->iInit = 1;
InvokeCallBack(self->pCall,DIMCHANGE,NULL);
SCSendOK(pCon);
} else {
self->iInit = 0;
}
return iRet;
} else {
return 0;
}
} else if (strcmp(argv[1], "clearhm") == 0) {
/*
clear the local copy of the HM. Assumes that the HM
clears itself on start. Which it does.
*/
if (SCMatchRights(pCon, usUser)) {
if(self->pDriv->data != NULL){
clearHMData(self->pDriv->data);
SCSendOK(pCon);
return 1;
} else {
return 0;
}
} else {
return 0;
}
} else if (strcmp(argv[1], "list") == 0) {
HMListOption(self, pCon);
return 1;
}
/* stop */
else if (strcmp(argv[1], "stop") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
self->pDriv->Halt(self->pDriv);
SCSendOK(pCon);
return 1;
}
/* pause */
else if (strcmp(argv[1], "pause") == 0) {
if (!SCMatchRights(pCon, usUser)) {
return 0;
}
self->pDriv->Pause(self->pDriv, pCon);
SCSendOK(pCon);
return 1;
}
/* state */
else if (strcmp(argv[1], "status") == 0) {
HistCountStatus(self,pCon);
if(isRunning(self->pCountInt)){
SCPrintf(pCon,eValue,"%s.status = run",argv[0]);
} else {
SCPrintf(pCon,eValue,"%s.status = idle",argv[0]);
}
return 1;
}
/* normal counting */
else if (strcmp(argv[1], "count") == 0) {
if (SCMatchRights(pCon, self->iAccess)) {
if (IsCounting(pServ->pExecutor)) {
SCWrite(pCon, "WARNING: already counting!", eWarning);
return 1;
}
iRet = HistDoCount(self, pCon);
if (iRet == 1) {
SCSendOK(pCon);
}
return iRet;
} else {
return 0;
}
}
/* forced count, for the case several hm need to be started */
else if (strcmp(argv[1], "countf") == 0) {
if (SCMatchRights(pCon, self->iAccess)) {
iRet = HistDoCount(self, pCon);
if (iRet == 1) {
SCSendOK(pCon);
}
return iRet;
} else {
return 0;
}
}
/* count in blocking mode */
else if (strcmp(argv[1], "countblock") == 0) {
if (SCMatchRights(pCon, self->iAccess)) {
iRet = HistBlockCount(self, pCon);
if (iRet == 1) {
SCSendOK(pCon);
}
return iRet;
} else {
return 0;
}
} else if (strcmp(argv[1], "initval") == 0) { /* initialize to a value */
/* check user rights */
if (!SCMatchRights(pCon, self->iAccess)) {
return 0;
}
/* enough arguments */
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: insufficient number of arguments to %s %s",
argv[0], argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
lVal = atoi(argv[2]);
iRet = PresetHistogram(self, pCon, lVal);
if (iRet) {
SCSendOK(pCon);
}
return iRet;
} else if (strcmp(argv[1], "initfile") == 0) { /* initialize from a file */
/* check user rights */
if (!SCMatchRights(pCon, self->iAccess)) {
return 0;
}
/* enough arguments */
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: insufficient number of arguments to %s %s",
argv[0], argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iRet = loadHMData(self->pDriv->data, pCon, argv[2]);
self->pDriv->SetHistogram(self->pDriv, pCon, 0, 0, GetHistLength(self),
self->pDriv->data->localBuffer);
if (iRet) {
SCSendOK(pCon);
}
return iRet;
} else if (strcmp(argv[1], "get") == 0) { /* get a histogram */
/* check parameters, first required: no of Hist */
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: insufficient number of arguments to %s %s",
argv[0], argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iNum = atoi(argv[2]);
/* optional iStart, default 0 */
iStart = 0;
if (argc > 3) {
iStart = atoi(argv[3]);
}
/* check iStart */
if (iStart < 0) {
SCWrite(pCon, "WARNING: Invalid start position defaulted to 0",
eWarning);
iStart = 0;
}
if (argc > 4) {
iEnd = checkHMEnd(self, argv[4]);
} else {
iEnd = checkHMEnd(self, NULL);
}
if (iNum != 0 && argc > 4) {
iEnd = atoi(argv[4]);
}
/* allocate data storage and get it */
lData = (HistInt *) malloc(iEnd * sizeof(HistInt));
if (!lData) {
SCWrite(pCon, "ERROR: no memory in HistAction/get", eError);
return 0;
}
memset(lData, 0, iEnd * sizeof(HistInt));
if (iNum == 0) {
iRet = GetHistogram(self, pCon, iNum, iStart, iEnd,
lData, iEnd * sizeof(long));
} else {
iRet = GetHistogramDirect(self, pCon, iNum, iStart, iEnd,
lData, iEnd * sizeof(long));
}
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: cannot retrieve histogram %d", iNum);
SCWrite(pCon, pBueffel, eError);
free(lData);
return 0;
}
/* OK, got it, convert to text using Tcl's Dstring for lazyness */
Tcl_DStringInit(&tResult);
Tcl_DStringAppend(&tResult, "Histogram =", -1);
for (i = 0; i < iEnd - iStart; i++) {
snprintf(pNumber,sizeof(pNumber)-1, " %d", lData[i]);
Tcl_DStringAppend(&tResult, pNumber, -1);
}
/* Write it */
SCWrite(pCon, Tcl_DStringValue(&tResult), eValue);
/* clean up and go */
free(lData);
Tcl_DStringFree(&tResult);
return 1;
}
/*-------- get uuencoded */
else if (strcmp(argv[1], "uuget") == 0) { /* get a histogram */
/* check parameters, first required: no of Hist */
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: insufficient number of arguments to %s %s",
argv[0], argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iNum = atoi(argv[2]);
/* optional iStart, default 0 */
iStart = 0;
if (argc > 3) {
iStart = atoi(argv[3]);
}
/* check iStart */
if (iStart < 0) {
SCWrite(pCon, "WARNING: Invalid start position defaulted to 0",
eWarning);
iStart = 0;
}
if (argc > 4) {
iEnd = checkHMEnd(self, argv[4]);
} else {
iEnd = checkHMEnd(self, NULL);
}
/* allocate data storage and get it */
lData = (HistInt *) malloc((iEnd + 1) * sizeof(HistInt));
if (!lData) {
SCWrite(pCon, "ERROR: no memory in HistAction/get", eError);
return 0;
}
memset(lData, 0, (iEnd + 1) * sizeof(HistInt));
iRet = GetHistogram(self, pCon, iNum, iStart, iEnd,
&lData[1], iEnd * sizeof(HistInt));
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: cannot retrieve histogram %d", iNum);
SCWrite(pCon, pBueffel, eError);
free(lData);
return 0;
}
/* lData[0] is the length of the histogram */
lData[0] = iEnd;
/* convert to network byte order */
for (i = 0; i < iEnd + 1; i++) {
lData[i] = htonl(lData[i]);
}
/* Write it */
SCWriteUUencoded(pCon, "SicsHistogram", lData,
(iEnd + 1) * sizeof(HistInt));
/* clean up and go */
free(lData);
return 1;
} else if (strcmp(argv[1], "zipget") == 0) { /* get a histogram */
/* check parameters, first required: no of Hist */
if (argc < 3) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: insufficient number of arguments to %s %s",
argv[0], argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iNum = atoi(argv[2]);
/* optional iStart, default 0 */
iStart = 0;
if (argc > 3) {
iStart = atoi(argv[3]);
}
/* check iStart */
if (iStart < 0) {
SCWrite(pCon, "WARNING: Invalid start position defaulted to 0",
eWarning);
iStart = 0;
}
if (argc > 4) {
iEnd = checkHMEnd(self, argv[4]);
} else {
iEnd = checkHMEnd(self, NULL);
}
/* allocate data storage and get it */
lData = (HistInt *) malloc((iEnd + 1) * sizeof(HistInt));
if (!lData) {
SCWrite(pCon, "ERROR: no memory in HistAction/get", eError);
return 0;
}
memset(lData, 0, (iEnd + 1) * sizeof(HistInt));
iRet = GetHistogram(self, pCon, iNum, iStart, iEnd,
&lData[0], iEnd * sizeof(HistInt));
if (!iRet) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: cannot retrieve histogram %d", iNum);
SCWrite(pCon, pBueffel, eError);
free(lData);
return 0;
}
/* convert to network byte order */
for (i = 0; i < iEnd; i++) {
lData[i] = htonl(lData[i]);
}
/* Write it */
SCWriteZipped(pCon, argv[0], lData, iEnd * sizeof(HistInt));
/* clean up and go */
free(lData);
return 1;
}
/* retrive no of Timebins */
else if (strcmp(argv[1], "notimebin") == 0) {
snprintf(pBueffel,sizeof(pBueffel)-1,
"%s.notimebin = %d", argv[0],
getNoOfTimebins(self->pDriv->data));
SCWrite(pCon, pBueffel, eValue);
return 1;
}
/* retrive time binning */
else if (strcmp(argv[1], "timebin") == 0) {
Tcl_DStringInit(&tResult);
Tcl_DStringAppend(&tResult, "histogram.timebins =", -1);
for (i = 0; i < self->pDriv->data->nTimeChan; i++) {
snprintf(pBueffel,sizeof(pBueffel)-1, "%.2f ", self->pDriv->data->timeBinning[i]);
Tcl_DStringAppend(&tResult, pBueffel, -1);
}
/* Write it */
SCWrite(pCon, Tcl_DStringValue(&tResult), eValue);
/* clean up and go */
Tcl_DStringFree(&tResult);
return 1;
}
/* getdelay */
else if(strcmp(argv[1],"getdelay") == 0){
if(self->pDriv->data->nTimeChan > 1) {
iVal = (int)self->pDriv->data->timeBinning[0];
SCPrintf(pCon,eValue,"hm.delay = %d", iVal);
return 1;
} else {
SCPrintf(pCon,eError,"ERROR: no TOF configured");
return 0;
}
}
/* formattof */
else if(strcmp(argv[1],"formattof") == 0){
tofres = formatTOF(self);
if(tofres == NULL){
SCWrite(pCon,"ERROR: out of memory or not TOF", eError);
return 0;
} else {
SCWrite(pCon,GetCharArray(tofres), eValue);
DeleteDynString(tofres);
return 1;
}
}
/* generate time binning */
else if (strcmp(argv[1], "genbin") == 0) {
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change time binning while counting",
eError);
return 0;
}
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
if (argc < 5) {
SCWrite(pCon, "ERROR: not enough aguments to genbin", eError);
return 0;
}
iRet = Tcl_GetDouble(pSics->pTcl, argv[2], &dStart);
if (iRet != TCL_OK) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: Failed to convert %s to number", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iRet = Tcl_GetDouble(pSics->pTcl, argv[3], &dStep);
if (iRet != TCL_OK) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: Failed to convert %s to number", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl, argv[4], &iNum);
if (iRet != TCL_OK) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: Failed to convert %s to number", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
if (iNum >= MAXCHAN) {
SCWrite(pCon,
"ERROR: number of requested time bins exceeds maximum permissible number",
eError);
return 0;
}
if (iNum <= 0) {
SCWrite(pCon, "ERROR: at least one time bin required!", eError);
return 0;
}
/* do it */
genTimeBinning(self->pDriv->data, (float) dStart, (float) dStep, iNum);
InvokeCallBack(self->pCall,DIMCHANGE,NULL);
SCparChange(pCon);
SCSendOK(pCon);
return 1;
}
/* set a time bin */
else if (strcmp(argv[1], "setbin") == 0) {
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change time binning while counting",
eError);
return 0;
}
if (!SCMatchRights(pCon, usMugger)) {
return 0;
}
if (argc < 4) {
SCWrite(pCon, "ERROR: not enough aguments to setbin", eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl, argv[2], &iNum);
if (iRet != TCL_OK) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: Failed to convert %s to number", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
iRet = Tcl_GetDouble(pSics->pTcl, argv[3], &dStep);
if (iRet != TCL_OK) {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: Failed to convert %s to number", argv[2]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
if ((iNum < 0) || (iNum > MAXCHAN)) {
SCWrite(pCon, "ERROR: requested time bin out or permissible range",
eError);
return 0;
}
setTimeBin(self->pDriv->data, iNum, (float) dStep);
InvokeCallBack(self->pCall,DIMCHANGE,NULL);
self->iInit = 0;
SCSendOK(pCon);
return 1;
}
/* clear time bin info */
else if (strcmp(argv[1], "clearbin") == 0) {
if (isRunning(self->pCountInt)) {
SCWrite(pCon, "ERROR: cannot change time binning while counting",
eError);
return 0;
}
clearTimeBinning(self->pDriv->data);
InvokeCallBack(self->pCall,DIMCHANGE,NULL);
SCSendOK(pCon);
return 1;
}
/* error */
else if (strcmp(argv[1], "error") == 0) {
StringDictGet(self->pDriv->pOption, "error", pBueffel, sizeof(pBueffel));
SCPrintf(pCon,eValue,"%s.error = %s", argv[0], pBueffel);
return 1;
}
/*-------- sum */
else if (strcmp(argv[1], "sum") == 0) {
/* read following arguments as ints and put them
into the iStart and iEnd array in succession.
But first check if we have an even number.
*/
if (((argc - 2) % 2) || (argc - 2) == 0) {
SCWrite(pCon,
"ERROR: need start and end for each dimension", eError);
return 0;
}
nDim = 0;
iSwitch = 0;
for (i = 0; i < argc - 2; i++) {
iRet = Tcl_GetInt(pSics->pTcl, argv[i + 2], &iVal);
if (iSwitch) {
iaEnd[nDim] = iVal;
nDim++;
iSwitch = 0;
} else {
iSwitch = 1;
iaStart[nDim] = iVal;
}
}
lVal = HistSum(self, pCon, iaStart, iaEnd);
snprintf(pBueffel,sizeof(pBueffel)-1, "%s.sum = %ld", argv[0], lVal);
SCWrite(pCon, pBueffel, eValue);
return 1;
} else {
snprintf(pBueffel,sizeof(pBueffel)-1, "ERROR: %s does not understand command %s",
argv[0], argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
return 0;
}