/*------------------------------------------------------------------------- A module implementing functionality for reading single time frames from PSD time-of-flight datasets. This can be done either from SINQHM histogram memories or from old data files visible from the SICS server. The result is sent to the demanding client in UUencoded format. copyright: see file COPYRIGHT Mark Koennecke, February-March 2003 ---------------------------------------------------------------------------*/ #include #include #include #include "fortify.h" #include "sics.h" #include "stringdict.h" #include "counter.h" #include "HistMem.h" #include "HistMem.i" #include "HistDriv.i" #include #include #include "nxdict.h" #include "frame.h" extern int isSINQHTTP(pHistDriver self); /*======================================================================*/ static int readHMFrame(SConnection * pCon, pHistMem pHM, int nFrame, int sansflag) { HistInt *buffer = NULL, *subbuf = NULL; int iDim[MAXDIM], rank, length, status, i, noTimeBins; pSINQHM pHist; SinqHMDriv *pTata; const float *timeBin; char histCommand[132]; /* find dimensions and allocate data */ GetHistDim(pHM, iDim, &rank); timeBin = GetHistTimeBin(pHM, &noTimeBins); if (rank < 2) { SCWrite(pCon, "ERROR: no PSD data present, cannot send frame", eError); return 0; } length = iDim[0] * iDim[1]; buffer = (HistInt *) malloc((length + 2) * sizeof(HistInt)); if (!buffer) { SCWrite(pCon, "ERROR: out of memory in readHMFrame", eError); return 0; } memset(buffer, 0, (length + 2) * sizeof(HistInt)); /* first two values are dimensions */ buffer[0] = htonl(iDim[0]); buffer[1] = htonl(iDim[1]); if (nFrame < 0) { nFrame = 0; } if (nFrame >= noTimeBins) { nFrame = noTimeBins - 1; } if (!isSecondGen(pHM) && isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) { /* read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h Again: be friendly: fix out of range frames */ pTata = (SinqHMDriv *) pHM->pDriv->pPriv; pHist = (pSINQHM) pTata->pMaster; status = SINQHMProject(pHist, 0x0005, 0, nFrame, 0, iDim[1], buffer + 2, length * sizeof(HistInt)); if (status != 1) { SCWrite(pCon, "ERROR: SINQHM refused to deliver frame", eError); free(buffer); return 0; } } else if(!isSecondGen(pHM) && isSINQHTTP(pHM->pDriv) && noTimeBins > 2){ if(sansflag){ snprintf(histCommand,132,"sample:0:%d:%d:%d", iDim[0]*iDim[1], nFrame, nFrame+1); } else { snprintf(histCommand,132,"sample:0:%d:0:%d:%d:%d", iDim[0], iDim[1], nFrame, nFrame+1); } if(pHM->pDriv->SubSample != NULL){ subbuf = pHM->pDriv->SubSample(pHM->pDriv, pCon,0,histCommand); if(subbuf == NULL){ SCWrite(pCon,"ERROR: subsampling failed ", eError); return 0; } memcpy(buffer+2,subbuf, length *sizeof(HistInt)); free(subbuf); } } else { /* be friendly, just read the 2D data which is there */ status = GetHistogram(pHM, pCon, 0, 0, length, buffer + 2, length * sizeof(HistInt)); if (!status) { free(buffer); return status; } } /* enforce network byte order */ for (i = 0; i < length; i++) { buffer[i + 2] = htonl(buffer[i + 2]); } SCWriteUUencoded(pCon, "framedata", buffer, (length + 2) * sizeof(HistInt)); free(buffer); return 1; } /*=======================================================================*/ static int readFileFrame(SConnection * pCon, char *file, char *dictFile, char *alias, int nFrame) { int status, iDim[NX_MAXRANK], rank = 0, type = 0; int iStart[3], iSize[3], length, i; int *buffer = NULL; NXhandle fileHandle; NXdict dictHandle; char error[512]; status = NXopen(file, NXACC_READ, &fileHandle); if (status != NX_OK) { snprintf(error,sizeof(error)-1, "ERROR: failed to open %s", file); SCWrite(pCon, error, eError); return 0; } status = NXDinitfromfile(dictFile, &dictHandle); if (status != NX_OK) { snprintf(error,sizeof(error)-1, "ERROR: failed to open dictionary %s", dictFile); NXclose(&fileHandle); SCWrite(pCon, error, eError); return 0; } status = NXDopenalias(fileHandle, dictHandle, alias); if (status != NX_OK) { snprintf(error,sizeof(error)-1, "ERROR: failed to open alias %s", alias); NXclose(&fileHandle); NXDclose(dictHandle, NULL); SCWrite(pCon, error, eError); return 0; } status = NXgetinfo(fileHandle, &rank, iDim, &type); if (type != NX_INT32 && type != NX_UINT32) type = -1; if (status != NX_OK || rank < 2 || type < 0) { snprintf(error,sizeof(error)-1, "ERROR: Dataset does not match!"); NXclose(&fileHandle); NXDclose(dictHandle, NULL); SCWrite(pCon, error, eError); return 0; } /* allocate space */ length = iDim[0] * iDim[1]; buffer = (int *) malloc((length + 2) * sizeof(int)); if (!buffer) { NXclose(&fileHandle); NXDclose(dictHandle, NULL); SCWrite(pCon, "ERROR: out of memory in readFrameFromFile", eError); return 0; } memset(buffer, 0, (length + 2) * sizeof(int)); /* first two values: dimensions */ buffer[0] = htonl(iDim[0]); buffer[1] = htonl(iDim[1]); if (rank == 2) { /* be friendly */ status = NXgetdata(fileHandle, buffer + 2); } else { iStart[0] = iStart[1] = 0; iStart[2] = nFrame; iSize[0] = iDim[0]; iSize[1] = iDim[1]; iSize[2] = 1; status = NXgetslab(fileHandle, buffer + 2, iStart, iSize); } if (status != NX_OK) { NXclose(&fileHandle); NXDclose(dictHandle, NULL); free(buffer); SCWrite(pCon, "ERROR: failed to read data", eError); return 0; } /* enforce network byte order */ for (i = 0; i < length; i++) { buffer[2 + i] = htonl(buffer[2 + i]); } SCWriteUUencoded(pCon, "framedata", buffer, (length + 2) * sizeof(int)); NXclose(&fileHandle); NXDclose(dictHandle, NULL); free(buffer); return 1; } /*=======================================================================*/ int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { pHistMem pHM; int nFrame; int sansflag; /* this is unique and special for the SANS at PSI */ if (argc < 2) { SCWrite(pCon, "ERROR: Insufficient number of arguments to PSDFrame", eError); return 0; } strtolower(argv[1]); if (strcmp(argv[1], "hm") == 0) { if (argc < 4) { SCWrite(pCon, "ERROR: Insufficient number of arguments to PSDFrame", eError); return 0; } pHM = (pHistMem) FindHM(pSics, argv[2]); if (pHM == NULL) { SCWrite(pCon, "ERROR: Did not find histogram memory", eError); return 0; } nFrame = atoi(argv[3]); if(argc > 3 && (strcmp(argv[4],"sans") == 0) ){ sansflag = 1; } else { sansflag = 0; } return readHMFrame(pCon, pHM, nFrame, sansflag); } else if (strcmp(argv[1], "file") == 0) { if (argc < 6) { SCWrite(pCon, "ERROR: Insufficient number of arguments to PSDframe file", eError); return 0; } nFrame = atoi(argv[5]); return readFileFrame(pCon, argv[2], argv[3], argv[4], nFrame); } else { SCWrite(pCon, "ERROR: subcommand to PSDframe not recognised", eError); return 0; } } /*======================================================================*/ int MakeFrameFunc(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) { return AddCommand(pSics, "PSDframe", PSDFrameAction, NULL, NULL); }