Files
sicspsi/tricssupport.c

224 lines
6.1 KiB
C

/*------------------------------------------------------------------------
This is a little helper module for SICS which implements some
status display support functions.
COPYRIGHT: see file COPYRIGHT
Extracted from nextrics
Mark Koennecke, August 2004
--------------------------------------------------------------------------*/
#include "tricssupport.h"
#include "napi.h"
#include "HistMem.h"
#define NEWFRAME 1166
/*------------------------------------------------------------------------
a data structure plus support functions
------------------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pICallBack pCall;
} TricsSupport, *pTricsSupport;
/*----------------------------------------------------------------------*/
static pTricsSupport CreateTricsSupport()
{
pTricsSupport pNew = NULL;
pNew = (pTricsSupport) malloc(sizeof(TricsSupport));
if (pNew == NULL) {
return NULL;
}
memset(pNew, 0, sizeof(TricsSupport));
pNew->pDes = CreateDescriptor("TricsSupport");
pNew->pCall = CreateCallBackInterface();
if (pNew->pDes == NULL || pNew->pCall == NULL) {
free(pNew);
return NULL;
}
return pNew;
}
/*--------------------------------------------------------------------*/
static void KillTricsSupport(void *pData)
{
pTricsSupport pNew = (pTricsSupport) pData;
if (pNew != NULL) {
if (pNew->pDes != NULL) {
DeleteDescriptor(pNew->pDes);
pNew->pDes = NULL;
}
if (pNew->pCall != NULL) {
DeleteCallBackInterface(pNew->pCall);
pNew->pCall = NULL;
}
}
}
/*=====================================================================*/
static int FrameSupInterest(int iEvent, void *pEvent, void *pUser)
{
SConnection *pCon = NULL;
int *iFrame;
char pBueffel[512];
pCon = (SConnection *) pUser;
/* check kill condition */
if (pCon == NULL || !SCisConnected(pCon)) {
return -1;
}
if (iEvent != NEWFRAME) {
return 0;
}
iFrame = (int *) pEvent;
assert(pCon);
sprintf(pBueffel, "framenumber = %d", *iFrame);
SCWrite(pCon, pBueffel, eEvent);
return 1;
}
/*======================================================================
NexusGetFrame opens a TRICS NeXus file and retrieves a frame for the
specified detector from it. This is a special feature for the
status display.
---------------------------------------------------------------------------*/
static int NexusGetFrameSup(SConnection * pCon, char *filename,
int iDetector, int iFrame)
{
char pBueffel[132];
int iRet, type, rank, iDim[2];
NXhandle hfil;
HistInt *lData = NULL;
/* do a few range checks */
if (iDetector < 1 || iDetector > 3) {
sprintf(pBueffel, "ERROR: unknown detector %d requested", iDetector);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* open file */
iRet = NXopen(filename, NXACC_READ, &hfil);
if (iRet != NX_OK) {
sprintf(pBueffel, "ERROR: cannot open %s", filename);
SCWrite(pCon, pBueffel, eError);
return 0;
}
snprintf(pBueffel, 131, "/frame%4.4d/detector%1.1d/counts", iFrame,
iDetector);
iRet = NXopenpath(hfil, pBueffel);
if (iRet != NX_OK) {
sprintf(pBueffel, "ERROR: frame %d, detector %d not found in %s",
iFrame, iDetector, filename);
SCWrite(pCon, pBueffel, eError);
NXclose(&hfil);
return 0;
}
NXgetinfo(hfil, &rank, iDim, &type);
lData = (HistInt *) malloc(iDim[0] * iDim[1] * sizeof(HistInt));
if (!lData) {
SCWrite(pCon, "ERROR: out of memory in NexusGetFrame", eError);
NXclose(&hfil);
return 0;
}
memset(lData, 0, iDim[0] * iDim[1] * sizeof(HistInt));
iRet = NXgetdata(hfil, lData);
if (iRet != NX_OK) {
SCWrite(pCon, "ERROR: failed to read data", eError);
NXclose(&hfil);
return 0;
}
/* send it */
sprintf(pBueffel, "detector%1.1d", iDetector);
SCWriteZipped(pCon, pBueffel, lData,
iDim[0] * iDim[1] * sizeof(HistInt));
/* clean up */
NXclose(&hfil);
free(lData);
return 1;
}
/*----------------------------------------------------------------------*/
int MakeTricsSupport(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pTricsSupport pNew = NULL;
pNew = CreateTricsSupport();
if (!pNew) {
SCWrite(pCon, "ERROR: out of memory creating TricsSupport", eError);
return 0;
}
if (AddCommand
(pSics, "tricssupport", TricsSupportAction, KillTricsSupport,
pNew) != 1) {
SCWrite(pCon, "ERROR: duplicate command tricssupport not created",
eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*-----------------------------------------------------------------------*/
int TricsSupportAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
int iDet, iFrame, iRet;
long lID;
char pBueffel[131];
pTricsSupport self = (pTricsSupport) pData;
assert(self);
/* check for subcommands */
if (argc < 2) {
snprintf(pBueffel, 130, "ERROR: no subcommand found for %s", argv[0]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
strtolower(argv[1]);
if (strcmp(argv[1], "oldframe") == 0) {
if (argc < 5) {
SCWrite(pCon, "ERROR: insufficient number of arguments to oldframe",
eError);
return 0;
}
iDet = atoi(argv[3]);
iFrame = atoi(argv[4]);
iRet = NexusGetFrameSup(pCon, argv[2], iDet, iFrame);
return 1;
} else if (strcmp(argv[1], "interest") == 0) {
lID = RegisterCallback(self->pCall,
NEWFRAME, FrameSupInterest,
SCCopyConnection(pCon), SCDeleteConnection);
SCSendOK(pCon);
return 1;
} else if (strcmp(argv[1], "newframe") == 0) {
if (argc < 3) {
SCWrite(pCon,
"ERROR: insufficient number of arguments to tricsupport newframe",
eError);
return 0;
}
iFrame = atoi(argv[2]);
InvokeCallBack(self->pCall, NEWFRAME, &iFrame);
SCSendOK(pCon);
return 1;
} else {
SCWrite(pCon, "ERROR: subcommand to tricssuport not understood",
eError);
return 0;
}
}