// sets the mean of the columns averages to zero void ComparatorNoiseCorrector::SetMeanToZero(float *inp) { int cndx, frame, comparator; v8f_u dc,framesU; v8f_u *srcPtr; int lw=cols/VEC8_SIZE; framesU.V = LD_VEC8F((float)frames); // get a pointer to where we will build the comparator signal average for (comparator=0;comparator<ncomp;comparator++) { srcPtr=(v8f_u *)(inp + comparator*frames*cols); for (cndx = 0; cndx < lw; cndx++) { dc.V = LD_VEC8F(0.0f); for (frame = 0; frame < frames; frame++) dc.V += srcPtr[lw*frame].V; dc.V /= framesU.V; // subtract dc offset for (frame = 0; frame < frames; frame++) srcPtr[lw*frame].V -= dc.V; srcPtr++; } } }
// accumulate the sum of all traces int PCACompr::AccumulateDotProducts(float *p, float *t, int skip) { v8f sumU0,sumU1,sumU2,sumU3; v8f_u pU,pU0,pU1,pU2,pU3; v8f *trcsV; int pt; int k; int lw=ntrcsL/VEC8_SIZE; // double start = PCATimer(); for (pt=0;pt < npts;pt++) t[pt]=0.0f; for (int itrc=0;itrc < ntrcsL;itrc+=VEC8_SIZE*4*skip) { sumU0=LD_VEC8F(0); sumU1=LD_VEC8F(0); sumU2=LD_VEC8F(0); sumU3=LD_VEC8F(0); trcsV=(v8f *)&TRCS_ACCESS(itrc,0); for (pt=0;pt < npts;pt++,trcsV+=lw) { pU.V=LD_VEC8F(p[pt]); sumU0 += (trcsV[0])*pU.V; sumU1 += (trcsV[1])*pU.V; sumU2 += (trcsV[2])*pU.V; sumU3 += (trcsV[3])*pU.V; } trcsV=(v8f *)&TRCS_ACCESS(itrc,0); for (pt=0;pt < npts;pt++,trcsV+=lw) { pU0.V=sumU0*(trcsV[0]); pU1.V=sumU1*(trcsV[1]); pU2.V=sumU2*(trcsV[2]); pU3.V=sumU3*(trcsV[3]); pU0.V+=pU1.V + pU2.V + pU3.V; for(k=0;k<VEC8_SIZE;k++) t[pt] += pU0.A[k]; } } // parent->timing.Accumulate += PCATimer()-start; return 0; }
void ComparatorNoiseCorrector::HighPassFilter(float *pnn,int n_comparators,int nframes,int span) { //v8f_u* trc_scratch = new v8f_u[nframes]; v8f_u trc_scratch[nframes]; for ( int i=0;i < n_comparators;i+=VEC8_SIZE ) { float *cptr; // get a pointer to the comparator noise signal cptr = pnn + i*nframes; // make smooth version of noise signal for (int j=0;j < nframes;j++) { v8f_u sum; sum.V = LD_VEC8F(0.0f); float cnt=0; for (int idx=(j-span);idx <=(j+span);idx++) { if ((idx >= 0) && (idx < nframes) && (idx!=j)) { for(int k=0;k<VEC8_SIZE;k++) sum.A[k] += cptr[idx+k*nframes]; cnt=cnt+1.0f; } } v8f cntV = LD_VEC8F(cnt); for(int k=0;k<VEC8_SIZE;k++) trc_scratch[j].V = sum.V/cntV; } // now subtract off the smoothed signal to eliminate low frequency // components, most of which are residual background effects that the // neighbor subtraction algorithm doesn't completely fitler out // this unfortunately does also somtimes eliminate some real comparator // noise... for (int j=0;j < nframes;j++) { for(int k=0;k<VEC8_SIZE;k++) cptr[j+k*nframes] -= trc_scratch[j].A[k]; } } }
float PCACompr::SubtractVector(int nvect, int skip) { uint32_t ntrcsLV=ntrcsL/VEC8_SIZE; float ptgv[npts]; float gv[npts]; int pt; for (pt = 0; pt < npts; pt++) gv[pt] = 1.0f; // ComputeEmphasisVector(gv, 2.0f, 1.4f, 10.0f); // ComputeEmphasisVector(gv, 0.0f, 1.0f, 10.0f); { float ssum = 0; for (pt = 0; pt < npts; pt++) { float ptgvv = COEFF_ACCESS(pt,nvect)*gv[pt]; ssum+=ptgvv*ptgvv; } ssum = sqrt(ssum); if(ssum == 0) ssum = 1.0f; // dont divide by 0 for (pt = 0; pt < npts; pt++) ptgv[pt] = ((COEFF_ACCESS(pt,nvect)*gv[pt])/ssum); } for (int itrc=0;itrc < ntrcsL;itrc+=4*VEC8_SIZE*skip) { { v8f *sumPtr=(v8f *)&TRC_COEFF_ACC(nvect,itrc); v8f *trcsUp = (v8f *)&TRCS_ACCESS(itrc,0); v8f sumU0=LD_VEC8F(0); v8f sumU1=LD_VEC8F(0); v8f sumU2=LD_VEC8F(0); v8f sumU3=LD_VEC8F(0); for (int pt=0;pt < npts;pt++) { v8f ptgv_tmp = LD_VEC8F(ptgv[pt]/*COEFF_ACCESS(pt,nvect)*/); sumU0 += trcsUp[0] * ptgv_tmp; sumU1 += trcsUp[1] * ptgv_tmp; sumU2 += trcsUp[2] * ptgv_tmp; sumU3 += trcsUp[3] * ptgv_tmp; trcsUp += ntrcsLV; } trcsUp = (v8f *)&TRCS_ACCESS(itrc,0); for (int pt=0;pt < npts;pt++) { v8f ptgv_tmp = LD_VEC8F(ptgv[pt]/*COEFF_ACCESS(pt,nvect)*/); trcsUp[0] -= sumU0 * ptgv_tmp; trcsUp[1] -= sumU1 * ptgv_tmp; trcsUp[2] -= sumU2 * ptgv_tmp; trcsUp[3] -= sumU3 * ptgv_tmp; trcsUp += ntrcsLV; } sumPtr[0] = sumU0; sumPtr[1] = sumU1; sumPtr[2] = sumU2; sumPtr[3] = sumU3; } } return 0; }
// sum the columns from row_start to row_end and put the answer in mComparator_sigs // mMask has a 1 in it for every active column and a zero for every pinned pixel void ComparatorNoiseCorrector::SumColumns(int row_start, int row_end) { int frame,x,y,comparator; int frameStride=rows*cols; double startTime=CNCTimer(); memset(mAvg_num,0,mAvg_num_len); #ifdef __AVX__ if((cols%VEC8_SIZE) == 0) { int lw=cols/VEC8_SIZE; v8f_u valU; valU.V=LD_VEC8F(0); for (frame = 0; frame < frames; frame++) { for (y = row_start; y < row_end; y++) { comparator = (y - row_start) & 0x3; short int *sptr = &image[frame * frameStride + y * cols]; v8f *dstPtr = (v8f *) (mComparator_sigs + comparator * cols * frames + frame * cols); v8f *sumPtr = (v8f *) (mAvg_num + comparator * cols * frames + frame * cols); v8f *mskPtr = (v8f *) (mMask + cols*y); for (x = 0; x < lw; x++,sptr+=VEC8_SIZE,dstPtr++,sumPtr++,mskPtr++) { LD_VEC8S_CVT_VEC8F(sptr,valU); *dstPtr += valU.V; *sumPtr += *mskPtr; } } } for (frame = 0; frame < frames; frame++) { for (comparator = 0; comparator < 4; comparator++) { float *dstPtr = (float *) (mComparator_sigs + comparator * cols * frames + frame * cols); float *sumPtr = (float *) (mAvg_num + comparator * cols * frames + frame * cols); for (x = 0; x < cols; x++) { float valU = (float)((sumPtr[x])?sumPtr[x]:1); dstPtr[x] /= valU; } } } } else #endif { for (frame = 0; frame < frames; frame++) { for (y = row_start; y < row_end; y++) { comparator = (y - row_start) & 0x3; float valU; short int *srcPtr = (short int *) (&image[frame * frameStride + y * cols]); float *dstPtr = (float *) (mComparator_sigs + comparator * cols * frames + frame * cols); float *sumPtr = (float *) (mAvg_num + comparator * cols); float *mskPtr = (float *) (mMask + cols*y); if(frame==0){ for (x = 0; x < cols; x++) { valU= (float)srcPtr[x]; dstPtr[x] += valU; sumPtr[x] += mskPtr[x]; } } else{ for (x = 0; x < cols; x++) { valU= (float)srcPtr[x]; dstPtr[x] += valU; } } } } for (frame = 0; frame < frames; frame++) { for (comparator = 0; comparator < 4; comparator++) { float *dstPtr = (float *) (mComparator_sigs + comparator * cols * frames + frame * cols); float *sumPtr = (float *) (mAvg_num + comparator * cols); for (x = 0; x < cols; x++) { float valU = (float)((sumPtr[x])?sumPtr[x]:1); dstPtr[x] /= valU; } } } } sumTime += CNCTimer() - startTime; }
// generates a mask of pinned pixels void ComparatorNoiseCorrector::GenerateMask(float *_mask) { int frm,idx; int frameStride=rows*cols; int len=frameStride/VEC8_SIZE; v8f_u *mskPtr,tmp; v8f_u high,low; int cnt=0; mMaskGenerated=1; high.V=LD_VEC8F(16380); low.V=LD_VEC8F(5); // initialize the mask to all 1's tmp.V=LD_VEC8F(1.0f); mskPtr=(v8f_u *)_mask; for(idx=0;idx<len;idx++) mskPtr[idx].V=tmp.V; for(frm=0;frm<frames;frm++) { mskPtr=(v8f_u *)_mask; #if 0//def __AVX__ v8f_u tmpV; uint16_t *src=(uint16_t *)(image + rows*cols*frm); for(idx=0;idx<len;idx++) { LD_VEC8S_CVT_VEC8F(src,tmpV); // now, do the pinned pixel comparisons mskPtr[idx].V += __builtin_ia32_cmpps256(tmpV.V , low.V, _CMP_LT_OS); mskPtr[idx].V += __builtin_ia32_cmpps256(high.V, tmpV.V, _CMP_LT_OS); } #else v8s_u *src=(v8s_u *)(image + rows*cols*frm); for(idx=0;idx<len;idx++) { for(int k=0;k<VEC8_SIZE;k++) { if(src[idx].A[k] >= high.A[k] || low.A[k] >= src[idx].A[k]) mskPtr[idx].A[k]=0; } } #endif } // now, clear all pinned pixels so the column adds will be quick for(idx=0;idx<frameStride;idx++) { if(_mask[idx]==0) { cnt++; // this pixel is pinned.. clear all the frame values for(frm=0;frm<frames;frm++) { image[rows*cols*frm + idx] = 0; } } } // printf("found %d pinned pixels out of %d pixels\n",cnt,frameStride); }