/*-------------------------------------------------------------------------- This is a driver for a histogram memory which is meant to interoperate with a McStas simulation. For reasons of lazyness the control of counting operations is delegated to a single counter object and this driver only provides data space and means to access and copy data. This driver also works without a counter connected in order to support multi HM control via the hmcontrol module. copyright: see file COPYRIGHT Mark Koennecke, June 2005 -------------------------------------------------------------------------*/ #include #include #include "sics.h" #include "counter.h" #include "stringdict.h" #include "HistDriv.i" /*================= operator functions ====================================*/ static int McHMConfigure(pHistDriver self, SConnection * pCon, pStringDict pOpt, SicsInterp * pSics) { char counterName[80]; char pError[256]; if (StringDictGet(pOpt, "counter", counterName, 79) == 1) { self->pPriv = FindCommandData(pSics, counterName, "SingleCounter"); if (self->pPriv == NULL) { snprintf(pError, 255, "ERROR: tried to configure counter but %s not found", counterName); SCWrite(pCon, pError, eError); return 0; } } self->iReconfig = 0; return configureHMdata(self->data, pOpt, pCon); } /*-------------------------------------------------------------------------*/ static int McHMStart(pHistDriver self, SConnection * pCon) { pCounter pCount = NULL; /* * clear data */ clearHMData(self->data); /* * if there is a counter, make him start */ pCount = (pCounter) self->pPriv; if (pCount != NULL) { pCount->pDriv->eMode = self->eCount; pCount->pDriv->fPreset = self->fCountPreset; return pCount->pCountInt->StartCount(pCount, pCon); } else { return 1; } } /*------------------------------------------------------------------------*/ static int McHMHalt(pHistDriver self) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return pCount->pCountInt->Halt(pCount); } else { return 1; } } /*-------------------------------------------------------------------------*/ static int McHMCountStatus(pHistDriver self, SConnection * pCon) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return pCount->pCountInt->CheckCountStatus(pCount, pCon); } else { return HWIdle; } } /*------------------------------------------------------------------------*/ static int McHMGetError(pHistDriver self, int *iCode, char *error, int errLen) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return pCount->pDriv->GetError(pCount->pDriv, iCode, error, errLen); } else { *iCode = -1000; strlcpy(error, "Feature not implemented in McStasHM", errLen); return 1; } } /*-------------------------------------------------------------------------*/ static int McHMFixIt(pHistDriver self, int iCode) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return pCount->pDriv->TryAndFixIt(pCount->pDriv, iCode); } else { return COTERM; } } /*-----------------------------------------------------------------------*/ static int McHMGetData(pHistDriver self, SConnection * pCon) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return pCount->pCountInt->TransferData(pCount, pCon); } else { return 1; } } /*-----------------------------------------------------------------------*/ static int McHMGetHistogram(pHistDriver self, SConnection * pCon, int bank, int start, int end, HistInt * pData) { /* * make sure data gets transferred */ return McHMGetData(self, pCon); } /*-------------------------------------------------------------------------*/ static int McHMSetHistogram(pHistDriver self, SConnection * pCon, int bank, int start, int end, HistInt * pData) { int i, count = 0; HistInt *hmData; assert(bank == 0); hmData = self->data->localBuffer; for (i = start; i < end; i++, count++) { hmData[i] = pData[count]; } return 1; } /*-------------------------------------------------------------------------*/ static long McHMMonitor(pHistDriver self, int i, SConnection * pCon) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return GetMonitor(pCount, i, pCon); } else { return 0L; } } /*-------------------------------------------------------------------------*/ static float McHMGetTime(pHistDriver self, SConnection * pCon) { pCounter pCount = NULL; pCount = (pCounter) self->pPriv; if (pCount != NULL) { return GetCountTime(pCount, pCon);; } else { return -999.99; } } /*--------------------------------------------------------------------------*/ static int McHMPreset(pHistDriver self, SConnection * pCon, HistInt val) { int i; long length; HistInt *data; length = getHMDataLength(self->data); data = self->data->localBuffer; for (i = 0; i < length; i++) { data[i] = val; } return 1; } /*------------------------------------------------------------------------*/ static int McHMPause(pHistDriver self, SConnection * pCon) { return HWFault; } /*-----------------------------------------------------------------------*/ static int McHMContinue(pHistDriver self, SConnection * pCon) { return HWFault; } /*========================== the actual creation function ================*/ pHistDriver NewMcStasHM(pStringDict pOpt) { pHistDriver pNew = NULL; pNew = CreateHistDriver(pOpt); if (pNew == NULL) { return NULL; } pNew->Configure = McHMConfigure; pNew->Start = McHMStart; pNew->Halt = McHMHalt; pNew->GetCountStatus = McHMCountStatus; pNew->GetError = McHMGetError; pNew->TryAndFixIt = McHMFixIt; pNew->GetData = McHMGetData; pNew->GetHistogram = McHMGetHistogram; pNew->SetHistogram = McHMSetHistogram; pNew->GetMonitor = McHMMonitor; pNew->GetTime = McHMGetTime; pNew->Preset = McHMPreset; pNew->FreePrivate = NULL; pNew->Pause = McHMPause; pNew->Continue = McHMContinue; StringDictAddPair(pOpt, "counter", "UNKNOWN"); StringDictUpdate(pOpt, "update", "10"); return pNew; }