448 lines
13 KiB
C++
448 lines
13 KiB
C++
/*----------------------------------------------------------------------------
|
|
|
|
A N S T O H M
|
|
|
|
A histogramming memory driver for the ANSTO histogrammer. This version
|
|
assumes the histogrammer is a TANGO device server and uses the TANGO
|
|
api to communicate with the histogrammer. It has to be compiled with
|
|
the C++ compiler and the SICServer has to be linked with C++.
|
|
|
|
Andy Gotz, February 2004
|
|
|
|
Copyright:
|
|
|
|
ANSTO
|
|
Lucas Heights
|
|
New South Wales
|
|
AUSTRALIA
|
|
|
|
|
|
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>
|
|
extern "C" {
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "countdriv.h"
|
|
#include "counter.h"
|
|
#include "stringdict.h"
|
|
#include "HistMem.h"
|
|
#include "HistDriv.i"
|
|
#include "anstohm.h"
|
|
}
|
|
#include <tango.h>
|
|
|
|
/*
|
|
|
|
#define TESTVAL 128
|
|
|
|
define TESTVAL to set the simulated histogram to a fixed value for
|
|
testing
|
|
*/
|
|
static int iSet = 0;
|
|
static HistInt iSetVal = 0;
|
|
static HistMode eHistMode;
|
|
/*
|
|
* histogrammer proxy and data globals
|
|
*
|
|
* NOTE: defining this as globals means ONLY one histogrammer can be
|
|
* interfaces from SICS. If we need more we need to manage multiple
|
|
* histogram devices e.g. by adding them to the pHistDriver structure
|
|
*/
|
|
|
|
static char *hm_device = "localhost:30001/hifar/mrpd/hm#dbase=no";
|
|
static Tango::DeviceProxy *hm_proxy=NULL;
|
|
static vector<long> hm_data;
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int AnstoHMConfig(pHistDriver self, SConnection *pCon,
|
|
pStringDict pOption, SicsInterp *pSics)
|
|
{
|
|
int i, iLength = 1, status;
|
|
char pData[132];
|
|
|
|
if(eHistMode == eHTOF)
|
|
{
|
|
for(i = 0; i < self->data->rank; i++)
|
|
{
|
|
iLength *= self->data->iDim[i];
|
|
}
|
|
iLength *= self->data->nTimeChan;
|
|
}
|
|
|
|
/*
|
|
* set count mode
|
|
*/
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
string count_mode;
|
|
if (self->eCount == ePreset)
|
|
{
|
|
count_mode = "monitor";
|
|
}
|
|
else
|
|
{
|
|
count_mode = "time";
|
|
}
|
|
Tango::DeviceAttribute attr_write((const char*)"count_mode",count_mode);
|
|
hm_proxy->write_attribute(attr_write);
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram Count Mode failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* send preset to histogrammer
|
|
*/
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
/*
|
|
* QUESTION: what are the time units of fCountPreset ? Might have to scale it
|
|
* should iExponent be taken into account here ?
|
|
*/
|
|
long preset = (long)self->fCountPreset;
|
|
Tango::DeviceAttribute attr_write((const char*)"preset",preset);
|
|
hm_proxy->write_attribute(attr_write);
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram Preset failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMStart(pHistDriver self, SConnection *pCon)
|
|
{
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
hm_proxy->command_inout("Start");
|
|
}
|
|
catch (Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: TANGO Histogram Start failed",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMPause(pHistDriver self, SConnection *pCon)
|
|
{
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
hm_proxy->command_inout("Pause");
|
|
}
|
|
catch (Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram Pause failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int AnstoHMContinue(pHistDriver self, SConnection *pCon)
|
|
{
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
hm_proxy->command_inout("Continue");
|
|
}
|
|
catch (Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram Continue failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMHalt(pHistDriver self)
|
|
{
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
hm_proxy->command_inout("Halt");
|
|
}
|
|
catch (Tango::DevFailed &exception)
|
|
{
|
|
/*
|
|
SCWrite(pCon,"ERROR: Histogram Halt failed",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
*/
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMGetCountStatus(pHistDriver self, SConnection *pCon)
|
|
{
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
Tango::DevState state;
|
|
state = hm_proxy->state();
|
|
switch (state)
|
|
{
|
|
case Tango::OFF :
|
|
return HWIdle;
|
|
case Tango::RUNNING :
|
|
return HWBusy;
|
|
case Tango::STANDBY :
|
|
return HWPause;
|
|
case Tango::FAULT :
|
|
return HWFault;
|
|
default :
|
|
return HWFault;
|
|
}
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram state() failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMGetError(pHistDriver self, int *iCode, char *pError, int iLen)
|
|
{
|
|
return 0;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMTryAndFixIt(pHistDriver self, int iCode)
|
|
{
|
|
if (hm_proxy != NULL)
|
|
{
|
|
try
|
|
{
|
|
hm_proxy->command_inout("Reset");
|
|
}
|
|
catch (Tango::DevFailed &exception)
|
|
{
|
|
/*
|
|
SCWrite(pCon,"ERROR: Histogram Reset failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
*/
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int AnstoHMGetData(pHistDriver self, SConnection *pCon)
|
|
{
|
|
try
|
|
{
|
|
Tango::DeviceAttribute attr_read = hm_proxy->read_attribute("data");
|
|
|
|
// return data in global hm_data variable
|
|
|
|
attr_read >> hm_data;
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram GetData failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static int AnstoHMGetHistogram(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;
|
|
}
|
|
#ifdef TESTVAL
|
|
for(ii = iStart; ii < iEnd; ii++)
|
|
{
|
|
lData[ii] = TESTVAL;
|
|
}
|
|
#else
|
|
AnstoHMGetData(self, pCon);
|
|
for(ii = iStart; ii < iEnd; ii++)
|
|
{
|
|
if (ii < hm_data.size()) lData[ii-iStart] = hm_data[ii];
|
|
}
|
|
#endif
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int AnstoHMSetHistogram(pHistDriver self, SConnection *pCon,
|
|
int i, int iStart, int iEnd, HistInt *lData)
|
|
{
|
|
iSet = 1;
|
|
iSetVal = lData[0];
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int AnstoHMPreset(pHistDriver self, SConnection *pCon, HistInt iVal)
|
|
{
|
|
iSet = 1;
|
|
iSetVal = iVal;
|
|
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static int AnstoHMFreePrivate(pHistDriver self)
|
|
{
|
|
return 1;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static long AnstoHMGetMonitor(pHistDriver self, int i, SConnection *pCon)
|
|
{
|
|
long hm_monitor;
|
|
try
|
|
{
|
|
Tango::DeviceAttribute attr_read = hm_proxy->read_attribute("monitor");
|
|
|
|
// return data in global hm_data variable
|
|
|
|
attr_read >> hm_monitor;
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram GetData failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
return hm_monitor;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
static float AnstoHMGetTime(pHistDriver self, SConnection *pCon)
|
|
{
|
|
double hm_time;
|
|
try
|
|
{
|
|
Tango::DeviceAttribute attr_read = hm_proxy->read_attribute("time");
|
|
|
|
// return data in global hm_data variable
|
|
|
|
attr_read >> hm_time;
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
SCWrite(pCon,"ERROR: Histogram GetData failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
return 0;
|
|
}
|
|
return (float)hm_time;
|
|
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
pHistDriver CreateAnstoHM(pStringDict pOpt)
|
|
{
|
|
pHistDriver pNew = NULL;
|
|
|
|
/* create the general driver */
|
|
pNew = CreateHistDriver(pOpt);
|
|
if(!pNew)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/* not using private data currently */
|
|
pNew->pPriv = NULL;
|
|
|
|
/* configure all those functions */
|
|
pNew->Configure = AnstoHMConfig;
|
|
pNew->Start = AnstoHMStart;
|
|
pNew->Halt = AnstoHMHalt;
|
|
pNew->GetCountStatus = AnstoHMGetCountStatus;
|
|
pNew->GetError = AnstoHMGetError;
|
|
pNew->TryAndFixIt = AnstoHMTryAndFixIt;
|
|
pNew->GetData = AnstoHMGetData;
|
|
pNew->GetHistogram = AnstoHMGetHistogram;
|
|
pNew->SetHistogram = AnstoHMSetHistogram;
|
|
pNew->GetMonitor = AnstoHMGetMonitor;
|
|
pNew->GetTime = AnstoHMGetTime;
|
|
pNew->Preset = AnstoHMPreset;
|
|
pNew->FreePrivate = AnstoHMFreePrivate;
|
|
pNew->Pause = AnstoHMPause;
|
|
pNew->Continue = AnstoHMContinue;
|
|
pNew->fCountPreset = 1;
|
|
StringDictAddPair(pOpt,"device",hm_device);
|
|
|
|
try
|
|
{
|
|
hm_proxy = new Tango::DeviceProxy(hm_device);
|
|
}
|
|
catch(Tango::DevFailed &exception)
|
|
{
|
|
printf("ERROR: New Tango DeviceProxy failed\n");
|
|
/*
|
|
SCWrite(pCon,"ERROR: New Tango DeviceProxy failed",eError);
|
|
SCWrite(pCon,"Tango error :",eError);
|
|
SCWrite(pCon,exception.errors[0].desc,eError);
|
|
*/
|
|
return 0;
|
|
}
|
|
hm_data.resize(10);
|
|
|
|
return pNew;
|
|
}
|
|
|