1039 lines
27 KiB
C++
1039 lines
27 KiB
C++
/*----------------------------------------------------------------------------
|
|
|
|
H M _ A S I M
|
|
|
|
A simulation histogramming memory driver for the ANSTO histogrammer.
|
|
It has to be compiled with the C++ compiler and the SICServer has to
|
|
be linked with C++.
|
|
|
|
Paul Hathaway, September 2004
|
|
|
|
Copyright: see Copyright.txt
|
|
----------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <time.h>
|
|
#include <math.h>
|
|
#include <vector>
|
|
extern "C" {
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "countdriv.h"
|
|
#include "counter.h"
|
|
#include "stringdict.h"
|
|
#include "HistMem.h"
|
|
#include "HistDriv.i"
|
|
#include "hm_asim.h"
|
|
}
|
|
#include <tango.h>
|
|
#define TESTVAL 128
|
|
/*
|
|
define TESTVAL to set the simulated histogram to a fixed value for
|
|
testing
|
|
*/
|
|
#define HM_ASIM_IDLE 0
|
|
#define HM_ASIM_BUSY 1
|
|
#define HM_ASIM_PAUSE 2
|
|
#define HM_ASIM_FAULT 3
|
|
|
|
#define HM_MODE_TIME 0
|
|
#define HM_MODE_COUNT 1
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
class AsimDetector
|
|
{
|
|
public:
|
|
int iSet;
|
|
HistInt iSetVal;
|
|
|
|
AsimDetector(char *deviceName)
|
|
{
|
|
if(0<strlen(deviceName))
|
|
{
|
|
strncpy(hm_device,deviceName,79);
|
|
}
|
|
else
|
|
{
|
|
strcpy(hm_device,"simulation");
|
|
}
|
|
iSet = 0;
|
|
iSetVal = 0;
|
|
iMonCtr = 0;
|
|
eHistMode = eHNormal;
|
|
hm_state = HM_ASIM_IDLE;
|
|
iCountMode = HM_MODE_TIME;
|
|
iChannels = 0;
|
|
iCounters = 10;
|
|
lVetoThreshold = 0;
|
|
lPreset = 10;
|
|
hm_ctr.resize(iCounters);
|
|
hm_tgt.resize(iCounters);
|
|
fFlux = 60.0;
|
|
}
|
|
|
|
~AsimDetector() { };
|
|
|
|
int SetCounters(int numCounters);
|
|
int GetCounters();
|
|
int SetChannels(int numChannels);
|
|
int GetChannels();
|
|
int SetPatch(int destChn, int srcCtr);
|
|
void PatchHistogram();
|
|
int SetCountMode(int iMode);
|
|
HistMode GetHistMode();
|
|
int SetPreset(long iPreset);
|
|
int GetData();
|
|
int GetHistogram(int iStart, int iEnd, HistInt *lData);
|
|
int GetCountStatus(int *iStatus);
|
|
int SetCountStatus(int iStatus);
|
|
int SetMonitorInput(int iCtr);
|
|
int GetMonitor(HistInt *lData);
|
|
int SetVetoInput(int iCtr);
|
|
int SetVetoThreshold(HistInt lLevel);
|
|
int GetVetoThreshold(HistInt *lLevel);
|
|
int GetVeto(HistInt *lVeto);
|
|
int GetRunningTime(float *ftime);
|
|
int SetFlux(float flux);
|
|
int GetFlux(float *flux);
|
|
int IsCountComplete();
|
|
int Start();
|
|
int Halt();
|
|
int Pause();
|
|
int Continue();
|
|
int Reset();
|
|
|
|
private:
|
|
float SimRandom();
|
|
int FillTarget();
|
|
int FillCounters(float fraction);
|
|
int UpdateRunningTime();
|
|
int UpdateCounters();
|
|
int UpdateState();
|
|
|
|
char hm_device[80];
|
|
vector<long> hm_data;
|
|
HistMode eHistMode;
|
|
|
|
vector<int> hm_patch;
|
|
vector<long> hm_ctr;
|
|
vector<long> hm_tgt;
|
|
static const long zero = 0;
|
|
int iChannels;
|
|
int iCounters;
|
|
int iVetoCtr;
|
|
int iMonCtr;
|
|
long hm_monitor;
|
|
int hm_state;
|
|
int iCountMode;
|
|
long lPreset;
|
|
long lVetoThreshold;
|
|
long iDuration;
|
|
long iLastPollTime;
|
|
long iRunningTime;
|
|
float fFlux;
|
|
};
|
|
/*---------------------------------------------------------------------------*/
|
|
float AsimDetector::SimRandom(void)
|
|
{
|
|
float fVal;
|
|
fVal = ( (float) rand() / (float)RAND_MAX ) * 100.0;
|
|
return fVal;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int AsimDetector::UpdateRunningTime()
|
|
{
|
|
time_t tD;
|
|
|
|
time(&tD); /* This fn valid between Jan 1970 and Jan 2038 */
|
|
if (HM_ASIM_BUSY == hm_state)
|
|
{
|
|
iRunningTime += ((long)tD - iLastPollTime);
|
|
}
|
|
iLastPollTime = (long)tD;
|
|
return 1;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
int AsimDetector::UpdateCounters()
|
|
{
|
|
float fraction;
|
|
switch (hm_state)
|
|
{
|
|
case HM_ASIM_BUSY:
|
|
UpdateRunningTime();
|
|
fraction = (float)iRunningTime / (float)iDuration;
|
|
FillCounters(fraction);
|
|
// if (iRunningTime >= iDuration)
|
|
// {
|
|
// iRunningTime = iDuration;
|
|
// FillCounters(1.0);
|
|
// }
|
|
// else /* Counting. Calculate intermediate counts */
|
|
// {
|
|
// fraction = (float)iRunningTime / (float)iDuration;
|
|
// FillCounters(fraction);
|
|
// }
|
|
|
|
if(1==IsCountComplete())
|
|
{
|
|
hm_state = HM_ASIM_IDLE;
|
|
}
|
|
break;
|
|
case HM_ASIM_PAUSE:
|
|
UpdateRunningTime();
|
|
break;
|
|
case HM_ASIM_IDLE:
|
|
case HM_ASIM_FAULT:
|
|
default: break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int AsimDetector::IsCountComplete()
|
|
{
|
|
switch(iCountMode)
|
|
{
|
|
case HM_MODE_TIME:
|
|
if (iRunningTime >= iDuration) return 1; else return 0;
|
|
break;
|
|
case HM_MODE_COUNT:
|
|
if (hm_monitor >= lPreset) return 1; else return 0;
|
|
break;
|
|
default:
|
|
hm_state = HM_ASIM_FAULT; return 0;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::SetCounters(int numCounters)
|
|
{
|
|
// todo: test validity of numCounters
|
|
hm_tgt.resize(numCounters);
|
|
hm_ctr.resize(numCounters);
|
|
for(int i=iCounters; i<numCounters; i++)
|
|
{
|
|
hm_tgt[i] = 0;
|
|
hm_ctr[i] = 0;
|
|
}
|
|
iCounters = numCounters;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetCounters()
|
|
{
|
|
return iCounters;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::SetChannels(int numChannels)
|
|
{
|
|
// todo: test validity of numChannels
|
|
hm_data.resize(numChannels);
|
|
hm_patch.resize(numChannels);
|
|
for(int i=iChannels; i<numChannels; i++)
|
|
{
|
|
hm_patch[i] = -1;
|
|
hm_data[i] = 0;
|
|
}
|
|
iChannels = numChannels;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetChannels()
|
|
{
|
|
return iChannels;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetCountMode(int iMode)
|
|
{
|
|
switch(hm_state)
|
|
{
|
|
case HM_ASIM_IDLE:
|
|
switch(iMode)
|
|
{
|
|
case HM_MODE_COUNT:
|
|
case HM_MODE_TIME:
|
|
iCountMode = iMode;
|
|
break;
|
|
default:
|
|
iCountMode = HM_MODE_TIME;
|
|
}
|
|
return 1;
|
|
case HM_ASIM_BUSY:
|
|
case HM_ASIM_PAUSE:
|
|
case HM_ASIM_FAULT:
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
HistMode AsimDetector::GetHistMode()
|
|
{
|
|
return eHistMode;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetPatch(int destChn, int srcCtr)
|
|
{
|
|
if((destChn>iChannels)||(destChn<0))
|
|
{
|
|
return 0;
|
|
}
|
|
hm_patch[destChn] = srcCtr;
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
void AsimDetector::PatchHistogram()
|
|
{
|
|
for(int i=0;i<iChannels;i++)
|
|
{
|
|
if(-1==hm_patch[i])
|
|
{
|
|
hm_data[i] = 0;
|
|
}
|
|
else
|
|
{
|
|
hm_data[i] = hm_ctr[hm_patch[i]];
|
|
}
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::GetData()
|
|
{
|
|
UpdateCounters();
|
|
PatchHistogram();
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::SetPreset(long iPreset)
|
|
{
|
|
switch(hm_state)
|
|
{
|
|
case HM_ASIM_IDLE:
|
|
lPreset = iPreset;
|
|
return 1;
|
|
case HM_ASIM_BUSY:
|
|
case HM_ASIM_PAUSE:
|
|
case HM_ASIM_FAULT:
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::FillCounters(float fraction)
|
|
{
|
|
float localFraction;
|
|
if(100.0 < fraction) localFraction = 100.0; else localFraction = fraction;
|
|
for(int i=0; i<iCounters; i++)
|
|
{
|
|
hm_ctr[i] = (long)(localFraction * hm_tgt[i]);
|
|
}
|
|
hm_monitor = hm_ctr[iMonCtr];
|
|
// if((HM_MODE_COUNT==iCountMode)&&(0.98<fraction))
|
|
// {
|
|
// hm_monitor = lPreset;
|
|
// }
|
|
// else
|
|
// {
|
|
// hm_monitor = (long) (iRunningTime * fFlux);
|
|
// }
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::FillTarget()
|
|
{
|
|
float level;
|
|
float middle = ((float)iCounters) / 2;
|
|
float target = lPreset;
|
|
if(HM_MODE_TIME==iCountMode)
|
|
{
|
|
target = lPreset * fFlux;
|
|
iDuration = lPreset;
|
|
}
|
|
else
|
|
{
|
|
target = lPreset;
|
|
iDuration = (long) (((float)lPreset)/fFlux);
|
|
}
|
|
if(1>iDuration) iDuration = 1;
|
|
for(int i=0; i<iCounters; i++)
|
|
{
|
|
level = 1.0 - fabsf(middle - (float)i)/middle;
|
|
hm_tgt[i] = (long)(level * (float)target);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int AsimDetector::GetHistogram(int iStart, int iEnd, HistInt *lData)
|
|
{
|
|
if(0<=iVetoCtr)
|
|
{
|
|
if(lVetoThreshold < hm_ctr[iVetoCtr])
|
|
{
|
|
for(int i=iStart; i<=iEnd; i++)
|
|
{
|
|
lData[i-iStart] = 0;
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
for(int i=iStart; i<iEnd; i++)
|
|
{
|
|
if(i<hm_data.size())
|
|
{
|
|
lData[i-iStart] = (HistInt) hm_data[i];
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetCountStatus(int *iStatus)
|
|
{
|
|
UpdateCounters();
|
|
(*iStatus) = hm_state;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetCountStatus(int iStatus)
|
|
{
|
|
switch(iStatus)
|
|
{
|
|
case HM_ASIM_IDLE:
|
|
case HM_ASIM_BUSY:
|
|
case HM_ASIM_PAUSE:
|
|
case HM_ASIM_FAULT:
|
|
hm_state = iStatus;
|
|
return 1;
|
|
default:
|
|
hm_state = HM_ASIM_FAULT;
|
|
return 0;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetMonitorInput(int iCtr)
|
|
{
|
|
if((iCtr>(iCounters-1))||(iCtr<0))
|
|
{
|
|
iMonCtr = 0;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
iMonCtr = iCtr;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetMonitor(HistInt *lData)
|
|
{
|
|
hm_monitor = hm_ctr[iMonCtr];
|
|
(*lData) = (HistInt) hm_monitor;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetVetoInput(int iCtr)
|
|
{
|
|
if((iCtr>iChannels)||(iCtr<-1))
|
|
{
|
|
iVetoCtr = -1;
|
|
return 0;
|
|
}
|
|
iVetoCtr = iCtr;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetVetoThreshold(HistInt lLevel)
|
|
{
|
|
lVetoThreshold = (long) lLevel;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetVetoThreshold(HistInt *lLevel)
|
|
{
|
|
*lLevel = (HistInt) lVetoThreshold;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetVeto(HistInt *lVeto)
|
|
{
|
|
if(0<iVetoCtr)
|
|
{
|
|
(*lVeto) = (HistInt) hm_ctr[iVetoCtr];
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
(*lVeto) = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetRunningTime(float *fTime)
|
|
{
|
|
switch(hm_state)
|
|
{
|
|
case HM_ASIM_BUSY:
|
|
case HM_ASIM_PAUSE:
|
|
UpdateCounters();
|
|
(*fTime) = (float) iRunningTime;
|
|
return 1;
|
|
case HM_ASIM_FAULT:
|
|
case HM_ASIM_IDLE:
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::SetFlux(float flux)
|
|
{
|
|
float eta = 0.01;
|
|
if(eta<=flux)
|
|
{
|
|
fFlux = flux;
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
fFlux = 0.0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::GetFlux(float *flux)
|
|
{
|
|
*flux = fFlux;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::Start()
|
|
{
|
|
Halt(); // hm_state = HM_ASIM_IDLE;
|
|
UpdateRunningTime(); //resets iLastPoll
|
|
iRunningTime = 0;
|
|
FillTarget();
|
|
FillCounters(0.0);
|
|
hm_state = HM_ASIM_BUSY;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::Halt()
|
|
{
|
|
UpdateCounters();
|
|
hm_state = HM_ASIM_IDLE;
|
|
iRunningTime = 0;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::Pause()
|
|
{
|
|
switch(hm_state)
|
|
{
|
|
case HM_ASIM_PAUSE: return 1;
|
|
case HM_ASIM_IDLE: return 0;
|
|
case HM_ASIM_FAULT: return 0;
|
|
case HM_ASIM_BUSY:
|
|
UpdateCounters();
|
|
hm_state = HM_ASIM_PAUSE;
|
|
return 1;
|
|
default:
|
|
hm_state = HM_ASIM_FAULT;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int AsimDetector::Continue()
|
|
{
|
|
switch(hm_state)
|
|
{
|
|
case HM_ASIM_IDLE: return 0;
|
|
case HM_ASIM_FAULT: return 0;
|
|
case HM_ASIM_BUSY: return 1;
|
|
case HM_ASIM_PAUSE:
|
|
UpdateCounters();
|
|
hm_state = HM_ASIM_BUSY;
|
|
return 1;
|
|
default:
|
|
hm_state = HM_ASIM_FAULT;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int AsimDetector::Reset()
|
|
{
|
|
Halt();
|
|
FillTarget();
|
|
UpdateCounters();
|
|
hm_state = HM_ASIM_IDLE;
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
/* Wrapper functions for use of the class AsimDetector by SICS
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimConfig(pHistDriver self, SConnection *pCon,
|
|
pStringDict pOption, SicsInterp *pSics)
|
|
{
|
|
int i, iLength = 1, status;
|
|
int iSuccess = 1;
|
|
char pBuffer[132];
|
|
char error[132];
|
|
memset(error,0,131);
|
|
memset(error,'a',130);
|
|
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
|
|
// Configure TOF Mode
|
|
if(pAsim->GetHistMode() == eHTOF)
|
|
{
|
|
for(i = 0; i < self->data->rank; i++)
|
|
{
|
|
iLength *= self->data->iDim[i];
|
|
}
|
|
iLength *= self->data->nTimeChan;
|
|
}
|
|
|
|
// Configure Counters
|
|
{
|
|
int numCtrs = 0;
|
|
float fVal;
|
|
int iRet = StringDictGetAsNumber(pOption,"counters",&fVal);
|
|
if(0<iRet) {
|
|
numCtrs = (int)rint(fVal);
|
|
}
|
|
pAsim->SetCounters(numCtrs);
|
|
numCtrs = pAsim->GetCounters();
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Register %d counters",numCtrs);
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
snprintf(pBuffer,10,"%-d",numCtrs);
|
|
if(0==StringDictUpdate(pOption,"counters",pBuffer))
|
|
{
|
|
StringDictAddPair(pOption,"counters",pBuffer);
|
|
}
|
|
}
|
|
|
|
// Configure Channels
|
|
{
|
|
int numChan = 0;
|
|
float fVal;
|
|
int iRet = StringDictGetAsNumber(pOption,"channels",&fVal);
|
|
if(0<iRet) {
|
|
numChan = (int)rint(fVal);
|
|
}
|
|
pAsim->SetChannels(numChan);
|
|
numChan = pAsim->GetChannels();
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Register %d channels",numChan);
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
snprintf(pBuffer,10,"%-d",numChan);
|
|
if(0==StringDictUpdate(pOption,"channels",pBuffer))
|
|
{
|
|
StringDictAddPair(pOption,"channels",pBuffer);
|
|
}
|
|
}
|
|
|
|
// Configure Count Mode
|
|
if (self->eCount == ePreset)
|
|
{
|
|
pAsim->SetCountMode(HM_MODE_COUNT);
|
|
}
|
|
else
|
|
{
|
|
pAsim->SetCountMode(HM_MODE_TIME);
|
|
}
|
|
|
|
// Configure Preset
|
|
pAsim->SetPreset((long)(self->fCountPreset));
|
|
|
|
// Configure Channel to Counter patches
|
|
int numChn = pAsim->GetChannels();
|
|
for(int ch=0; ch<numChn; ch++)
|
|
{
|
|
char channel[8];
|
|
char pBuffer[80];
|
|
float fVal;
|
|
sprintf(channel,"chan%-1d",ch);
|
|
int iRet = StringDictGetAsNumber(pOption,channel,&fVal);
|
|
if(0<iRet) {
|
|
int iCtr = (int)rint(fVal);
|
|
pAsim->SetPatch(ch,iCtr);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Patch Channel %d to Counter %d",ch,iCtr);
|
|
} else {
|
|
pAsim->SetPatch(ch,-1);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Disconnect Channel %d",ch);
|
|
}
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
}
|
|
|
|
// Configure Monitor Input (always set, default 0)
|
|
{
|
|
int iMonCtr = 0;
|
|
float fVal;
|
|
int iRet = StringDictGetAsNumber(pOption,"monitor_input",&fVal);
|
|
if(0<iRet) {
|
|
iMonCtr = (int)rint(fVal);
|
|
}
|
|
pAsim->SetMonitorInput(iMonCtr);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Monitor Input Counter %d",iMonCtr);
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
snprintf(pBuffer,10,"%-d",iMonCtr);
|
|
if(0==StringDictUpdate(pOption,"monitor_input",pBuffer))
|
|
{
|
|
StringDictAddPair(pOption,"monitor_input",pBuffer);
|
|
}
|
|
}
|
|
|
|
// Configure Veto Input (set to valid counter or disconnected(-1))
|
|
{
|
|
int iVetoCtr;
|
|
float fVal;
|
|
int iRet = StringDictGetAsNumber(pOption,"veto_input",&fVal);
|
|
if(0<iRet) {
|
|
iVetoCtr = (int)rint(fVal);
|
|
pAsim->SetVetoInput(iVetoCtr);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Veto Input Counter %d",iVetoCtr);
|
|
}
|
|
else
|
|
{
|
|
iVetoCtr = -1;
|
|
pAsim->SetVetoInput(iVetoCtr);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Veto Input Disconnected");
|
|
}
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
snprintf(pBuffer,10,"%-d",iVetoCtr);
|
|
if(0==StringDictUpdate(pOption,"veto_input",pBuffer))
|
|
{
|
|
StringDictAddPair(pOption,"veto_input",pBuffer);
|
|
}
|
|
}
|
|
|
|
// Configure Veto Threshold (default 0)
|
|
{
|
|
HistInt lThreshold;
|
|
float fVal;
|
|
int iRet = StringDictGetAsNumber(pOption,"veto_threshold",&fVal);
|
|
if(0<iRet) {
|
|
lThreshold = (HistInt)rint(fVal);
|
|
}
|
|
else
|
|
{
|
|
lThreshold = 0;
|
|
}
|
|
pAsim->SetVetoThreshold(lThreshold);
|
|
pAsim->GetVetoThreshold(&lThreshold);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Veto Threshold %d",lThreshold);
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
snprintf(pBuffer,10,"%-d",lThreshold);
|
|
if(0==StringDictUpdate(pOption,"veto_threshold",pBuffer))
|
|
{
|
|
StringDictAddPair(pOption,"veto_threshold",pBuffer);
|
|
}
|
|
}
|
|
|
|
// Configure Flux
|
|
{
|
|
float fVal;
|
|
int iRet = StringDictGetAsNumber(pOption,"flux",&fVal);
|
|
if(0<iRet)
|
|
{
|
|
pAsim->SetFlux(fVal);
|
|
}
|
|
pAsim->GetFlux(&fVal);
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: Flux set to %.1f cps",fVal);
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
snprintf(pBuffer,16,"%.1f",fVal);
|
|
if(0==StringDictUpdate(pOption,"flux",pBuffer))
|
|
{
|
|
StringDictAddPair(pOption,"flux",pBuffer);
|
|
}
|
|
}
|
|
pAsim->Reset();
|
|
|
|
if(1==iSuccess)
|
|
{
|
|
sprintf(pBuffer,"STATUS:HM_ASIM: AsimConfig Successful");
|
|
SCWrite(pCon,pBuffer,eStatus);
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
sprintf(pBuffer,"ERROR:HM_ASIM: AsimConfig Failed");
|
|
SCWrite(pCon,pBuffer,eError);
|
|
return HWFault;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimStart(pHistDriver self, SConnection *pCon)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
|
|
// Configure Count Mode
|
|
if (self->eCount == ePreset)
|
|
pAsim->SetCountMode(HM_MODE_COUNT);
|
|
else
|
|
pAsim->SetCountMode(HM_MODE_TIME);
|
|
|
|
pAsim->SetPreset((long)(self->fCountPreset));
|
|
|
|
if(1==pAsim->Start())
|
|
{
|
|
SCWrite(pCon,"STATUS:HM_ASIM: Histogram Start Count",eStatus);
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
SCWrite(pCon,"ERROR:HM_ASIM: Histogram Start Count Failed",eError);
|
|
return HWFault;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimPause(pHistDriver self, SConnection *pCon)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
if(1==pAsim->Pause())
|
|
{
|
|
SCWrite(pCon,"STATUS:HM_ASIM: Histogram Pause Count",eStatus);
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
SCWrite(pCon,"ERROR:HM_ASIM: Histogram Pause Count Failed",eError);
|
|
return HWFault;
|
|
}
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int AsimContinue(pHistDriver self, SConnection *pCon)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
int iState;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
if(1==pAsim->Continue())
|
|
{
|
|
SCWrite(pCon,"STATUS:HM_ASIM: Histogram Continue Count",eStatus);
|
|
return OKOK;
|
|
}
|
|
else
|
|
{
|
|
SCWrite(pCon,"ERROR:HM_ASIM: Histogram Continue Count Failed",eError);
|
|
return HWFault;
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimHalt(pHistDriver self)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
if(1==pAsim->Halt()) return OKOK; else return HWFault;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimGetCountStatus(pHistDriver self, SConnection *pCon)
|
|
{
|
|
int status;
|
|
int retCode;
|
|
char error[80];
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
pAsim->GetCountStatus(&status);
|
|
switch (status)
|
|
{
|
|
case HM_ASIM_IDLE: retCode = OKOK; break;
|
|
case HM_ASIM_BUSY: retCode = HWBusy; break;
|
|
case HM_ASIM_PAUSE: retCode = HWPause; break;
|
|
case HM_ASIM_FAULT:
|
|
default: retCode = HWFault; break;
|
|
}
|
|
return retCode;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimGetError(pHistDriver self, int *iCode, char *pError, int iLen)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
*iCode = 0;
|
|
strncpy(pError,"ERROR:HM_ASIM: 0", iLen);
|
|
return OKOK; // QUESTION: Return 0 or OKOK; ?
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimTryAndFixIt(pHistDriver self, int iCode)
|
|
{
|
|
int status;
|
|
AsimDetector *pAsim = NULL;
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
pAsim->GetCountStatus(&status);
|
|
return AsimHalt(self);
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int AsimGetData(pHistDriver self, SConnection *pCon)
|
|
{
|
|
char error[80];
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
if (NULL!=pAsim)
|
|
{
|
|
if(0==pAsim->GetData())
|
|
{
|
|
SCWrite(pCon,"ERROR:HM_ASIM: Histogram GetData failed",eError);
|
|
return HWFault;
|
|
}
|
|
return OKOK;
|
|
}
|
|
return HWFault;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int AsimGetHistogram(pHistDriver self, SConnection *pCon,
|
|
int i, int iStart, int iEnd, HistInt *lData)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
|
|
switch(AsimGetData(self,pCon))
|
|
{
|
|
case OKOK:
|
|
if(1==pAsim->GetHistogram(iStart,iEnd,lData))
|
|
{
|
|
return OKOK;
|
|
}
|
|
else return HWFault;
|
|
default:
|
|
return HWFault;
|
|
}
|
|
return HWFault;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int AsimSetHistogram(pHistDriver self, SConnection *pCon,
|
|
int i, int iStart, int iEnd, HistInt *lData)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
|
|
pAsim->iSet = 1;
|
|
pAsim->iSetVal = lData[0];
|
|
return OKOK;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AsimPreset(pHistDriver self, SConnection *pCon, HistInt iVal)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
pAsim->iSet = 1;
|
|
pAsim->iSetVal = iVal;
|
|
return OKOK;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int AsimFreePrivate(pHistDriver self)
|
|
{
|
|
AsimDetector *pAsim = NULL;
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
delete pAsim;
|
|
return OKOK;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static long AsimGetMonitor(pHistDriver self, int i, SConnection *pCon)
|
|
{
|
|
HistInt value;
|
|
AsimDetector *pAsim = NULL;
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
pAsim->GetMonitor(&value);
|
|
return value;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static float AsimGetTime(pHistDriver self, SConnection *pCon)
|
|
{
|
|
float value;
|
|
AsimDetector *pAsim = NULL;
|
|
pAsim = (AsimDetector *) (self->pPriv);
|
|
pAsim->GetRunningTime(&value);
|
|
return value;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
pHistDriver CreateHmAsim(pStringDict pOpt)
|
|
{
|
|
pHistDriver pNew = NULL;
|
|
AsimDetector *pAsim = NULL;
|
|
|
|
/* create the general driver */
|
|
pNew = CreateHistDriver(pOpt);
|
|
if(!pNew)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
pAsim = new AsimDetector("simulation");
|
|
if(NULL==pAsim)
|
|
{
|
|
return NULL;
|
|
}
|
|
StringDictAddPair(pOpt,"device","hm_asim simulation");
|
|
pAsim->SetCounters(16);
|
|
pAsim->SetChannels(10);
|
|
|
|
/* if not using private data currently: pNew->pPriv = NULL; */
|
|
pNew->pPriv = pAsim;
|
|
|
|
/* configure all those functions */
|
|
pNew->Configure = AsimConfig;
|
|
pNew->Start = AsimStart;
|
|
pNew->Halt = AsimHalt;
|
|
pNew->GetCountStatus = AsimGetCountStatus;
|
|
pNew->GetError = AsimGetError;
|
|
pNew->TryAndFixIt = AsimTryAndFixIt;
|
|
pNew->GetData = AsimGetData;
|
|
pNew->GetHistogram = AsimGetHistogram;
|
|
pNew->SetHistogram = AsimSetHistogram;
|
|
pNew->GetMonitor = AsimGetMonitor;
|
|
pNew->GetTime = AsimGetTime;
|
|
pNew->Preset = AsimPreset;
|
|
pNew->FreePrivate = AsimFreePrivate;
|
|
pNew->Pause = AsimPause;
|
|
pNew->Continue = AsimContinue;
|
|
pNew->fCountPreset = 1;
|
|
|
|
return pNew;
|
|
}
|
|
|