Skip to content
Snippets Groups Projects
histogram.cc 5.37 KiB
Newer Older
Christian Beckmann's avatar
Christian Beckmann committed
/*  histogram.cc

Matthew Webster's avatar
Matthew Webster committed
    Mark Woolrich, Matthew Webster and Emma Robinson, FMRIB Image Analysis Group
Christian Beckmann's avatar
Christian Beckmann committed

    Copyright (C) 1999-2000 University of Oxford  */

Matthew Webster's avatar
Matthew Webster committed
/*  CCOPYRIGHT  */
Christian Beckmann's avatar
Christian Beckmann committed

#include "miscmaths.h"
David Flitney's avatar
David Flitney committed
#include "histogram.h"

using namespace std;
using namespace NEWMAT;
Christian Beckmann's avatar
Christian Beckmann committed

namespace MISCMATHS {

Paul McCarthy's avatar
Paul McCarthy committed
  float Histogram::getPercentile(float perc)
Matthew Webster's avatar
Matthew Webster committed
  {
    if(histogram.Nrows()==0) generate();
Paul McCarthy's avatar
Paul McCarthy committed

Matthew Webster's avatar
Matthew Webster committed
    generateCDF();
    float percentile=getValue(1);
Paul McCarthy's avatar
Paul McCarthy committed

Matthew Webster's avatar
Matthew Webster committed
    for (int i=2;i<=CDF.Nrows();i++){
      if(CDF(i)>perc){
	double diff=(CDF(i)-perc)/(CDF(i)-CDF(i-1));
	percentile=getValue(i-1)+diff*(getValue(i)-getValue(i-1));
	break;
      }

    }
    return percentile;
  }
Christian Beckmann's avatar
Christian Beckmann committed
  void Histogram::generate()
  {
    Tracer ts("Histogram::generate");
Paul McCarthy's avatar
Paul McCarthy committed

    int size = sourceData.Nrows();
Paul McCarthy's avatar
Paul McCarthy committed

    if(calcRange)
      {
	// calculate range automatically
	histMin=histMax=sourceData(1);
	for(int i=1; i<=size; i++)
	  {
	    if (sourceData(i)>histMax)
	      histMax=sourceData(i);
	    if (sourceData(i)<histMin)
	      histMin=sourceData(i);
	  }
      }
Paul McCarthy's avatar
Paul McCarthy committed

  // zero histogram
    histogram.ReSize(bins);
    histogram=0;
Paul McCarthy's avatar
Paul McCarthy committed

    // create histogram; the MIN is so that the maximum value falls in the
    // last valid bin, not the (last+1) bin
    for(int i=1; i<=size; i++)
Paul McCarthy's avatar
Paul McCarthy committed
      {
      histogram(getBin(sourceData(i)))++;
      }

    datapoints=size;
  }
Paul McCarthy's avatar
Paul McCarthy committed

  void Histogram::generate(ColumnVector exclude)
  {
    Tracer ts("Histogram::generate");
    int size = sourceData.Nrows();
    if(calcRange)
      {
	// calculate range automatically
	histMin=histMax=sourceData(1);
	for(int i=1; i<=size; i++)
	  {
	    if (sourceData(i)>histMax)
	      histMax=sourceData(i);
	    if (sourceData(i)<histMin)
	      histMin=sourceData(i);
	  }
      }
    histogram.ReSize(bins);
    histogram=0;
Paul McCarthy's avatar
Paul McCarthy committed

    datapoints=size;
Paul McCarthy's avatar
Paul McCarthy committed

    for(int i=1; i<=size; i++)
      {
	if(exclude(i)>0){
	  histogram(getBin(sourceData(i)))++;
	}else datapoints--;

      }
Paul McCarthy's avatar
Paul McCarthy committed

Mark Woolrich's avatar
Mark Woolrich committed
  void Histogram::smooth()
    {
      Tracer ts("Histogram::smooth");

      ColumnVector newhist=histogram;

      // smooth in i direction
      newhist=0;
Paul McCarthy's avatar
Paul McCarthy committed
      ColumnVector kernel(3);
Mark Woolrich's avatar
Mark Woolrich committed
      // corresponds to Gaussian with sigma=0.8 voxels
      //       kernel(1)=0.5;
Paul McCarthy's avatar
Paul McCarthy committed
      //       kernel(2)=0.2283;
Mark Woolrich's avatar
Mark Woolrich committed
      //       kernel(3)=0.0219;
      // corresponds to Gaussian with sigma=0.6 voxels
      //       kernel(1)=0.6638;
Paul McCarthy's avatar
Paul McCarthy committed
      //       kernel(2)=0.1655;
Mark Woolrich's avatar
Mark Woolrich committed
      //       kernel(3)=0.0026;

      //gauss(0.5,5,1)
      kernel(1)=0.7866;
Paul McCarthy's avatar
Paul McCarthy committed
      kernel(2)=0.1065;
Mark Woolrich's avatar
Mark Woolrich committed
      kernel(3)=0.0003;
Mark Woolrich's avatar
Mark Woolrich committed

      for(int i=1; i<=bins; i++)
	  {
	    float val=0.5*histogram(i);
Mark Woolrich's avatar
Mark Woolrich committed
	    float norm=kernel(1);
Mark Woolrich's avatar
Mark Woolrich committed
		val+=kernel(2)*(histogram(i-1));
		norm+=kernel(2);
Mark Woolrich's avatar
Mark Woolrich committed
		val+=kernel(3)*(histogram(i-2));
Paul McCarthy's avatar
Paul McCarthy committed
		norm+=kernel(3);
Mark Woolrich's avatar
Mark Woolrich committed
	      }
	    if(i<bins)
	      {
Mark Woolrich's avatar
Mark Woolrich committed
		val+=kernel(2)*(histogram(i+1));
		norm+=kernel(2);
Mark Woolrich's avatar
Mark Woolrich committed
	      }
	    if(i<bins-1)
	      {
Mark Woolrich's avatar
Mark Woolrich committed
		val+=kernel(3)*(histogram(i+2));
Paul McCarthy's avatar
Paul McCarthy committed
		norm+=kernel(3);
Mark Woolrich's avatar
Mark Woolrich committed
	      }
	    val/=norm;

	    newhist(i)=val;
	  }

      histogram=newhist;

    }

Christian Beckmann's avatar
Christian Beckmann committed
  int Histogram::integrate(float value1, float value2) const
    {
      int upperLimit = getBin(value2);
      int sum = 0;

      for(int i = getBin(value1)+1; i< upperLimit; i++)
	{
	  sum += (int)histogram(i);
	}
      return sum;
    }

