Files
sics/mcreader.c
koennecke 93c349314c - Fix to various drivers due to changes in rs232controller
- hkl now searches psi in .5 steps
- first point of fastscan is driven normally


SKIPPED:
	psi/amor2t.c
	psi/amor2t.h
	psi/amor2t.i
	psi/amor2t.tex
	psi/amor2t.w
	psi/dornier2.c
	psi/el734hp.c
	psi/nxamor.c
	psi/slsmagnet.c
	psi/sps.c
2005-09-07 13:51:11 +00:00

468 lines
12 KiB
C

/*-----------------------------------------------------------------------------
Implementation file for the McStas reader module. This module helps
transferring McStasresult data into SICS counters and histogram memories.
copyright: see file COPYRIGHT
Mark Koennecke, June 2005
-----------------------------------------------------------------------------*/
#include <assert.h>
#include <ctype.h>
#include "mcreader.h"
#include "counter.h"
#include "HistMem.h"
#include "sicsdata.h"
/*-------------------------------------------------------------------------*/
static void KillMcReader(void *pData){
pMcStasReader self = (pMcStasReader)pData;
if(self == NULL){
return;
}
if(self->pDes){
DeleteDescriptor(self->pDes);
}
if(self->handle != NULL){
NXclose(&self->handle);
}
free(self);
}
/*--------------------------------------------------------------------------*/
int McStasReaderFactory(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[]){
pMcStasReader pNew = NULL;
pNew = (pMcStasReader)malloc(sizeof(McStasReader));
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating McStasReader",eError);
return 0;
}
memset(pNew,0,sizeof(McStasReader));
pNew->pDes = CreateDescriptor("McStasReader");
if(pNew->pDes == NULL){
SCWrite(pCon,"ERROR: out of memory creating McStasReader",eError);
free(pNew);
return 0;
}
return AddCommand(pSics,"mcreader",
McStasReaderWrapper,
KillMcReader,
pNew);
}
/*==================== interpreter interface ===============================*/
static void MCReportError(void *pData, char *txt){
pMcStasReader self = NULL;
self = (pMcStasReader)pData;
if(self != NULL){
strncpy(self->nexusError,txt,1024);
} else {
printf(
"ERROR: NeXus error in McStasReader without McStasReader data structure: %s\n",
txt);
}
}
/*-------------------------------------------------------------------------*/
static int openMcStasFile(pMcStasReader self, SConnection *pCon,
int argc, char *argv[]){
int status;
char pBueffel[512];
if(argc < 3){
SCWrite(pCon,"ERROR: need filename argument for opening file",
eError);
}
/*
* be nice to users: if file still open, close it
*/
if(self->handle != NULL){
NXclose(&self->handle);
self->handle = NULL;
}
/**
* open the file
*/
NXMSetError(self,MCReportError);
status = NXopen((const char*)argv[2],NXACC_READ,&self->handle);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: NeXus reported %s",
self->nexusError);
SCWrite(pCon,pBueffel,eError);
return 0;
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
static int closeMcStasFile(pMcStasReader self, SConnection *pCon){
if(self->handle != NULL){
NXclose(&self->handle);
self->handle = NULL;
}
SCSendOK(pCon);
return 1;
}
/*-------------------------------------------------------------------*/
static char *getNextMCNumber(char *pStart, char pNumber[80]){
int charCount = 0;
pNumber[0] = '\0';
/* advance to first digit */
while(isspace(*pStart) && *pStart != '\0'){
pStart++;
}
if(*pStart == '\0'){
return NULL;
}
/* copy */
while(!isspace(*pStart) && *pStart != '\0' && charCount < 78){
pNumber[charCount] = *pStart;
pStart++;
charCount++;
}
pNumber[charCount] = '\0';
return pStart;
}
/*--------------------------------------------------------------------------*/
static int insertMonitor(pMcStasReader self, SConnection *pCon,
SicsInterp *pSics, int argc, char *argv[]){
char pBueffel[512], *pPtr, pNumber[80];
pCounter pCount = NULL;
int status, mon, type, rank, iDim[NX_MAXRANK];
float monValue, scale = 1.;
if(argc < 5){
SCWrite(pCon,\
"ERROR: insufficient number of arguments to mcreader insertmon",
eError);
return 0;
}
if(self->handle == NULL){
SCWrite(pCon,"ERROR: no file open to read data from",eError);
return 0;
}
pCount = FindCommandData(pSics,argv[3],"SingleCounter");
if(pCount == NULL){
snprintf(pBueffel,511,
"ERROR: %s is no counter object",
argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
mon = atoi(argv[4]);
status = NXopenpath(self->handle,argv[2]);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while opening %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(argc > 5) {
scale = atof(argv[5]);
}
status = NXgetinfo(self->handle,&rank,iDim,&type);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(rank != 1 || type != NX_CHAR || iDim[0] > 511){
snprintf(pBueffel,511,"ERROR: %s is no valid monitor data",
argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = NXgetdata(self->handle,pBueffel);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/*
* the monitor value we want is the third value in the values field
*/
pPtr = pBueffel;
memset(pNumber,0,80*sizeof(char));
pPtr = getNextMCNumber(pPtr,pNumber);
pPtr = getNextMCNumber(pPtr,pNumber);
pPtr = getNextMCNumber(pPtr,pNumber);
monValue = atof(pNumber);
monValue *= scale;
if(pCount != NULL){
SetMonitorValue(pCount,mon,(long)monValue);
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
static int insertMonitorDirect(pMcStasReader self, SConnection *pCon,
SicsInterp *pSics, int argc, char *argv[]){
char pBueffel[512], *pPtr, pNumber[80];
pCounter pCount = NULL;
int status, mon;
float monValue;
if(argc < 5){
SCWrite(pCon,\
"ERROR: insufficient number of arguments to mcreader insertmondirect",
eError);
return 0;
}
pCount = FindCommandData(pSics,argv[2],"SingleCounter");
if(pCount == NULL){
snprintf(pBueffel,511,
"ERROR: %s is no counter object",
argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
mon = atoi(argv[3]);
monValue = atof(argv[4]);
if(pCount != NULL){
SetMonitorValue(pCount,mon,(long)monValue);
}
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
static int insertHM(pMcStasReader self, SConnection *pCon,
SicsInterp *pSics, int argc, char *argv[]){
char pBueffel[512], *pPtr, pNumber[80], *pData = NULL;
pHistMem pHM = NULL;
int status, type, rank, iDim[NX_MAXRANK];
int length, i;
HistInt *lData = NULL;
float scale = 1.;
double val;
if(argc < 4){
SCWrite(pCon,\
"ERROR: insufficient number of arguments to mcreader inserthm",
eError);
return 0;
}
if(self->handle == NULL){
SCWrite(pCon,"ERROR: no file open to read data from",eError);
return 0;
}
pHM = FindCommandData(pSics,argv[3],"HistMem");
if(pHM == NULL){
snprintf(pBueffel,511,
"ERROR: %s is no histogram memory object",
argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = NXopenpath(self->handle,argv[2]);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while opening %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(argc > 4){
scale = atof(argv[4]);
}
status = NXgetinfo(self->handle,&rank,iDim,&type);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pData = (char *)malloc((iDim[0]+1)*sizeof(char));
if(pData == NULL){
SCWrite(pCon,"ERROR: out of memory in mcreader inserthm",eError);
return 0;
}
memset(pData,0,(iDim[0]+1)*sizeof(char));
status = NXgetdata(self->handle,pData);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
length = GetHistLength(pHM);
lData = (HistInt *)malloc(length*sizeof(HistInt));
if(lData== NULL){
SCWrite(pCon,"ERROR: out of memory in mcreader inserthm",eError);
free(pData);
return 0;
}
memset(lData,0,length*sizeof(HistInt));
pPtr = pData;
for(i = 0; i < length && pPtr != NULL; i++){
pPtr = getNextMCNumber(pPtr,pNumber);
val = atof(pNumber);
val *= scale;
lData[i] = (HistInt)val;
}
SetHistogram(pHM,pCon,0,0,length,lData);
free(pData);
free(lData);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
static int getField(pMcStasReader self, SConnection *pCon,
SicsInterp *pSics, int argc, char *argv[]){
char pBueffel[512], *pPtr, pNumber[80], *pData = NULL;
int status, type, rank, iDim[NX_MAXRANK];
if(argc < 2){
SCWrite(pCon,\
"ERROR: insufficient number of arguments to mcreader getfield",
eError);
return 0;
}
if(self->handle == NULL){
SCWrite(pCon,"ERROR: no file open to read data from",eError);
return 0;
}
status = NXopenpath(self->handle,argv[2]);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while opening %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
status = NXgetinfo(self->handle,&rank,iDim,&type);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pData = (char *)malloc((iDim[0]+1)*sizeof(char));
if(pData == NULL){
SCWrite(pCon,"ERROR: out of memory in mcreader getfield",eError);
return 0;
}
memset(pData,0,(iDim[0]+1)*sizeof(char));
status = NXgetdata(self->handle,pData);
if(status != NX_OK){
snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s",
self->nexusError, argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
SCWrite(pCon,pData,eValue);
free(pData);
return 1;
}
/*--------------------------------------------------------------------------*/
static int insertHMFromData(pMcStasReader self, SConnection *pCon,
SicsInterp *pSics, int argc, char *argv[]){
char pBueffel[512];
pHistMem pHM = NULL;
int length, i;
HistInt *lData = NULL;
pSICSData data = NULL;
if(argc < 4){
SCWrite(pCon,\
"ERROR: insufficient number of arguments to mcreader inserthmfromdata",
eError);
return 0;
}
pHM = FindCommandData(pSics,argv[2],"HistMem");
if(pHM == NULL){
snprintf(pBueffel,511,
"ERROR: %s is no histogram memory object",
argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
data = FindCommandData(pSics,argv[3],"SICSData");
if(data == NULL){
snprintf(pBueffel,511,
"ERROR: %s is no SICSData object",
argv[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
length = GetHistLength(pHM);
if(data->currentDataSize < length){
snprintf(pBueffel,511,"WARNING: data in %s to short for HM %s",
argv[3],argv[2]);
SCWrite(pCon,pBueffel,eWarning);
}
lData = (HistInt *)malloc(length*sizeof(HistInt));
if(lData== NULL){
SCWrite(pCon,"ERROR: out of memory in mcreader inserthm",eError);
return 0;
}
memset(lData,0,length*sizeof(HistInt));
if(data->currentDataSize < length){
length = data->currentDataSize;
}
for(i = 0; i < length; i++){
lData[i] = (HistInt)data->data[i];
}
SetHistogram(pHM,pCon,0,0,length,lData);
free(lData);
SCSendOK(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
int McStasReaderWrapper(SConnection *pCon, SicsInterp *pSics,
void *pData, int argc, char *argv[]){
pMcStasReader self = NULL;
char pBueffel[512];
self = (pMcStasReader)pData;
assert(self != NULL);
if(argc < 2){
SCWrite(pCon,"ERROR: insufficient number of arguments to mcreader",
eError);
return 0;
}
strtolower(argv[1]);
if(strcmp(argv[1],"open") == 0){
return openMcStasFile(self, pCon, argc, argv);
} else if(strcmp(argv[1],"close") == 0){
return closeMcStasFile(self,pCon);
} else if(strcmp(argv[1],"insertmon") == 0){
return insertMonitor(self,pCon, pSics,argc,argv);
} else if(strcmp(argv[1],"insertmondirect") == 0){
return insertMonitorDirect(self,pCon, pSics,argc,argv);
} else if(strcmp(argv[1],"inserthm") == 0){
return insertHM(self,pCon, pSics,argc,argv);
} else if(strcmp(argv[1],"inserthmfromdata") == 0){
return insertHMFromData(self,pCon, pSics,argc,argv);
} else if(strcmp(argv[1],"getfield") == 0){
return getField(self,pCon, pSics,argc,argv);
} else {
snprintf(pBueffel,511,"ERROR: invalid subcommand %s to %s",
argv[1],argv[0]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
return 1;
}