1370 lines
40 KiB
C
1370 lines
40 KiB
C
/*-------------------------------------------------------------------------
|
|
|
|
N E X T R I C S
|
|
|
|
NeXus file writing for the four circle diffractometer TRICS at Sinq, PSI.
|
|
|
|
This object uses the NXDICT-API. A further speciality is that objects
|
|
which are constantly written are kept in cache. This means, on
|
|
initialisation pointers to all relevant objects which have to be stored with
|
|
a data frame are searched and kept in the objects data structure.
|
|
|
|
copyright: see copyright.h
|
|
|
|
Mark Koennecke, April 1998
|
|
|
|
Revised: Mark Koennecke, October 2000
|
|
Revised: Mark Koennecke, July 2001
|
|
|
|
This is defunct as of 2009.
|
|
|
|
Mark Koennecke, March 2009
|
|
----------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <time.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "sicsvar.h"
|
|
#include "motor.h"
|
|
#include "countdriv.h"
|
|
#include "counter.h"
|
|
#include "HistMem.h"
|
|
#include "danu.h"
|
|
#include "nxdict.h"
|
|
#include "nxutil.h"
|
|
#include "hkl.h"
|
|
#include "udpquieck.h"
|
|
#include "nextrics.h"
|
|
#include "nxscript.h"
|
|
|
|
|
|
#define DET1X 256 /* x -length of detector 1 */
|
|
#define DET1Y 128 /* y-length of detector 1 */
|
|
#define DET1XS -.78 /* pixel size in x of detector 1 */
|
|
#define DET1YS 1.486 /* pixel size in y of detector 1 */
|
|
#define DET1DESC "EMBL PSD"
|
|
#define DET2X 256 /* x -length of detector 1 */
|
|
#define DET2Y 128 /* y-length of detector 1 */
|
|
#define DET2XS -.78 /* pixel size in x of detector 1 */
|
|
#define DET2YS 1.486 /* pixel size in y of detector 1 */
|
|
#define DET2DESC "EMBL PSD"
|
|
#define DET3X 256 /* x -length of detector 1 */
|
|
#define DET3Y 128 /* y-length of detector 1 */
|
|
#define DET3XS -.78 /* pixel size in x of detector 1 */
|
|
#define DET3YS 1.486 /* pixel size in y of detector 1 */
|
|
#define DET3DESC "EMBL PSD"
|
|
#define DETAMAX 256 /* maximum length of pixelsize array */
|
|
|
|
/* histogram memory names */
|
|
#define HM1 "hm1"
|
|
#define HM2 "hm2"
|
|
#define HM3 "hm3"
|
|
|
|
/*
|
|
offset variable names
|
|
*/
|
|
#define HM2OFF "hm2off"
|
|
#define HM3OFF "hm3off"
|
|
#define HM1OFF "hm1off"
|
|
|
|
/*
|
|
name of hkl object holding crystallographic information
|
|
*/
|
|
#define HKLNAME "hkl"
|
|
|
|
/*------------------------ the data structure ----------------------------*/
|
|
typedef struct __NexTrics {
|
|
pObjectDescriptor pDes;
|
|
char *pCurrentFile;
|
|
char *pFileRoot;
|
|
pDataNumber pDanu;
|
|
NXdict pDict;
|
|
pHistMem pHistogram1, pHistogram2, pHistogram3;
|
|
int iFirst;
|
|
int iFrameNum;
|
|
pICallBack pCall;
|
|
float hm2Off, hm3Off, hm1off;
|
|
pHKL pCrystal;
|
|
int iHDF5;
|
|
pCounter pCount;
|
|
} NexTrics;
|
|
|
|
/* event type */
|
|
#define NEWFRAME 1166
|
|
/*----------------------------------------------------------------------*/
|
|
pNexTrics CreateNexTrics(pDataNumber pNum, char *pRoot, char *pDict,
|
|
SicsInterp * pSics)
|
|
{
|
|
pNexTrics pNew = NULL;
|
|
int iRet;
|
|
CommandList *pCom = NULL;
|
|
pSicsVariable pVar = NULL;
|
|
|
|
/* allocate memory */
|
|
pNew = (pNexTrics) malloc(sizeof(NexTrics));
|
|
if (!pNew) {
|
|
return NULL;
|
|
}
|
|
memset(pNew, 0, sizeof(NexTrics));
|
|
|
|
/* new object descriptor and callback interface */
|
|
pNew->pDes = CreateDescriptor(HM1);
|
|
pNew->pCall = CreateCallBackInterface();
|
|
if (!pNew->pDes || !pNew->pCall) {
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
|
|
/* initialize dictionary */
|
|
iRet = NXDinitfromfile(pDict, &pNew->pDict);
|
|
if (iRet != NX_OK) {
|
|
DeleteNexTrics(pNew);
|
|
return NULL;
|
|
}
|
|
if (strstr(pDict, "5") != NULL) {
|
|
pNew->iHDF5 = 1;
|
|
}
|
|
pNew->pFileRoot = strdup(pRoot);
|
|
pNew->pDanu = pNum;
|
|
|
|
/* find things in interpreter */
|
|
pCom = FindCommand(pSics, HM1);
|
|
if (pCom) {
|
|
pNew->pHistogram1 = (pHistMem) pCom->pData;
|
|
} else {
|
|
pNew->pHistogram1 = NULL;
|
|
}
|
|
|
|
pCom = FindCommand(pSics, HM2);
|
|
if (pCom) {
|
|
pNew->pHistogram2 = (pHistMem) pCom->pData;
|
|
} else {
|
|
pNew->pHistogram2 = NULL;
|
|
}
|
|
pCom = FindCommand(pSics, HM3);
|
|
if (pCom) {
|
|
pNew->pHistogram3 = (pHistMem) pCom->pData;
|
|
} else {
|
|
pNew->pHistogram3 = NULL;
|
|
}
|
|
pCom = FindCommand(pSics, HKLNAME);
|
|
if (pCom) {
|
|
pNew->pCrystal = (pHKL) pCom->pData;
|
|
} else {
|
|
pNew->pCrystal = NULL;
|
|
}
|
|
pCom = FindCommand(pSics, "counter");
|
|
if (pCom) {
|
|
pNew->pCount = (pCounter) pCom->pData;
|
|
} else {
|
|
pNew->pCrystal = NULL;
|
|
}
|
|
pNew->iFirst = 1;
|
|
pNew->iFrameNum = 0;
|
|
|
|
pVar = FindVariable(pSics, HM1OFF);
|
|
if (pVar) {
|
|
pNew->hm1off = pVar->fVal;
|
|
} else {
|
|
pNew->hm1off = 0;
|
|
}
|
|
pVar = FindVariable(pSics, HM2OFF);
|
|
if (pVar) {
|
|
pNew->hm2Off = pVar->fVal;
|
|
} else {
|
|
pNew->hm2Off = +45.;
|
|
}
|
|
pVar = FindVariable(pSics, HM3OFF);
|
|
if (pVar) {
|
|
pNew->hm3Off = pVar->fVal;
|
|
} else {
|
|
pNew->hm3Off = 90.;
|
|
}
|
|
|
|
|
|
return pNew;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
void DeleteNexTrics(void *pData)
|
|
{
|
|
pNexTrics self = NULL;
|
|
|
|
self = (pNexTrics) pData;
|
|
if (!self)
|
|
return;
|
|
|
|
if (self->pDes)
|
|
DeleteDescriptor(self->pDes);
|
|
|
|
if (self->pCurrentFile)
|
|
free(self->pCurrentFile);
|
|
|
|
if (self->pFileRoot)
|
|
free(self->pFileRoot);
|
|
|
|
if (self->pDict)
|
|
NXDclose(self->pDict, NULL);
|
|
|
|
if (self->pCall)
|
|
DeleteCallBackInterface(self->pCall);
|
|
|
|
free(self);
|
|
}
|
|
|
|
/*---------------------- a neXus error handler ---------------------------*/
|
|
static void SNError(void *pData, char *text)
|
|
{
|
|
SConnection *pCon;
|
|
|
|
assert(pData);
|
|
pCon = (SConnection *) pData;
|
|
SCWrite(pCon, text, eError);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int NexTricsFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pNexTrics pNew = NULL;
|
|
pDataNumber pDanu = NULL;
|
|
CommandList *pCom;
|
|
char pBueffel[512];
|
|
int iRet;
|
|
pDummy pDum;
|
|
|
|
if (argc < 4) {
|
|
SCWrite(pCon,
|
|
"ERROR: Insufficient number of arguments to NexTricsFactory",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
/* first item must be the name of a datanumber variable */
|
|
pCom = FindCommand(pSics, argv[1]);
|
|
if (pCom) {
|
|
pDanu = (pDataNumber) pCom->pData;
|
|
}
|
|
if ((!pCom) || (!pDanu)) {
|
|
SCWrite(pCon, "ERROR: DataNumber object NOT found", eError);
|
|
return 0;
|
|
}
|
|
pDum = (pDummy) pDanu;
|
|
if (strcmp(pDum->pDescriptor->name, "DataNumber") != 0) {
|
|
sprintf(pBueffel, "ERROR: %s is no DataNumber object", argv[1]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* install an error handler */
|
|
NXMSetError((void *) pCon, SNError);
|
|
|
|
pNew = CreateNexTrics(pDanu, argv[2], argv[3], pSics);
|
|
if (!pNew) {
|
|
SCWrite(pCon, "ERROR: cannot create nexTrics, invalid dictionary file",
|
|
eError);
|
|
SCWrite(pCon, "ERROR: or system objects missing.", eError);
|
|
return 0;
|
|
}
|
|
|
|
/* create the command */
|
|
iRet = AddCommand(pSics, "nxtrics", NexTricsAction, DeleteNexTrics,
|
|
pNew);
|
|
if (!iRet) {
|
|
SCWrite(pCon, "ERROR: duplicate command nxtrics not created", eError);
|
|
}
|
|
return iRet;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int DumpData(pNexTrics self, SConnection * pCon, NXhandle hfil,
|
|
int iFrameNum)
|
|
{
|
|
int iRet;
|
|
char pBueffel[512];
|
|
CounterMode eMode;
|
|
HistInt lData[DET1X * DET1Y], i, lVal;
|
|
int iVal, lBeam;
|
|
float fVal, fTTheta, fTime = 0.;
|
|
pMotor pMot;
|
|
|
|
/* write motors */
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict, "framechi", "CHI");
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict, "framephi", "PHI");
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict, "frameomega", "OM");
|
|
/*
|
|
read two theta
|
|
*/
|
|
pMot = FindMotor(pServ->pSics, "stt");
|
|
if (!pMot) {
|
|
sprintf(pBueffel, "WARNING: cannot find motor stt");
|
|
SCWrite(pCon, pBueffel, eWarning);
|
|
return 0;
|
|
}
|
|
|
|
/* get the position */
|
|
iRet = MotorGetSoftPosition(pMot, pCon, &fTTheta);
|
|
|
|
|
|
/* write frame time */
|
|
SNXFormatTime(pBueffel, 512);
|
|
iRet = NXDputalias(hfil, self->pDict, "etime", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: cannot write frame time", eError);
|
|
}
|
|
|
|
/* write counting parameters */
|
|
if (self->pHistogram1 != NULL) {
|
|
eMode = GetHistCountMode(self->pHistogram1);
|
|
fVal = GetHistPreset(self->pHistogram1);
|
|
lVal = GetHistMonitor(self->pHistogram1, 1, pCon);
|
|
lBeam = GetHistMonitor(self->pHistogram1, 4, pCon);
|
|
}
|
|
if (self->pHistogram2 != NULL) {
|
|
eMode = GetHistCountMode(self->pHistogram2);
|
|
fVal = GetHistPreset(self->pHistogram2);
|
|
lVal = GetHistMonitor(self->pHistogram2, 1, pCon);
|
|
lBeam = GetHistMonitor(self->pHistogram2, 4, pCon);
|
|
}
|
|
if (self->pHistogram3 != NULL) {
|
|
eMode = GetHistCountMode(self->pHistogram3);
|
|
fVal = GetHistPreset(self->pHistogram3);
|
|
lVal = GetHistMonitor(self->pHistogram3, 1, pCon);
|
|
lBeam = GetHistMonitor(self->pHistogram3, 4, pCon);
|
|
}
|
|
if (self->pCount != NULL) {
|
|
eMode = GetCounterMode(self->pCount);
|
|
fVal = GetCounterPreset(self->pCount);
|
|
lVal = GetMonitor(self->pCount, 1, pCon);
|
|
fTime = GetCountTime(self->pCount, pCon);
|
|
lBeam = GetMonitor(self->pCount, 4, pCon);
|
|
}
|
|
if (eMode == eTimer) {
|
|
strcpy(pBueffel, "Timer");
|
|
} else {
|
|
strcpy(pBueffel, "Monitor");
|
|
}
|
|
NXDputalias(hfil, self->pDict, "framemode", pBueffel);
|
|
NXDputalias(hfil, self->pDict, "framepreset", &fVal);
|
|
iVal = (int) lVal;
|
|
NXDputalias(hfil, self->pDict, "framemonitor", &iVal);
|
|
iVal = (int) lBeam;
|
|
NXDputalias(hfil, self->pDict, "sinqmonitor", &iVal);
|
|
NXDputalias(hfil, self->pDict, "cctime", &fTime);
|
|
|
|
/* write detector1 histogram */
|
|
if (self->pHistogram1 != NULL) {
|
|
strcpy(pBueffel, "detector1");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict,
|
|
"frametilt", "DG1");
|
|
GetHistogram(self->pHistogram1, pCon, 0, 0, DET1X * DET1Y, lData,
|
|
DET1X * DET1Y * sizeof(HistInt));
|
|
NXDputalias(hfil, self->pDict, "framecounts", lData);
|
|
|
|
/*
|
|
NXDopenalias(hfil,self->pDict,"framecounts");
|
|
NXputdata(hfil,lData);
|
|
NXsetdimname(hfil,0,"frame_x");
|
|
NXsetdimname(hfil,1,"frame_y");
|
|
NXclosedata(hfil);
|
|
*/
|
|
|
|
fVal = fTTheta + self->hm1off;
|
|
NXDputalias(hfil, self->pDict, "frame2theta", &fVal);
|
|
|
|
/* the NXdata links */
|
|
NXDaliaslink(hfil, self->pDict, "frame", "detectorx");
|
|
NXDaliaslink(hfil, self->pDict, "frame", "detectory");
|
|
NXDaliaslink(hfil, self->pDict, "frame", "framecounts");
|
|
}
|
|
/*
|
|
do detector 2 histogram
|
|
*/
|
|
if (self->pHistogram2 != NULL) {
|
|
strcpy(pBueffel, "detector2");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict,
|
|
"frametilt", "DG2");
|
|
GetHistogram(self->pHistogram2, pCon, 0, 0, DET2X * DET2Y, lData,
|
|
DET2X * DET2Y * sizeof(HistInt));
|
|
NXDputalias(hfil, self->pDict, "framecounts", lData);
|
|
|
|
/* code for reducing object number in HDF-4
|
|
NXDopenalias(hfil,self->pDict,"framecounts");
|
|
NXputdata(hfil,lData);
|
|
NXsetdimname(hfil,0,"frame_x");
|
|
NXsetdimname(hfil,1,"frame_y");
|
|
NXclosedata(hfil);
|
|
*/
|
|
|
|
fVal = fTTheta + self->hm2Off;
|
|
NXDputalias(hfil, self->pDict, "frame2theta", &fVal);
|
|
|
|
/* the NXdata links */
|
|
NXDaliaslink(hfil, self->pDict, "frame", "detectorx");
|
|
NXDaliaslink(hfil, self->pDict, "frame", "detectory");
|
|
NXDaliaslink(hfil, self->pDict, "frame", "framecounts");
|
|
}
|
|
/*
|
|
do detector 3 histogram
|
|
*/
|
|
if (self->pHistogram3 != NULL) {
|
|
strcpy(pBueffel, "detector3");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict,
|
|
"frametilt", "DG3");
|
|
GetHistogram(self->pHistogram3, pCon, 0, 0, DET3X * DET3Y, lData,
|
|
DET3X * DET3Y * sizeof(HistInt));
|
|
|
|
NXDputalias(hfil, self->pDict, "framecounts", lData);
|
|
|
|
/* code for reducing object numbers in HDF-4
|
|
NXDopenalias(hfil,self->pDict,"framecounts");
|
|
NXputdata(hfil,lData);
|
|
NXsetdimname(hfil,0,"frame_x");
|
|
NXsetdimname(hfil,1,"frame_y");
|
|
NXclosedata(hfil);
|
|
*/
|
|
|
|
|
|
fVal = fTTheta + self->hm3Off;
|
|
NXDputalias(hfil, self->pDict, "frame2theta", &fVal);
|
|
|
|
/* the NXdata links */
|
|
NXDaliaslink(hfil, self->pDict, "frame", "detectorx");
|
|
NXDaliaslink(hfil, self->pDict, "frame", "detectory");
|
|
NXDaliaslink(hfil, self->pDict, "frame", "framecounts");
|
|
}
|
|
|
|
|
|
/* temperature */
|
|
SNXSPutEVVar(hfil, self->pDict, "temperature",
|
|
pCon, "frametemp", "framestdev");
|
|
|
|
/* close and done */
|
|
sprintf(pBueffel, "Frame %d succesfully written", iFrameNum - 1);
|
|
SCWrite(pCon, pBueffel, eLog);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
static int WriteFirstFrame(pNexTrics self, SConnection * pCon)
|
|
{
|
|
char pBueffel[1024];
|
|
NXhandle hfil;
|
|
int iRet, iYear, i;
|
|
pSicsVariable pVar;
|
|
char *pText;
|
|
CommandList *pCom = NULL;
|
|
pHKL pCryst = NULL;
|
|
float fVal, fPix[DETAMAX];
|
|
float fHKL[3], fUB[9];
|
|
|
|
iRet = NXopen(self->pCurrentFile, NXACC_RDWR, &hfil);
|
|
if (iRet != NX_OK) {
|
|
sprintf(pBueffel, "ERROR: cannot open %s", self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* make sure: first frame */
|
|
NXDupdate(self->pDict, "framename", "frame0000");
|
|
self->iFrameNum = 0;
|
|
|
|
/* title */
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "title");
|
|
if (pVar) {
|
|
pText = pVar->text;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable title not found ", eError);
|
|
pText = pBueffel;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "etitle", pText);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write title", eError);
|
|
}
|
|
|
|
/* start time */
|
|
SNXFormatTime(pBueffel, 1023);
|
|
iRet = NXDputalias(hfil, self->pDict, "etime", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write start time", eError);
|
|
}
|
|
|
|
/* source info */
|
|
strcpy(pBueffel, "SINQ at Paul Scherrer Institut, Villigen");
|
|
iRet = NXDputalias(hfil, self->pDict, "sname", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write source name", eError);
|
|
}
|
|
strcpy(pBueffel, "Spallation Neutron Source");
|
|
iRet = NXDputalias(hfil, self->pDict, "stype", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write source type", eError);
|
|
}
|
|
|
|
/* instrument name */
|
|
strcpy(pBueffel, "TRICS at SINQ, Paul Scherrer Institut, Switzerland");
|
|
iRet = NXDputalias(hfil, self->pDict, "iname0", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write instrument name", eError);
|
|
}
|
|
|
|
/* Collimator */
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict, "cex1", "cex1");
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict, "cex2", "cex2");
|
|
|
|
|
|
/* Monochromator */
|
|
pVar = NULL;
|
|
strcpy(pBueffel, "UNKNOWN");
|
|
pVar = FindVariable(pServ->pSics, "monodescription");
|
|
if (pVar) {
|
|
pText = pVar->text;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable monodescription not found ", eError);
|
|
pText = pBueffel;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "monodes", pText);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write monodescription", eError);
|
|
}
|
|
|
|
/* lambda */
|
|
if (self->pCrystal != NULL) {
|
|
GetLambda(self->pCrystal, &fVal);
|
|
iRet = NXDputalias(hfil, self->pDict, "monolambda", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write lambda", eError);
|
|
}
|
|
}
|
|
|
|
/* two theta */
|
|
pVar = NULL;
|
|
strcpy(pBueffel, "UNKNOWN");
|
|
pVar = FindVariable(pServ->pSics, "mono2theta");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable mono2theta not found ", eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "mono2theta", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write monochromator 2 Theta", eError);
|
|
}
|
|
/* theta, needs work when lift operational */
|
|
SNXSPutMotor(pServ->pSics, pCon, hfil, self->pDict, "monotheta", "MUCA");
|
|
|
|
|
|
/* detector data
|
|
first set detector variables in dictionary
|
|
This is the first detector.
|
|
*/
|
|
if (self->pHistogram1 != NULL) {
|
|
strcpy(pBueffel, "detector1");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
sprintf(pBueffel, "%d", DET1X);
|
|
NXDupdate(self->pDict, "framedim1", pBueffel);
|
|
sprintf(pBueffel, "%d", DET1Y);
|
|
NXDupdate(self->pDict, "framedim2", pBueffel);
|
|
strcpy(pBueffel, DET1DESC);
|
|
iRet = NXDputalias(hfil, self->pDict, "ddescription", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector1 description",
|
|
eError);
|
|
}
|
|
for (i = 0; i < DET1X; i++) {
|
|
fPix[i] = i * DET1XS;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detectorx", fPix);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector1 x-axis description",
|
|
eError);
|
|
}
|
|
for (i = 0; i < DET1Y; i++) {
|
|
fPix[i] = i * DET1YS;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detectory", fPix);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector1 y-axis description",
|
|
eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "det1zerox");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector x zero point not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detzerox", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor x zero point", eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "det1zeroy");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector y zero point not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detzeroy", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor y zero point", eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "detdist1");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector distance not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detdist", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor y zero point", eError);
|
|
}
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "detvalid", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write frame validity", eError);
|
|
}
|
|
}
|
|
/*
|
|
second frame, but only if present
|
|
*/
|
|
if (self->pHistogram2 != NULL) {
|
|
strcpy(pBueffel, "detector2");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
sprintf(pBueffel, "%d", DET2X);
|
|
NXDupdate(self->pDict, "framedim1", pBueffel);
|
|
sprintf(pBueffel, "%d", DET2Y);
|
|
NXDupdate(self->pDict, "framedim2", pBueffel);
|
|
strcpy(pBueffel, DET2DESC);
|
|
iRet = NXDputalias(hfil, self->pDict, "ddescription", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector2 description",
|
|
eError);
|
|
}
|
|
for (i = 0; i < DET2X; i++) {
|
|
fPix[i] = i * DET2XS;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detectorx", fPix);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector2 x-axis description",
|
|
eError);
|
|
}
|
|
for (i = 0; i < DET2Y; i++) {
|
|
fPix[i] = i * DET2YS;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detectory", fPix);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector1 y-axis description",
|
|
eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "det2zerox");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector x zero point not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detzerox", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor x zero point", eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "det2zeroy");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector2 y zero point not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detzeroy", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor y zero point", eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "detdist2");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector distance not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detdist", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor2 y distance", eError);
|
|
}
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "detvalid", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write frame validity", eError);
|
|
}
|
|
}
|
|
/*
|
|
third detector, but only if present
|
|
*/
|
|
if (self->pHistogram3 != NULL) {
|
|
strcpy(pBueffel, "detector3");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
sprintf(pBueffel, "%d", DET3X);
|
|
NXDupdate(self->pDict, "framedim1", pBueffel);
|
|
sprintf(pBueffel, "%d", DET3Y);
|
|
NXDupdate(self->pDict, "framedim2", pBueffel);
|
|
strcpy(pBueffel, DET3DESC);
|
|
iRet = NXDputalias(hfil, self->pDict, "ddescription", pBueffel);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector3 description",
|
|
eError);
|
|
}
|
|
for (i = 0; i < DET3X; i++) {
|
|
fPix[i] = i * DET3XS;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detectorx", fPix);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector2 x-axis description",
|
|
eError);
|
|
}
|
|
for (i = 0; i < DET3Y; i++) {
|
|
fPix[i] = i * DET3YS;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detectory", fPix);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detector1 y-axis description",
|
|
eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "det3zerox");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector 3 x zero point not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detzerox", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor x zero point", eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "det3zeroy");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector 3 y zero point not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detzeroy", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor y zero point", eError);
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pServ->pSics, "detdist3");
|
|
if (pVar) {
|
|
fVal = pVar->fVal;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable detector 3 distance not found ",
|
|
eError);
|
|
fVal = -2188.99;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "detdist", &fVal);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write detecor 3 y distance", eError);
|
|
}
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "detvalid", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write frame validity", eError);
|
|
}
|
|
}
|
|
|
|
/* do sample information */
|
|
strcpy(pBueffel, "UNKNOWN");
|
|
pVar = FindVariable(pServ->pSics, "sample");
|
|
if (pVar) {
|
|
pText = pVar->text;
|
|
} else {
|
|
SCWrite(pCon, "ERROR: Variable sample not found ", eError);
|
|
pText = pBueffel;
|
|
}
|
|
iRet = NXDputalias(hfil, self->pDict, "samplename", pText);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write sample name", eError);
|
|
}
|
|
if (self->pCrystal != NULL) {
|
|
GetUB(self->pCrystal, fUB);
|
|
iRet = NXDputalias(hfil, self->pDict, "sampleub", fUB);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write sample UB", eError);
|
|
}
|
|
GetCurrentHKL(self->pCrystal, fHKL);
|
|
iRet = NXDputalias(hfil, self->pDict, "samplehkl", fHKL);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write HKL", eError);
|
|
}
|
|
}
|
|
|
|
/* put the frame number */
|
|
iRet = 0;
|
|
iRet = NXDputalias(hfil, self->pDict, "fnum", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write initial frame number", eError);
|
|
}
|
|
|
|
/* write actual data */
|
|
iRet = DumpData(self, pCon, hfil, 1);
|
|
|
|
/* put the frame number */
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "fnum", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write initial frame number", eError);
|
|
}
|
|
self->iFrameNum = 1;
|
|
InvokeCallBack(self->pCall, NEWFRAME, &(self->iFrameNum));
|
|
|
|
self->iFirst = 0;
|
|
|
|
/* close the file and go */
|
|
NXclose(&hfil);
|
|
SendQuieck(QUIECK, self->pCurrentFile);
|
|
return iRet;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int ContinueFile(pNexTrics self, SConnection * pCon)
|
|
{
|
|
int iFrameNum, iRet;
|
|
char pBueffel[1024];
|
|
float fVal;
|
|
NXhandle hfil;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
assert(self->iFirst == 0);
|
|
|
|
/* let's start by opening the file */
|
|
iRet = NXopen(self->pCurrentFile, NXACC_RDWR, &hfil);
|
|
if (iRet != NX_OK) {
|
|
sprintf(pBueffel, "ERROR: cannot reopen %s, NO data written",
|
|
self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* read the frame number, set the framename for further reading,
|
|
increment and write back again
|
|
*/
|
|
iRet = NXDgetalias(hfil, self->pDict, "fnum", &iFrameNum);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "EERROR: cannot read old framenumber, NO data written",
|
|
eError);
|
|
return 0;
|
|
}
|
|
sprintf(pBueffel, "frame%4.4d", iFrameNum);
|
|
NXDupdate(self->pDict, "framename", pBueffel);
|
|
iFrameNum++;
|
|
self->iFrameNum++;
|
|
InvokeCallBack(self->pCall, NEWFRAME, &(self->iFrameNum));
|
|
iRet = NXDputalias(hfil, self->pDict, "fnum", &iFrameNum);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: cannot write new framenumber, NO data written",
|
|
eError);
|
|
return 0;
|
|
}
|
|
|
|
/* put in links to duplicates: entry */
|
|
iRet = NXDaliaslink(hfil, self->pDict, "entry", "etitle0");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against title", eWarning);
|
|
}
|
|
|
|
/* links to instrument */
|
|
iRet = NXDaliaslink(hfil, self->pDict, "inst0", "iname0");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against instrument name",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "inst0", "source0");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against source group", eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "inst0", "mono0");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against monochromator group",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "inst0", "coll0");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against collimator group",
|
|
eWarning);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
links in detector group
|
|
detector 1
|
|
*/
|
|
if (self->pHistogram1 != NULL) {
|
|
strcpy(pBueffel, "detector1");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "ddescription");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector description",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detectorx");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector x-axis",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detectory");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector y-axis",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detzerox");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector x zero ",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detzeroy");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector y zero",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detdist");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector distance",
|
|
eWarning);
|
|
}
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "detvalid", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write frame validity", eError);
|
|
}
|
|
}
|
|
/*
|
|
links in detector group, detector 2
|
|
*/
|
|
if (self->pHistogram2) {
|
|
strcpy(pBueffel, "detector2");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "ddescription");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector description",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detectorx");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector x-axis",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detectory");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector y-axis",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detzerox");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector x zero ",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detzeroy");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector y zero",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detdist");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector distance",
|
|
eWarning);
|
|
}
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "detvalid", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write frame validity", eError);
|
|
}
|
|
}
|
|
|
|
/*
|
|
links in detector group, detector 3
|
|
*/
|
|
if (self->pHistogram3) {
|
|
strcpy(pBueffel, "detector3");
|
|
NXDupdate(self->pDict, "dnumber", pBueffel);
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "ddescription");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector description",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detectorx");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector x-axis",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detectory");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector y-axis",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detzerox");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector x zero ",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detzeroy");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector y zero",
|
|
eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "det1", "detdist");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against detector distance",
|
|
eWarning);
|
|
}
|
|
iRet = 1;
|
|
iRet = NXDputalias(hfil, self->pDict, "detvalid", &iRet);
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: failed to write frame validity", eError);
|
|
}
|
|
}
|
|
|
|
|
|
/* links in sample group */
|
|
iRet = NXDaliaslink(hfil, self->pDict, "samplev", "samplename");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against sample name", eWarning);
|
|
}
|
|
if (self->pCrystal != NULL) {
|
|
iRet = NXDaliaslink(hfil, self->pDict, "samplev", "sampleub");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against sample UB", eWarning);
|
|
}
|
|
iRet = NXDaliaslink(hfil, self->pDict, "samplev", "samplehkl");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "WARNING: cannot link against sample HKL", eWarning);
|
|
}
|
|
}
|
|
|
|
/* write actual data */
|
|
iRet = DumpData(self, pCon, hfil, iFrameNum);
|
|
|
|
/* close the file and go */
|
|
NXclose(&hfil);
|
|
SendQuieck(QUIECK, self->pCurrentFile);
|
|
return iRet;
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int StartFile(pNexTrics self, SConnection * pCon)
|
|
{
|
|
char pBueffel[1024];
|
|
NXhandle hfil;
|
|
int iRet, iYear, i;
|
|
pSicsVariable pVar;
|
|
char *pText;
|
|
CommandList *pCom = NULL;
|
|
pHKL pCryst = NULL;
|
|
float fVal, fPix[DETAMAX];
|
|
|
|
/* make a filename and open it */
|
|
if (self->pCurrentFile)
|
|
free(self->pCurrentFile);
|
|
|
|
pText = makeFilename(pServ->pSics, pCon);
|
|
changeExtension(pText, "hdf");
|
|
if (pText == NULL) {
|
|
return 0;
|
|
}
|
|
self->pCurrentFile = strdup(pText);
|
|
if (self->iHDF5) {
|
|
iRet = NXopen(self->pCurrentFile, NXACC_CREATE5, &hfil);
|
|
} else {
|
|
iRet = NXopen(self->pCurrentFile, NXACC_CREATE, &hfil);
|
|
}
|
|
if (iRet != NX_OK) {
|
|
sprintf(pBueffel, "ERROR: cannot open %s", self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* tell user what we are doing */
|
|
sprintf(pBueffel, "Initialising file %s ......", self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eWarning);
|
|
|
|
|
|
/* Write header data */
|
|
SNXSPutGlobals(hfil, self->pCurrentFile,
|
|
"TRICS at SinQ, Paul Scherrer Institut, Switzerland",
|
|
pCon);
|
|
|
|
self->iFirst = 1;
|
|
self->iFrameNum = 0;
|
|
InvokeCallBack(self->pCall, NEWFRAME, &(self->iFrameNum));
|
|
|
|
/* close the file and go */
|
|
NXclose(&hfil);
|
|
return 1;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int ReopenFile(pNexTrics self, char *filename)
|
|
{
|
|
char pBueffel[1024];
|
|
NXhandle hfil;
|
|
int iRet, iFrameNum;
|
|
|
|
assert(self);
|
|
|
|
/* concat with data root and check for existence */
|
|
sprintf(pBueffel, "%s/%s", self->pFileRoot, filename);
|
|
iRet = NXopen(pBueffel, NXACC_RDWR, &hfil);
|
|
if (iRet != NX_OK) {
|
|
return 0;
|
|
} else {
|
|
if (self->pCurrentFile)
|
|
free(self->pCurrentFile);
|
|
self->pCurrentFile = strdup(pBueffel);
|
|
}
|
|
|
|
/* check the framenumber, if already data written */
|
|
iRet = NXDgetalias(hfil, self->pDict, "fnum", &iFrameNum);
|
|
if (iRet != NX_OK) {
|
|
self->iFirst = 1;
|
|
} else {
|
|
self->iFirst = 0;
|
|
}
|
|
self->iFrameNum = iFrameNum;
|
|
InvokeCallBack(self->pCall, NEWFRAME, &(self->iFrameNum));
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int DumpFrame(pNexTrics self, SConnection * pCon)
|
|
{
|
|
int iRet;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
|
|
if (self->iFirst == 1) {
|
|
iRet = WriteFirstFrame(self, pCon);
|
|
} else {
|
|
iRet = ContinueFile(self, pCon);
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
static int FrameInterest(int iEvent, void *pEvent, void *pUser)
|
|
{
|
|
SConnection *pCon = NULL;
|
|
int *iFrame;
|
|
char pBueffel[512];
|
|
pCon = (SConnection *) pUser;
|
|
|
|
/* kill condition check */
|
|
if (pCon == NULL || !SCisConnected(pCon)) {
|
|
return -1;
|
|
}
|
|
|
|
if (iEvent != NEWFRAME) {
|
|
return 0;
|
|
}
|
|
|
|
iFrame = (int *) pEvent;
|
|
assert(pCon);
|
|
sprintf(pBueffel, "framenumber = %d", *iFrame);
|
|
SCWrite(pCon, pBueffel, eWarning);
|
|
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 NexusGetFrame(SConnection * pCon, pNexTrics self,
|
|
int iDetector, int iFrame)
|
|
{
|
|
char pBueffel[132];
|
|
int iRet;
|
|
NXhandle hfil;
|
|
HistInt *lData = NULL;
|
|
|
|
/* do a few range checks */
|
|
if (iDetector < 1 || iDetector > 3) {
|
|
sprintf(pBueffel, "ERROR: unknown detector %d requested", iDetector);
|
|
return 0;
|
|
}
|
|
if (iFrame < 0 || iFrame >= self->iFrameNum) {
|
|
sprintf(pBueffel, "ERROR: frame %d not yet written", iDetector);
|
|
return 0;
|
|
}
|
|
|
|
/* open file */
|
|
iRet = NXopen(self->pCurrentFile, NXACC_READ, &hfil);
|
|
if (iRet != NX_OK) {
|
|
sprintf(pBueffel, "ERROR: cannot open %s", self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* open groups */
|
|
sprintf(pBueffel, "frame%4.4d", iFrame);
|
|
iRet = NXopengroup(hfil, pBueffel, "NXentry");
|
|
if (iRet != NX_OK) {
|
|
sprintf(pBueffel, "ERROR: frame %d not found in %s", iFrame,
|
|
self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
NXclose(&hfil);
|
|
return 0;
|
|
}
|
|
sprintf(pBueffel, "detector%1.1d", iDetector);
|
|
iRet = NXopengroup(hfil, pBueffel, "NXdata");
|
|
if (iRet != NX_OK) {
|
|
sprintf(pBueffel, "ERROR: detector %d not found in %s", iFrame,
|
|
self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
NXclose(&hfil);
|
|
return 0;
|
|
}
|
|
iRet = NXopendata(hfil, "counts");
|
|
if (iRet != NX_OK) {
|
|
SCWrite(pCon, "ERROR: no counts found, file corrupted", eError);
|
|
NXclose(&hfil);
|
|
return 0;
|
|
}
|
|
|
|
/* read data */
|
|
lData = (HistInt *) malloc(DET1X * DET1Y * sizeof(HistInt));
|
|
if (!lData) {
|
|
SCWrite(pCon, "ERROR: out of memory in NexusGetFrame", eError);
|
|
NXclose(&hfil);
|
|
return 0;
|
|
}
|
|
memset(lData, 0, DET1X * DET1Y * 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, DET1X * DET1Y * sizeof(HistInt));
|
|
|
|
/* clean up */
|
|
NXclose(&hfil);
|
|
free(lData);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int NexTricsAction(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pNexTrics self;
|
|
char pBueffel[1024];
|
|
int iRet, iDet, iFrame;
|
|
long lID;
|
|
commandContext comCon;
|
|
|
|
self = (pNexTrics) pData;
|
|
assert(self);
|
|
assert(pCon);
|
|
|
|
/* check for subcommands */
|
|
if (argc < 2) {
|
|
sprintf(pBueffel, "ERROR: no subcommand found for %s", argv[0]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|
|
|
|
/* install an error handler */
|
|
NXMSetError((void *) pCon, SNError);
|
|
|
|
comCon = SCGetContext(pCon);
|
|
strtolower(argv[1]);
|
|
if (strcmp(argv[1], "start") == 0) {
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
iRet = StartFile(self, pCon);
|
|
if (iRet) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
} else if (strcmp(argv[1], "file") == 0) {
|
|
sprintf(pBueffel, "Currently writing to: %s", self->pCurrentFile);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "oldframe") == 0) {
|
|
if (argc < 4) {
|
|
SCWrite(pCon, "ERROR: insufficient number of arguments to oldframe",
|
|
eError);
|
|
return 0;
|
|
}
|
|
iDet = atoi(argv[2]);
|
|
iFrame = atoi(argv[3]);
|
|
iRet = NexusGetFrame(pCon, self, iDet, iFrame);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "interest") == 0) {
|
|
lID = RegisterCallback(self->pCall, NEWFRAME, FrameInterest,
|
|
SCCopyConnection(pCon), SCDeleteConnection);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "framenum") == 0) {
|
|
sprintf(pBueffel, "framenumber = %d", self->iFrameNum);
|
|
SCWrite(pCon, pBueffel, eValue);
|
|
return 1;
|
|
} else if (strcmp(argv[1], "dumpframe") == 0) {
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
iRet = DumpFrame(self, pCon);
|
|
if (iRet) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
} else if (strcmp(argv[1], "reopen") == 0) {
|
|
if (!SCMatchRights(pCon, usUser)) {
|
|
return 0;
|
|
}
|
|
if (argc < 3) {
|
|
SCWrite(pCon, "ERROR: expected filename as parameter for reopen",
|
|
eError);
|
|
return 0;
|
|
}
|
|
iRet = ReopenFile(self, argv[2]);
|
|
if (iRet) {
|
|
SCSendOK(pCon);
|
|
}
|
|
return iRet;
|
|
}
|
|
sprintf(pBueffel, "ERROR: subcommand %s not recognized", argv[1]);
|
|
SCWrite(pCon, pBueffel, eError);
|
|
return 0;
|
|
}
|