- Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
This commit is contained in:
550
integrate.c
550
integrate.c
@@ -25,35 +25,34 @@ in between
|
||||
#define LEFT -1
|
||||
#define RIGHT 1
|
||||
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
|
||||
/*----------------- a private data structure to keep track of things ----*/
|
||||
|
||||
typedef struct {
|
||||
long *lCounts;
|
||||
int iCounts;
|
||||
int m;
|
||||
int iLeft;
|
||||
int iMaxCount;
|
||||
int iRight;
|
||||
} IntegData, *pIntegData;
|
||||
|
||||
typedef struct {
|
||||
long *lCounts;
|
||||
int iCounts;
|
||||
int m;
|
||||
int iLeft;
|
||||
int iMaxCount;
|
||||
int iRight;
|
||||
} IntegData, *pIntegData;
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int FindMaxCount(long lCounts[], int iCounts)
|
||||
{
|
||||
int i, iPtr;
|
||||
long l = -100000;
|
||||
|
||||
for(i = 0, iPtr = 0; i < iCounts;i++)
|
||||
{
|
||||
if(lCounts[i] > l)
|
||||
{
|
||||
l = lCounts[i];
|
||||
iPtr = i;
|
||||
}
|
||||
}
|
||||
return iPtr;
|
||||
}
|
||||
static int FindMaxCount(long lCounts[], int iCounts)
|
||||
{
|
||||
int i, iPtr;
|
||||
long l = -100000;
|
||||
|
||||
for (i = 0, iPtr = 0; i < iCounts; i++) {
|
||||
if (lCounts[i] > l) {
|
||||
l = lCounts[i];
|
||||
iPtr = i;
|
||||
}
|
||||
}
|
||||
return iPtr;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
Finds the index where the counts are less then half peak height. Assumes
|
||||
that iMaxCount has been set to a proper value beforehand. This helps to
|
||||
@@ -63,291 +62,262 @@ in between
|
||||
from there. Saves calculation time as well. FindHalf returns an index on
|
||||
success, else - 1 if it goes beyond limits!
|
||||
-----------------------------------------------------------------------*/
|
||||
static int FindHalf(pIntegData self, int iSign)
|
||||
{
|
||||
int i;
|
||||
long lHalf;
|
||||
|
||||
assert(self);
|
||||
|
||||
lHalf = self->lCounts[self->iMaxCount]/2;
|
||||
i = self->iMaxCount;
|
||||
while(self->lCounts[i] > lHalf)
|
||||
{
|
||||
i += iSign;
|
||||
if( (i < 0) || (i > self->iCounts) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
static int FindHalf(pIntegData self, int iSign)
|
||||
{
|
||||
int i;
|
||||
long lHalf;
|
||||
|
||||
assert(self);
|
||||
|
||||
lHalf = self->lCounts[self->iMaxCount] / 2;
|
||||
i = self->iMaxCount;
|
||||
while (self->lCounts[i] > lHalf) {
|
||||
i += iSign;
|
||||
if ((i < 0) || (i > self->iCounts)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
FindWindowHits find the number of hits in the window defined by
|
||||
0.67 sigma of the value at iPos and m. Returns -1 if insufficient data
|
||||
is available to do the trick. iSign can be -1 for search to left or
|
||||
1 for search to right.
|
||||
---------------------------------------------------------------------------*/
|
||||
static int FindWindowHits(pIntegData self, int iPos, int iSign)
|
||||
{
|
||||
float fWinMin, fWinMax, fVar;
|
||||
int i, iTest, iCount;
|
||||
|
||||
assert(self);
|
||||
assert( (iSign == -1) || (iSign == 1) );
|
||||
|
||||
/* check limits of the show */
|
||||
iTest = iPos + iSign * self->m;
|
||||
if( (iTest < 0) || (iTest >= self->iCounts) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* calculate limits */
|
||||
if(self->lCounts[iPos] > 0)
|
||||
{
|
||||
fVar = sqrt((double)self->lCounts[iPos]);
|
||||
fWinMin = (float)self->lCounts[iPos] - 0.67 * fVar;
|
||||
fWinMax = (float)self->lCounts[iPos] + 0.67 * fVar;
|
||||
}
|
||||
else
|
||||
{
|
||||
fWinMin = 0.;
|
||||
fWinMax = 1.;
|
||||
}
|
||||
|
||||
/* count the window hits */
|
||||
for(i = 0, iCount = 0; i < self->m; i++)
|
||||
{
|
||||
iTest = iPos + iSign * i;
|
||||
if( (self->lCounts[iTest] >= fWinMin) &&
|
||||
(self->lCounts[iTest] <= fWinMax) )
|
||||
{
|
||||
iCount++;
|
||||
}
|
||||
}
|
||||
return iCount;
|
||||
}
|
||||
---------------------------------------------------------------------------*/
|
||||
static int FindWindowHits(pIntegData self, int iPos, int iSign)
|
||||
{
|
||||
float fWinMin, fWinMax, fVar;
|
||||
int i, iTest, iCount;
|
||||
|
||||
assert(self);
|
||||
assert((iSign == -1) || (iSign == 1));
|
||||
|
||||
/* check limits of the show */
|
||||
iTest = iPos + iSign * self->m;
|
||||
if ((iTest < 0) || (iTest >= self->iCounts)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* calculate limits */
|
||||
if (self->lCounts[iPos] > 0) {
|
||||
fVar = sqrt((double) self->lCounts[iPos]);
|
||||
fWinMin = (float) self->lCounts[iPos] - 0.67 * fVar;
|
||||
fWinMax = (float) self->lCounts[iPos] + 0.67 * fVar;
|
||||
} else {
|
||||
fWinMin = 0.;
|
||||
fWinMax = 1.;
|
||||
}
|
||||
|
||||
/* count the window hits */
|
||||
for (i = 0, iCount = 0; i < self->m; i++) {
|
||||
iTest = iPos + iSign * i;
|
||||
if ((self->lCounts[iTest] >= fWinMin) &&
|
||||
(self->lCounts[iTest] <= fWinMax)) {
|
||||
iCount++;
|
||||
}
|
||||
}
|
||||
return iCount;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
AdvanceBackground advances in the background until the predefined
|
||||
Probability has been reached. The probability is defined at the top
|
||||
of the file. iSign and errors are the same as above.
|
||||
----------------------------------------------------------------------------*/
|
||||
static int AdvanceBackground(pIntegData self, int iPos, int iSign)
|
||||
{
|
||||
float fProb;
|
||||
int iRet, iTest;
|
||||
|
||||
assert(self);
|
||||
assert( (iSign == 1) || (iSign == -1) );
|
||||
|
||||
/* initialize, calculate initial Probability */
|
||||
iRet = FindWindowHits(self,iPos,iSign);
|
||||
if(iRet < 0)
|
||||
{
|
||||
return iRet;
|
||||
}
|
||||
fProb = (self->m - iRet)/self->m;
|
||||
iTest = iPos;
|
||||
|
||||
/* loop further on */
|
||||
while(fProb > PROBABILITY)
|
||||
{
|
||||
iTest += iSign;
|
||||
iRet = FindWindowHits(self,iTest,iSign);
|
||||
if(iRet < 0)
|
||||
{
|
||||
return iRet;
|
||||
}
|
||||
fProb *= (self->m - iRet)/self->m;
|
||||
}
|
||||
|
||||
if( (iTest < 0) || (iTest >= self->iCounts) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return iTest;
|
||||
}
|
||||
}
|
||||
----------------------------------------------------------------------------*/
|
||||
static int AdvanceBackground(pIntegData self, int iPos, int iSign)
|
||||
{
|
||||
float fProb;
|
||||
int iRet, iTest;
|
||||
|
||||
assert(self);
|
||||
assert((iSign == 1) || (iSign == -1));
|
||||
|
||||
/* initialize, calculate initial Probability */
|
||||
iRet = FindWindowHits(self, iPos, iSign);
|
||||
if (iRet < 0) {
|
||||
return iRet;
|
||||
}
|
||||
fProb = (self->m - iRet) / self->m;
|
||||
iTest = iPos;
|
||||
|
||||
/* loop further on */
|
||||
while (fProb > PROBABILITY) {
|
||||
iTest += iSign;
|
||||
iRet = FindWindowHits(self, iTest, iSign);
|
||||
if (iRet < 0) {
|
||||
return iRet;
|
||||
}
|
||||
fProb *= (self->m - iRet) / self->m;
|
||||
}
|
||||
|
||||
if ((iTest < 0) || (iTest >= self->iCounts)) {
|
||||
return -1;
|
||||
} else {
|
||||
return iTest;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
FindLimit assumes, that iMaxCount has been set to something sensible
|
||||
in advance!
|
||||
--------------------------------------------------------------------------*/
|
||||
static int FindLimit(pIntegData self, int iStart, int iSign)
|
||||
{
|
||||
int i, iHalf, iHit, iLeft, iTest;
|
||||
|
||||
assert(self);
|
||||
assert( (iSign == 1) || (iSign == -1) );
|
||||
|
||||
iHit = 0;
|
||||
iHalf = self->m/2;
|
||||
i = iStart;
|
||||
|
||||
/* loop until iHalf is reached */
|
||||
while((iHit = FindWindowHits(self,i,iSign)) < iHalf)
|
||||
{
|
||||
i += iSign;
|
||||
if(iHit < 0)
|
||||
{
|
||||
if(iSign == LEFT)
|
||||
{
|
||||
return INTEGLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return INTEGRIGHT;
|
||||
}
|
||||
}
|
||||
--------------------------------------------------------------------------*/
|
||||
static int FindLimit(pIntegData self, int iStart, int iSign)
|
||||
{
|
||||
int i, iHalf, iHit, iLeft, iTest;
|
||||
|
||||
assert(self);
|
||||
assert((iSign == 1) || (iSign == -1));
|
||||
|
||||
iHit = 0;
|
||||
iHalf = self->m / 2;
|
||||
i = iStart;
|
||||
|
||||
/* loop until iHalf is reached */
|
||||
while ((iHit = FindWindowHits(self, i, iSign)) < iHalf) {
|
||||
i += iSign;
|
||||
if (iHit < 0) {
|
||||
if (iSign == LEFT) {
|
||||
return INTEGLEFT;
|
||||
} else {
|
||||
return INTEGRIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/* step further into the backgound */
|
||||
iTest = AdvanceBackground(self,i,iSign);
|
||||
if(iTest < 0)
|
||||
{
|
||||
if(iSign == LEFT)
|
||||
{
|
||||
return INTEGLEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return INTEGRIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/* store it away and return success */
|
||||
if(iSign == LEFT)
|
||||
{
|
||||
self->iLeft = iTest;
|
||||
}
|
||||
else
|
||||
{
|
||||
self->iRight = iTest;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* step further into the backgound */
|
||||
iTest = AdvanceBackground(self, i, iSign);
|
||||
if (iTest < 0) {
|
||||
if (iSign == LEFT) {
|
||||
return INTEGLEFT;
|
||||
} else {
|
||||
return INTEGRIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/* store it away and return success */
|
||||
if (iSign == LEFT) {
|
||||
self->iLeft = iTest;
|
||||
} else {
|
||||
self->iRight = iTest;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
This routine does the actual integration once the limits have been
|
||||
determined.
|
||||
--------------------------------------------------------------------------*/
|
||||
static int DoIntegrate(pIntegData self, float *fSum, float *fVariance)
|
||||
{
|
||||
long lLeftBack, lRightBack, lBackMean;
|
||||
int i,iRes = 1;
|
||||
float fScan, fBackVar,fLeft, fRight, fN, fNP, fNB, fSumm;
|
||||
float fMLeft, fMRight;
|
||||
|
||||
assert(self);
|
||||
assert( (self->iLeft != 0) && (self->iRight != 0) );
|
||||
|
||||
|
||||
/* sum the left background */
|
||||
for(i = 0, lLeftBack = 0; i < self->iLeft; i++)
|
||||
{
|
||||
lLeftBack += self->lCounts[i];
|
||||
}
|
||||
lLeftBack = lLeftBack;
|
||||
|
||||
/* sum the right background */
|
||||
for(i = self->iRight, lRightBack = 0; i < self->iCounts; i++)
|
||||
{
|
||||
lRightBack += self->lCounts[i];
|
||||
}
|
||||
lRightBack = lRightBack;
|
||||
|
||||
|
||||
/* sum all of it */
|
||||
fScan = 0.;
|
||||
for(i = 0; i < self->iCounts; i++)
|
||||
{
|
||||
fScan += self->lCounts[i];
|
||||
}
|
||||
--------------------------------------------------------------------------*/
|
||||
static int DoIntegrate(pIntegData self, float *fSum, float *fVariance)
|
||||
{
|
||||
long lLeftBack, lRightBack, lBackMean;
|
||||
int i, iRes = 1;
|
||||
float fScan, fBackVar, fLeft, fRight, fN, fNP, fNB, fSumm;
|
||||
float fMLeft, fMRight;
|
||||
|
||||
/* sum the peak */
|
||||
fSumm = 0.;
|
||||
for(i = self->iLeft; i < self->iRight +1; i++)
|
||||
{
|
||||
fSumm += (float)self->lCounts[i];
|
||||
}
|
||||
|
||||
/* calculate the values */
|
||||
fLeft = (float)self->iLeft;
|
||||
fRight = (float)self->iRight;
|
||||
fN = (float)self->iCounts;
|
||||
|
||||
fNP = fRight - fLeft + 1.;
|
||||
fNB = fLeft + (fN - fRight);
|
||||
|
||||
*fSum = fSumm - (fNP/fNB)*((float)lLeftBack + (float)lRightBack);
|
||||
*fVariance = sqrt(fSumm + (fNP/fNB)*(fNP/fNB)*((float)lLeftBack
|
||||
+ (float)lRightBack));
|
||||
|
||||
/* check the background */
|
||||
fMLeft = lLeftBack/fLeft;
|
||||
fMRight = lRightBack/fRight;
|
||||
if(ABS(fMLeft - fMRight) > ((fMLeft + fMRight)/2) )
|
||||
{
|
||||
iRes = INTEGFUNNYBACK;
|
||||
}
|
||||
assert(self);
|
||||
assert((self->iLeft != 0) && (self->iRight != 0));
|
||||
|
||||
return iRes;
|
||||
|
||||
/* sum the left background */
|
||||
for (i = 0, lLeftBack = 0; i < self->iLeft; i++) {
|
||||
lLeftBack += self->lCounts[i];
|
||||
}
|
||||
lLeftBack = lLeftBack;
|
||||
|
||||
/* sum the right background */
|
||||
for (i = self->iRight, lRightBack = 0; i < self->iCounts; i++) {
|
||||
lRightBack += self->lCounts[i];
|
||||
}
|
||||
lRightBack = lRightBack;
|
||||
|
||||
|
||||
/* sum all of it */
|
||||
fScan = 0.;
|
||||
for (i = 0; i < self->iCounts; i++) {
|
||||
fScan += self->lCounts[i];
|
||||
}
|
||||
|
||||
/* sum the peak */
|
||||
fSumm = 0.;
|
||||
for (i = self->iLeft; i < self->iRight + 1; i++) {
|
||||
fSumm += (float) self->lCounts[i];
|
||||
}
|
||||
|
||||
/* calculate the values */
|
||||
fLeft = (float) self->iLeft;
|
||||
fRight = (float) self->iRight;
|
||||
fN = (float) self->iCounts;
|
||||
|
||||
fNP = fRight - fLeft + 1.;
|
||||
fNB = fLeft + (fN - fRight);
|
||||
|
||||
*fSum = fSumm - (fNP / fNB) * ((float) lLeftBack + (float) lRightBack);
|
||||
*fVariance = sqrt(fSumm + (fNP / fNB) * (fNP / fNB) * ((float) lLeftBack
|
||||
+
|
||||
(float)
|
||||
lRightBack));
|
||||
|
||||
/* check the background */
|
||||
fMLeft = lLeftBack / fLeft;
|
||||
fMRight = lRightBack / fRight;
|
||||
if (ABS(fMLeft - fMRight) > ((fMLeft + fMRight) / 2)) {
|
||||
iRes = INTEGFUNNYBACK;
|
||||
}
|
||||
|
||||
return iRes;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int GabePeakIntegrate(int m, int iCounts, long lCounts[],
|
||||
float *fIntens, float *fVariance)
|
||||
{
|
||||
IntegData self;
|
||||
int iTest,i, iStart;
|
||||
|
||||
/* check input */
|
||||
assert(iCounts > 0);
|
||||
assert(lCounts);
|
||||
|
||||
|
||||
/* initialize Data Structure */
|
||||
self.iCounts = iCounts;
|
||||
self.lCounts = lCounts; /* no need to duplicate data */
|
||||
self.iLeft = 0;
|
||||
self.iRight = 0;
|
||||
self.iMaxCount = 0;
|
||||
self.m = m;
|
||||
|
||||
/* find maximum */
|
||||
self.iMaxCount = FindMaxCount(self.lCounts, self.iCounts);
|
||||
|
||||
/* find Left Limit */
|
||||
iStart = FindHalf(&self,LEFT);
|
||||
if(iStart < 0)
|
||||
{
|
||||
return INTEGLEFT;
|
||||
}
|
||||
iTest = FindLimit(&self,iStart,LEFT);
|
||||
if(iTest < 0)
|
||||
{
|
||||
return iTest;
|
||||
}
|
||||
|
||||
/* find right limit */
|
||||
iStart = FindHalf(&self,RIGHT);
|
||||
if(iStart < 0)
|
||||
{
|
||||
return INTEGRIGHT;
|
||||
}
|
||||
iTest = FindLimit(&self,iStart,RIGHT);
|
||||
if(iTest < 0)
|
||||
{
|
||||
return iTest;
|
||||
}
|
||||
int GabePeakIntegrate(int m, int iCounts, long lCounts[],
|
||||
float *fIntens, float *fVariance)
|
||||
{
|
||||
IntegData self;
|
||||
int iTest, i, iStart;
|
||||
|
||||
/* check input */
|
||||
assert(iCounts > 0);
|
||||
assert(lCounts);
|
||||
|
||||
|
||||
/* initialize Data Structure */
|
||||
self.iCounts = iCounts;
|
||||
self.lCounts = lCounts; /* no need to duplicate data */
|
||||
self.iLeft = 0;
|
||||
self.iRight = 0;
|
||||
self.iMaxCount = 0;
|
||||
self.m = m;
|
||||
|
||||
/* find maximum */
|
||||
self.iMaxCount = FindMaxCount(self.lCounts, self.iCounts);
|
||||
|
||||
/* find Left Limit */
|
||||
iStart = FindHalf(&self, LEFT);
|
||||
if (iStart < 0) {
|
||||
return INTEGLEFT;
|
||||
}
|
||||
iTest = FindLimit(&self, iStart, LEFT);
|
||||
if (iTest < 0) {
|
||||
return iTest;
|
||||
}
|
||||
|
||||
/* find right limit */
|
||||
iStart = FindHalf(&self, RIGHT);
|
||||
if (iStart < 0) {
|
||||
return INTEGRIGHT;
|
||||
}
|
||||
iTest = FindLimit(&self, iStart, RIGHT);
|
||||
if (iTest < 0) {
|
||||
return iTest;
|
||||
}
|
||||
#ifdef PRINT
|
||||
printf("Limits: %d %d\n",self.iLeft, self.iRight);
|
||||
for(i = self.iLeft; i < self.iRight; i++)
|
||||
{
|
||||
printf(" %d\n",self.lCounts[i]);
|
||||
}
|
||||
printf("Limits: %d %d\n", self.iLeft, self.iRight);
|
||||
for (i = self.iLeft; i < self.iRight; i++) {
|
||||
printf(" %d\n", self.lCounts[i]);
|
||||
}
|
||||
#endif
|
||||
/* integrate */
|
||||
return DoIntegrate(&self,fIntens, fVariance);
|
||||
|
||||
}
|
||||
/* integrate */
|
||||
return DoIntegrate(&self, fIntens, fVariance);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user