- Fixed a bug in processnode which hangs SICS when processnode is called from multiple clients on the same node - Fixed a bug in multicountsersec which caused thrashing of the Tcl results which caused ugly error messages when calling the transfer script. Now a copy of the connection is made before calling the transfer script
313 lines
8.5 KiB
C
313 lines
8.5 KiB
C
/*----------------------------------------------------------------------------
|
|
|
|
H I S T S I M
|
|
|
|
A simulated histogram memory. For software test purposes.
|
|
|
|
Mark Koennecke, April 1997
|
|
|
|
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 <stdlib.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "countdriv.h"
|
|
#include "counter.h"
|
|
#include "stringdict.h"
|
|
#include "HistMem.h"
|
|
#include "HistDriv.i"
|
|
#include "histsim.h"
|
|
|
|
static int iSet = 0;
|
|
static HistInt iSetVal = 0;
|
|
static HistMode eHistMode;
|
|
/*--------------------------------------------------------------------------*/
|
|
static int SimConfig(pHistDriver self, SConnection * pCon,
|
|
pStringDict pOption, SicsInterp * pSics)
|
|
{
|
|
int i, iLength = 1, status;
|
|
char pData[132];
|
|
float fFail;
|
|
|
|
if (eHistMode == eHTOF) {
|
|
for (i = 0; i < self->data->rank; i++) {
|
|
iLength *= self->data->iDim[i];
|
|
}
|
|
iLength *= self->data->nTimeChan;
|
|
}
|
|
|
|
/*
|
|
deal with failrate
|
|
*/
|
|
status = StringDictGet(pOption, "failrate", pData, 131);
|
|
if (status) {
|
|
fFail = atof(pData);
|
|
free(self->pPriv);
|
|
self->pPriv = NewSIMCounter("HistoSim", fFail);
|
|
}
|
|
|
|
|
|
/*
|
|
configured test value
|
|
*/
|
|
status = StringDictGet(pOption, "testval", pData, 131);
|
|
if (status) {
|
|
iSet = 1;
|
|
iSetVal = atoi(pData);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimStart(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
pDriv->fPreset = self->fCountPreset;
|
|
pDriv->eMode = self->eCount;
|
|
return pDriv->Start(pDriv);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimPause(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
pDriv->fPreset = self->fCountPreset;
|
|
pDriv->eMode = self->eCount;
|
|
return pDriv->Pause(pDriv);
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SimContinue(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
pDriv->fPreset = self->fCountPreset;
|
|
pDriv->eMode = self->eCount;
|
|
return pDriv->Continue(pDriv);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimHalt(pHistDriver self)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
return pDriv->Halt(pDriv);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimGetCountStatus(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
float fControl;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
return pDriv->GetStatus(pDriv, &fControl);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimGetError(pHistDriver self, int *iCode, char *pError,
|
|
int iLen)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
return pDriv->GetError(pDriv, iCode, pError, iLen);
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimTryAndFixIt(pHistDriver self, int iCode)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
return pDriv->TryAndFixIt(pDriv, iCode);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int SimGetData(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
|
|
return pDriv->ReadValues(pDriv);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int SimGetHistogram(pHistDriver self, SConnection * pCon,
|
|
int i, int iStart, int iEnd, HistInt * lData)
|
|
{
|
|
int ii;
|
|
|
|
if (i < 0) {
|
|
SCWrite(pCon, "ERROR: histogram out of range", eError);
|
|
return 0;
|
|
}
|
|
|
|
if (iSet == 1) {
|
|
for (ii = iStart; ii < iEnd; ii++) {
|
|
lData[ii - iStart] = iSetVal;
|
|
}
|
|
} else if (iSet == 2) {
|
|
for (ii = iStart; ii < iEnd; ii++) {
|
|
lData[ii - iStart] = self->data->localBuffer[ii];
|
|
}
|
|
} else {
|
|
for (ii = iStart; ii < iEnd; ii++) {
|
|
lData[ii - iStart] = random();
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SimSetHistogram(pHistDriver self, SConnection * pCon,
|
|
int i, int iStart, int iEnd, HistInt * lData)
|
|
{
|
|
iSet = 2;
|
|
if (self->data->localBuffer == NULL) {
|
|
resizeBuffer(self->data);
|
|
}
|
|
iSetVal = lData[0];
|
|
if (iEnd <= getHMDataLength(self->data)) {
|
|
memcpy(self->data->localBuffer + iStart, lData,
|
|
(iEnd - iStart) * sizeof(HistInt));
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int SimPreset(pHistDriver self, SConnection * pCon, HistInt iVal)
|
|
{
|
|
iSet = 1;
|
|
iSetVal = iVal;
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static int SimFreePrivate(pHistDriver self)
|
|
{
|
|
pCounterDriver pDriv;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
DeleteCounterDriver(pDriv);
|
|
return 1;
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static long SimGetMonitor(pHistDriver self, int i, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
long lVal;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
return pDriv->lCounts[i];
|
|
|
|
}
|
|
|
|
/*------------------------------------------------------------------------*/
|
|
static float SimGetTime(pHistDriver self, SConnection * pCon)
|
|
{
|
|
pCounterDriver pDriv;
|
|
long lVal;
|
|
|
|
pDriv = (pCounterDriver) self->pPriv;
|
|
return pDriv->fTime;
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
HistInt *DefaultSubSample(pHistDriver self, SConnection * pCon,
|
|
int bank, char *command)
|
|
{
|
|
HistInt *data = NULL;
|
|
char error[132];
|
|
|
|
assert(bank == 0); /* no bank handling yet.. */
|
|
|
|
memset(error, 0, 132 * sizeof(char));
|
|
data = subSample(self->data, command, error, 132);
|
|
if (data == NULL) {
|
|
SCWrite(pCon, error, eError);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
pHistDriver CreateSIMHM(pStringDict pOpt)
|
|
{
|
|
pHistDriver pNew = NULL;
|
|
|
|
/* create the general driver */
|
|
pNew = CreateHistDriver(pOpt);
|
|
if (!pNew) {
|
|
return NULL;
|
|
}
|
|
|
|
/* put a SIMcounter in */
|
|
pNew->pPriv = (void *) NewSIMCounter("HistoSim", -1.);
|
|
if (!pNew->pPriv) {
|
|
DeleteHistDriver(pNew);
|
|
return NULL;
|
|
}
|
|
|
|
/* configure all those functions */
|
|
pNew->Configure = SimConfig;
|
|
pNew->Start = SimStart;
|
|
pNew->Halt = SimHalt;
|
|
pNew->GetCountStatus = SimGetCountStatus;
|
|
pNew->GetError = SimGetError;
|
|
pNew->TryAndFixIt = SimTryAndFixIt;
|
|
pNew->GetData = SimGetData;
|
|
pNew->GetHistogram = SimGetHistogram;
|
|
pNew->SetHistogram = SimSetHistogram;
|
|
pNew->GetMonitor = SimGetMonitor;
|
|
pNew->GetTime = SimGetTime;
|
|
pNew->Preset = SimPreset;
|
|
pNew->FreePrivate = SimFreePrivate;
|
|
pNew->Pause = SimPause;
|
|
pNew->Continue = SimContinue;
|
|
pNew->SubSample = DefaultSubSample;
|
|
StringDictAddPair(pOpt, "failrate", "-1");
|
|
|
|
return pNew;
|
|
}
|