- 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
407 lines
9.8 KiB
C
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);
|
|
}
|
|
}
|
|
|
|
|