
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c Conflicts: .gitignore SICSmain.c asynnet.c confvirtualmot.c counter.c devexec.c drive.c event.h exebuf.c exeman.c histmem.c interface.h motor.c motorlist.c motorsec.c multicounter.c napi.c napi.h napi4.c network.c nwatch.c nxscript.c nxxml.c nxxml.h ofac.c reflist.c scan.c sicshipadaba.c sicsobj.c site_ansto/docs/Copyright.txt site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl statusfile.c tasdrive.c tasub.c tasub.h tasublib.c tasublib.h
280 lines
7.7 KiB
C
280 lines
7.7 KiB
C
/*-------------------------------------------------------------------------
|
|
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 <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "stringdict.h"
|
|
#include "counter.h"
|
|
#include "HistMem.h"
|
|
#include "HistMem.i"
|
|
#include "HistDriv.i"
|
|
#include <hardsup/sinqhm.h>
|
|
#include <sinqhmdriv.i>
|
|
#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);
|
|
}
|