* update after a1-a6 drive * intrduction of targets - POLDI writing - Moved HKL calculation 4 TRICS to fourlib
376 lines
10 KiB
C
376 lines
10 KiB
C
/*--------------------------------------------------------------------------
|
|
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 <stdlib.h>
|
|
#include <assert.h>
|
|
#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);
|
|
}
|
|
|
|
|
|
|