PSI sics-cvs-psi_pre-ansto
This commit is contained in:
835
nxamor.c
Normal file
835
nxamor.c
Normal file
@@ -0,0 +1,835 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
Updated, Mark Koennecke, August 2001
|
||||
Updated to store TOF-monitor, Mark Koennecke, September 2002
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
#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"
|
||||
#include "obpar.h"
|
||||
#include "motor.h"
|
||||
#include "status.h"
|
||||
|
||||
#define MAXMOT 13 /* must be same as in amor2t.c */
|
||||
#include "amor2t.i"
|
||||
#include "amor2t.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"
|
||||
|
||||
/*
|
||||
The rough size of each detector chunk to write in TOF mode
|
||||
(currently 16MB)
|
||||
#define TOFBLOCK 8192000
|
||||
*/
|
||||
#define TOFBLOCK 16384000
|
||||
|
||||
/*
|
||||
a pointer to amor2t which we need for a couple of parameters
|
||||
*/
|
||||
pAmor2T pAmor = NULL;
|
||||
|
||||
/*
|
||||
if to save psd data in TOF mode or not. This is in order to save time
|
||||
when measureing TOF with a single detector only.
|
||||
*/
|
||||
|
||||
static int psdSave = 1;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void WriteDiaphragm(NXhandle hfil, NXdict hdict, int i,
|
||||
SConnection *pCon)
|
||||
{
|
||||
char pThing[30];
|
||||
|
||||
|
||||
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], pThing[80];
|
||||
CounterMode eMode;
|
||||
CommandList *pCom = NULL;
|
||||
float fVal;
|
||||
|
||||
/* open files */
|
||||
NXsetcache(TOFBLOCK);
|
||||
iRet = NXopen(file,NXACC_CREATE5,&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",AMORDICT);
|
||||
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);
|
||||
sprintf(pThing,"d%1.1ddist",1);
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,pThing,pThing);
|
||||
|
||||
/* 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);
|
||||
sprintf(pThing,"d%1.1ddist",2);
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,pThing,pThing);
|
||||
|
||||
/* third Diaphragm */
|
||||
WriteDiaphragm(hfil,hdict,3,pCon);
|
||||
sprintf(pThing,"d%1.1ddist",3);
|
||||
SNXSPutVariable(pServ->pSics,pCon,hfil, hdict,pThing,pThing);
|
||||
|
||||
/* 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");
|
||||
fVal = ObVal(pAmor->aParameter,PARDH);
|
||||
NXDputalias(hfil,hdict,"baseheight",&fVal);
|
||||
|
||||
|
||||
/* fourth Diaphragm */
|
||||
WriteDiaphragm(hfil,hdict,4,pCon);
|
||||
fVal = ObVal(pAmor->aParameter,PARDD4);
|
||||
NXDputalias(hfil,hdict,"d4dist",&fVal);
|
||||
fVal = ObVal(pAmor->aParameter,PARD4H);
|
||||
NXDputalias(hfil,hdict,"d4base",&fVal);
|
||||
|
||||
/* 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");
|
||||
fVal = ObVal(pAmor->aParameter,PARADIS);
|
||||
NXDputalias(hfil,hdict,"adis",&fVal);
|
||||
fVal = ObVal(pAmor->aParameter,PARANA);
|
||||
NXDputalias(hfil,hdict,"abase",&fVal);
|
||||
|
||||
|
||||
/* fifth Diaphragm!!!!!!!!! */
|
||||
WriteDiaphragm(hfil,hdict,5,pCon);
|
||||
fVal = ObVal(pAmor->aParameter,PARDD5);
|
||||
NXDputalias(hfil,hdict,"d5dist",&fVal);
|
||||
fVal = ObVal(pAmor->aParameter,PARD5H);
|
||||
NXDputalias(hfil,hdict,"d5base",&fVal);
|
||||
|
||||
/* 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",file);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
iRet = NXDinitfromfile(AMORDICT,&hdict);
|
||||
if(iRet != NX_OK)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: cannot open dictionary file %s",AMORDICT);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
/*-----------------------------------------------------------------------
|
||||
WriteTOFDetector writes the histogram memory data in TOF mode. As
|
||||
the histogram memory can become quite large at AMOR, the data is
|
||||
read and stored in chunks if it is to big. All this is handled
|
||||
in this routine.
|
||||
-------------------------------------------------------------------------*/
|
||||
static int WriteTOFDetector(char *name, pHistMem pHM, int *iDim,
|
||||
NXhandle hfil, NXdict hdict,
|
||||
SConnection *pCon)
|
||||
{
|
||||
int iLength, nChunk, chunkSize, iChunk[3], i, iStart[3], nTime, iRet;
|
||||
HistInt *lData = NULL;
|
||||
char pBueffel[132];
|
||||
const float *fTime;
|
||||
|
||||
fTime = GetHistTimeBin(pHM,&nTime);
|
||||
iDim[2] = nTime;
|
||||
iLength = iDim[0]*iDim[1]*iDim[2];
|
||||
if( (iLength*4) < TOFBLOCK)
|
||||
{
|
||||
sprintf(pBueffel," -chunk {%d,%d,%d} ",iDim[0], iDim[1], iDim[2]);
|
||||
NXDupdate(hdict,"chunk",pBueffel);
|
||||
lData = (HistInt *)malloc(iLength*sizeof(HistInt));
|
||||
if(!lData)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: out of memory, failed to write histogram",eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
return 0;
|
||||
}
|
||||
memset(lData,0,iLength*sizeof(HistInt));
|
||||
iRet = GetHistogramDirect(pHM,pCon,
|
||||
0,0,iLength,lData,iLength*sizeof(HistInt));
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to read Hm data",eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
free(lData);
|
||||
return 0;
|
||||
}
|
||||
NXDputalias(hfil,hdict,name,lData);
|
||||
NXDputalias(hfil,hdict,"detchunk",iDim);
|
||||
NXDaliaslink(hfil,hdict,"dana",name);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
implement chunked writing. We strive to write layers in Y. The
|
||||
number of chunks needs to fulfill three conditions then:
|
||||
- multiple of xSize* timeBin;
|
||||
- close to TOFBLOCK in size
|
||||
- divide Y without remainder.
|
||||
*/
|
||||
iChunk[0] = iDim[0];
|
||||
iChunk[2] = iDim[2];
|
||||
iChunk[1] = 1;
|
||||
chunkSize = iDim[0]*iDim[2];
|
||||
for(i = 1; i < 64; i++)
|
||||
{
|
||||
if( (iDim[1] % i) == 0)
|
||||
{
|
||||
if(i*chunkSize*sizeof(HistInt) < TOFBLOCK)
|
||||
{
|
||||
iChunk[1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
sprintf(pBueffel,"Segmented TOF data in %d chunks",iDim[1]/iChunk[1]);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
/*
|
||||
now we have a chunkSize, lets go and write!
|
||||
*/
|
||||
NXDputalias(hfil,hdict,"detchunk",iChunk);
|
||||
chunkSize = iChunk[1]*iChunk[0]*iChunk[2];
|
||||
sprintf(pBueffel," -chunk {%d,%d,%d} ",iChunk[0], iChunk[1], iChunk[2]);
|
||||
NXDupdate(hdict,"chunk",pBueffel);
|
||||
lData = (HistInt *)malloc(chunkSize*sizeof(HistInt));
|
||||
if(!lData)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory while writing TOF data",
|
||||
eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
return 0;
|
||||
}
|
||||
NXDopenalias(hfil,hdict,name);
|
||||
for(i = 0; i < iDim[1]/iChunk[1]; i++)
|
||||
{
|
||||
memset(lData,0,chunkSize*sizeof(HistInt));
|
||||
iRet = GetHistogramDirect(pHM,pCon,
|
||||
0,i*chunkSize,(i+1)*chunkSize,lData,
|
||||
chunkSize*sizeof(HistInt));
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to read HM data",eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
free(lData);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
yield a little in order to allow other clients to receive a
|
||||
response. Also allow for interrupting.
|
||||
*/
|
||||
SicsWait(2);
|
||||
if(SCGetInterrupt(pCon) != eContinue)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: dataset writing interrupted, data probably corrupted",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
iStart[0] = 0;
|
||||
iStart[1] = i*iChunk[1];
|
||||
iStart[2] = 0;
|
||||
NXputslab(hfil,lData,iStart, iChunk);
|
||||
sprintf(pBueffel,"Wrote chunk %d", i);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
/*
|
||||
yield a little in order to allow other clients to receive a
|
||||
response. Also allow for interrupting.
|
||||
*/
|
||||
SicsWait(2);
|
||||
if(SCGetInterrupt(pCon) != eContinue)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: dataset writing interrupted, data probably corrupted",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
close groups till root
|
||||
*/
|
||||
NXclosedata(hfil);
|
||||
NXclosegroup(hfil);
|
||||
NXclosegroup(hfil);
|
||||
NXclosegroup(hfil);
|
||||
|
||||
/*
|
||||
make link
|
||||
*/
|
||||
NXDaliaslink(hfil,hdict,"dana",name);
|
||||
NXDaliaslink(hfil,hdict,"dana","detchunk");
|
||||
|
||||
}
|
||||
if(lData)
|
||||
free(lData);
|
||||
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;
|
||||
int detxsize, detysize, iDim[MAXDIM];
|
||||
|
||||
|
||||
/* open files */
|
||||
iRet = NXopen(file,NXACC_RDWR,&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",AMORDICT);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
find dimensions of detector
|
||||
*/
|
||||
GetHistDim(pHM,iDim,&iLength);
|
||||
detxsize = iDim[0];
|
||||
detysize = iDim[1];
|
||||
/* update detector size */
|
||||
sprintf(pBueffel,"%d",detxsize);
|
||||
NXDupdate(hdict,"detxsize",pBueffel);
|
||||
sprintf(pBueffel,"%d",detysize);
|
||||
NXDupdate(hdict,"detysize",pBueffel);
|
||||
|
||||
|
||||
/* write two axis */
|
||||
if(detxsize > detysize)
|
||||
iLength = detxsize;
|
||||
else
|
||||
iLength = detysize;
|
||||
|
||||
fAxis = (float *)malloc(iLength*sizeof(float));
|
||||
if(!fAxis)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory in WriteAmorTOF",eError);
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < detxsize; i++)
|
||||
{
|
||||
fAxis[i] = (float)i;
|
||||
}
|
||||
NXDputalias(hfil,hdict,"detxx",fAxis);
|
||||
for(i = 0; i < detysize; i++)
|
||||
{
|
||||
fAxis[i] = (float)i;
|
||||
}
|
||||
NXDputalias(hfil,hdict,"dety",fAxis);
|
||||
NXDaliaslink(hfil,hdict,"dana","detxx");
|
||||
NXDaliaslink(hfil,hdict,"dana","dety");
|
||||
free(fAxis);
|
||||
|
||||
|
||||
/* add height and distances */
|
||||
fVal = ObVal(pAmor->aParameter,PARDS);
|
||||
NXDputalias(hfil,hdict,"detdist",&fVal);
|
||||
fVal = ObVal(pAmor->aParameter,PARDDH);
|
||||
NXDputalias(hfil,hdict,"detbase",&fVal);
|
||||
|
||||
|
||||
/* deal with time binning */
|
||||
fTime = GetHistTimeBin(pHM,&iLength);
|
||||
iDim[2] = 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);
|
||||
NXDputalias(hfil,hdict,"singletime",fTime2);
|
||||
NXDaliaslink(hfil,hdict,"dana","dettime");
|
||||
free(fTime2);
|
||||
fTime2 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory while writing time binning",
|
||||
eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* finally get histogram */
|
||||
if(iDim[2] == 2) /* 2D data, no time binning on this detector */
|
||||
{
|
||||
iLength = detxsize*detysize;
|
||||
lData = (HistInt *)malloc(iLength*sizeof(HistInt));
|
||||
if(!lData)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: out of memory, failed to write histogram",eError);
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
return 0;
|
||||
}
|
||||
memset(lData,0,iLength*sizeof(HistInt));
|
||||
iRet = GetHistogram(pHM,pCon, 0,0,iLength,
|
||||
lData,iLength*sizeof(HistInt));
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to read HM", eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
return 0;
|
||||
}
|
||||
NXDputalias(hfil,hdict,"spinup2d",lData);
|
||||
NXDaliaslink(hfil,hdict,"dana","spinup2d");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(psdSave){
|
||||
iRet = WriteTOFDetector("spinup",pHM, iDim,hfil,hdict,pCon);
|
||||
if(!iRet)
|
||||
{
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
SCWrite(pCon,"PSD writing supressed!",eWarning);
|
||||
}
|
||||
#define MAXSINGLE 3
|
||||
/*
|
||||
now get and write single detectors
|
||||
*/
|
||||
iLength = iDim[0]*iDim[1]*iDim[2];
|
||||
lData = (HistInt *)malloc(MAXSINGLE*iDim[2]*sizeof(HistInt));
|
||||
if(!lData)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: out of memory while writing single detectors",
|
||||
eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(lData,0,MAXSINGLE*iDim[2]*sizeof(HistInt));
|
||||
iRet = GetHistogramDirect(pHM,pCon,0,iLength,
|
||||
iLength + MAXSINGLE*iDim[2],
|
||||
lData, MAXSINGLE*iDim[2]*sizeof(HistInt));
|
||||
if(!iRet)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to read single detector HM data",
|
||||
eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
free(lData);
|
||||
NXclose(&hfil);
|
||||
NXDclose(hdict,NULL);
|
||||
return 0;
|
||||
}
|
||||
NXDputalias(hfil,hdict,"singleup",lData);
|
||||
NXDaliaslink(hfil,hdict,"singledana","singleup");
|
||||
NXDaliaslink(hfil,hdict,"singledana","singletime");
|
||||
/*
|
||||
the TOF monitor
|
||||
*/
|
||||
NXDputalias(hfil,hdict,"singletofmon",lData+2*iDim[2]);
|
||||
NXDaliaslink(hfil,hdict,"dana","singletofmon");
|
||||
NXDaliaslink(hfil,hdict,"singledana","singletofmon");
|
||||
}
|
||||
}
|
||||
|
||||
/* to do: add polarizing code */
|
||||
|
||||
if(lData)
|
||||
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, iFlag;
|
||||
Status oldStatus;
|
||||
|
||||
/*
|
||||
if arguments, check for psdsave
|
||||
*/
|
||||
if(argc > 1){
|
||||
strtolower(argv[1]);
|
||||
if(strcmp(argv[1],"psdsave") == 0){
|
||||
if(argc > 2){
|
||||
psdSave = atof(argv[2]);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
} else {
|
||||
sprintf(pBueffel,"storeamor.psdSave = %d",psdSave);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pFile = SNXMakeFileName(pSics,pCon);
|
||||
sprintf(pBueffel,"Writing file %s .....",pFile);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
|
||||
oldStatus = GetStatus();
|
||||
SetStatus(eWriting);
|
||||
LockDeviceExecutor(pServ->pExecutor);
|
||||
iRet = WriteAmorHeader(pFile,pCon);
|
||||
if(iRet)
|
||||
{
|
||||
iRet = WriteAmorTOF(pFile,pCon,pMeme);
|
||||
}
|
||||
SetStatus(oldStatus);
|
||||
UnlockDeviceExecutor(pServ->pExecutor);
|
||||
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 < 3)
|
||||
{
|
||||
SCWrite(pCon,
|
||||
"ERROR: insufficient number of arguments to AmorStoreMake",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need a 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;
|
||||
|
||||
/* we need another parameter which is the name of the
|
||||
2theta calculation module
|
||||
*/
|
||||
pCom = FindCommand(pServ->pSics,argv[2]);
|
||||
if(!pCom)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: amor2T module %s NOT found", argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
if(!pCom->pData)
|
||||
{
|
||||
sprintf(pBueffel,"ERROR: amor2t module %s NOT found", argv[2]);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
return 0;
|
||||
}
|
||||
pAmor = (pAmor2T)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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user