- Added Pause and Continue commands - Fixed simulation counter to deal properly with pause - Fixed nxdict HDF5 problem
797 lines
22 KiB
C
797 lines
22 KiB
C
/*--------------------------------------------------------------------------
|
|
N X S A N S
|
|
|
|
a module of utility functions which serve to write Nexus
|
|
data files for SANS.
|
|
|
|
Mark Koennecke, August 1997 - November 1998
|
|
|
|
Updated to support the larger detector resolution and possible
|
|
TOF and stroboscopic modes, Mark Koennecke, February 2001
|
|
|
|
Added additional monitors for stroboscopic gummi mode,
|
|
Mark Koennecke, September 2002
|
|
|
|
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 <time.h>
|
|
#include "fortify.h"
|
|
#include "sics.h"
|
|
#include "sicsvar.h"
|
|
#include "napi.h"
|
|
#include "nxdict.h"
|
|
#include "modriv.h"
|
|
#include "motor.h"
|
|
#include "nxutil.h"
|
|
#include "nxdata.h"
|
|
#include "countdriv.h"
|
|
#include "counter.h"
|
|
#include "danu.h"
|
|
#include "HistMem.h"
|
|
#include "velo.h"
|
|
#include "sps.h"
|
|
#include "udpquieck.h"
|
|
#include "mumo.h"
|
|
#include "sanswave.h"
|
|
|
|
|
|
#define HISTNAME "banana"
|
|
#define SAMPLETABLE "sampletable"
|
|
|
|
static int gummiFlag = 0; /* a flag indicating stroboscopic, or gummi mode */
|
|
|
|
/*-----------------------------------------------------------------------*/
|
|
static void SNError(void *pData, char *text)
|
|
{
|
|
SConnection *pCon;
|
|
|
|
assert(pData);
|
|
pCon = (SConnection *)pData;
|
|
SCWrite(pCon,text,eError);
|
|
}
|
|
/*-------------------------------------------------------------------------*/
|
|
NXhandle SNXStartSANS(SConnection *pCon, SicsInterp *pSics)
|
|
{
|
|
NXhandle pFile = NULL;
|
|
char *filename = NULL;
|
|
pSicsVariable pVar = NULL;
|
|
int iStat;
|
|
char pBueffel[512];
|
|
|
|
/* 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);
|
|
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);
|
|
}
|
|
|
|
/* throw away filename, no longer needed */
|
|
free(filename);
|
|
|
|
/* write creation time */
|
|
SNXFormatTime(pBueffel,512);
|
|
iStat = NXputattr(pFile,"file_time",pBueffel,
|
|
strlen(pBueffel)+1,NX_CHAR);
|
|
if(iStat == NX_ERROR)
|
|
{
|
|
SCWrite(pCon,"ERROR: writing date attribute to Nexus file",eError);
|
|
}
|
|
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,"adress");
|
|
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 SNMakeSANS(SConnection *pCon, SicsInterp *pSics, NXdict pDict)
|
|
{
|
|
NXhandle Nfil = NULL;
|
|
char pBueffel[512];
|
|
float fVal;
|
|
int iVal, iSet;
|
|
int iAxis[256];
|
|
int i, iRet;
|
|
long lVal;
|
|
HistInt *lData = NULL;
|
|
const float *fTime = NULL;
|
|
CommandList *pCom = NULL;
|
|
pHistMem self = NULL;
|
|
CounterMode eMode;
|
|
pVelSel pVelo = NULL;
|
|
pSPS pSiem = NULL;
|
|
const char *pNamPos = NULL;
|
|
float fRot, fTilt, fLambda;
|
|
pDummy pDum;
|
|
pIDrivable pDrive;
|
|
int iDim[MAXDIM], nDim, histSize,iStart;
|
|
|
|
/* start file */
|
|
Nfil = SNXStartSANS(pCon,pSics);
|
|
if(!Nfil)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
during all this, no extensive error checking will be done,
|
|
just write the error and continue, save at all cost
|
|
*/
|
|
|
|
/* put all this global information */
|
|
SNXSPutVariable(pSics,pCon,Nfil,pDict,"etitle","title");
|
|
SNXSPutVariable(pSics,pCon,Nfil,pDict,"etime","starttime");
|
|
SNXFormatTime(pBueffel,511);
|
|
NXDputalias(Nfil,pDict,"endtime",pBueffel);
|
|
strcpy(pBueffel,"SANS at SINQ,PSI");
|
|
NXDputalias(Nfil,pDict,"iname",pBueffel);
|
|
strcpy(pBueffel,"SINQ at PSI,Villigen, Switzerland");
|
|
NXDputalias(Nfil,pDict,"sname",pBueffel);
|
|
strcpy(pBueffel,"Spallation");
|
|
NXDputalias(Nfil,pDict,"stype",pBueffel);
|
|
|
|
/* put the velocity selector data */
|
|
NXDputalias(Nfil,pDict,"vname","Dornier Velocity Selector");
|
|
|
|
fRot = 0.;
|
|
fTilt = 0.;
|
|
pCom = FindCommand(pSics,"nvs");
|
|
if(pCom)
|
|
{
|
|
pVelo = (pVelSel)pCom->pData;
|
|
if(!pVelo)
|
|
{
|
|
SCWrite(pCon,"WARNING: Velocity Selctor not found",eWarning);
|
|
}
|
|
iRet = VSGetRotation(pVelo,&fVal);
|
|
if(!iRet)
|
|
{
|
|
SCWrite(pCon,"WARNING: failed to read velocity selector speed",
|
|
eWarning);
|
|
}
|
|
else
|
|
{
|
|
fRot = fVal;
|
|
NXDputalias(Nfil,pDict,"vrot",&fVal);
|
|
}
|
|
iRet = VSGetTilt(pVelo,&fTilt);
|
|
if(!iRet)
|
|
{
|
|
SCWrite(pCon,"WARNING: failed to read velocity selector tilt angle",eWarning);
|
|
}
|
|
}
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"vtilt","tilt");
|
|
CalculateLambda(fRot, fTilt, &fLambda);
|
|
NXDputalias(Nfil,pDict,"vlambda",&fLambda);
|
|
|
|
|
|
/* monitor 1 */
|
|
pCom = FindCommand(pSics,HISTNAME);
|
|
if(!pCom)
|
|
{
|
|
sprintf(pBueffel,"ERROR: histogram memory %s not found",HISTNAME);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
self = (pHistMem)pCom->pData;
|
|
assert(self);
|
|
lVal = GetHistMonitor(self,0,pCon);
|
|
iVal = (int)lVal;
|
|
NXDputalias(Nfil,pDict,"m1counts",&iVal);
|
|
lVal = GetHistMonitor(self,4,pCon);
|
|
iVal = (int)lVal;
|
|
NXDputalias(Nfil,pDict,"pbcounts",&iVal);
|
|
|
|
/* the collimator */
|
|
pCom = FindCommand(pSics,"sps2");
|
|
if(!pCom)
|
|
{
|
|
SCWrite(pCon,"WARNING: sps-unit for reading collimator NOT found",
|
|
eWarning);
|
|
}
|
|
else
|
|
{
|
|
pSiem = (pSPS)pCom->pData;
|
|
if(!pSiem)
|
|
{
|
|
SCWrite(pCon,"WARNING: sps-unit for reading collimator NOT found",
|
|
eWarning);
|
|
}
|
|
else
|
|
{
|
|
iRet = SPSGetSANS(pSiem,&fVal);
|
|
if(iRet <= 0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
NXDputalias(Nfil,pDict,"colli",&fVal);
|
|
}
|
|
/* as we got the sps, get the attenuator as well */
|
|
iRet = SPSGetStatus(pSiem,38,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 0;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,39,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 1;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,40,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 2;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,41,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 3;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,42,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 4;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,43,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 5;
|
|
}
|
|
}
|
|
NXDputalias(Nfil,pDict,"atti",&iVal);
|
|
}
|
|
}
|
|
|
|
/* the sample */
|
|
SNXSPutVariable(pSics,pCon,Nfil,pDict,"san","sample");
|
|
SNXSPutVariable(pSics,pCon,Nfil,pDict,"saenv","environment");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"sax","sax");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"say","say");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"saz","saz");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"saxn","sax");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"sayn","say");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"sazn","saz");
|
|
|
|
|
|
/* goniometer */
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"gphi","gphi");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"gtheta","gtheta");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"gphin","gphi");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"gthetan","gtheta");
|
|
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"saom","som");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"saomn","som");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"sapos","spos");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"saposn","spos");
|
|
pCom = FindCommand(pSics,SAMPLETABLE);
|
|
if(pCom)
|
|
{
|
|
if(pCom->pData)
|
|
{
|
|
pNamPos = FindNamPos((pMulMot)pCom->pData,pCon);
|
|
if(pNamPos)
|
|
{
|
|
NXDputalias(Nfil,pDict,"sanampos",(char *)pNamPos);
|
|
}
|
|
}
|
|
}
|
|
/* 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 */
|
|
{
|
|
fVal = pDrive->GetValue(pDum,pCon);
|
|
NXDputalias(Nfil,pDict,"satemp",&fVal);
|
|
}
|
|
}
|
|
pCom = FindCommand(pSics,"magnet");
|
|
if(pCom)
|
|
{
|
|
pDum = (pDummy)pCom->pData;
|
|
pDrive = pDum->pDescriptor->GetInterface(pDum,DRIVEID);
|
|
if(pDrive) /* a proper environment device */
|
|
{
|
|
fVal = pDrive->GetValue(pDum,pCon);
|
|
NXDputalias(Nfil,pDict,"samag",&fVal);
|
|
}
|
|
}
|
|
|
|
/* magnet motors. This instrument has motorized magnets crawling
|
|
through the hall */
|
|
pCom = FindCommand(pSics,"mom");
|
|
if(pCom)
|
|
{
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"mom","mom");
|
|
}
|
|
pCom = FindCommand(pSics,"mz");
|
|
if(pCom)
|
|
{
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"mz","mz");
|
|
}
|
|
|
|
|
|
/* put Beam Stop */
|
|
/* read beamstop number */
|
|
iVal = 1;
|
|
pCom = FindCommand(pSics,"sps1");
|
|
if(!pCom)
|
|
{
|
|
SCWrite(pCon,"WARNING: sps-unit for reading beamstop NOT found",eWarning);
|
|
}
|
|
else
|
|
{
|
|
pSiem = (pSPS)pCom->pData;
|
|
if(!pSiem)
|
|
{
|
|
SCWrite(pCon,"WARNING: sps-unit for reading beamstop NOT found",eWarning);
|
|
}
|
|
else
|
|
{
|
|
iRet = SPSGetStatus(pSiem,8,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 2;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,9,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 3;
|
|
}
|
|
}
|
|
iRet = SPSGetStatus(pSiem,10,&iSet);
|
|
if(iRet <0)
|
|
{
|
|
SCWrite(pCon,"WARNING: Failed to read SPS",eWarning);
|
|
}
|
|
else
|
|
{
|
|
if(iSet)
|
|
{
|
|
iVal = 4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
NXDputalias(Nfil,pDict,"bst",&iVal);
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"vsx","BeamStopX");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"vsy","BeamStopY");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"vsxnull","BeamStopX");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"vsynull","BeamStopY");
|
|
|
|
/* what this is all about: the detector */
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"ddx","DetectorX");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"ddy","DetectorY");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"ddxn","DetectorX");
|
|
SNXSPutMotorNull(pSics,pCon,Nfil,pDict,"ddyn","DetectorY");
|
|
SNXSPutMotor(pSics,pCon,Nfil,pDict,"ddchi","DetectorRotation");
|
|
pCom = FindCommand(pSics,HISTNAME);
|
|
if(!pCom)
|
|
{
|
|
sprintf(pBueffel,"ERROR: histogram memory %s not found",HISTNAME);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
self = (pHistMem)pCom->pData;
|
|
assert(self);
|
|
eMode = GetHistCountMode(self);
|
|
if(eMode == eTimer)
|
|
{
|
|
strcpy(pBueffel,"Timer");
|
|
}
|
|
else
|
|
{
|
|
strcpy(pBueffel,"Monitor");
|
|
}
|
|
NXDputalias(Nfil,pDict,"ddm",pBueffel);
|
|
fVal = GetHistPreset(self);
|
|
NXDputalias(Nfil,pDict,"ddp",&fVal);
|
|
lVal = GetHistMonitor(self,1,pCon);
|
|
iVal = (int)lVal;
|
|
NXDputalias(Nfil,pDict,"ddmo",&iVal);
|
|
fVal = GetHistCountTime(self,pCon);
|
|
NXDputalias(Nfil,pDict,"ddtime",&fVal);
|
|
|
|
/*
|
|
Deal with actual histogram. Due to stroboscopic modes and the
|
|
new detector electronics we need to find out about the size
|
|
ourselves now. And possibly write time binning information.
|
|
*/
|
|
GetHistDim(self, iDim,&nDim);
|
|
/*
|
|
handle time binning
|
|
*/
|
|
fTime = GetHistTimeBin(self,&iVal);
|
|
if(iVal > 2)
|
|
{
|
|
NXDputalias(Nfil,pDict,"ddtb",(void *)fTime);
|
|
nDim = 3;
|
|
iDim[2] = iVal;
|
|
}
|
|
|
|
histSize = 1;
|
|
for(i = 0; i < nDim; i++)
|
|
{
|
|
histSize *= iDim[i];
|
|
}
|
|
lData = (HistInt *)malloc(histSize*sizeof(HistInt));
|
|
if(!lData)
|
|
{
|
|
SCWrite(pCon,"ERROR: out of memory, FAILED to store data, file corrupt",
|
|
eError);
|
|
NXclose(&Nfil);
|
|
return 0;
|
|
}
|
|
GetHistogram(self,pCon,0,0,histSize,lData,histSize*sizeof(HistInt));
|
|
sprintf(pBueffel," %d ",iDim[0]);
|
|
NXDupdate(pDict,"dim1",pBueffel);
|
|
sprintf(pBueffel," %d ",iDim[1]);
|
|
NXDupdate(pDict,"dim2",pBueffel);
|
|
if(nDim == 2)
|
|
{
|
|
sprintf(pBueffel," -rank 2 -dim {%d,%d} ", iDim[0], iDim[1]);
|
|
NXDupdate(pDict,"countdim",pBueffel);
|
|
}
|
|
else if (nDim == 3)
|
|
{
|
|
sprintf(pBueffel," -rank 3 -dim {%d,%d,%d} ", iDim[0], iDim[1],
|
|
iDim[2]);
|
|
NXDupdate(pDict,"countdim",pBueffel);
|
|
sprintf(pBueffel," %d ",iDim[2]);
|
|
NXDupdate(pDict,"timedim",pBueffel);
|
|
}
|
|
NXDputalias(Nfil,pDict,"ddcounts",lData);
|
|
free(lData);
|
|
|
|
/* write x and y axis */
|
|
for(i = 0; i < iDim[0]; i++)
|
|
{
|
|
iAxis[i] = i;
|
|
}
|
|
NXDputalias(Nfil,pDict,"ddcx",iAxis);
|
|
for(i = 0; i < iDim[1]; i++)
|
|
{
|
|
iAxis[i] = i;
|
|
}
|
|
NXDputalias(Nfil,pDict,"ddcy",iAxis);
|
|
|
|
|
|
|
|
/*
|
|
write gummi monitors when apropriate
|
|
*/
|
|
if(nDim == 3 && gummiFlag != 0)
|
|
{
|
|
histSize = 3*iDim[2];
|
|
lData = (HistInt *)malloc(histSize*sizeof(HistInt));
|
|
if(lData == NULL)
|
|
{
|
|
SCWrite(pCon,"WARNING: failed to allocate memory for monitors",
|
|
eWarning);
|
|
} else {
|
|
memset(lData,0,histSize*sizeof(HistInt));
|
|
iStart = iDim[0]*iDim[1]*iDim[2];
|
|
GetHistogramDirect(self,pCon,0,iStart,iStart+histSize,
|
|
lData,histSize*sizeof(HistInt));
|
|
NXDputalias(Nfil,pDict,"gummimon1",lData);
|
|
NXDputalias(Nfil,pDict,"gummimon2",lData+iDim[2]);
|
|
NXDputalias(Nfil,pDict,"gummimon3",lData+2*iDim[2]);
|
|
free(lData);
|
|
}
|
|
}
|
|
|
|
/*
|
|
write detector temperature. It is a hot one............
|
|
*/
|
|
if(pSiem)
|
|
{
|
|
iRet = SPSGetADC(pSiem,1,&iVal);
|
|
if(iRet)
|
|
{
|
|
fVal = iVal/269.9;
|
|
NXDputalias(Nfil,pDict,"ddtemp",&fVal);
|
|
}
|
|
}
|
|
|
|
/* do the linking in th data vgroup */
|
|
NXDaliaslink(Nfil,pDict,"dan","ddcounts");
|
|
NXDaliaslink(Nfil,pDict,"dan","ddcx");
|
|
NXDaliaslink(Nfil,pDict,"dan","ddcy");
|
|
NXDaliaslink(Nfil,pDict,"dan","ddmo");
|
|
NXDaliaslink(Nfil,pDict,"dan","vlambda");
|
|
if(nDim == 3)
|
|
{
|
|
NXDaliaslink(Nfil,pDict,"dan","ddtb");
|
|
}
|
|
|
|
/* send quieck message for automatic copying*/
|
|
i = 131;
|
|
iVal = NX_CHAR;
|
|
NXgetattr(Nfil,"file_name",pBueffel,&i,&iVal);
|
|
SendQuieck(QUIECK,pBueffel);
|
|
/* close this and go ............. */
|
|
NXclose(&Nfil);
|
|
return 1;
|
|
}
|
|
/*------------------- The Mechanics for setting Up ------------------------*/
|
|
typedef struct {
|
|
pObjectDescriptor pDes;
|
|
NXdict pDict;
|
|
} DictStruct, *pDictStruct;
|
|
/*-------------------------------------------------------------------------*/
|
|
static pDictStruct MakeDictStruct(char *pFile)
|
|
{
|
|
pDictStruct pNew = NULL;
|
|
int iRet;
|
|
|
|
pNew = (pDictStruct)malloc(sizeof(DictStruct));
|
|
if(!pNew)
|
|
{
|
|
return NULL;
|
|
}
|
|
memset(pNew,0,sizeof(DictStruct));
|
|
pNew->pDes = CreateDescriptor("StoreData");
|
|
if(!pNew->pDes)
|
|
{
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
|
|
iRet = NXDinitfromfile(pFile,&(pNew->pDict));
|
|
if(iRet != NX_OK)
|
|
{
|
|
DeleteDescriptor(pNew->pDes);
|
|
free(pNew);
|
|
return NULL;
|
|
}
|
|
return pNew;
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
static void KillDictStruct(void *pData)
|
|
{
|
|
pDictStruct self = NULL;
|
|
|
|
self = (pDictStruct)pData;
|
|
assert(self);
|
|
|
|
if(self->pDes)
|
|
{
|
|
DeleteDescriptor(self->pDes);
|
|
}
|
|
if(self->pDict)
|
|
{
|
|
NXDclose(self->pDict,NULL);
|
|
}
|
|
free(self);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*/
|
|
int SNStoreSANS(SConnection *pCon, SicsInterp *pSics, void *pData, int argc,
|
|
char *argv[])
|
|
|
|
{
|
|
char pBueffel[80];
|
|
pDictStruct self = NULL;
|
|
self = (pDictStruct)pData;
|
|
|
|
assert(self);
|
|
assert(pCon);
|
|
assert(pSics);
|
|
|
|
if(argc > 1){
|
|
strtolower(argv[1]);
|
|
if(strcmp(argv[1],"gummi") == 0){
|
|
if(argc > 2){
|
|
if(!SCMatchRights(pCon,usMugger)){
|
|
return 0;
|
|
}
|
|
gummiFlag = atoi(argv[2]);
|
|
SCSendOK(pCon);
|
|
return 1;
|
|
} else
|
|
{
|
|
sprintf(pBueffel,"%s.gummi = %d",argv[0], gummiFlag);
|
|
SCWrite(pCon,pBueffel,eValue);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return SNMakeSANS(pCon,pSics,self->pDict);
|
|
}
|
|
/*--------------------------------------------------------------------------*/
|
|
int InitSANS(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[])
|
|
{
|
|
pDictStruct pNew = NULL;
|
|
char pBueffel[512];
|
|
|
|
if(argc < 2)
|
|
{
|
|
SCWrite(pCon,"ERROR: not enough arguments for IniSANS",eError);
|
|
return 0;
|
|
}
|
|
|
|
pNew = MakeDictStruct(argv[1]);
|
|
if(!pNew)
|
|
{
|
|
sprintf(pBueffel,"ERROR: failed to initialise NXDDL from file %s",
|
|
argv[1]);
|
|
SCWrite(pCon,pBueffel,eError);
|
|
return 0;
|
|
}
|
|
AddCommand(pSics,"StoreData",SNStoreSANS,KillDictStruct,pNew);
|
|
return 1;
|
|
}
|