void deconvolve( double * mod_p , double * res_p , double * psf_p // not a 'const' because modifies the pad area (zeroes) , int siz , int pitch , unsigned int niters , double gain , double threshold ) { place found_place_psf , found_place_res ; memset(mod_p, 0, siz * pitch * sizeof(double)); findPeak(psf_p, &found_place_psf, siz, pitch); for (unsigned int i = 0; i < niters; ++i) { findPeak(res_p, &found_place_res, siz, pitch); if (abs(found_place_res.val) < threshold) break; subtractPSF(res_p, psf_p, found_place_res.pos, found_place_psf.pos, pitch, found_place_res.val * gain); mod_p[found_place_res.pos] += found_place_res.val * gain; } }
int findPeak(const vector<int> &num, int begin, int end) { if(begin > end) return 0; if(begin == end) return begin; int mid = (begin+end)/2; if ((mid == 0 || num[mid-1] <= num[mid]) && (mid == num.size()-1 || num[mid+1] <= num[mid])) // Compare middle element with its neighbours (if neighbours exist) return mid; else if (mid > 0 && num[mid-1] > num[mid]) // If middle element is not peak and its left neighbor is greater than it // then left half must have a peak element return findPeak(num, begin, mid); else return findPeak(num, mid+1, end); // If middle element is not peak and its right neighbor is greater than it // then right half must have a peak element }
/* Driver program to check above functions */ int main() { int arr[] = {1,4,3,2,1,0,1,4}; int n = sizeof(arr)/sizeof(arr[0]); printf("Index of a peak point is %d", findPeak(arr, n)); return 0; }
void FastMultiScaleClean<ImageSetType>::cleanThreadFunc(ao::lane<CleanTask> *taskLane, ao::lane<CleanResult> *resultLane, CleanThreadData cleanData) { CleanTask task; // This initialization is not really necessary, but gcc warns about possible uninitialized values otherwise task.peak = ImageSetType::Value::Zero(); ImageSetType& imageSet = *cleanData.parent->_dataImageLargeScale; ImageSetType& nextScaleSet = *cleanData.parent->_dataImageNextScale; const std::vector<double*>& psfs = *cleanData.parent->_scaledPsfs; while(taskLane->read(task)) { for(size_t i=0; i!=imageSet.ImageCount(); ++i) { subtractImage(imageSet.GetImage(i), psfs[ImageSetType::PSFIndex(i)], task.cleanCompX, task.cleanCompY, this->_subtractionGain * task.peak.GetValue(i), cleanData.startY, cleanData.endY); } for(size_t i=0; i!=nextScaleSet.ImageCount(); ++i) { subtractImage(nextScaleSet.GetImage(i), psfs[ImageSetType::PSFIndex(i)], task.cleanCompX, task.cleanCompY, this->_subtractionGain * task.peak.GetValue(i), cleanData.startY, cleanData.endY); } CleanResult result; findPeak(result.nextPeakX, result.nextPeakY, cleanData.startY, cleanData.endY); if(result.nextPeakX == _rescaledWidth) result.peakLevelUnnormalized = std::numeric_limits<double>::quiet_NaN(); else result.peakLevelUnnormalized = imageSet.AbsJoinedValue(result.nextPeakX + result.nextPeakY*_rescaledWidth); resultLane->write(result); } }
// The implementation of the QRS flow-chart. Searchers for RPeaks. void qrs(int i, int recursive) { int TIME, PEAK, TYPE = 0, prbool = 0; if(recursive == 0){ peakmem.peaks[mem.index[5]] = findPeak(mem.mwimem[getIndex(3, mem.index[4], -2)], mem.mwimem[getIndex(3, mem.index[4], -1)], mem.mwimem[getIndex(3, mem.index[4], 0)]); peakmem.RR_COUNTER++; } if(mem.mwimem[getIndex(3, mem.index[4], -1)] < peakmem.THRESHOLD1){ bool = 1; }
/*Return the average doppler centroid (in fractional PRF) of inFile using fftLen lines starting at startLine*/ double fftEstDop(getRec *inFile,int startLine,int xStride,int fftLen) { int x,y,i,wid=inFile->nSamples; float *power,peak; complexFloat *in,*fft; /*Allocate arrays.*/ in=(complexFloat *)MALLOC(sizeof(complexFloat)*fftLen*wid); fft=(complexFloat *)MALLOC(sizeof(complexFloat)*fftLen); power=(float *)MALLOC(sizeof(float)*fftLen); /*Set power sum to zero.*/ for (i=0;i<fftLen;i++) power[i]=0; /*Read in fftLen lines of data.*/ for (y=0;y<fftLen;y++) getSignalLine(inFile,startLine+y,&(in[y*wid]),0,wid); /*FFT each column, add to power sum array.*/ cfft1d(fftLen,NULL,0); for (x=0;x<wid;x+=xStride) { for (y=0;y<fftLen;y++) fft[y]=in[y*wid+x]; cfft1d(fftLen,fft,-1); for (i=0;i<fftLen;i++) power[i] += fft[i].real*fft[i].real + fft[i].imag*fft[i].imag; } /*Find peak of azimuth power array-- this is the center of the doppler.*/ power[0]=0.0;/*Zero out DC component (misleading).*/ filter_lowPass(power,fftLen,4);/*Do a low-pass on the power array.*/ peak=findPeak(power,fftLen); if (!quietflag) printf("Peak at %f\n",peak); FREE(in); FREE(fft); FREE(power); return peak/fftLen; }
void findFittingWindow(par * p, const data * d) { int i; if(p->verbose>=0) printf("\nPEAK FINDER\n-----------\n"); peak_search_par pspar; for (i=0;i<p->numSpectra;i++) { pspar.searchMin=p->startCh[i]; pspar.searchMax=p->endCh[i]; pspar.windowSize=(int)(pspar.searchMax-pspar.searchMin)/10; peak_fit_par pfpar = findPeak(&pspar, d->expHist[p->spectrum[i]], S32K); if(p->verbose>=0) printf("Spectrum %i: peak found with centroid at channel %i.\n",i,(int)pfpar.centroid); int range=abs(pspar.searchMax-pspar.searchMin); if(p->peakSearchWidth>0) range=p->peakSearchWidth; p->startCh[i]=pfpar.centroid-(int)(range/2); p->endCh[i]=pfpar.centroid+(int)(range/2); } if(p->verbose>=0) printf("Fit window(s) centered on peak(s)...\n"); }
int findPeakElement(const vector<int> &num) { if(num.empty()) return 0; int n = num.size(); return findPeak(num, 0, n-1); }
int main() { DDRB |= _BV(5); PORTB &= ~_BV(5); ///////////////////////////// // Set up the analogue input setupAdcOnPin(0); adcStartConversion(); // Start ADC measurement pulseSetFrameBuffer(frameBuffer, NUM_LEDS); const uint8_t pulseCount = 10; uint8_t pulseIdx = 0; struct cPulse pulses[pulseCount]; memset(pulses, 0, sizeof(struct cPulse) * pulseCount); for (int i = 0; i < pulseCount; i += 2) { pulses[i].direction = 1; } uint8_t sampleHistory[HISTORY_COUNT]; memset(sampleHistory, 0, HISTORY_COUNT); int8_t startingPosition = 0; while(1) { ++toggle; toggle = toggle % 50; setIndicator(toggle == 0); // Hist = = = = = // Wind - - // Copy - - for (int i = 0; i < (HISTORY_COUNT - WINDOW_SIZE); ++i) { sampleHistory[i] = sampleHistory[i + WINDOW_SIZE]; } for (int i = 0; i < WINDOW_SIZE; ++i) { adcStartConversion(); _delay_us(500); adcWaitReady(); sampleHistory[WINDOW_START + i] = ADCH; } uint8_t historicalPeak = findPeak(sampleHistory, 0, WINDOW_START); uint8_t currentPeak = findPeak(sampleHistory, WINDOW_START, WINDOW_SIZE); if (isPulseDetected(historicalPeak, currentPeak)) { // Generate a new pulse if (++pulseIdx >= pulseCount) pulseIdx = 0; pulses[pulseIdx].colour.h = rand() % MAX_HUE; pulses[pulseIdx].colour.s = (MAX_SAT / 2) + (rand() % (MAX_SAT / 2)); pulses[pulseIdx].colour.v = MAX_VAL; pulses[pulseIdx].position = startingPosition; startingPosition -= 3; if (startingPosition < 0) startingPosition += NUM_LEDS; } pulseClearFrameBuffer(); for (int i = 0; i < pulseCount; ++i) { pulseUpdate(pulses + i); pulseRender(pulses + i); } ws2812_setleds(frameBuffer, 40); // Blocks for ~1.2ms _delay_ms(2); // The sensor line will be noisy for a little while } }
int fftMatch(char *inFile1, char *inFile2, char *corrFile, float *bestLocX, float *bestLocY, float *certainty) { int nl,ns; int mX,mY; /*Invariant: 2^mX=ns; 2^mY=nl.*/ int chipX, chipY; /*Chip location (top left corner) in second image*/ int chipDX,chipDY; /*Chip size in second image.*/ int searchX,searchY; /*Maximum distance to search for peak*/ int x,y; float doubt; float *corrImage=NULL; FILE *corrF=NULL,*in1F,*in2F; meta_parameters *metaMaster, *metaSlave, *metaOut; in1F = fopenImage(inFile1,"rb"); in2F = fopenImage(inFile2,"rb"); metaMaster = meta_read(inFile1); metaSlave = meta_read(inFile2); /*Round to find nearest power of 2 for FFT size.*/ mX = (int)(log((float)(metaMaster->general->sample_count))/log(2.0)+0.5); mY = (int)(log((float)(metaMaster->general->line_count))/log(2.0)+0.5); /* Keep size of fft's reasonable */ if (mX > 13) mX = 13; if (mY > 15) mY = 15; ns = 1<<mX; nl = 1<<mY; /* Test chip size to see if we have enough memory for it */ /* Reduce it if necessary, but not below 1024x1024 (which needs 4 Mb of memory) */ float *test_mem = (float *)malloc(sizeof(float)*ns*nl*2); if (!test_mem && !quietflag) asfPrintStatus("\n"); while (!test_mem) { mX--; mY--; ns = 1<<mX; nl = 1<<mY; if (ns < 1024 || nl < 1024) { asfPrintError("FFT Size too small (%dx%d)...\n", ns, nl); } if (!quietflag) asfPrintStatus(" Not enough memory... reducing FFT Size to %dx%d\n", ns, nl); test_mem = (float *)malloc(sizeof(float)*ns*nl*2); } FREE(test_mem); if (!quietflag) asfPrintStatus("\n"); /*Set up search chip size.*/ chipDX=MINI(metaSlave->general->sample_count,ns)*3/4; chipDY=MINI(metaSlave->general->line_count,nl)*3/4; chipX=MINI(metaSlave->general->sample_count,ns)/8; chipY=MINI(metaSlave->general->line_count,nl)/8; searchX=MINI(metaSlave->general->sample_count,ns)*3/8; searchY=MINI(metaSlave->general->line_count,nl)*3/8; fft2dInit(mY, mX); if (!quietflag && ns*nl*2*sizeof(float)>20*1024*1024) { asfPrintStatus( " These images will take %d megabytes of memory to match.\n\n", ns*nl*2*sizeof(float)/(1024*1024)); } /*Optionally open the correlation image file.*/ if (corrFile) { metaOut = meta_read(inFile1); metaOut->general->data_type= REAL32; metaOut->general->line_count = 2*searchY; metaOut->general->sample_count = 2*searchX; corrF=fopenImage(corrFile,"w"); } /*Perform the correlation.*/ fftProd(in1F,metaMaster,in2F,metaSlave,&corrImage,ns,nl,mX,mY, chipX,chipY,chipDX,chipDY,searchX,searchY); /*Optionally write out correlation image.*/ if (corrFile) { int outY=0; float *outBuf=(float*)MALLOC(sizeof(float)*metaOut->general->sample_count); for (y=chipY-searchY;y<chipY+searchY;y++) { int index=ns*modY(y,nl); int outX=0; for (x=chipX-searchX;x<chipX+searchX;x++) { outBuf[outX++]=corrImage[index+modX(x,ns)]; } put_float_line(corrF,metaOut,outY++,outBuf); } meta_write(metaOut, corrFile); meta_free(metaOut); FREE(outBuf); FCLOSE(corrF); } /*Search correlation image for a peak.*/ findPeak(corrImage,bestLocX,bestLocY,&doubt,nl,ns, chipX,chipY,searchX,searchY); *certainty = 1-doubt; FREE(corrImage); if (!quietflag) { asfPrintStatus(" Offset slave image: dx = %f, dy = %f\n" " Certainty: %f%%\n",*bestLocX,*bestLocY,100*(1-doubt)); } meta_free(metaSlave); meta_free(metaMaster); FCLOSE(in1F); FCLOSE(in2F); return (0); }
void FastMultiScaleClean<ImageSetType>::executeMajorIterationForScale(double currentScale, double nextScale, bool& reachedStopGain, bool& canCleanFurther) { ImageBufferAllocator& allocator = *_dataImageOriginal->Allocator(); // Scale down the image so that the "scale size" is 10 pixels // 10 pixels is so that the peak finding is still reasonably accurate _rescaledWidth = size_t(ceil(double(_originalWidth)*(10.0/currentScale))), _rescaledHeight = size_t(ceil(double(_originalHeight)*(10.0/currentScale))); double rescaleFactor = double(_rescaledWidth) / _originalWidth; if(_rescaledWidth > _originalWidth || _rescaledHeight > _originalHeight) { _rescaledWidth = _originalWidth; _rescaledHeight = _originalHeight; rescaleFactor = 1.0; } ImageSetType largeScaleImage(_rescaledWidth*_rescaledHeight, *_dataImageOriginal), nextScaleImage(_rescaledWidth*_rescaledHeight, *_dataImageOriginal), currentScaleModel(_rescaledWidth*_rescaledHeight, *_modelImage); std::vector<double*> scaledPsfs(_originalPsfs->size()); _dataImageLargeScale = &largeScaleImage; _dataImageNextScale = &nextScaleImage; _scaledPsfs = &scaledPsfs; canCleanFurther = true; size_t cpuCount = this->_threadCount; double thresholdBias = pow(this->_multiscaleThresholdBias, log2(currentScale)); std::cout << "Threshold bias: " << thresholdBias << '\n'; double oldSubtractionGain = this->_subtractionGain; this->_subtractionGain *= sqrt(thresholdBias); // Fill the large and next scale images with the rescaled images FFTResampler imageResampler(_originalWidth, _originalHeight, _rescaledWidth, _rescaledHeight, cpuCount, false); imageResampler.Start(); for(size_t i=0; i!=_dataImageOriginal->ImageCount(); ++i) imageResampler.AddTask(_dataImageOriginal->GetImage(i), largeScaleImage.GetImage(i)); for(size_t i=0; i!=_originalPsfs->size(); ++i) { scaledPsfs[i] = allocator.Allocate(_rescaledWidth*_rescaledHeight); imageResampler.AddTask((*_originalPsfs)[i], scaledPsfs[i]); } imageResampler.Finish(); for(size_t i=0; i!=_dataImageOriginal->ImageCount(); ++i) memcpy(nextScaleImage.GetImage(i), largeScaleImage.GetImage(i), sizeof(double)*_rescaledWidth*_rescaledHeight); for(size_t i=0; i!=currentScaleModel.ImageCount(); ++i) memset(currentScaleModel.GetImage(i), 0, sizeof(double)*_rescaledWidth*_rescaledHeight); // Convolve the large and next scale images and the psfs double* kernelImage = allocator.Allocate(_rescaledWidth * _rescaledHeight); ao::uvector<double> shape; size_t kernelSize; MakeShapeFunction(currentScale * rescaleFactor, shape, kernelSize); memset(kernelImage, 0, sizeof(double) * _rescaledWidth * _rescaledHeight); FFTConvolver::PrepareSmallKernel(kernelImage, _rescaledWidth, _rescaledHeight, shape.data(), kernelSize); for(size_t i=0; i!=largeScaleImage.ImageCount(); ++i) FFTConvolver::ConvolveSameSize(largeScaleImage.GetImage(i), kernelImage, _rescaledWidth, _rescaledHeight); for(size_t i=0; i!=scaledPsfs.size(); ++i) { FFTConvolver::ConvolveSameSize(scaledPsfs[i], kernelImage, _rescaledWidth, _rescaledHeight); FFTConvolver::ConvolveSameSize(scaledPsfs[i], kernelImage, _rescaledWidth, _rescaledHeight); } MakeShapeFunction(nextScale * rescaleFactor, shape, kernelSize); memset(kernelImage, 0, sizeof(double) * _rescaledWidth * _rescaledHeight); FFTConvolver::PrepareSmallKernel(kernelImage, _rescaledWidth, _rescaledHeight, shape.data(), kernelSize); for(size_t i=0; i!=nextScaleImage.ImageCount(); ++i) FFTConvolver::ConvolveSameSize(nextScaleImage.GetImage(i), kernelImage, _rescaledWidth, _rescaledHeight); //FitsWriter writer; //writer.SetImageDimensions(_rescaledWidth, _rescaledHeight); //writer.Write("multiscale-kernel.fits", kernelImage); //writer.Write("multiscale-current-scale.fits", largeScaleImage.GetImage(0)); //writer.Write("multiscale-next-scale.fits", nextScaleImage.GetImage(0)); //writer.Write("multiscale-psf.fits", scaledPsfs[0]); //writer.SetImageDimensions(kernelSize, kernelSize); //writer.Write("multiscale-shape.fits", shape.data()); size_t componentX=0, componentY=0; findPeak(componentX, componentY); std::cout << "Initial peak: " << peakDescription(largeScaleImage, componentX, componentY, rescaleFactor) << '\n'; size_t peakIndex = componentX + componentY*_rescaledWidth; double peakNormalized = _dataImageLargeScale->JoinedValueNormalized(peakIndex) * rescaleFactor * rescaleFactor; double firstThreshold = this->_threshold, stopGainThreshold = fabs(peakNormalized*(1.0-this->_stopGain)/thresholdBias); std::cout << "Scale-adjusted threshold: " << firstThreshold*thresholdBias << ", major iteration stops at " << stopGainThreshold*thresholdBias << '\n'; if(stopGainThreshold > firstThreshold) { firstThreshold = stopGainThreshold; std::cout << "Next major iteration for this scale at: " << stopGainThreshold << '\n'; } else if(this->_stopGain != 1.0) { std::cout << "Major iteration threshold reached global threshold of " << this->_threshold << " for this scale.\n"; } std::vector<ao::lane<CleanTask>*> taskLanes(cpuCount); std::vector<ao::lane<CleanResult>*> resultLanes(cpuCount); boost::thread_group threadGroup; for(size_t i=0; i!=cpuCount; ++i) { taskLanes[i] = new ao::lane<CleanTask>(1); resultLanes[i] = new ao::lane<CleanResult>(1); CleanThreadData cleanThreadData; cleanThreadData.startY = (_rescaledHeight*i)/cpuCount; cleanThreadData.endY = _rescaledHeight*(i+1)/cpuCount; cleanThreadData.parent = this; threadGroup.add_thread(new boost::thread(&FastMultiScaleClean<ImageSetType>::cleanThreadFunc, this, &*taskLanes[i], &*resultLanes[i], cleanThreadData)); } while(fabs(peakNormalized) > firstThreshold*thresholdBias && this->_iterationNumber < this->_maxIter && !(largeScaleImage.IsComponentNegative(peakIndex) && this->_stopOnNegativeComponent)) { if(this->_iterationNumber <= 10 || (this->_iterationNumber <= 100 && this->_iterationNumber % 10 == 0) || (this->_iterationNumber <= 1000 && this->_iterationNumber % 100 == 0) || this->_iterationNumber % 1000 == 0) std::cout << "Iteration " << this->_iterationNumber << ": " << peakDescription(largeScaleImage, componentX, componentY, rescaleFactor) << '\n'; CleanTask task; task.cleanCompX = componentX; task.cleanCompY = componentY; task.peak = largeScaleImage.Get(peakIndex); for(size_t i=0; i!=cpuCount; ++i) taskLanes[i]->write(task); currentScaleModel.AddComponent(largeScaleImage, peakIndex, this->_subtractionGain * rescaleFactor * rescaleFactor); double peakUnnormalized = 0.0; for(size_t i=0; i!=cpuCount; ++i) { CleanResult result; resultLanes[i]->read(result); if(result.peakLevelUnnormalized >= peakUnnormalized && std::isfinite(result.peakLevelUnnormalized)) { peakUnnormalized = result.peakLevelUnnormalized; componentX = result.nextPeakX; componentY = result.nextPeakY; } } if(peakUnnormalized == 0.0) { std::cout << "No more components found at current scale: continuing to next scale.\n"; canCleanFurther = false; break; } peakIndex = componentX + componentY*_rescaledWidth; peakNormalized = largeScaleImage.JoinedValueNormalized(peakIndex) * rescaleFactor * rescaleFactor; ++this->_iterationNumber; } for(size_t i=0; i!=cpuCount; ++i) taskLanes[i]->write_end(); threadGroup.join_all(); for(size_t i=0; i!=cpuCount; ++i) { delete taskLanes[i]; delete resultLanes[i]; } std::cout << "Stopped on peak " << peakNormalized << '\n'; reachedStopGain = fabs(peakNormalized) <= stopGainThreshold*thresholdBias; for(size_t i=0; i!=scaledPsfs.size(); ++i) allocator.Free(scaledPsfs[i]); MakeShapeFunction(currentScale * rescaleFactor, shape, kernelSize); memset(kernelImage, 0, sizeof(double) * _rescaledWidth * _rescaledHeight); FFTConvolver::PrepareSmallKernel(kernelImage, _rescaledWidth, _rescaledHeight, shape.data(), kernelSize); double* convolvedModel = allocator.Allocate(_originalWidth * _originalHeight); double* preparedPsf = allocator.Allocate(_originalWidth * _originalHeight); FFTResampler modelResampler(_rescaledWidth, _rescaledHeight, _originalWidth, _originalHeight, cpuCount, false); for(size_t i=0; i!=currentScaleModel.ImageCount(); ++i) { FFTConvolver::ConvolveSameSize(currentScaleModel.GetImage(i), kernelImage, _rescaledWidth, _rescaledHeight); //writer.SetImageDimensions(_rescaledWidth, _rescaledHeight); //writer.Write("multiscale-model-small.fits", currentScaleModel.GetImage(i)); modelResampler.RunSingle(currentScaleModel.GetImage(i), convolvedModel); double *modelPtr = convolvedModel; double *dest = _modelImage->GetImage(i), *destEnd = dest + _originalWidth*_originalHeight; while(dest != destEnd) { *dest += *modelPtr; ++modelPtr; ++dest; } FFTConvolver::PrepareKernel(preparedPsf, (*_originalPsfs)[_modelImage->PSFIndex(i)], _originalWidth, _originalHeight); FFTConvolver::ConvolveSameSize(convolvedModel, preparedPsf, _originalWidth, _originalHeight); dest = _dataImageOriginal->GetImage(i); destEnd = dest + _originalWidth*_originalHeight; modelPtr = convolvedModel; while(dest != destEnd) { *dest -= *modelPtr; ++modelPtr; ++dest; } } allocator.Free(preparedPsf); allocator.Free(convolvedModel); allocator.Free(kernelImage); this->_subtractionGain = oldSubtractionGain; }
int main(){ vector<int> A = {1, 2, 1, 3, 4, 5, 7, 6}; cout<<findPeak(A)<<endl; return 0; }
/* Start of main progam */ int main(int argc, char *argv[]) { char szOut[255], szImg1[255], szImg2[255], *maskFile; int x1, x2, y1, y2; int goodPoints=0, attemptedPoints=0; FILE *fp_output; meta_parameters *masterMeta, *slaveMeta; int logflag=FALSE, ampFlag=TRUE, currArg=1; while (currArg < (argc-NUM_ARGS)) { char *key = argv[currArg++]; if (strmatches(key,"-log","--log",NULL)) { CHECK_ARG(1); strcpy(logFile,GET_ARG(1)); fLog = FOPEN(logFile, "a"); logflag = TRUE; } else if (strmatches(key,"-mask","--mask",NULL)) { CHECK_ARG(1); maskFile = GET_ARG(1); } else { printf("\n**Invalid option: %s\n", argv[currArg-1]); usage(argv[0]); } } if ((argc-currArg) < NUM_ARGS) { printf("Insufficient arguments.\n"); usage(argv[0]); } // Fetch required arguments strcpy(szImg1,argv[argc - 3]); strcpy(szImg2,argv[argc - 2]); strcpy(szOut, argv[argc - 1]); /* Read metadata */ masterMeta = meta_read(szImg1); slaveMeta = meta_read(szImg2); if (masterMeta->general->line_count != slaveMeta->general->line_count || masterMeta->general->sample_count != slaveMeta->general->sample_count) asfPrintWarning("Input images have different dimension!\n"); else if (masterMeta->general->data_type != slaveMeta->general->data_type) asfPrintError("Input image have different data type!\n"); else if (masterMeta->general->data_type > 5 && masterMeta->general->data_type != COMPLEX_REAL32) asfPrintError("Cannot compare raw images for offsets!\n"); lines = masterMeta->general->line_count; samples = masterMeta->general->sample_count; if (masterMeta->general->data_type == COMPLEX_REAL32) { srcSize = 32; ampFlag = FALSE; cZero = Czero(); } /* Create output file */ fp_output=FOPEN(szOut, "w"); /* Loop over grid, performing forward and backward correlations */ while (getNextPoint(&x1,&y1,&x2,&y2)) { float dx=0.0, dy=0.0, snr=0.0, dxFW, dyFW, snrFW, dxBW, dyBW, snrBW; attemptedPoints++; // Check bounds and mask if (!(outOfBounds(x1, y1, srcSize, maskFile))) { /* ...check forward correlation... */ if (ampFlag) { if (!(findPeak(x1,y1,szImg1,x2,y2,szImg2,&dxFW,&dyFW,&snrFW))) { attemptedPoints--; continue; /* next point if chip in complete background fill */ } } else { getPeak(x1,y1,szImg1,x2,y2,szImg2,&dxFW,&dyFW,&snrFW); } if ((!ampFlag && snrFW>minSNR) || (ampFlag)) { /* ...check backward correlation... */ if (ampFlag) { if (!(findPeak(x2,y2,szImg2,x1,y1,szImg1,&dxBW,&dyBW,&snrBW))) { attemptedPoints--; continue; /* next point if chip in complete background fill */ printf("dxFW: %.2f, dyFW: %.2f\n", dxFW, dyFW); } } else { getPeak(x2,y2,szImg2,x1,y1,szImg1,&dxBW,&dyBW,&snrBW); } dxBW*=-1.0;dyBW*=-1.0; if (((!ampFlag && snrFW>minSNR) || (ampFlag)) && (fabs(dxFW-dxBW) < maxDisp) && (fabs(dyFW-dyBW) < maxDisp)) { dx = (dxFW+dxBW)/2; dy = (dyFW+dyBW)/2; snr = snrFW*snrBW; if (dx < maxDxDy && dy < maxDxDy) goodPoints++; } } fprintf(fp_output,"%6d %6d %8.5f %8.5f %4.2f\n", x1, y1, x2+dx, y2+dy, snr); fflush(fp_output); } } if (goodPoints < attemptedPoints) printf("\n WARNING: %i out of %i points moved by " "more than one pixel!\n\n", (attemptedPoints-goodPoints), attemptedPoints); else printf("\n There is no difference between the images\n\n"); FCLOSE(fp_output); FREE(masterMeta); FREE(slaveMeta); return(0); }
bool PeakPicker::process( const vector< float > & vfMS2TimeInput, const vector< float > & vfRetentionTimeInput, vector< double > & vdTreatmentChroInput, vector< double > & vdReferenceChroInput ) { iChroLength = vfRetentionTimeInput.size(); if ( iChroLength <= ProRataConfig::getPeakPickerWindowSize() ) { cout << "ERROR! The input chromatograms have too few MS1 scans!" << endl; return false; } if( vdTreatmentChroInput.size() != iChroLength || vdReferenceChroInput.size() != iChroLength ) { cout << "ERROR! the input chromatograms are in different length!" << endl; return false; } if ( ( ProRataConfig::getPeakPickerWindowSize() % 2) == 0 ) { cout << "ERROR! The window size for Sav-Gol smoothing has to be odd! " << endl; return false; } if ( ProRataConfig::getPeakPickerWindowSize() < 3 ) { cout << "ERROR! The window size for Sav-Gol smoothing is too small! " << endl; return false; } vfRetentionTime = vfRetentionTimeInput; // set the earliest MS2 time and the last MS2 scan time // used for initialize left valley and right valley fLeftMS2Time = *( min_element( vfMS2TimeInput.begin(), vfMS2TimeInput.end() ) ); fRightMS2Time = *( max_element( vfMS2TimeInput.begin(), vfMS2TimeInput.end() ) ); // the fLeftMS2Time and fRightMS2Time have to be within the RT range if( fLeftMS2Time < vfRetentionTime.front() ) fLeftMS2Time = vfRetentionTime.front(); if( fRightMS2Time > vfRetentionTime.back() ) fRightMS2Time = vfRetentionTime.back(); if( (ProRataConfig::getLeftPeakShift() < 0.001) && (ProRataConfig::getRightPeakShift() < 0.001) ) { iNumberofScansShifted = 0; // compute the final vdCovarianceChro computeCovarianceChro( iNumberofScansShifted, vdTreatmentChroInput, vdReferenceChroInput ); // compute the final peak findPeak(); return true; } /* * detect peak shift */ int i; // the calcuated peak height in PPC for all tested peak shift // vector< double > vdPeakHeight; // vector< int > viScanShift; map< int, double > mScanShift2Height; // scans that shifts left is negative and scans that shifts right is positive for( i = 0; i < vfRetentionTime.size() - 3; i++ ) { if( (vfRetentionTime[i] - vfRetentionTime[0]) >= ProRataConfig::getLeftPeakShift() - 0.001) break; } int iScanShiftLeft = -i; for( i = (vfRetentionTime.size() - 1); i > 2; i-- ) { if( (vfRetentionTime.back() - vfRetentionTime[i]) >= ProRataConfig::getRightPeakShift() - 0.001) break; } int iScanShiftRight = vfRetentionTime.size() - i - 1; double dMaxPeakHeight = -100; for( i = iScanShiftLeft; i < ( iScanShiftRight + 1 ); ++i ) { // viScanShift.push_back( i ); computeCovarianceChro( i, vdTreatmentChroInput, vdReferenceChroInput ); findPeak(); mScanShift2Height[i] = dPeakHeightPPC; if( dPeakHeightPPC > dMaxPeakHeight ) dMaxPeakHeight = dPeakHeightPPC; // vdPeakHeight.push_back( dPeakHeightPPC ); } if( mScanShift2Height[ 0 ] > dMaxPeakHeight*0.9 ) { iNumberofScansShifted = 0; } else { iNumberofScansShifted = 0; bool bIsMaxFound = false; if( abs( iScanShiftLeft ) > iScanShiftRight ) { for( i = 0; i > ( iScanShiftLeft - 1 ); --i ) { if( mScanShift2Height[i] > dMaxPeakHeight*0.95 ) { iNumberofScansShifted = i; bIsMaxFound = true; break; } } if( !bIsMaxFound ) { for( i = 0; i < iScanShiftRight + 1 ; ++i ) { if( mScanShift2Height[i] > dMaxPeakHeight*0.95 ) { iNumberofScansShifted = i; break; } } } } else { for( i = 0; i < iScanShiftRight + 1 ; ++i ) { if( mScanShift2Height[i] > dMaxPeakHeight*0.95 ) { iNumberofScansShifted = i; bIsMaxFound = true; break; } } if( !bIsMaxFound ) { for( i = 0; i > ( iScanShiftLeft - 1 ); --i ) { if( mScanShift2Height[i] > dMaxPeakHeight*0.95 ) { iNumberofScansShifted = i; break; } } } } } // compute the final vdCovarianceChro computeCovarianceChro( iNumberofScansShifted, vdTreatmentChroInput, vdReferenceChroInput ); // compute the final peak findPeak(); // actually change the input vdReferenceChroInput shiftChro( iNumberofScansShifted, vdReferenceChroInput ); // cout << "bPeakValidity = " << boolalpha << bPeakValidity << endl; return true; }
void CorrelationUGenInternal::processBlock(bool& shouldDelete, const unsigned int blockID, const int channel) throw() { const int blockSize = uGenOutput.getBlockSize(); int numSamplesToProcess = blockSize; float* inputASamples = inputs[InputA].processBlock(shouldDelete, blockID, channel); float* inputBSamples = inputs[InputB].processBlock(shouldDelete, blockID, channel); float* outputSamples = uGenOutput.getSampleData(); float* const windowsSamples = window.getDataUnchecked(0); float* const scoreSamples = score.getDataUnchecked(0); float* const bufferASamples = buffers.getDataUnchecked(InputBufferA); float* const bufferBSamples = buffers.getDataUnchecked(InputBufferB); float* const outputBufferSamples = buffers.getDataUnchecked(OutputBuffer); while(numSamplesToProcess > 0) { int bufferSamplesToProcess = length_ - bufferIndex; if(bufferSamplesToProcess > numSamplesToProcess) { // buffer the inputs memcpy(bufferASamples + bufferIndex, inputASamples, numSamplesToProcess * sizeof(float)); memcpy(bufferBSamples + bufferIndex, inputBSamples, numSamplesToProcess * sizeof(float)); bufferIndex += numSamplesToProcess; inputASamples += numSamplesToProcess; inputBSamples += numSamplesToProcess; // ...and the output - output the lockedIndexOfMax into the outputSamples outputIndex(outputSamples, numSamplesToProcess); // outputBuffer(outputSamples, numSamplesToProcess); // outputScore(outputSamples, numSamplesToProcess); outputSamples += numSamplesToProcess; numSamplesToProcess = 0; } else { numSamplesToProcess -= bufferSamplesToProcess; memcpy(bufferASamples + bufferIndex, inputASamples, bufferSamplesToProcess * sizeof(float)); memcpy(bufferBSamples + bufferIndex, inputBSamples, bufferSamplesToProcess * sizeof(float)); memset(outputBufferSamples, 0, (length_ + length_) * sizeof(float)); //apply windows for (int i = 0; i < length_; i++) { bufferASamples[i] *= windowsSamples[i]; bufferBSamples[i] *= windowsSamples[i]; } bufferIndex += bufferSamplesToProcess; inputASamples += bufferSamplesToProcess; inputBSamples += bufferSamplesToProcess; vDSP_conv (bufferASamples, 1, bufferBSamples, 1, outputBufferSamples, 1, length_, length_); for (int i = 0; i < length_; i++) scoreSamples[i] *= 0.9f; indexOfMax = findPeak(outputBufferSamples, length_); if ((indexOfMax >= 0) && (indexOfMax < length_)) { if (lockedIndexOfMax >= 0) { int diff = indexOfMax - lockedIndexOfMax; if (diff < 0) diff = -diff; int maximum = length_ / 4; diff = ugen::min(diff, maximum); int score = maximum - diff; float fScore = (float)score / maximum; fScore = ugen::cubed(fScore); scoreSamples[indexOfMax] += fScore; } else { scoreSamples[indexOfMax] += 1.f; } } lockedIndexOfMax = findPeak(scoreSamples, length_); // output the lockedIndexOfMax into the outputSamples outputIndex(outputSamples, bufferSamplesToProcess); // outputBuffer(outputSamples, bufferSamplesToProcess); // outputScore(outputSamples, bufferSamplesToProcess); outputSamples += bufferSamplesToProcess; bufferSamplesToProcess = 0; bufferIndex = 0; } } }
int main(int argc, char *argv[]) { char szImg[255], szImage[255], buffer[1000], crID[10], szCrList[255], szOut[255]; int ii, kk, size, bigSize=oversampling_factor*srcSize; int mainlobe_azimuth_min, mainlobe_azimuth_max, mainlobe_range_min; int mainlobe_range_max, sidelobe_azimuth_min, sidelobe_azimuth_max; int sidelobe_range_min, sidelobe_range_max, peak_line, peak_sample; float azimuth_processing_bandwidth, chirp_rate, pulse_duration, sampling_rate; float prf, srcPeakX, srcPeakY, bigPeakX, bigPeakY, clutter_power, peak_power, scr; float azimuth_resolution, range_resolution, azimuth_pslr, range_pslr; float azimuth_window_size, range_window_size; float azimuth_profile[bigSize], range_profile[bigSize]; static complexFloat *s, *t; double lat, lon, elev, posX, posY, look_angle; FILE *fpIn, *fpOut, *fp, *fpText; meta_parameters *meta, *meta_debug; float *original_amplitude, *amplitude, *phase; fcpx *src_fft, *trg_fft; int debug=FALSE; char *text=NULL; int overwrite=FALSE; if (argc==1) usage(); if (strcmp(argv[1],"-help")==0) help_page(); /* exits program */ if (strcmp(argv[1],"-overwrite")==0) overwrite=TRUE; int required_args = 4; if (overwrite) ++required_args; if(argc != required_args) usage();/*This exits with a failure*/ /* Fetch required arguments */ strcpy(szImg, argv[argc - 3]); strcpy(szCrList,argv[argc - 2]); strcpy(szOut,argv[argc - 1]); /* DEFAULT VALUES: size of region to oversample - 64 pixels mainlobe width factor - 2.6 sidelobe width factor - 20.0 maximum oversampling factor - 8 */ // Read metadata sprintf(szImage, "%s.img", szImg); meta = meta_read(szImage); lines = meta->general->line_count; samples = meta->general->sample_count; text = (char *) MALLOC(255*sizeof(char)); // Handle input and output file fpIn = FOPEN(szCrList, "r"); fpOut = FOPEN(szOut, "w"); fprintf(fpOut, "POINT TARGET ANALYSIS RESULTS\n\n"); fprintf(fpOut, "CR\tLat\tLon\tElev\tAz peak\tRng peak\tLook\t" "Az res\tRng res\tAz PSLR\tRng PSLR\tSCR\n"); // RCS needs some more coding // Loop through corner reflector location file while (fgets(buffer, 1000, fpIn)) { if (overwrite) { sscanf(buffer, "%s\t%lf\t%lf", crID, &posY, &posX); printf(" %s: posX = %.2lf, posY = %.2lf\n", crID, posX, posY); } else { sscanf(buffer, "%s\t%lf\t%lf\t%lf", crID, &lat, &lon, &elev); meta_get_lineSamp(meta, lat, lon, elev, &posY, &posX); printf(" %s: lat = %.4lf, lon = %.4lf, posX = %.2lf, posY = %.2lf\n", crID, lat, lon, posX, posY); } // Check bounds - Get average spectra from chip in range direction if (!(outOfBounds(posX, posY, srcSize))) { // READ SUBSET FROM THE IMAGE WITH CORNER REFLECTOR IN THE CENTER size = srcSize*srcSize*sizeof(float); original_amplitude = (float *) MALLOC(size); phase = (float *) MALLOC(size); s = (complexFloat *) MALLOC(2*size); readComplexSubset(szImage, srcSize, srcSize, posX-srcSize/2, posY-srcSize/2, s); my_complex2polar(s, srcSize, srcSize, original_amplitude, phase); if (debug) { // Store original image for debugging fp = FOPEN("original.img", "wb"); size = bigSize*bigSize*sizeof(float); FWRITE(original_amplitude, size, 1, fp); FCLOSE(fp); meta_debug = meta_init(szImage); meta_debug->general->line_count = meta_debug->general->sample_count = srcSize; meta_debug->general->data_type = REAL32; meta_debug->general->start_line = posY-srcSize/2; meta_debug->general->start_sample = posX-srcSize/2; meta_debug->general->center_latitude = lat; meta_debug->general->center_longitude = lon; meta_write(meta_debug, "original.meta"); meta_free(meta_debug); } // Find amplitude peak in original image chip if (!findPeak(original_amplitude, srcSize, &srcPeakX, &srcPeakY)) { fprintf(fpOut, " Could not find amplitude peak in original image chip!\n"); goto SKIP; } // Cut out the subset again around the peak to make sure we have data for // the analysis readComplexSubset(szImage, srcSize, srcSize, posX-srcSize+srcPeakY, posY-srcSize+srcPeakX, s); my_complex2polar(s, srcSize, srcSize, original_amplitude, phase); FREE(phase); findPeak(original_amplitude, srcSize, &srcPeakX, &srcPeakY); // Determine look angle look_angle = meta_look(meta, srcSize/2, srcSize/2); /**************************** - special ScanSAR case: images are "projected" - need to be rotated back to allow analysis in azimuth and range direction (ss_extract.c) *********************/ // BASEBAND THE DATA IN EACH DIMENSION IN THE FREQUENCY DOMAIN // Oversample image src_fft = forward_fft(s, srcSize, srcSize); trg_fft = oversample(src_fft, srcSize, oversampling_factor); // Determine azimuth and range window size azimuth_processing_bandwidth = (float) meta->sar->azimuth_processing_bandwidth; prf = (float) meta->sar->prf; chirp_rate = (float) meta->sar->chirp_rate; pulse_duration = (float) meta->sar->pulse_duration; sampling_rate = (float) meta->sar->range_sampling_rate; azimuth_window_size = azimuth_processing_bandwidth / prf; range_window_size = fabs(chirp_rate) * pulse_duration / sampling_rate; printf("azimuth window size: %.2f, range window size: %.2f\n", azimuth_window_size, range_window_size); asfRequire(azimuth_window_size > 0.0 && azimuth_window_size < 1.0, "azimuth window size out of range (0 to 1)!\n"); asfRequire(range_window_size > 0.0 && range_window_size < 1.0, "range window size out of range (0 to 1)!\n"); if (range_window_size < 0.5) range_window_size = 0.5; // for ScanSAR both 0.5 // run debugger to check units are correct! // Baseband image in range direction //baseband(src_fft, range_window_size); /* // Transpose matrix to work in azimuth direction //transpose(s); // Baseband image in azimuth direction // baseband(s, azimuth_window_size); // Transpose matrix back into original orientation //transpose(s); */ t = inverse_fft(trg_fft, bigSize, bigSize); amplitude = (float *) MALLOC(sizeof(float)*bigSize*bigSize); phase = (float *) MALLOC(sizeof(float)*bigSize*bigSize); my_complex2polar(t, bigSize, bigSize, amplitude, phase); FREE(phase); if (debug) { // Store oversampled image for debugging fp = FOPEN("oversample.img", "wb"); size = bigSize*bigSize*sizeof(float); FWRITE(amplitude, size, 1, fp); FCLOSE(fp); meta_debug = meta_init("oversample.meta"); meta_debug->general->line_count = meta_debug->general->sample_count = bigSize; meta_debug->general->data_type = REAL32; meta_write(meta_debug, "oversample.meta"); meta_free(meta_debug); } // Find the amplitude peak in oversampled image if (!findPeak(amplitude, bigSize, &bigPeakX, &bigPeakY)) { fprintf(fpOut, " Could not find amplitude peak in oversampled image chip!\n"); goto SKIP; } peak_line = (int)(bigPeakX + 0.5); peak_sample = (int)(bigPeakY + 0.5); // Write text version of oversampled image sprintf(text, "%s_%s_chip.txt", szImg, crID); fpText = FOPEN(text, "w"); for (ii=peak_line-32; ii<peak_line+32; ii++) { for (kk=peak_sample-32; kk<peak_sample+32; kk++) fprintf(fpText, "%12.4f\t", amplitude[ii*bigSize+kk]); fprintf(fpText, "\n"); } FCLOSE(fpText); // EXTRACTING PROFILES IN AZIMUTH AND RANGE THROUGH PEAK for (ii=0; ii<bigSize; ii++) { azimuth_profile[ii] = amplitude[ii*bigSize+peak_sample]; range_profile[ii] = amplitude[bigSize*peak_line+ii]; } sprintf(text, "%s_%s_azimuth.txt", szImg, crID); fp = FOPEN(text, "w"); fprintf(fp, "Azimuth profile\n"); for (ii=0; ii<bigSize; ii++) fprintf(fp, "%.3f\n", azimuth_profile[ii]); FCLOSE(fp); sprintf(text, "%s_%s_range.txt", szImg, crID); fp = FOPEN(text, "w"); fprintf(fp, "Range profile\n"); for (ii=0; ii<bigSize; ii++) fprintf(fp, "%.3f\n", range_profile[ii]); FCLOSE(fp); // FINALLY GET TO THE IMAGE QUALITY PARAMETERS clutter_power = 0.0; // Find main lobes in oversampled image if (!find_mainlobe(amplitude, azimuth_profile, bigSize, peak_line, clutter_power, &mainlobe_azimuth_min, &mainlobe_azimuth_max)) { fprintf(fpOut, " No mainlobes could be found for %s in azimuth!\n", crID); goto SKIP; } //printf("mainlobe azimuth: min = %d, max = %d\n", // mainlobe_azimuth_min, mainlobe_azimuth_max); if (!find_mainlobe(amplitude, range_profile, bigSize, peak_sample, clutter_power, &mainlobe_range_min, &mainlobe_range_max)) { fprintf(fpOut, " No mainlobes could be found for %s in range!\n", crID); goto SKIP; } //printf("mainlobe range: min = %d, max = %d\n", // mainlobe_range_min, mainlobe_range_max); // Calculate resolution in azimuth and range for profiles if (!calc_resolution(azimuth_profile, mainlobe_azimuth_min, mainlobe_azimuth_max, peak_line, meta->general->y_pixel_size, clutter_power, &azimuth_resolution)) fprintf(fpOut, " Negative azimuth resolution for %s - invalid result!" "\n", crID); //printf("azimuth resolution = %.2f\n", azimuth_resolution); if (!calc_resolution(range_profile, mainlobe_range_min, mainlobe_range_max, peak_sample, meta->general->x_pixel_size, clutter_power, &range_resolution)) fprintf(fpOut, " Negative range resolution for %s - invalid result!\n", crID); //printf("range resolution = %.2f\n", range_resolution); // Find peak of original data - thought we had that already: check !!! // Calculate the clutter power azimuth_resolution /= meta->general->x_pixel_size; range_resolution /= meta->general->y_pixel_size; clutter_power = calc_clutter_power(original_amplitude, srcSize, peak_sample, peak_line, azimuth_resolution, range_resolution); //printf(" Clutter power: %8.3f\n", clutter_power); // Calculate resolution in azimuth and range with estimated clutter power if (!calc_resolution(azimuth_profile, mainlobe_azimuth_min, mainlobe_azimuth_max, peak_line, meta->general->y_pixel_size, clutter_power, &azimuth_resolution)) fprintf(fpOut, " Negative azimuth resolution for %s - invalid result!" "\n", crID); if (!calc_resolution(range_profile, mainlobe_range_min, mainlobe_range_max, peak_sample, meta->general->x_pixel_size, clutter_power, &range_resolution)) fprintf(fpOut, " Negative range resolution for %s - invalid result!\n", crID); //printf(" Azimuth resolution: %.3f\n", azimuth_resolution); //printf(" Range resolution: %.3f\n", range_resolution); // Find sidelobes in oversampled image and calculate the point-to-sidelobe // ratio in azimuth and range direction if (find_sidelobe(azimuth_profile, bigSize, 1, peak_line, mainlobe_azimuth_max, &sidelobe_azimuth_max) && find_sidelobe(azimuth_profile, bigSize, -1, peak_line, mainlobe_azimuth_min, &sidelobe_azimuth_min)) { if (!calc_pslr(azimuth_profile, bigSize, peak_line, sidelobe_azimuth_min, sidelobe_azimuth_max, &azimuth_pslr)) //printf(" Azimuth PSLR: %.3f\n", azimuth_pslr); //printf(" No valid PSLR in azimuth could be determined!\n"); ; } else { fprintf(fpOut, " Problem in finding sidelobes for %s in azimuth - " "invalid PSLR!\n", crID); } if (find_sidelobe(range_profile, bigSize, 1, peak_sample, mainlobe_range_max, &sidelobe_range_max) && find_sidelobe(range_profile, bigSize, -1, peak_sample, mainlobe_range_min, &sidelobe_range_min)) { if (!calc_pslr(range_profile, bigSize, peak_sample, sidelobe_range_min, sidelobe_range_max, &range_pslr)) //printf(" Range PSLR: %.3f\n", range_pslr); //printf(" No valid PSLR in range could be determined!\n"); ; } else { fprintf(fpOut, " Problem in finding sidelobes for %s in range -" " invalid PSLR!\n", crID); } //printf("sidelobe_azimuth: min = %d, max = %d\n", // sidelobe_azimuth_min, sidelobe_azimuth_max); //printf("sidelobe_range: min = %d, max = %d\n", // sidelobe_range_min, sidelobe_range_max); // Calculate the signal-to-clutter ratio (SCR) peak_power = amplitude[peak_line*bigSize+peak_sample] * amplitude[peak_line*bigSize+peak_sample]; if (clutter_power>0 && peak_power>clutter_power) scr = 10 * log((peak_power - clutter_power)/clutter_power); else scr = 0.0; if (peak_power > 0.0) { peak_power = 10 * log(peak_power); //printf(" Peak power: %.3f\n", peak_power); //printf(" SCR: %.3f\n", scr); } else fprintf(fpOut, " Negative peak power - invalid result!\n"); FREE(amplitude); FREE(original_amplitude); // Write values in output files fprintf(fpOut, "%s\t%.4lf\t%.4lf\t%.1lf\t%.1lf\t%.1f\t%.3f\t" "%.3f\t%.3f\t%.3f\t%.3f\t%.3f\n", crID, lat, lon, elev, posX-srcSize+srcPeakY, posY-srcSize+srcPeakX, look_angle*R2D, azimuth_resolution, range_resolution, azimuth_pslr, range_pslr, scr); SKIP: continue; } else fprintf(fpOut, "\n WARNING: Target %s outside the image boundaries!\n", crID); } FCLOSE(fpIn); FCLOSE(fpOut); FREE(meta); return(0); }