/*------------------------------------------------------------------------- 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 #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" #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; 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,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); } /* 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); 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; }