Beispiel #1
0
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;
  }
}
Beispiel #2
0
 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
 }
Beispiel #3
0
/* 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);
	}
}
Beispiel #5
0
// 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;
	}
Beispiel #6
0
/*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;
}
Beispiel #7
0
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");

}
Beispiel #8
0
 int findPeakElement(const vector<int> &num) {
     if(num.empty()) return 0;
     int n = num.size();
     return findPeak(num, 0, n-1);
 }
Beispiel #9
0
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
    }
}
Beispiel #10
0
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;
}
Beispiel #13
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);
}
Beispiel #14
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;
}
Beispiel #15
0
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;
		}
	}
}
Beispiel #16
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);
}