Files
sics/frame.c
koennecke 86e246416b - Added bridge functions to histmemsec to make it look more like histmem
- Modifed many modules using histmem to work also with histmemsec
- Extended tasker with task names and task groups
- There is a new taskobj which allows to list tasks and to interact with them.
- Task now supports running Tcl functions as tasks
- There is a new experimental sctcomtask module which allows to define communication
  tasks against a scriptcontext. This is a new feature which should facilitate
  writing sequential scripts using asynchronous communication.
- A fix to make spss7 work when there are no switches
- ORION support for single X. TRICS measures crystals hanging down, ORION
  standing up


SKIPPED:
	psi/ease.c
	psi/faverage.c
	psi/jvlprot.c
	psi/make_gen
	psi/pardef.c
	psi/polterwrite.c
	psi/psi.c
	psi/sinq.c
	psi/spss7.c
2012-12-20 11:32:33 +00:00

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 "psi/hardsup/sinqhm.h"
#include "psi/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);
}