Files
sics/fomerge.c
cvs f3853c20f0 - Fixed bug with ECB not stopping when no beam
- Fixed synchronisation issues
- Fixed hsitogram memory writing from nxscript
- Started module for writing SICS interfaces in Tcl
- Fixed a bug in scan, which allowed to corrupt files
- Fixed memory problems in napi5
2003-05-23 15:06:47 +00:00

407 lines
9.8 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
--------------------------------------------------------------------------*/
#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 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);
}
}