/*------------------------------------------------------------------------ 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; } }