  float Histogram::mode() const
    {
      int maxbin = 0;
      int maxnum = 0;

      for(int i = 1; i< bins; i++)
	{
	  if((int)histogram(i) > maxnum) {
	    maxnum = (int)histogram(i);
	    maxbin = i;
	  }
	}

      return getValue(maxbin);
    }



  void Histogram::match(Histogram &target){
Paul McCarthy's avatar
Paul McCarthy committed

    int bin, newbin;
    double cdfval, val,dist;
    ColumnVector CDF_ref;
    ColumnVector olddata;
    ColumnVector histnew(bins);
    vector<double> rangein,rangetarg;

    CDF_ref=target.getCDF();
    olddata=sourceData;
    histnew=0; dist=0;
    if(exclusion.Nrows()==0){cout << " Histogram::match no excl " << endl; exclusion.ReSize(sourceData.Nrows()); exclusion=1;}
Paul McCarthy's avatar
Paul McCarthy committed

    float binwidthtarget=(target.getHistMax() - target.getHistMin())/target.getNumBins();
    for (int i=1;i<=sourceData.Nrows();i++){
Paul McCarthy's avatar
Paul McCarthy committed

      if(exclusion(i)>0){

	bin=getBin(sourceData(i));
Paul McCarthy's avatar
Paul McCarthy committed

	cdfval=CDF(bin);
	newbin=1;
Paul McCarthy's avatar
Paul McCarthy committed

	val=sourceData(i)-histMin;
Paul McCarthy's avatar
Paul McCarthy committed

	if(bin==target.getNumBins()){
	  newbin=bin;
	}else if( (cdfval- CDF_ref(bin)) > 1e-20){
	  for (int j=bin;j<target.getNumBins();j++){
Paul McCarthy's avatar
Paul McCarthy committed

	    if((cdfval - CDF_ref(j)) > 1e-20 && (cdfval - CDF_ref(j+1)) <= 1e-20 ){
	      newbin=j+1;
	      dist=(cdfval-CDF_ref(j))/(CDF_ref(j+1)-CDF_ref(j)); // find distance between current bins as proportion of bin width
	     break;
	    }
	  }
Paul McCarthy's avatar
Paul McCarthy committed

Paul McCarthy's avatar
Paul McCarthy committed

	  //search backwards
	  int j=bin-1;
	  while (j>0){
Paul McCarthy's avatar
Paul McCarthy committed

	    //  if(sourceData(i)<1.2 && sourceData(i)>1)
	    if((cdfval - CDF_ref(1)) < -1e-20 &&  fabs(CDF_ref(bin) - CDF_ref(1)) < 1e-20){newbin=j+1; break; }
	    else if ((cdfval - CDF_ref(1)) > -1e-20 &&  fabs(CDF_ref(bin) - CDF_ref(1)) < 1e-20){newbin=j+1; break; }
	    else if((cdfval - CDF_ref(j)) > 1e-20 && (cdfval - CDF_ref(j+1)) <= 1e-20 ){
	      newbin=j+1;

Paul McCarthy's avatar
Paul McCarthy committed

	      dist=(cdfval-CDF_ref(j))/(CDF_ref(j+1)-CDF_ref(j)); // find distance between current bins as proportion of bin width
	      break;
	    }
	    j--;
	  }
	  //search forwards
	}

	sourceData(i)=target.getHistMin() + (newbin-1)*binwidthtarget+dist*binwidthtarget;

	histnew(newbin)++;
Paul McCarthy's avatar
Paul McCarthy committed

	if(sourceData(i) < target.getHistMin()) sourceData(i) = target.getHistMin();
	if(sourceData(i) > target.getHistMax()) sourceData(i) = target.getHistMax();

      }
    }
  }
Paul McCarthy's avatar
Paul McCarthy committed
}