/*------------------------------------------------------------------------ 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, commandContext cc){ SConnection *pCon = NULL; int *iFrame; char pBueffel[512]; if(iEvent != NEWFRAME){ return 0; } pCon = (SConnection *)pUser; iFrame = (int *)pEvent; assert(pCon); sprintf(pBueffel,"framenumber = %d",*iFrame); SCPushContext2(pCon,cc); SCWrite(pCon,pBueffel,eWarning); SCPopContext(pCon); 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, SCGetContext(pCon), NEWFRAME, FrameSupInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); 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; } }