Files
sics/fomerge.c
Ferdi Franceschini 10d29d597c Cleaned up ANSTO code to merge with sinqdev.sics
This is our new RELEASE-4_0 branch which was taken from ansto/93d9a7c
Conflicts:
	.gitignore
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	event.h
	exebuf.c
	exeman.c
	histmem.c
	interface.h
	motor.c
	motorlist.c
	motorsec.c
	multicounter.c
	napi.c
	napi.h
	napi4.c
	network.c
	nwatch.c
	nxscript.c
	nxxml.c
	nxxml.h
	ofac.c
	reflist.c
	scan.c
	sicshipadaba.c
	sicsobj.c
	site_ansto/docs/Copyright.txt
	site_ansto/instrument/lyrebird/config/tasmad/sicscommon/nxsupport.tcl
	site_ansto/instrument/lyrebird/config/tasmad/taspub_sics/tasscript.tcl
	statusfile.c
	tasdrive.c
	tasub.c
	tasub.h
	tasublib.c
	tasublib.h
2015-04-23 20:49:26 +10:00

1027 lines
27 KiB
C

/*---------------------------------------------------------------------------
F O M E R G E
This module is for the FOCUS instrument. FOCUS has three detector
banks. These are sent to SICS as one big array by the histogram memory.
However, depending on the situation these need to be accessed either:
- as single banks.
- or as a merged bank, where detector counts from all three banks are
summed onto a common two theta scale.
This module is responsible for accessing single banks and for doing
the merging operation.
copyright: see copyright.h
Mark Koennecke, March 2000
extended to support nxscripted file writing: Mark Koennecke, May 2004
extended to support GTSE, Mark Koennecke, May 2008
modifed to support second generation HM's via the bridge,
Mark Koennecke, December 2012
--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
#include "sics.h"
#include "nxscript.h"
#include "HistMem.h"
#include "fortify.h"
#include "scan.h"
#include "fitcenter.h"
#include "sicsdata.h"
static pFit fitter = NULL;
#include "fomerge.h"
/*================== module static data items ==========================*/
static HistInt *masterData, *upperData, *mediumData, *lowerData,
*mergedData = NULL;
static int timeBin, nUpper, nLower, nMedium, nMerged;
static float *upperTheta, *lowerTheta, *mediumTheta, *mergedTheta;
static int *mergeUp, *mergeMed, *mergeLow;
int iMerged;
int medium, upper, lower;
/*------------------------------------------------------------------------
The tables with the theta values for the detector banks and the merge
table living in mergeUp, mergeMed, mergeLow is initialized from a
data file, the mergefile. mergeUp, mergeLow, mergeMed contain a 0 if
the detector from this bank does not need to be summed for this merged
two theta value or the number of the detector from this bank to use.
-------------------------------------------------------------------------*/
int initializeFM(char *mergefile)
{
FILE *fd = NULL;
int i, j, iTest;
char pBuffer[132];
char *pPtr = NULL;
/* open the file */
fd = fopen(mergefile, "r");
if (!fd) {
fprintf(stdout, "ERROR: merge data file not found!\n");
return 0;
}
/* skip first line */
pPtr = fgets(pBuffer, 131, fd);
/* read the number of merged data points */
fgets(pBuffer, 131, fd);
iTest = sscanf(pBuffer, "%d", &nMerged);
if ((iTest != 1) || (nMerged <= 0)) {
fprintf(stdout, "ERROR: Invalid or corrupt merge dat file");
return 0;
}
/* allocate space */
mergedTheta = (float *) malloc(nMerged * sizeof(float));
mergeUp = (int *) malloc(nMerged * sizeof(int));
mergeMed = (int *) malloc(nMerged * sizeof(int));
mergeLow = (int *) malloc(nMerged * sizeof(int));
if (mergedTheta == NULL || mergeUp == NULL || mergeMed == NULL
|| mergeLow == NULL) {
fprintf(stdout, "ERROR: out of memory in fomerge\n");
return 0;
}
/* read the merge table */
for (i = 0; i < nMerged; i++) {
fgets(pBuffer, 131, fd);
iTest = sscanf(pBuffer, "%d %f %d %d %d", &j, &mergedTheta[i],
&mergeUp[i], &mergeMed[i], &mergeLow[i]);
if (iTest != 5) {
fprintf(stdout, "ERROR: Invalid or corrupt merge dat file");
return 0;
}
}
/* read upper bank two theta */
fgets(pBuffer, 131, fd);
fgets(pBuffer, 131, fd);
iTest = sscanf(pBuffer, "%d", &nUpper);
if ((iTest != 1) || (nUpper <= 0)) {
fprintf(stdout, "ERROR: Invalid or corrupt merge data file");
return 0;
}
upperTheta = (float *) malloc(nUpper * sizeof(float));
if (upperTheta == NULL) {
fprintf(stdout, "ERROR: out of memory in fomerge\n");
return 0;
}
for (i = 0; i < nUpper; i++) {
fgets(pBuffer, 131, fd);
sscanf(pBuffer, "%f", &upperTheta[i]);
}
/* read middle bank two theta */
fgets(pBuffer, 131, fd);
fgets(pBuffer, 131, fd);
iTest = sscanf(pBuffer, "%d", &nMedium);
if ((iTest != 1) || (nMedium <= 0)) {
fprintf(stdout, "ERROR: Invalid or corrupt merge data file");
return 0;
}
mediumTheta = (float *) malloc(nMedium * sizeof(float));
if (mediumTheta == NULL) {
fprintf(stdout, "ERROR: out of memory in fomerge\n");
return 0;
}
for (i = 0; i < nMedium; i++) {
fgets(pBuffer, 131, fd);
sscanf(pBuffer, "%f", &mediumTheta[i]);
}
/* read lower bank two theta */
fgets(pBuffer, 131, fd);
fgets(pBuffer, 131, fd);
iTest = sscanf(pBuffer, "%d", &nLower);
if ((iTest != 1) || (nLower <= 0)) {
fprintf(stdout, "ERROR: Invalid or corrupt merge data file");
return 0;
}
lowerTheta = (float *) malloc(nLower * sizeof(float));
if (lowerTheta == NULL) {
fprintf(stdout, "ERROR: out of memory in fomerge\n");
return 0;
}
for (i = 0; i < nLower; i++) {
fgets(pBuffer, 131, fd);
sscanf(pBuffer, "%f", &lowerTheta[i]);
}
/* done */
timeBin = 0;
iMerged = 0;
medium = 1;
upper = lower = 1;
fclose(fd);
return 1;
}
/*--------------------------------------------------------------------------
sets the data pointer and finds the starting points for the different
banks. This routine contains the knowledge how the detector banks are
laid out in the histogram returned from the histogram memory.
-------------------------------------------------------------------------*/
int setFMDataPointer(HistInt * lData, int mytimeBins, int bank)
{
HistInt *dataPtr;
if (lData == NULL)
return 0;
/* the first set is the medium bank */
masterData = dataPtr = lData;
if (bank == 2) {
if (medium) {
mediumData = masterData;
} else {
mediumData = NULL;
}
}
/* the next set is the upper bank */
if (bank == 1) {
if (upper) {
upperData = masterData;
} else {
upperData = NULL;
}
}
/* the last is the lower bank */
if (bank == 3) {
if (lower) {
lowerData = masterData;
} else {
lowerData = NULL;
}
}
/* deal with data allocation for merged data */
if (mytimeBins != timeBin) {
if (mergedData != NULL) {
free(mergedData);
}
timeBin = mytimeBins;
mergedData = (HistInt *) malloc(nMerged * timeBin * sizeof(HistInt));
if (mergedData == NULL) {
fprintf(stdout,
"ERROR: out of memory in fomerge.setFMdataPointer\n");
return 0;
}
}
/*
clear mergedData to 0
*/
memset(mergedData, 0, nMerged * timeBin * sizeof(HistInt));
iMerged = 0;
return 1;
}
/*-----------------------------------------------------------------------*/
void setFMconfiguration(int up, int med, int low)
{
upper = up;
medium = med;
lower = low;
}
/*--------------------------------------------------------------------------
The algorithm is suboptimal because we have to take care of the case of
missing detector banks due to missing or broken electronics or whatever.
*/
static void mergeData(void)
{
int i, j, nDiv;
HistInt *startMerge, *startData;
if (!mergedData)
return;
memset(mergedData, 0, nMerged * sizeof(HistInt));
for (i = 0; i < nMerged; i++) {
startMerge = mergedData + i * timeBin;
nDiv = 0;
/* upper bank contribution */
if (mergeUp[i] != 0 && upperData != NULL) {
startData = upperData + (mergeUp[i] - 1) * timeBin;
for (j = 0; j < timeBin; j++) {
startMerge[j] += startData[j];
}
nDiv++;
}
/* medium bank contribution */
if (mergeMed[i] != 0 && mediumData != NULL) {
startData = mediumData + (mergeMed[i] - 1) * timeBin;
for (j = 0; j < timeBin; j++) {
startMerge[j] += startData[j];
}
nDiv++;
}
/* lower bank contribution */
if (mergeLow[i] != 0 && lowerData != NULL) {
startData = lowerData + (mergeLow[i] - 1) * timeBin;
for (j = 0; j < timeBin; j++) {
startMerge[j] += startData[j];
}
nDiv++;
}
/* do we need to run a division? */
if (nDiv > 1) {
for (j = 0; j < timeBin; j++) {
startMerge[j] /= nDiv;
}
}
} /* end of for */
iMerged = 1;
}
/*-----------------------------------------------------------------------*/
void killFM(void)
{
if (mergedData != NULL)
free(mergedData);
if (lowerTheta != NULL)
free(lowerTheta);
if (mediumTheta != NULL)
free(mediumTheta);
if (upperTheta != NULL)
free(upperTheta);
if (mergedTheta != NULL)
free(mergedTheta);
if (mergeUp != NULL)
free(mergeUp);
if (mergeMed != NULL)
free(mergeMed);
if (mergeLow != NULL)
free(mergeLow);
}
/*--------------------------------------------------------------------------
Below are some not very interesting data access routines
---------------------------------------------------------------------------*/
HistInt *getFMBankPointer(int which)
{
switch (which) {
case UPPER:
return upperData;
break;
case MIDDLE:
return mediumData;
break;
case LOWER:
return lowerData;
break;
case MERGED:
if (!iMerged)
mergeData();
return mergedData;
break;
default:
assert(0);
}
}
/*-------------------------------------------------------------------------*/
float *getFMBankTheta(int which)
{
switch (which) {
case UPPER:
return upperTheta;
break;
case MIDDLE:
return mediumTheta;
break;
case LOWER:
return lowerTheta;
break;
case MERGED:
return mergedTheta;
break;
default:
assert(0);
}
}
/*-------------------------------------------------------------------------*/
int getFMdim(int which)
{
switch (which) {
case UPPER:
return nUpper;
break;
case MIDDLE:
return nMedium;
break;
case LOWER:
return nLower;
break;
case MERGED:
return nMerged;
break;
case TIMEBIN:
return timeBin;
break;
default:
assert(0);
}
}
/*---------------------------------------------------------------------*/
int InstallFocusMerge(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
int status;
char pBueffel[256];
if (argc < 2) {
SCWrite(pCon, "ERROR: Insufficient arguments to InstallFocusMerge",
eError);
return 0;
}
status = initializeFM(argv[1]);
if (!status) {
snprintf(pBueffel, 255, "ERROR: failed to read mergefile %s", argv[1]);
SCWrite(pCon, pBueffel, eError);
return 0;
}
/* Install command */
AddCommand(pSics, "focusmerge", FocusMergeAction, NULL, NULL);
return 1;
}
/*---------------------------------------------------------------------*/
static pNXScript checkNXScript(SicsInterp * pSics, char *name)
{
pNXScript result = NULL;
result = FindCommandData(pSics, name, "NXScript");
if (result == NULL) {
return NULL;
}
if (result->fileHandle == NULL || result->dictHandle == NULL) {
return NULL;
}
return result;
}
/*---------------------------------------------------------------------*/
static int updateHMFMData(SicsInterp * pSics, SConnection * pCon)
{
int status, iTime;
const float *fTimeBin = NULL;
HistInt *data = NULL;
pHistMem pMem = NULL;
pMem = (pHistMem) FindHM(pSics, "hm2");
if (pMem == NULL) {
return 0;
}
fTimeBin = GetHistTimeBin(pMem, &iTime);
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, MIDDLE);
pMem = (pHistMem) FindHM(pSics, "hm1");
if (pMem == NULL) {
return 0;
}
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, LOWER);
pMem = (pHistMem) FindHM(pSics, "hm3");
if (pMem == NULL) {
return 0;
}
setFMDataPointer(GetHistogramPointer(pMem, pCon), iTime, UPPER);
setFMconfiguration(1, 1, 1);
return 1;
}
/*-------------------------------------------------------------------*/
static int *calculateDetSum(HistInt * data, int iDet, int iTime)
{
int i, j, iIndex;
int *sum = NULL;
sum = (int *) malloc(iDet * sizeof(int));
if (!sum) {
return NULL;
}
memset(sum, 0, iDet * sizeof(int));
for (i = 0; i < iDet; i++) {
iIndex = i * iTime;
for (j = 0; j < iTime; j++) {
sum[i] += data[iIndex + j];
}
}
return sum;
}
/*-------------------------------------------------------------------*/
static int *calculateTimeSum(HistInt * data, int iDet, int iTime)
{
int i, j;
int *sum = NULL;
if(data == NULL){
return NULL;
}
sum = (int *) malloc(iTime * sizeof(int));
if (!sum) {
return NULL;
}
memset(sum, 0, iTime * sizeof(int));
for (i = 0; i < iTime; i++) {
for (j = 0; j < iDet; j++) {
sum[i] += data[j * iTime + i];
}
}
return sum;
}
/*--------------------------------------------------------------------*/
static void checkSum(HistInt * sum, int iDet, char *name,
SConnection * pCon)
{
int i, count;
char pBueffel[256];
for (i = 0, count = 0; i < iDet; i++) {
if (sum[i] == 0) {
count++;
}
}
if (count == iDet || count == 0) {
return;
}
snprintf(pBueffel, 255,
"WARNING: %d of %d detectors in bank %s are empty", count, iDet,
name);
SCWrite(pCon, pBueffel, eWarning);
}
/*---------------------------------------------------------------------*/
static int putSum(SicsInterp * pSics, SConnection * pCon,
pNXScript nxscript, char *name, char *alias)
{
HistInt *data = NULL;
HistInt *sum = NULL;
int iDet, iTime, i, j, iIndex, status;
iTime = getFMdim(TIMEBIN);
if (strcmp(name, "upper") == 0) {
iDet = getFMdim(UPPER);
data = getFMBankPointer(UPPER);
} else if (strcmp(name, "middle") == 0) {
iDet = getFMdim(MIDDLE);
data = getFMBankPointer(MIDDLE);
} else if (strcmp(name, "lower") == 0) {
iDet = getFMdim(LOWER);
data = getFMBankPointer(LOWER);
} else if (strcmp(name, "merged") == 0) {
iDet = getFMdim(MERGED);
data = getFMBankPointer(MERGED);
} else {
SCWrite(pCon, "ERROR: detector bank to sum not recognised", eError);
return NX_ERROR;
}
sum = calculateDetSum(data, iDet, iTime);
if (!sum) {
SCWrite(pCon, "ERROR: out of memory summing bank", eError);
return NX_ERROR;
}
checkSum(sum, iDet, name, pCon);
status = NXDputalias(nxscript->fileHandle, nxscript->dictHandle,
alias, sum);
free(sum);
return status;
}
/*---------------------------------------------------------------------*/
static int TOFLambda(SicsInterp * pSics, SConnection * pCon,
int argc, char *argv[])
{
int status, iTime, iDet, i;
const float *fTimeBin = NULL;
int *sum = NULL;
long *lSum = NULL;
pHistMem pMem = NULL;
float fCenter, fFWHM, fStdDev, fVal;
float fMon, fData, distMonoDet, distFermiDet, tdiff, lambda;
pMem = (pHistMem) FindHM(pSics, "hm1");
if (pMem == NULL) {
SCWrite(pCon,
"ERROR: need lower detector bank for lambda calculation",
eError);
return 0;
}
/**
* locate elastic position in data
*/
fTimeBin = GetHistTimeBin(pMem, &iTime);
iDet = getFMdim(LOWER);
sum = calculateTimeSum(GetHistogramPointer(pMem, pCon), iDet, iTime);
if (!sum) {
SCWrite(pCon, "ERROR: out of memory calculating lambda", eError);
return 0;
}
if (fitter == NULL) {
fitter = CreateFitCenter(NULL);
if (!fitter) {
SCWrite(pCon, "ERROR: cannot allocate fitting structure", eError);
return 0;
}
}
/*
copy sum to make compiler happy
*/
lSum = (long *) malloc(iTime * sizeof(long));
if (lSum == NULL) {
SCWrite(pCon, "ERROR: out of memory in TOFLambda", eError);
free(sum);
return 0;
}
for (i = 0; i < iTime; i++) {
lSum[i] = sum[i];
}
status = CalculateFitFromData(fitter, (float *) fTimeBin, lSum, iTime);
if (status < 0) {
SCWrite(pCon, "ERROR: no peak in data", eError);
free(sum);
free(lSum);
return 0;
}
GetFitResults(fitter, &fCenter, &fStdDev, &fFWHM, &fVal);
fData = fCenter;
/*
* locate elastic position in tofmon
*/
GetHistogram(pMem, pCon, 0, iTime * iDet, iTime * (iDet + 1),
sum, iTime * sizeof(HistInt));
for (i = 0; i < iTime; i++) {
lSum[i] = sum[i];
}
status = CalculateFitFromData(fitter, (float *) fTimeBin, lSum, iTime);
GetFitResults(fitter, &fCenter, &fStdDev, &fFWHM, &fVal);
fMon = fCenter;
free(sum);
free(lSum);
/*
* calculate
*/
distFermiDet = 3000.;
distMonoDet = distFermiDet - 215.7;
tdiff = fData - fMon;
lambda = tdiff / (252.78 * distMonoDet * .001);
SCPrintf(pCon, eValue, "toflambda = %f", lambda);
return 1;
}
/*---------------------------------------------------------------------*/
static float calcElastic(SicsInterp * pSics, SConnection * pCon)
{
int status, iTime, iDet, i;
const float *fTimeBin = NULL;
int *sum = NULL;
long *lSum = NULL;
pHistMem pMem = NULL;
float fCenter, fFWHM, fStdDev, fVal;
pMem = (pHistMem) FindHM(pSics, "hm2");
if (pMem == NULL) {
SCWrite(pCon,
"ERROR: need middle detector bank for elastic peak calculation",
eError);
return -1.;
}
fTimeBin = GetHistTimeBin(pMem, &iTime);
iDet = getFMdim(MIDDLE);
sum = calculateTimeSum(GetHistogramPointer(pMem, pCon), iDet, iTime);
if (!sum) {
SCWrite(pCon, "ERROR: out of memory calculating elastic peak position",
eError);
return -1;
}
if (fitter == NULL) {
fitter = CreateFitCenter(NULL);
if (!fitter) {
SCWrite(pCon, "ERROR: cannot allocate fitting structure", eError);
return -1.;
}
}
/*
copy sum to make compiler happy
*/
lSum = (long *) malloc(iTime * sizeof(long));
if (lSum == NULL) {
SCWrite(pCon, "ERROR: out of memory in putElastic", eError);
free(sum);
return -1.;
}
for (i = 0; i < iTime; i++) {
lSum[i] = sum[i];
}
status = CalculateFitFromData(fitter, (float *) fTimeBin, lSum, iTime);
free(lSum);
GetFitResults(fitter, &fCenter, &fStdDev, &fFWHM, &fVal);
free(sum);
return fCenter;
}
/*---------------------------------------------------------------------*/
#define ABS(x) (x < 0 ? -(x) : (x))
static int putElastic(SicsInterp * pSics, SConnection * pCon,
pNXScript pNexus, char *alias, float fElastic)
{
float fCalc;
int status;
fCalc = calcElastic(pSics, pCon);
if (ABS(fElastic - fCalc) < 20) {
fElastic = fCalc;
}
status = NXDputalias(pNexus->fileHandle, pNexus->dictHandle, alias,
&fElastic);
return status;
}
/*----------------------------------------------------------------------*/
static int FMputTTH(SConnection * pCon, int argc, char *argv[])
{
pSICSData data = NULL;
int length = -1, i;
float *tthData = NULL;
if (argc < 4) {
SCWrite(pCon, "ERROR: insufficient no of arguments to FMputTTH",
eError);
return 0;
}
data = (pSICSData) FindCommandData(pServ->pSics, argv[3], "SICSData");
if (data == NULL) {
SCWrite(pCon, "ERROR: SICSData object not found", eError);
return 0;
}
if (strcmp(argv[2], "upper") == 0) {
length = getFMdim(UPPER);
tthData = getFMBankTheta(UPPER);
} else if (strcmp(argv[2], "middle") == 0) {
length = getFMdim(MIDDLE);
tthData = getFMBankTheta(MIDDLE);
} else if (strcmp(argv[2], "lower") == 0) {
length = getFMdim(LOWER);
tthData = getFMBankTheta(LOWER);
} else if (strcmp(argv[2], "merged") == 0) {
length = getFMdim(MERGED);
tthData = getFMBankTheta(MERGED);
} else {
SCWrite(pCon, "ERROR: requested two_theta for invalid detector bank",
eError);
return 0;
}
if (length < 0 || tthData == NULL) {
SCWrite(pCon, "ERROR: requested two_theta for invalid detector bank",
eError);
return 0;
}
clearSICSData(data);
for (i = 0; i < length; i++) {
setSICSDataFloat(data, i, tthData[i]);
}
SCSendOK(pCon);
return 1;
}
/*---------------------------------------------------------------------*/
static int FMcopyMerged(SConnection * pCon, int argc, char *argv[])
{
pSICSData data = NULL;
int i, length;
HistInt *hmData = NULL;
if (argc < 3) {
SCWrite(pCon, "ERROR: insufficient no of arguments to FMcopyMerged",
eError);
return 0;
}
data = (pSICSData) FindCommandData(pServ->pSics, argv[2], "SICSData");
if (data == NULL) {
SCWrite(pCon, "ERROR: SICSData object not found", eError);
return 0;
}
if (!updateHMFMData(pServ->pSics, pCon)) {
SCWrite(pCon,
"ERROR: not enough HM's to merge or bad names in fomerge.c",
eError);
return 0;
}
clearSICSData(data);
length = getFMdim(MERGED) * getFMdim(TIMEBIN);
hmData = getFMBankPointer(MERGED);
if (hmData == NULL) {
SCWrite(pCon, "ERROR: merged data not available", eError);
return 0;
}
for (i = 0; i < length; i++) {
setSICSDataInt(data, i, hmData[i]);
}
SCSendOK(pCon);
return 1;
}
/*---------------------------------------------------------------------*/
static int FMcopyMergedSum(SConnection * pCon, int argc, char *argv[])
{
pSICSData data = NULL;
int i, length, tbin, j, row;
HistInt *hmData = NULL, *sumData = NULL;
if (argc < 3) {
SCWrite(pCon, "ERROR: insufficient no of arguments to FMcopyMerged",
eError);
return 0;
}
data = (pSICSData) FindCommandData(pServ->pSics, argv[2], "SICSData");
if (data == NULL) {
SCWrite(pCon, "ERROR: SICSData object not found", eError);
return 0;
}
if (!updateHMFMData(pServ->pSics, pCon)) {
SCWrite(pCon,
"ERROR: not enough HM's to merge or bad names in fomerge.c",
eError);
return 0;
}
clearSICSData(data);
length = getFMdim(MERGED);
tbin = getFMdim(TIMEBIN);
hmData = getFMBankPointer(MERGED);
if (hmData == NULL) {
SCWrite(pCon, "ERROR: merged data not available", eError);
return 0;
}
sumData = malloc(tbin * sizeof(int));
if (sumData == NULL) {
SCWrite(pCon, "ERROR: out-of-memory in FMcopyMergedSum", eError);
return 0;
}
memset(sumData, 0, tbin * sizeof(int));
for (j = 0; j < length; j++) {
row = j * tbin;
for (i = 0; i < tbin; i++) {
sumData[i] += hmData[row + i];
}
}
for (i = 0; i < tbin; i++) {
setSICSDataInt(data, i, sumData[i]);
}
free(sumData);
SCSendOK(pCon);
return 1;
}
/*-----------------------------------------------------------------------
Usage:
focusmerge puttwotheta nxscriptmod bankname alias
focusmerge puttth bankname sicsdataname
focusmerge copymerged sicsdataname
focusmerge copymergedsum sicsdataname
focusmerge putmerged nxscriptmod alias
focusmerge putsum nxscriptmod bankname alias
focusmerge putelastic nxscriptmod alias theoelastic
focusmerge toflambda
focusmerge elastic
nxscriptmod = name of the nxscript module used for writing, must be open
alias = The alias under which to write the data item
theoelastic = theoretical elastic peak position
------------------------------------------------------------------------*/
int FocusMergeAction(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
int status;
pNXScript pNexus = NULL;
float fElastic;
char pNum[20];
if (argc < 2) {
SCWrite(pCon, "ERROR: Insufficient arguments to focusmerge", eError);
return 0;
}
strtolower(argv[1]);
if (strcmp(argv[1], "puttth") == 0) {
return FMputTTH(pCon, argc, argv);
}
if (strcmp(argv[1], "copymerged") == 0) {
return FMcopyMerged(pCon, argc, argv);
}
if (strcmp(argv[1], "copymergedsum") == 0) {
return FMcopyMergedSum(pCon, argc, argv);
}
if (strcmp(argv[1], "toflambda") == 0) {
return TOFLambda(pSics, pCon, argc, argv);
}
if (strcmp(argv[1], "elastic") == 0) {
fElastic = calcElastic(pSics, pCon);
SCPrintf(pCon, eValue, "tofelastic = %f", fElastic);
return 1;
}
if (strcmp(argv[1], "puttwotheta") == 0) {
if (argc < 4) {
SCWrite(pCon,
"ERROR: Insufficient arguments to focusmerge puttwotheta",
eError);
return 0;
}
pNexus = checkNXScript(pSics, argv[2]);
if (pNexus == NULL) {
SCWrite(pCon, "ERROR: bad nxscript name or NeXus file not open",
eError);
return 0;
}
strtolower(argv[3]);
if (strcmp(argv[3], "upper") == 0) {
status = NXDputalias(pNexus->fileHandle, pNexus->dictHandle,
argv[4], getFMBankTheta(UPPER));
} else if (strcmp(argv[3], "middle") == 0) {
status = NXDputalias(pNexus->fileHandle, pNexus->dictHandle,
argv[4], getFMBankTheta(MIDDLE));
} else if (strcmp(argv[3], "lower") == 0) {
status = NXDputalias(pNexus->fileHandle, pNexus->dictHandle,
argv[4], getFMBankTheta(LOWER));
} else if (strcmp(argv[3], "merged") == 0) {
status = NXDputalias(pNexus->fileHandle, pNexus->dictHandle,
argv[4], getFMBankTheta(MERGED));
} else {
SCWrite(pCon, "ERROR: requested two_theta for invalid detector bank",
eError);
return 0;
}
if (status == NX_OK) {
SCSendOK(pCon);
return 1;
} else {
SCWrite(pCon, "ERROR: failed to write two theta array to file",
eError);
return 0;
}
} else if (strcmp(argv[1], "putmerged") == 0) {
if (argc < 4) {
SCWrite(pCon, "ERROR: Insufficient arguments to focusmerge", eError);
return 0;
}
pNexus = checkNXScript(pSics, argv[2]);
if (pNexus == NULL) {
SCWrite(pCon, "ERROR: bad nxscript name or NeXus file not open",
eError);
return 0;
}
if (!updateHMFMData(pSics, pCon)) {
SCWrite(pCon,
"ERROR: not enough HM's to merge or bad names in fomerge.c",
eError);
return 0;
}
snprintf(pNum, 19, "%d", getFMdim(MERGED));
NXDupdate(pNexus->dictHandle, "noofdetectors", pNum);
snprintf(pNum, 19, "%d", getFMdim(TIMEBIN));
NXDupdate(pNexus->dictHandle, "timebin", pNum);
status = NXDputalias(pNexus->fileHandle, pNexus->dictHandle,
argv[3], getFMBankPointer(MERGED));
if (status == NX_OK) {
SCSendOK(pCon);
return 1;
} else {
SCWrite(pCon, "ERROR: failed to write merged data to file", eError);
return 0;
}
} else if (strcmp(argv[1], "putsum") == 0) {
if (argc < 4) {
SCWrite(pCon, "ERROR: Insufficient arguments to focusmerge putsum",
eError);
return 0;
}
pNexus = checkNXScript(pSics, argv[2]);
if (pNexus == NULL) {
SCWrite(pCon, "ERROR: bad nxscript name or NeXus file not open",
eError);
return 0;
}
updateHMFMData(pSics, pCon);
status = putSum(pSics, pCon, pNexus, argv[3], argv[4]);
if (status == NX_OK) {
SCSendOK(pCon);
return 1;
} else {
SCWrite(pCon, "ERROR: failed to write summed data to file", eError);
return 0;
}
} else if (strcmp(argv[1], "putelastic") == 0) {
if (argc < 4) {
SCWrite(pCon,
"ERROR: Insufficient arguments to focusmerge putelastic",
eError);
return 0;
}
pNexus = checkNXScript(pSics, argv[2]);
if (pNexus == NULL) {
SCWrite(pCon, "ERROR: bad nxscript name or NeXus file not open",
eError);
return 0;
}
fElastic = atof(argv[4]);
status = putElastic(pSics, pCon, pNexus, argv[3], fElastic);
if (status == NX_OK) {
SCSendOK(pCon);
return 1;
} else {
SCWrite(pCon, "ERROR: failed to write elastic peak position",
eError);
return 0;
}
} else {
SCWrite(pCon, "ERROR: subcommand to focusmerge not understood",
eError);
return 0;
}
return 0;
}