00001 #ifndef Impala_Core_Histogram_Histogram2dTem_h
00002 #define Impala_Core_Histogram_Histogram2dTem_h
00003
00004 #include <iostream>
00005 #include "Core/Array/Array2dTem.h"
00006 #include "Core/Array/SetVal.h"
00007 #include "Core/Array/PixSum.h"
00008
00009 namespace Impala
00010 {
00011 namespace Core
00012 {
00013 namespace Histogram
00014 {
00015
00016
00017 template <class ElemT>
00018 class Histogram2dTem : public Array::Array2dTem<ElemT, 1, ElemT>
00019 {
00020 public:
00021
00022 Histogram2dTem(ElemT lowX, ElemT highX, int binCountX, ElemT lowY, ElemT highY, int binCountY)
00023 : Array::Array2dTem<ElemT, 1, ElemT>(binCountX, binCountY, 0, 0)
00024 {
00025 mBinCountX = binCountX;
00026 mBinCountY = binCountY;
00027 SetRange(lowX, highX, lowY, highY);
00028 Clear();
00029 }
00030
00031 virtual ~Histogram2dTem()
00032 {
00033 }
00034
00035 ElemT GetLowX()
00036 {
00037 return mLowX;
00038 }
00039
00040 ElemT GetLowY()
00041 {
00042 return mLowY;
00043 }
00044
00045 ElemT GetHighX()
00046 {
00047 return mHighX;
00048 }
00049
00050 ElemT GetHighY()
00051 {
00052 return mHighY;
00053 }
00054
00055 int GetBinCountX()
00056 {
00057 return mBinCountX;
00058 }
00059
00060 int GetBinCountY()
00061 {
00062 return mBinCountY;
00063 }
00064
00065 void GetBinRangeX(int bin, ElemT& low, ElemT& high)
00066 {
00067 low = mLowX + bin*mBinWidthX;
00068 high = mLowX + (bin+1)*mBinWidthX;
00069 }
00070
00071 void GetBinRangeY(int bin, ElemT& low, ElemT& high)
00072 {
00073 low = mLowY + bin*mBinWidthY;
00074 high = mLowY + (bin+1)*mBinWidthY;
00075 }
00076
00077 void SetRange(ElemT lowX, ElemT highX, ElemT lowY, ElemT highY)
00078 {
00079 mLowX = lowX;
00080 mLowY = lowY;
00081 mHighX = highX;
00082 mHighY = highY;
00083 mBinWidthX = (highX-lowX) / ((ElemT) mBinCountX);
00084 mBinWidthY = (highY-lowY) / ((ElemT) mBinCountY);
00085 }
00086
00087 void Clear()
00088 {
00089 SetVal(this, static_cast<ElemT>(0));
00090 }
00091
00092 void AddWeight(ElemT valueX, ElemT valueY, double weight = 1.)
00093 {
00094 *this->CPB(ValueToBinX(valueX), ValueToBinY(valueY)) += weight;
00095 }
00096
00097 void AddWeightSafe(ElemT valueX, ElemT valueY, double weight = 1.)
00098 {
00099 int indexX = ValueToBinX(valueX);
00100 int indexY = ValueToBinY(valueY);
00101 if (indexX<0 || indexX>=this->CW() || indexY<0 || indexY>=this->CH())
00102 {
00103 mOutliers += weight;
00104 }
00105 else
00106 *this->CPB(indexX, indexY) += weight;
00107 }
00108
00109 ElemT GetWeight(ElemT valueX, ElemT valueY)
00110 {
00111 return this->Elem(ValueToBinX(valueX), ValueToBinY(valueY));
00112 }
00113
00114 ElemT TotalWeight()
00115 {
00116 return PixSum(this);
00117 }
00118
00119 void Normalize()
00120 {
00121 ElemT tot = TotalWeight();
00122 DivVal(this, tot);
00123 }
00124
00125 int ValueToBinX(ElemT value)
00126 {
00127 return (int)((value-mLowX) / mBinWidthX);
00128 }
00129
00130 int ValueToBinY(ElemT value)
00131 {
00132 return (int)((value-mLowY) / mBinWidthY);
00133 }
00134
00135 Real64 OutlierPercentage()
00136 {
00137 ElemT sum = TotalWeight() + mOutliers;
00138 return ((Real64) mOutliers) / ((Real64) sum) * 100;
00139 }
00140
00141 void Dump(bool doData)
00142 {
00143 std::cout << "hist range x [" << mLowX << "," << mHighX << "] with "
00144 << mBinCountX << "range y [" << mLowY << "," << mHighY << "] with "
00145 << mBinCountY << " bins. Values: " << std::endl;
00146 if (doData)
00147 this->WriteTo(std::cout);
00148 std::cout << "Total weight: " << TotalWeight() << ", outlier %: "
00149 << OutlierPercentage() << std::endl;
00150 std::cout << std::endl;
00151 }
00152
00153 private:
00154
00155 ElemT mLowX;
00156 ElemT mHighX;
00157 ElemT mBinWidthX;
00158 int mBinCountX;
00159 ElemT mLowY;
00160 ElemT mHighY;
00161 ElemT mBinWidthY;
00162 int mBinCountY;
00163 ElemT mOutliers;
00164
00165 };
00166
00167 }
00168 }
00169 }
00170
00171 #endif