901 lines
26 KiB
C
901 lines
26 KiB
C
/*--------------------------------------------------------------------------
|
|
N X D A T A
|
|
|
|
This implements the data file writing for the Powder diffractometers
|
|
HRPT and DMC.
|
|
|
|
Mark Koennecke, March-April 1997
|
|
|
|
Updated and expanded: Mark Koennecke, November 1999
|
|
|
|
Copyright:
|
|
|
|
Labor fuer Neutronenstreuung
|
|
Paul Scherrer Institut
|
|
CH-5423 Villigen-PSI
|
|
|
|
|
|
The authors hereby grant permission to use, copy, modify, distribute,
|
|
and license this software and its documentation for any purpose, provided
|
|
that existing copyright notices are retained in all copies and that this
|
|
notice is included verbatim in any distributions. No written agreement,
|
|
license, or royalty fee is required for any of the authorized uses.
|
|
Modifications to this software may be copyrighted by their authors
|
|
and need not follow the licensing terms described here, provided that
|
|
the new terms are clearly indicated on the first page of each file where
|
|
they apply.
|
|
|
|
IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
|
|
FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
|
ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
|
|
DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
|
|
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
|
|
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
|
|
MODIFICATIONS.
|
|
----------------------------------------------------------------------------*/
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <time.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "sicsvar.h"
|
|
#include "nxdict.h"
|
|
#include "modriv.h"
|
|
#include "motor.h"
|
|
#include "nxdata.h"
|
|
#include "nxutil.h"
|
|
#include "selector.h"
|
|
#include "selvar.h"
|
|
#include "countdriv.h"
|
|
#include "counter.h"
|
|
#include "danu.h"
|
|
#include "HistMem.h"
|
|
#include "udpquieck.h"
|
|
#include "evcontroller.h"
|
|
#include "nxscript.h"
|
|
|
|
|
|
#define DMCDETNAM "DMC-BF3-Detector"
|
|
#define DMCDETOB "detector"
|
|
#define HRPTDETNAM "Cerca-Detector"
|
|
|
|
/*-----------------------------------------------------------------------*/
|
|
static void SNError(void *pData, char *text)
|
|
{
|
|
SConnection *pCon;
|
|
|
|
assert(pData);
|
|
pCon = (SConnection *)pData;
|
|
SCWrite(pCon,text,eError);
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
char *SNXMakeFileName(SicsInterp *pSics, SConnection *pCon)
|
|
{
|
|
char *pPtr = NULL;
|
|
pPtr = makeFilename(pSics,pCon);
|
|
if(pPtr == NULL)
|
|
{
|
|
pPtr = strdup("emergency.hdf");
|
|
}
|
|
return pPtr;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
char *SNXMakeFileNameOld(SicsInterp *pSics, SConnection *pCon)
|
|
{
|
|
pSicsVariable pPath = NULL, pPref = NULL, pEnd = NULL;
|
|
char *pRes = NULL;
|
|
int iLen, iNum, iYear;
|
|
char pNumText[10];
|
|
CommandList *pCom = NULL;
|
|
|
|
/* Try, get all the Variables */
|
|
pPath = FindVariable(pSics,"sicsdatapath");
|
|
pPref = FindVariable(pSics,"sicsdataprefix");
|
|
pCom = FindCommand(pSics,"sicsdatanumber");
|
|
pEnd = FindVariable(pSics,"sicsdatapostfix");
|
|
|
|
if( (!pPath) || (!pPref) || (!pCom) || (!pEnd) )
|
|
{
|
|
SCWrite(pCon,
|
|
"ERROR: cannot read variables for automatic data file name creation",
|
|
eError);
|
|
SCWrite(pCon,"ERROR: This is a VERY, VERY, VERY serious installation problem",
|
|
eError);
|
|
SCWrite(pCon,"ERROR: your data will be dumped into emergency.hdf",eError);
|
|
return strdup("emergency.hdf");
|
|
}
|
|
|
|
/* find length */
|
|
iLen = strlen(pPath->text);
|
|
iLen += strlen(pPref->text);
|
|
iLen += 8; /* for number + year */
|
|
iLen += strlen(pEnd->text);
|
|
iLen += 10; /* safety margin */
|
|
|
|
/* allocate memory */
|
|
pRes = (char *)malloc(iLen*sizeof(char));
|
|
if(!pRes)
|
|
{
|
|
SCWrite(pCon,"ERROR: no memory in SNXMakeFileName",eError);
|
|
return NULL;
|
|
}
|
|
memset(pRes,0,iLen);
|
|
|
|
/* build the filename */
|
|
strcpy(pRes,pPath->text);
|
|
strcat(pRes,pPref->text);
|
|
iNum = IncrementDataNumber(pCom->pData,&iYear);
|
|
if(iNum < 0)
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot increment data number!",eError);
|
|
SCWrite(pCon,"ERROR: your data will be dumped to emergency.hdf",eError);
|
|
free(pRes);
|
|
return strdup("emergency.hdf");
|
|
}
|
|
sprintf(pNumText,"%5.5d",iNum);
|
|
strcat(pRes,pNumText);
|
|
sprintf(pNumText,"%4.4d",iYear);
|
|
strcat(pRes,pNumText);
|
|
strcat(pRes,pEnd->text);
|
|
|
|
|
|
/* install an error handler */
|
|
NXMSetError((void *)pCon,SNError);
|
|
|
|
return pRes;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
NXhandle SNXStartFile(SConnection *pCon, SicsInterp *pSics)
|
|
{
|
|
NXhandle pFile = NULL;
|
|
char *filename = NULL;
|
|
pSicsVariable pVar = NULL;
|
|
int iStat;
|
|
char pBueffel[512], pTime[132];
|
|
|
|
/* get a filename */
|
|
filename = SNXMakeFileName(pSics,pCon);
|
|
if(!filename)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/* create a Nexus file */
|
|
NXopen(filename,NXACC_CREATE,&pFile);
|
|
if(!pFile)
|
|
{
|
|
SCWrite(pCon,"ERROR: cannot create data file ",eError);
|
|
free(filename);
|
|
return NULL;
|
|
}
|
|
|
|
/* tell Uwe User what we are doing */
|
|
sprintf(pBueffel,"Writing %s ......",filename);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
|
|
/* store global attributes */
|
|
iStat = NXputattr(pFile,"file_name",filename,
|
|
strlen(filename)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing file_name attribute to Nexus file",eError);
|
|
}
|
|
|
|
/* filename no longer needed*/
|
|
free(filename);
|
|
|
|
/* write creation time */
|
|
SNXFormatTime(pTime,132);
|
|
iStat = NXputattr(pFile,"file_time",pTime,
|
|
strlen(pTime)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing date attribute to Nexus file",eError);
|
|
}
|
|
sprintf(pBueffel,"File created at StarDate: %s",pTime);
|
|
SCWrite(pCon,pBueffel,eWarning);
|
|
|
|
pVar = FindVariable(pSics,"instrument");
|
|
if(pVar)
|
|
{
|
|
iStat = NXputattr(pFile,"instrument",pVar->text,
|
|
strlen(pVar->text)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing instrument attribute to Nexus file",eError);
|
|
}
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pSics,"user");
|
|
if(pVar)
|
|
{
|
|
iStat = NXputattr(pFile,"owner",pVar->text,
|
|
strlen(pVar->text)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing owner attribute to Nexus file",eError);
|
|
}
|
|
}
|
|
|
|
pVar = NULL;
|
|
pVar = FindVariable(pSics,"address");
|
|
if(pVar)
|
|
{
|
|
iStat = NXputattr(pFile,"owner_adress",pVar->text,
|
|
strlen(pVar->text)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing owner_adress attribute to Nexus file",eError);
|
|
}
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pSics,"phone");
|
|
if(pVar)
|
|
{
|
|
iStat = NXputattr(pFile,"owner_telephone_number",pVar->text,
|
|
strlen(pVar->text)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing owner_telephone_number attribute to Nexus file",eError);
|
|
}
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pSics,"fax");
|
|
if(pVar)
|
|
{
|
|
iStat = NXputattr(pFile,"owner_fax_number",pVar->text,
|
|
strlen(pVar->text)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing owner_fax_number attribute to Nexus file",eError);
|
|
}
|
|
}
|
|
pVar = NULL;
|
|
pVar = FindVariable(pSics,"email");
|
|
if(pVar)
|
|
{
|
|
iStat = NXputattr(pFile,"owner_email",pVar->text,
|
|
strlen(pVar->text)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing owner_email attribute to Nexus file",eError);
|
|
}
|
|
}
|
|
pVar = NULL;
|
|
return pFile;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int SNXStartEntry(NXhandle Nfil, int iNew, SicsInterp *pSics)
|
|
{
|
|
int iStat;
|
|
char pName[80];
|
|
pSicsVariable pVar = NULL;
|
|
int iDim[2];
|
|
|
|
/* format an entry name */
|
|
if(iNew < 10)
|
|
{
|
|
sprintf(pName,"entry%1.1d", iNew);
|
|
}
|
|
else if( (iNew > 9) && (iNew < 100) )
|
|
{
|
|
sprintf(pName,"entry%2.2d",iNew);
|
|
}
|
|
else if( (iNew > 99) && (iNew < 1000) )
|
|
{
|
|
sprintf(pName,"entry%3.3d",iNew);
|
|
}
|
|
else if( (iNew > 9999) && (iNew < 10000) )
|
|
{
|
|
sprintf(pName,"entry%4.4d",iNew);
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* create entry and step into it */
|
|
iStat = NXmakegroup(Nfil,pName,"NXentry");
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
return 0;
|
|
}
|
|
iStat = NXopengroup(Nfil,pName,"NXentry");
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* write entry level attributes here */
|
|
pVar = FindVariable(pSics,"title");
|
|
if(pVar)
|
|
{
|
|
iDim[0] = strlen(pVar->text) + 1;
|
|
NXmakedata(Nfil,"title",NX_CHAR,1,iDim);
|
|
NXopendata(Nfil,"title");
|
|
NXputdata(Nfil,pVar->text);
|
|
NXclosedata(Nfil);
|
|
}
|
|
/* write time */
|
|
SNXFormatTime(pName,79);
|
|
iDim[0] = strlen(pName) + 1;
|
|
NXmakedata(Nfil,"start_time",NX_CHAR,1,iDim);
|
|
NXopendata(Nfil,"start_time");
|
|
NXputdata(Nfil,pName);
|
|
NXclosedata(Nfil);
|
|
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int SNenter(NXhandle Nfil, char *name, char *class)
|
|
{
|
|
int iStat;
|
|
|
|
iStat = NXmakegroup(Nfil,name,class);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXopengroup(Nfil,name,class);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
int SNputdata1(NXhandle Nfil, char *name, int datatype, int iLong,
|
|
void *pData)
|
|
{
|
|
int iStat;
|
|
int iDim[2];
|
|
|
|
iDim[0] = iLong;
|
|
iStat = NXmakedata (Nfil, name, datatype, 1, (int *) iDim);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXopendata(Nfil,name);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXputdata(Nfil,pData);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXclosedata(Nfil);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
int SNputdata1att(NXhandle Nfil, char *name, int datatype, int iLong,
|
|
void *pData, char *attname, char *val)
|
|
{
|
|
int iStat;
|
|
int iDim[2];
|
|
|
|
iDim[0] = iLong;
|
|
iStat = NXmakedata (Nfil, name, datatype, 1, (int *) iDim);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXopendata(Nfil,name);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXputdata(Nfil,pData);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXputattr(Nfil,attname,val,
|
|
strlen(val) + 1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
iStat = NXclosedata(Nfil);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static int SNPutMotor(NXhandle hfil, SicsInterp *pSics,
|
|
SConnection *pCon,char *sicsname,
|
|
char *dataname, char *units)
|
|
{
|
|
float fVal;
|
|
char pBueffel[512];
|
|
int iRet;
|
|
pMotor pMot;
|
|
|
|
pMot = FindMotor(pSics,sicsname);
|
|
if(!pMot)
|
|
{
|
|
sprintf(pBueffel,"ERROR: motor %s not found ", sicsname);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
iRet = MotorGetSoftPosition(pMot,pCon,&fVal);
|
|
if(iRet != 1)
|
|
{
|
|
sprintf(pBueffel,"ERROR: cannot read motor %s", sicsname);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
return SNputdata1att(hfil,dataname, NX_FLOAT32,1,&fVal,"Units",units);
|
|
}
|
|
#ifdef NONINTF
|
|
extern float nintf(float f);
|
|
#endif
|
|
/*--------------------------------------------------------------------------*/
|
|
int SNMakeDMC(SConnection *pCon, SicsInterp *pSics)
|
|
{
|
|
NXhandle Nfil;
|
|
NXlink lWave, lDetData, lStart, lTemp, lMoni, lStep, lNumber,
|
|
lTheta, lSetData;
|
|
int iDim[2];
|
|
float fEnd,fStart, fStep;
|
|
int iStat;
|
|
pSicsVariable pVar;
|
|
pSicsSelector pSel = NULL;
|
|
pICountable pCountInt;
|
|
pIDrivable pDrive = NULL;
|
|
pSelVar pPell;
|
|
char *pP;
|
|
float fVal;
|
|
float *fTheta;
|
|
float fTh, f2Th, fB1, fB2;
|
|
pMotor pMot = NULL;
|
|
CommandList *pCom = NULL;
|
|
int iVal, i;
|
|
char pBuffer[132];
|
|
pHistMem pHist = NULL;
|
|
HistInt *lData = NULL;
|
|
CounterMode eCount;
|
|
int *iTVal = NULL;
|
|
pDummy pDum;
|
|
int bHRPT = 0;
|
|
float fMean, fStdDev;
|
|
pVarLog pLog = NULL;
|
|
|
|
/* open the file & entry */
|
|
Nfil = SNXStartFile(pCon,pSics);
|
|
if(!Nfil)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
iStat = SNXStartEntry(Nfil,1,pSics);
|
|
if(!iStat)
|
|
{
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
|
|
/* create the instrument Vgroup */
|
|
pVar = FindVariable(pSics,"instrument");
|
|
if(strcmp(pVar->text,"HRPT") == 0)
|
|
{
|
|
bHRPT = 1;
|
|
}
|
|
assert(pVar);
|
|
iStat = SNenter(Nfil,pVar->text,"NXpsdpowder");
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
/* write the Kollimator for HRPT */
|
|
if(bHRPT)
|
|
{
|
|
iStat = SNenter(Nfil,"kollimator","NXkollimator");
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
pMot = FindMotor(pSics,"CEX1");
|
|
if(pMot)
|
|
{
|
|
iStat = MotorGetSoftPosition(pMot,pCon,&fStart);
|
|
iStat = SNputdata1att(Nfil,"kollimator1",NX_FLOAT32,1,
|
|
&fStart,"Units","degrees");
|
|
}
|
|
pMot = FindMotor(pSics,"CEX2");
|
|
if(pMot)
|
|
{
|
|
iStat = MotorGetSoftPosition(pMot,pCon,&fStart);
|
|
iStat = SNputdata1att(Nfil,"kollimator2",NX_FLOAT32,1,
|
|
&fStart,"Units","degrees");
|
|
}
|
|
NXclosegroup(Nfil); /* leave kollimator */
|
|
}
|
|
|
|
/* write the Monochromator data */
|
|
iStat = SNenter(Nfil,"Monochromator","NXcrystal");
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
if(bHRPT)
|
|
{
|
|
pVar = FindVariable(pSics,"lambda");
|
|
if(pVar)
|
|
{
|
|
VarGetFloat(pVar,&fVal);
|
|
SNputdata1att(Nfil,"lambda",NX_FLOAT32,1,&fVal,
|
|
"Units","Angstroem");
|
|
NXopendata(Nfil,"lambda");
|
|
NXgetdataID(Nfil,&lWave);
|
|
NXclosedata(Nfil);
|
|
}
|
|
pVar = FindVariable(pSics,"monotype");
|
|
if(pVar)
|
|
{
|
|
iStat = SNputdata1(Nfil,"type",NX_CHAR,strlen(pVar->text),
|
|
pVar->text);
|
|
}
|
|
/* write tons of motors for the monochromator */
|
|
SNPutMotor(Nfil,pSics,pCon,"momu",
|
|
"omega_upper","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mtvu",
|
|
"vertical_translation_upper","mm");
|
|
SNPutMotor(Nfil,pSics,pCon,"mtpu",
|
|
"paralell_translation_upper","mm");
|
|
SNPutMotor(Nfil,pSics,pCon,"mgvu",
|
|
"vertical_tilt_upper","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mgpu",
|
|
"parallel_tilt_upper","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mcvu",
|
|
"curvature_upper","");
|
|
SNPutMotor(Nfil,pSics,pCon,"moml",
|
|
"omega_lower","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mtvl",
|
|
"vertical_translation_lower","mm");
|
|
SNPutMotor(Nfil,pSics,pCon,"mtpl",
|
|
"parallel_translation_lower","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mgvl",
|
|
"vertical_tilt_lower","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mgpl",
|
|
"parallel_tilt_lower","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mcvl",
|
|
"curvature_lower","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"mexz",
|
|
"lift","mm");
|
|
}
|
|
else
|
|
{
|
|
pCom = FindCommand(pSics,"mono");
|
|
assert(pCom);
|
|
pSel = (pSicsSelector)pCom->pData;
|
|
pP = MonoGetType(pSel);
|
|
iStat = SNputdata1(Nfil,"type",NX_CHAR,strlen(pP), pP);
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
pCom = NULL;
|
|
pCom = FindCommand(pSics,"lambda");
|
|
assert(pCom);
|
|
pPell = (pSelVar)pCom->pData;
|
|
assert(iHasType(pPell,"SicsSelVar"));
|
|
fVal = GetSelValue(pPell,pCon);
|
|
iStat = SNputdata1(Nfil,"lambda",NX_FLOAT32,1,&fVal);
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
NXopendata(Nfil,"lambda");
|
|
NXputattr(Nfil,"Units","Angstroem",10,NX_CHAR);
|
|
NXgetdataID(Nfil,&lWave);
|
|
NXclosedata(Nfil);
|
|
iStat = GetMonoPositions(pSel,pCon,&fTh,&f2Th, &fB1, &fB2);
|
|
if(iStat)
|
|
/* skip if not readable, error has been reported lower down */
|
|
{
|
|
SNputdata1att(Nfil,"theta",NX_FLOAT32,1,&fTh,
|
|
"Units","degrees");
|
|
SNputdata1att(Nfil,"two_theta",NX_FLOAT32, 1,&f2Th,
|
|
"Units","degrees");
|
|
SNputdata1att(Nfil,"curvature",NX_FLOAT32, 1,&fB1,
|
|
"Units","mm");
|
|
}
|
|
/* more monochromatic motors */
|
|
SNPutMotor(Nfil,pSics,pCon,"monox",
|
|
"x_translation","mm");
|
|
SNPutMotor(Nfil,pSics,pCon,"monoy",
|
|
"y_translation","mm");
|
|
SNPutMotor(Nfil,pSics,pCon,"monophi",
|
|
"phi","degree");
|
|
SNPutMotor(Nfil,pSics,pCon,"monochi",
|
|
"chi","degree");
|
|
}
|
|
NXclosegroup(Nfil); /* leave monochromator */
|
|
|
|
/* start Detector vGroup */
|
|
if(bHRPT)
|
|
{
|
|
iStat = SNenter(Nfil,HRPTDETNAM,"NXpsd");
|
|
}
|
|
else
|
|
{
|
|
iStat = SNenter(Nfil,DMCDETNAM,"NXpsd");
|
|
}
|
|
/* get the histogram memory object */
|
|
pCom = FindCommand(pSics,"banana");
|
|
assert(pCom);
|
|
pHist = pCom->pData;
|
|
assert(pHist);
|
|
|
|
/* counter mode */
|
|
eCount = GetHistCountMode(pHist);
|
|
if(eCount == eTimer)
|
|
{
|
|
strcpy(pBuffer,"Timer");
|
|
}
|
|
else
|
|
{
|
|
strcpy(pBuffer,"Monitor");
|
|
}
|
|
iStat = SNputdata1(Nfil,"CounterMode",NX_CHAR,strlen(pBuffer), pBuffer);
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* count preset */
|
|
fVal = GetHistPreset(pHist);
|
|
if(eCount == eTimer)
|
|
{
|
|
iStat = SNputdata1(Nfil,"Preset",NX_FLOAT32,1, &fVal);
|
|
}
|
|
else
|
|
{
|
|
fVal = nintf(fVal);
|
|
iStat = SNputdata1(Nfil,"Preset",NX_FLOAT32,1, &fVal);
|
|
}
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* monitor value */
|
|
pDum = (pDummy)pHist;
|
|
pCountInt = pDum->pDescriptor->GetInterface(pDum,COUNTID);
|
|
{
|
|
pCountInt->TransferData(pHist,pCon);
|
|
}
|
|
iVal = GetHistMonitor(pHist, 1, pCon);
|
|
if(iVal < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
iStat = SNputdata1(Nfil,"Monitor",NX_INT32,1, &iVal);
|
|
/*
|
|
count time
|
|
*/
|
|
fVal = GetHistCountTime(pHist,pCon);
|
|
SNputdata1att(Nfil,"time",NX_FLOAT32,1,&fVal,"Units","seconds");
|
|
|
|
/*
|
|
more monitors
|
|
*/
|
|
iVal = GetHistMonitor(pHist, 0, pCon);
|
|
SNputdata1(Nfil,"beam_monitor",NX_INT32,1, &iVal);
|
|
iVal = GetHistMonitor(pHist, 4, pCon);
|
|
SNputdata1(Nfil,"proton_monitor",NX_INT32,1, &iVal);
|
|
NXopendata(Nfil,"Monitor");
|
|
NXgetdataID(Nfil,&lMoni);
|
|
NXclosedata(Nfil);
|
|
|
|
|
|
/* stepwidth */
|
|
pVar = FindVariable(pSics,"detstepwidth");
|
|
if(!pVar)
|
|
{
|
|
return 0;
|
|
}
|
|
fVal = pVar->fVal;
|
|
iStat = SNputdata1(Nfil,"Step",NX_FLOAT32,1, &fVal);
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
NXopendata(Nfil,"Step");
|
|
NXgetdataID(Nfil,&lStep);
|
|
NXclosedata(Nfil);
|
|
|
|
/* histogram Length */
|
|
GetHistDim(pHist,iDim,&iVal);
|
|
iVal = iDim[0];
|
|
if(iVal < 1)
|
|
{
|
|
return 0;
|
|
}
|
|
iStat = SNputdata1(Nfil,"no_of_steps",NX_INT32,1, &iVal);
|
|
if(iStat < 1)
|
|
{
|
|
return 0;
|
|
}
|
|
NXopendata(Nfil,"no_of_steps");
|
|
NXgetdataID(Nfil,&lNumber);
|
|
NXclosedata(Nfil);
|
|
|
|
/* actual data */
|
|
lData = (HistInt *)malloc(iVal*sizeof(HistInt));
|
|
if(!lData)
|
|
{
|
|
return 0;
|
|
}
|
|
iStat = GetHistogram(pHist,pCon,0,0,iVal,lData,iVal*sizeof(HistInt));
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
iStat = SNputdata1(Nfil,"Counts",NX_INT32,iVal, lData);
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
free(lData);
|
|
NXopendata(Nfil,"Counts");
|
|
NXgetdataID(Nfil,&lSetData);
|
|
strcpy(pBuffer,"1");
|
|
NXputattr(Nfil,"signal",pBuffer,strlen(pBuffer)+1,NX_CHAR);
|
|
NXclosedata(Nfil);
|
|
|
|
/* motor position */
|
|
pMot = FindMotor(pSics,"a4");
|
|
assert(pMot);
|
|
iStat = MotorGetSoftPosition(pMot,pCon,&fStart);
|
|
iStat = SNputdata1att(Nfil,"two_theta_start",NX_FLOAT32,1,
|
|
&fStart,"Units","degrees");
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* create 2Theta array and store it */
|
|
fTheta = NULL;
|
|
fTheta = (float *)malloc(iVal*sizeof(NX_FLOAT32));
|
|
if(!fTheta)
|
|
{
|
|
return 0;
|
|
}
|
|
for(i = 0; i < iVal; i++)
|
|
{
|
|
fTheta[i] = fStart + i*fVal;
|
|
}
|
|
iStat = SNputdata1att(Nfil,"two_theta",NX_FLOAT32,iVal,
|
|
fTheta,"Units","degrees");
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
/* get link, put axis attribute */
|
|
NXopendata(Nfil,"two_theta");
|
|
NXputattr(Nfil,"axis","1",strlen("1")+1,NX_CHAR);
|
|
NXgetdataID(Nfil,&lTheta);
|
|
NXclosedata(Nfil);
|
|
free(fTheta);
|
|
|
|
|
|
NXopendata(Nfil,"two_theta_start");
|
|
NXgetdataID(Nfil,&lStart);
|
|
NXclosedata(Nfil);
|
|
NXclosegroup(Nfil); /* detector Vgroup */
|
|
NXclosegroup(Nfil); /* instrument Vgroup */
|
|
|
|
/* do the sample Vgroup */
|
|
iStat = SNenter(Nfil,"Sample","NXpowder");
|
|
if(!iStat)
|
|
{
|
|
return 0;
|
|
}
|
|
pVar = FindVariable(pSics,"sample");
|
|
if(pVar)
|
|
{
|
|
iDim[0] = strlen(pVar->text) + 1;
|
|
NXmakedata(Nfil,"sample_name",NX_CHAR,1,iDim);
|
|
NXopendata(Nfil,"sample_name");
|
|
NXputdata(Nfil,pVar->text);
|
|
NXclosedata(Nfil);
|
|
}
|
|
pVar = FindVariable(pSics,"sample_mur");
|
|
if(pVar)
|
|
{
|
|
SNputdata1att(Nfil,"sample_mur",NX_FLOAT32, 1,&pVar->fVal,
|
|
"Units","???");
|
|
}
|
|
/* do a3 */
|
|
SNPutMotor(Nfil,pSics,pCon,"a3",
|
|
"sample_table_rotation","degree");
|
|
|
|
/* write sample environment here */
|
|
pCom = FindCommand(pSics,"temperature");
|
|
if(pCom)
|
|
{
|
|
pDum = (pDummy)pCom->pData;
|
|
pDrive = pDum->pDescriptor->GetInterface(pDum,DRIVEID);
|
|
if(pDrive) /* a proper environment device */
|
|
{
|
|
pLog = EVCGetVarLog( (pEVControl)pCom->pData);
|
|
if(pLog)
|
|
{
|
|
VarlogGetMean(pLog,&fMean,&fStdDev);
|
|
SNputdata1att(Nfil,"temperature_mean",NX_FLOAT32, 1,&fMean,
|
|
"Units","K");
|
|
SNputdata1att(Nfil,"temperature_stddev",NX_FLOAT32, 1,
|
|
&fStdDev,"Units","K");
|
|
}
|
|
fVal = pDrive->GetValue(pCom->pData,pCon);
|
|
}
|
|
else /* a simple variable */
|
|
{
|
|
VarGetFloat((pSicsVariable)pDum,&fVal);
|
|
}
|
|
SNputdata1att(Nfil,"sample_temperature",NX_FLOAT32, 1,&fVal,
|
|
"Units","K");
|
|
}
|
|
NXclosegroup(Nfil); /* sample Vgroup */
|
|
|
|
/* write the data Vgroup */
|
|
SNenter(Nfil,"data1","NXdata");
|
|
NXmakelink(Nfil,&lWave);
|
|
NXmakelink(Nfil,&lTheta);
|
|
NXmakelink(Nfil,&lStart);
|
|
NXmakelink(Nfil,&lSetData);
|
|
NXmakelink(Nfil,&lMoni);
|
|
NXmakelink(Nfil,&lStep);
|
|
NXmakelink(Nfil,&lNumber);
|
|
|
|
/* send quieck message */
|
|
i = 131;
|
|
iVal = NX_CHAR;
|
|
NXgetattr(Nfil,"file_name",pBuffer,&i,&iVal);
|
|
SendQuieck(QUIECK,pBuffer);
|
|
|
|
/* done */
|
|
NXclose(&Nfil);
|
|
return 1;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int SNStoreDMC(SConnection *pCon, SicsInterp *pSics, void *pData, int argc,
|
|
char *argv[])
|
|
|
|
{
|
|
return SNMakeDMC(pCon,pSics);
|
|
}
|