/*------------------------------------------------------------------------- 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 #include #include #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; }