Added support for three detector banks for FOCUS
This commit is contained in:
394
fomerge.c
Normal file
394
fomerge.c
Normal file
@ -0,0 +1,394 @@
|
||||
/*---------------------------------------------------------------------------
|
||||
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
|
||||
--------------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include "fortify.h"
|
||||
|
||||
/* change this in line with HistMem.h */
|
||||
typedef int HistInt;
|
||||
|
||||
#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 aand 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 = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
HistInt *dataPtr;
|
||||
|
||||
if(lData == NULL)
|
||||
return 0;
|
||||
|
||||
/* the first set is the medium bank */
|
||||
masterData = dataPtr = lData;
|
||||
if(medium)
|
||||
{
|
||||
mediumData = masterData;
|
||||
}
|
||||
else
|
||||
{
|
||||
mediumData = NULL;
|
||||
}
|
||||
|
||||
/* the next set is the upper bank */
|
||||
if(upper)
|
||||
{
|
||||
upperData = dataPtr + mytimeBins*nMedium;
|
||||
dataPtr = upperData;
|
||||
}
|
||||
else
|
||||
{
|
||||
upperData = NULL;
|
||||
}
|
||||
|
||||
/* the last is the lower bank */
|
||||
if(lower)
|
||||
{
|
||||
lowerData = dataPtr + mytimeBins*nUpper;
|
||||
dataPtr = lowerData;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
assert(mergedData);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user