/*-------------------------------------------------------------------------- P O L T E R W R I T E fowrite is an object for writing POLTERDI data files. copyright: see copyright.h Uwe Filges, November 2001 ----------------------------------------------------------------------------*/ #include #include #include "fortify.h" #include "sics.h" #include "counter.h" #include "HistMem.h" #include "nxdict.h" #include "nxutil.h" #include "motor.h" #include "sicsvar.h" #include "polterwrite.h" /* diaphragm1 - chopper */ #define DIA1DIST 3000 /* diaphragm2 - diaphragm1 */ #define DIA2DIST 500 /* diaphragm2 - sample position */ #define SADIST 500 /* histogram memory name */ #define HM "hm" /* detector distance - sample */ #define DETDIST 700 /* no detectors, change in poldi.dic as well */ #define NODET 400 /* theta spacing */ #define THSPACE .3 typedef struct { pObjectDescriptor pDes; char *dictfile; }Polterdi, *pPolterdi; /*----------------------------------------------------------------------*/ static void KillPolterdi(void *pData){ pPolterdi self = (pPolterdi)pData; if(!self) return; if(self->pDes){ DeleteDescriptor(self->pDes); } if(self->dictfile){ free(self->dictfile); } free(self); } /*-----------------------------------------------------------------------*/ int PolterInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pPolterdi pNew = NULL; if(argc < 2){ SCWrite(pCon,"ERROR: insufficient number of arguments to PolterInstall", eError); return 0; } pNew = (pPolterdi)malloc(sizeof(Polterdi)); if(!pNew){ SCWrite(pCon,"ERROR: out of memory in PolterInstall", eError); return 0; } memset(pNew,0,sizeof(Polterdi)); pNew->pDes = CreateDescriptor("PolterdiWrite"); pNew->dictfile = strdup(argv[1]); if(!pNew->pDes || !pNew->dictfile){ SCWrite(pCon,"ERROR: out of memory in PolterInstall", eError); return 0; } return AddCommand(pSics,"storedata",PolterAction,KillPolterdi,pNew); } /*-------------------------------------------------------------------*/ static void writePolterdiGlobal(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics){ char pBueffel[512]; SNXSPutVariable(pSics,pCon,hfil,hdict,"etitle","title"); SNXFormatTime(pBueffel,511); NXDputalias(hfil,hdict,"estart",pBueffel); SNXSPutVariable(pSics,pCon,hfil,hdict,"iname","instrument"); sprintf(pBueffel,"%d",strlen("SINQ, PSI, Switzerland")); NXDupdate(hdict,"strdim",pBueffel); NXDputalias(hfil,hdict,"sname","SINQ, PSI, Switzerland"); sprintf(pBueffel,"%d",strlen("continous spallation source")); NXDupdate(hdict,"strdim",pBueffel); NXDputalias(hfil,hdict,"stype","continous spallation source"); NXDupdate(hdict,"strdim","132"); } /*-------------------------------------------------------------------*/ static void writeChopper(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics){ SNXSPutVariable(pSics,pCon,hfil,hdict,"cname","choppername"); SNXSPutDrivable(pSics,pCon,hfil,hdict,"chopperspeed","crot"); } /*-------------------------------------------------------------------*/ static void writeDiaphragm1(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics){ float dist; SNXSPutMotor(pSics,pCon,hfil,hdict,"dia1x","d1m"); SNXSPutMotorNull(pSics,pCon,hfil,hdict,"dia1x0","d1m"); SNXSPutMotor(pSics,pCon,hfil,hdict,"dia1y","d1o"); SNXSPutMotorNull(pSics,pCon,hfil,hdict,"dia1y0","d1o"); dist = (float)DIA1DIST; NXDputalias(hfil,hdict,"dia1dist",&dist); } /*------------------------------------------------------------------*/ static void writeDiaphragm2(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics){ float dist2; SNXSPutMotor(pSics, pCon, hfil, hdict, "dia2x_plus", "d2m"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "dia2xplus0", "d2m"); SNXSPutMotor(pSics, pCon, hfil, hdict, "dia2x_minus", "d2u"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "dia2xminus0", "d2u"); SNXSPutMotor(pSics, pCon, hfil, hdict, "dia2z_plus", "d2o"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "dia2zplus0", "d2o"); SNXSPutMotor(pSics, pCon, hfil, hdict, "dia2z_minus", "d2l"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "dia2zminus0", "d2l"); dist2 = (float) DIA2DIST; } /*--------------------------------------------------------------------*/ static void writeSample(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics) { float sadist = (float)SADIST; NXDputalias(hfil, hdict, "sdist", &sadist); SNXSPutVariable(pSics,pCon,hfil,hdict,"saname","sample"); SNXSPutVariable(pSics,pCon,hfil,hdict,"senvir","environment"); SNXSPutEVVar(hfil,hdict,"temperature",pCon,"stemp","stddev"); SNXSPutMotor(pSics, pCon, hfil, hdict, "srsu", "rsu"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "srsu0", "rsu"); SNXSPutMotor(pSics, pCon, hfil, hdict, "srsl", "rsl"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "srsl0", "rsl"); SNXSPutMotor(pSics, pCon, hfil, hdict, "srsa", "rsa"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "srsa0", "rsa"); SNXSPutMotor(pSics, pCon, hfil, hdict, "sshu", "shu"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "sshu0", "shu"); SNXSPutMotor(pSics, pCon, hfil, hdict, "sshl", "shl"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "sshl0", "shl"); SNXSPutMotor(pSics, pCon, hfil, hdict, "ssgu", "sgu"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "ssgu0", "sgu"); SNXSPutMotor(pSics, pCon, hfil, hdict, "ssgl", "sgl"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "ssgl0", "sgl"); SNXSPutMotor(pSics, pCon, hfil, hdict, "ssv", "sv"); SNXSPutMotorNull(pSics, pCon, hfil, hdict, "ssv0", "sv"); } /*-----------------------------------------------------------------------*/ static void writeDetector(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics) { const float *fTime = NULL; CounterMode eMode; pHistMem pHist= NULL; float *fTime2 = NULL, fTheta[NODET], fVal; int iLength, i; char pBueffel[80]; pMotor sa; HistInt *lData = NULL; long lVal; pHist = (pHistMem)FindCommandData(pSics,HM,"HistMem"); if(!pHist) { SCWrite(pCon,"ERROR: Histogram memory NOT found",eError); return; } /* write time binning */ fTime = GetHistTimeBin(pHist,&iLength); fTime2 = (float *)malloc(iLength*sizeof(float)); if(fTime2) { for(i = 0;i < iLength; i++) { fTime2[i] = fTime[i]/10.; } sprintf(pBueffel,"%d",iLength); NXDupdate(hdict,"timebin",pBueffel); NXDputalias(hfil,hdict,"dtime",fTime2); free(fTime2); } else { SCWrite(pCon,"ERROR: out of memory while writing time binning",eError); } /* do theta */ fVal = -999.; sa = FindMotor(pSics,"sa"); if(sa) { MotorGetSoftPosition(sa,pCon,&fVal); } else { SCWrite(pCon,"ERROR: failed to locate two theta motor",eError); } for(i = 0; i < NODET; i++) { fTheta[i] = fVal + i * THSPACE; } NXDputalias(hfil,hdict,"dtheta",fTheta); fVal = (float)DETDIST; NXDputalias(hfil,hdict,"ddist",&fVal); /* write Histogram */ lData = GetHistogramPointer(pHist,pCon); if(lData) { NXDputalias(hfil,hdict,"dcounts",lData); } else { SCWrite(pCon,"ERROR: failed to get histogram data",eError); } /* write counting data */ fVal = GetHistCountTime(pHist,pCon); NXDputalias(hfil,hdict,"cntime",&fVal); lVal = GetHistMonitor(pHist,1,pCon); NXDputalias(hfil,hdict,"cnmon1",&lVal); eMode = GetHistCountMode(pHist); if(eMode == eTimer) { strcpy(pBueffel,"timer"); } else { strcpy(pBueffel,"monitor"); } NXDputalias(hfil,hdict,"cnmode",pBueffel); fVal = GetHistPreset(pHist); NXDputalias(hfil,hdict,"cnpreset",&fVal); } /*---------------------------------------------------------------------*/ static void makeLinks(NXhandle hfil, NXdict hdict, SConnection *pCon, SicsInterp *pSics) { NXDaliaslink(hfil,hdict,"dana","dcounts"); NXDaliaslink(hfil,hdict,"dana","dtheta"); NXDaliaslink(hfil,hdict,"dana","dtime"); } /*--------------------------------------------------------------------*/ static int StoreData(SConnection *pCon, SicsInterp *pSics, pPolterdi self) { char pBueffel[256], *pFile = NULL; NXhandle hfil = NULL; NXdict hdict= NULL; int status; /* create filename */ pFile = SNXMakeFileName(pSics,pCon); if(!pFile) { SCWrite(pCon,"ERROR: Extra severe: failed to create data file name", eError); return 0; } /* create a Nexus file */ NXopen(pFile,NXACC_CREATE,&hfil); if(!hfil) { SCWrite(pCon,"ERROR: cannot create data file ",eError); return 0; } /* tell Uwe User what we are doing */ sprintf(pBueffel,"Writing %s ......",pFile); SCWrite(pCon,pBueffel,eWarning); /* write globals */ SNXSPutGlobals(hfil,pFile,"POLTERDI",pCon); free(pFile); pFile = NULL; /* open nxdict */ status = NXDinitfromfile(self->dictfile,&hdict); if(status != NX_OK) { sprintf(pBueffel,"ERROR: failed to open dictionary file %s", self->dictfile); SCWrite(pCon,pBueffel,eError); SCWrite(pCon,"ERROR: Aborting data file writing",eError); SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError); SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError); NXclose(&hfil); return 0; } writePolterdiGlobal(hfil,hdict,pCon,pSics); writeChopper(hfil,hdict,pCon,pSics); writeDiaphragm1(hfil,hdict,pCon,pSics); writeDiaphragm2(hfil,hdict,pCon,pSics); writeSample(hfil,hdict,pCon,pSics); writeDetector(hfil,hdict,pCon,pSics); makeLinks(hfil,hdict,pCon,pSics); /* close everything */ NXclose(&hfil); NXDclose(hdict,NULL); SCSendOK(pCon); return 1; } /*----------------------------------------------------------------------*/ int PolterAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pPolterdi self = (pPolterdi)pData; assert(self); assert(pCon); assert(pSics); return StoreData(pCon,pSics,self); }