706 lines
20 KiB
C
706 lines
20 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;
|
|
}
|