Files
sics/nxamor.c
2000-02-07 10:38:55 +00:00

500 lines
16 KiB
C

/*--------------------------------------------------------------------------
N X A M O R
Routines for writing NeXus files for the reflectometer AMOR at PSI.
copyright: see copyright.h
Mark Koennecke, September 1999
--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "fortify.h"
#include "sics.h"
#include "nxdict.h"
#include "nxutil.h"
#include "scan.h"
#include "scan.i"
#include "HistMem.h"
#include "counter.h"
#include "nxamor.h"
/* some defines for some names */
#define AMORDICT "amor.dic"
#define INSTNAME "AMOR at SINQ, PSI"
#define SOURCENAME "Spallation source SINQ"
#define SOURCETYPE "Continous flux spallation source"
#define CHOPPERNAME "Dornier Chopper System"
/*
this is the real detector size, the one in the dictionary will be
updated from this!
*/
#define DETSIZE 128
/*------------------------------------------------------------------------*/
static void WriteDiaphragm(NXhandle hfil, NXdict hdict, int i,
SConnection *pCon)
{
char pThing[30];
sprintf(pThing,"d%1.1ddist",i);
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,pThing,pThing);
sprintf(pThing,"d%1.1dt",i);
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,pThing,pThing);
sprintf(pThing,"d%1.1db",i);
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,pThing,pThing);
sprintf(pThing,"d%1.1dl",i);
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,pThing,pThing);
sprintf(pThing,"d%1.1dr",i);
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,pThing,pThing);
}
/*----------------------------------------------------------------------*/
int WriteAmorHeader(char *file, SConnection *pCon)
{
NXhandle hfil;
NXdict hdict;
int iRet;
char pBueffel[512];
CounterMode eMode;
CommandList *pCom = NULL;
float fVal;
/* open files */
iRet = NXopen(file,NXACC_CREATE,&hfil);
if(iRet != NX_OK)
{
sprintf(pBueffel,"ERROR: cannot open file %s for writing",file);
SCWrite(pCon,pBueffel,eError);
return 0;
}
iRet = NXDinitfromfile(AMORDICT,&hdict);
if(iRet != NX_OK)
{
sprintf(pBueffel,"ERROR: cannot open dictionary file %s");
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* put some global information */
SNXSPutGlobals(hfil,file,"AMOR",pCon);
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"etitle","title");
SNXFormatTime(pBueffel,512);
NXDputalias(hfil,hdict,"estart",pBueffel);
/* instrument vGroup */
NXDputalias(hfil,hdict,"iname",INSTNAME);
/* source */
NXDputalias(hfil,hdict,"sname",SOURCENAME);
NXDputalias(hfil,hdict,"stype",SOURCETYPE);
/* chopper */
NXDputalias(hfil,hdict,"cname",CHOPPERNAME);
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"crot",
"chopperrotation");
/* frame overlap mirror */
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"fomname",
"fomname");
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"fodist",
"fomdist");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"fomh","ftz");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"fomom","fom");
/* first Diaphragm */
WriteDiaphragm(hfil,hdict,1,pCon);
/* polarizing, monochromating mirror */
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"polname",
"polname");
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"poldist",
"poldist");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"polz","moz");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"polom","mom");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"poly","mty");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"polzom","mtz");
/* second Diaphragm */
WriteDiaphragm(hfil,hdict,2,pCon);
/* third Diaphragm */
WriteDiaphragm(hfil,hdict,3,pCon);
/* sample table */
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"saname",
"sample");
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"stdist",
"sampledist");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"somheight","stz");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"schi","sch");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"somega","som");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"stheight","soz");
/* fourth Diaphragm */
WriteDiaphragm(hfil,hdict,4,pCon);
/* analyzer */
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"anname",
"ananame");
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"andist",
"anadist");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"anoz","atz");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"anom","aom");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"antz","aoz");
/* fifth Diaphragm!!!!!!!!! */
WriteDiaphragm(hfil,hdict,5,pCon);
/* counting data */
pCom = FindCommand(pServ->pSics,"counter");
if(pCom)
{
if(pCom->pData)
{
eMode = GetCounterMode((pCounter)pCom->pData);
if(eMode == eTimer)
{
strcpy(pBueffel,"timer");
}
else
{
strcpy(pBueffel,"monitor");
}
NXDputalias(hfil,hdict,"cnmode",pBueffel);
fVal = GetCounterPreset((pCounter)pCom->pData);
NXDputalias(hfil,hdict,"cnpreset",&fVal);
}
}
else
{
SCWrite(pCon,"WARNING: failed to find counter!",eWarning);
}
NXclose(&hfil);
NXDclose(hdict,NULL);
return 1;
}
/*------------------------------------------------------------------------*/
int WriteAmorScan(char *file, SConnection *pCon, pScanData pScan)
{
NXhandle hfil;
NXdict hdict;
int iRet, i;
char pBueffel[512], pDefinition[1024];
CommandList *pCom = NULL;
float fVal;
float *fAxis = NULL;
long *lData = NULL;
int *iData = NULL;
/* open files */
iRet = NXopen(file,NXACC_RDWR,&hfil);
if(iRet != NX_OK)
{
sprintf(pBueffel,"ERROR: cannot open file %s for writing");
SCWrite(pCon,pBueffel,eError);
return 0;
}
iRet = NXDinitfromfile(AMORDICT,&hdict);
if(iRet != NX_OK)
{
sprintf(pBueffel,"ERROR: cannot open dictionary file %s");
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* write general detector data */
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"sdetdist",
"detectordist");
/* allocate memory for writing scan data */
fAxis = (float *)malloc(pScan->iNP*sizeof(float));
lData = (long *)malloc(pScan->iNP*sizeof(long));
iData = (int *)malloc(pScan->iNP*sizeof(int));
if( (!fAxis) || (!lData) || (!iData) )
{
SCWrite(pCon,"ERROR: out of memory in WriteAmorScan",eError);
return 0;
}
memset(fAxis,0,pScan->iNP*sizeof(float));
memset(lData,0,pScan->iNP*sizeof(long));
memset(iData,0,pScan->iNP*sizeof(int));
/* write scan variables */
for(i = 0; i < pScan->iScanVar; i++)
{
/* build definition string */
NXDget(hdict,"scanroot",pBueffel, 512);
strcpy(pDefinition,pBueffel);
strcat(pDefinition," ");
GetScanVarName(pScan,i,pBueffel,512);
strcat(pDefinition,pBueffel);
sprintf(pBueffel," -rank 1 -dim {%d} ", pScan->iNP);
strcat(pDefinition,pBueffel);
if(i == 0)
{
strcat(pDefinition," -attr {axis,1}");
}
/* get data and write */
GetScanVar(pScan,i,fAxis,pScan->iNP);
NXDputdef(hfil,hdict,pDefinition,fAxis);
if(i == 0)
{
NXDget(hdict,"sdana",pBueffel,512);
NXDdeflink(hfil,hdict,pBueffel,pDefinition);
}
}
/*
Write counted data: Here there is a convention which has to be
valid in amorscan as well: GetCounts gets the main detector.
GetMonitor 0 the second detector, GetMonitor 1 the first detector
other spin, GetMonitor 2, the second detector the other spin,
getMonitor 3, the first monitor, getMonitor 4 the second monitor
*/
sprintf(pBueffel,"%d",pScan->iNP);
NXDupdate(hdict,"scanlength",pBueffel);
GetScanCounts(pScan,lData,pScan->iNP);
for(i = 0; i < pScan->iNP; i++)
{
iData[i] = (int)lData[i];
}
NXDputalias(hfil,hdict, "spinupup",iData);
NXDaliaslink(hfil,hdict,"sdana","spinupup");
GetScanMonitor(pScan,0,lData,pScan->iNP);
for(i = 0; i < pScan->iNP; i++)
{
iData[i] = (int)lData[i];
}
NXDputalias(hfil,hdict, "spinuplo",iData);
NXDaliaslink(hfil,hdict,"sdana","spinuplo");
/* monitors */
GetScanMonitor(pScan,3,lData,pScan->iNP);
for(i = 0; i < pScan->iNP; i++)
{
iData[i] = (int)lData[i];
}
NXDputalias(hfil,hdict, "smonitor1",iData);
GetScanMonitor(pScan,4,lData,pScan->iNP);
for(i = 0; i < pScan->iNP; i++)
{
iData[i] = (int)lData[i];
}
NXDputalias(hfil,hdict, "smonitor2",iData);
/* to be added: polarizing mode, possibly coz, cox, com etc. */
/* a few motors which may or may not be useful */
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"sdetx","cox");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"sdetom","com");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"sdetheight","coz");
/* close and go */
NXclose(&hfil);
NXDclose(hdict,NULL);
free(fAxis);
free(lData);
free(iData);
return 1;
}
/*-----------------------------------------------------------------------*/
int WriteAmorTOF(char *file, SConnection *pCon, pHistMem pHM)
{
NXhandle hfil;
NXdict hdict;
int iRet, i, iLength;
char pBueffel[512];
float fVal, *fAxis = NULL, *fTime2 = NULL;
CommandList *pCom = NULL;
const float *fTime;
HistInt *lData = NULL, lVal;
/* open files */
iRet = NXopen(file,NXACC_RDWR,&hfil);
if(iRet != NX_OK)
{
sprintf(pBueffel,"ERROR: cannot open file %s for writing");
SCWrite(pCon,pBueffel,eError);
return 0;
}
iRet = NXDinitfromfile(AMORDICT,&hdict);
if(iRet != NX_OK)
{
sprintf(pBueffel,"ERROR: cannot open dictionary file %s");
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* write general detector data */
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,"detdist",
"detectordist");
/* a few motors which may or may not be useful */
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"detx","cox");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"detom","com");
SNXSPutMotor(pServ->pSics,pCon,hfil,hdict,"detheight","coz");
/* write counter related stuff */
pCom = FindCommand(pServ->pSics,"counter");
if(pCom)
{
if(pCom->pData)
{
fVal = GetCountTime((pCounter)pCom->pData,pCon);
NXDputalias(hfil,hdict,"cntime",&fVal);
/* the assignment of monitors has to be checked once
the Schlumpf is done
*/
lVal = GetMonitor((pCounter)pCom->pData,2, pCon);
NXDputalias(hfil,hdict,"cnmon1",&lVal);
lVal = GetMonitor((pCounter)pCom->pData,3, pCon);
NXDputalias(hfil,hdict,"cnmon2",&lVal);
}
}
else
{
SCWrite(pCon,"WARNING: failed to find counter!",eWarning);
}
/* write two axis */
fAxis = (float *)malloc(DETSIZE*sizeof(float));
if(!fAxis)
{
SCWrite(pCon,"ERROR: out of memory in WriteAmorTOF",eError);
return 0;
}
for(i = 0; i < DETSIZE; i++)
{
fAxis[i] = (float)i;
}
NXDputalias(hfil,hdict,"detxx",fAxis);
NXDputalias(hfil,hdict,"dety",fAxis);
NXDaliaslink(hfil,hdict,"dana","detxx");
NXDaliaslink(hfil,hdict,"dana","dety");
free(fAxis);
/* update detector size */
sprintf(pBueffel,"%d",DETSIZE);
NXDupdate(hdict,"detsize",pBueffel);
/* deal with time binning */
fTime = GetHistTimeBin(pHM,&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,"dettime",fTime2);
NXDaliaslink(hfil,hdict,"dana","dettime");
free(fTime2);
fTime2 = NULL;
}
else
{
SCWrite(pCon,"ERROR: out of memory while writing time binning",
eError);
}
/* finally get histogram */
iLength = GetHistLength(pHM);
lData = (HistInt *)malloc(iLength*sizeof(HistInt));
if(!lData)
{
SCWrite(pCon,
"ERROR: out of memory, failed to write histogram",eError);
return 0;
}
memset(lData,0,iLength*sizeof(HistInt));
GetHistogram(pHM,pCon, 0,0,iLength,lData,iLength*sizeof(HistInt));
NXDputalias(hfil,hdict,"spinup",lData);
NXDaliaslink(hfil,hdict,"dana","spinup");
/* to do: add polarizing code */
free(lData);
NXclose(&hfil);
NXDclose(hdict,NULL);
return 1;
}
/*-----------------------------------------------------------------------*/
static pHistMem pMeme = NULL;
int AmorStore(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
char pBueffel[512], *pFile = NULL;
int iRet;
pFile = SNXMakeFileName(pSics,pCon);
sprintf(pBueffel,"Writing file %s .....",pFile);
SCWrite(pCon,pBueffel,eWarning);
iRet = WriteAmorHeader(pFile,pCon);
if(iRet)
{
iRet = WriteAmorTOF(pFile,pCon,pMeme);
}
free(pFile);
SCSendOK(pCon);
return iRet;
}
/*---------------------------------------------------------------------*/
int AmorStoreMake(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
CommandList *pCom = NULL;
char pBueffel[512];
int iRet;
if(argc < 2)
{
SCWrite(pCon,
"ERROR: insufficient number of arguments to AmorStoreMake",
eError);
return 0;
}
/* we need one parameter which is the name of the histogram memory*/
pCom = FindCommand(pServ->pSics,argv[1]);
if(!pCom)
{
sprintf(pBueffel,"ERROR: Histogram memory %s NOT found", argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(!pCom->pData)
{
sprintf(pBueffel,"ERROR: Histogram memory %s NOT found", argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pMeme = (pHistMem)pCom->pData;
/* install command */
iRet = AddCommand(pSics,"storeamor",
AmorStore,NULL,NULL);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command amorstore NOT created");
SCWrite(pCon,pBueffel,eError);
return 0;
}
return 1;
}