Files
sics/nextrics.c
cvs 0daef05b2e - Poldi data file writing with automatic update
- many fixes to TAS
- Changed HM code for ILL PSD to account for Christoph's offset to
  positive.
2002-04-25 09:39:51 +00:00

1536 lines
42 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
----------------------------------------------------------------------------*/
#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"
#define DET1X 256 /* x -length of detector 1 */
#define DET1Y 128 /* y-length of detector 1 */
#define DET1XS 2 /* pixel size in x of detector 1 */
#define DET1YS 2 /* 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 2 /* pixel size in x of detector 1 */
#define DET2YS 2 /* 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 2 /* pixel size in x of detector 1 */
#define DET3YS 2 /* 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;
int32 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->pHistogram2,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 = (int32)lVal;
NXDputalias(hfil,self->pDict,"framemonitor",&iVal);
iVal = (int32)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,eStatus);
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);
}
/* 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);
}
/*
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);
iRet = IncrementDataNumber(self->pDanu,&iYear);
sprintf(pBueffel,"%s/trics%5.5d%4.4d.hdf",self->pFileRoot,iRet, iYear);
self->pCurrentFile = strdup(pBueffel);
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];
if(iEvent != NEWFRAME)
{
return 0;
}
pCon = (SConnection *)pUser;
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: farme %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;
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);
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,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
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;
}