00001 #include <algorithm>
00002 #include <cmath>
00003 #include <vector>
00004
00005 #include "XHistogram.h"
00006
00007 std::vector<XHistogram::position> XHistogram::splitSegment( Range rangeX, Range rangeY ) const
00008 {
00009 double deltaX = rangeX.second - rangeX.first;
00010 double deltaY = rangeY.second - rangeY.first;
00011 double length = hypot(deltaX, deltaY);
00012 double stepX = (m_xRange.second - m_xRange.first) / m_xBins;
00013 double stepY = (m_yRange.second - m_yRange.first) / m_yBins;
00014
00015 int min_i, max_i, min_j, max_j;
00016 if (rangeX.first < rangeX.second) {
00017 min_i = (int) ceil(rangeX.first / stepX);
00018 max_i = (int) floor(rangeX.second / stepX) + 1;
00019 } else {
00020 min_i = (int) ceil(rangeX.second / stepX);
00021 max_i = (int) floor(rangeX.first / stepX) + 1;
00022 }
00023 if (rangeY.first < rangeY.second) {
00024 min_j = (int) ceil(rangeY.first / stepY);
00025 max_j = (int) floor(rangeY.second / stepY) + 1;
00026 } else {
00027 min_j = (int) ceil(rangeY.second / stepY);
00028 max_j = (int) floor(rangeY.first / stepY) + 1;
00029 }
00030
00031 int steps = max_i-min_i + max_j-min_j + 2;
00032 std::vector<position> v;
00033 v.clear();
00034 v.reserve(steps);
00035
00036 v.push_back( position(0., rangeX.first, rangeY.first) );
00037 double x, y, f;
00038 for (int i = min_i; i < max_i; ++i) {
00039 x = i * stepX;
00040 y = rangeY.first + (x - rangeX.first) * deltaY / deltaX;
00041 f = std::fabs( (x - rangeX.first) / deltaX );
00042 v.push_back( position(f, x, y) );
00043 }
00044 for (int i = min_j; i < max_j; ++i) {
00045 y = i * stepY;
00046 x = rangeX.first + (y - rangeY.first) * deltaX / deltaY;
00047 f = std::fabs( (y - rangeY.first) / deltaY );
00048 v.push_back( position(f, x, y) );
00049 }
00050 v.push_back( position(1., rangeX.second, rangeY.second) );
00051
00052
00053 std::sort(v.begin(), v.end());
00054
00055
00056 std::vector<position> result;
00057 result.push_back( v.front() );
00058 for (int i = 1, s = v.size(); i < s; ++i) {
00059 double mx = (v[i].x + v[i-1].x) / 2.;
00060 double my = (v[i].y + v[i-1].y) / 2.;
00061 double df = (v[i].f - v[i-1].f);
00062 if (df * length < m_minDl)
00063 continue;
00064 result.push_back( position( df, mx, my ) );
00065 }
00066
00067 return result;
00068 }
00069
00071 void XHistogram::fill( double x, double y, const std::vector<double> & weight, double norm )
00072 {
00073 check_weight( weight );
00074
00075 for (size_t h = 0; h < m_size; ++h)
00076 m_histograms[h]->Fill( x, y, weight[h] );
00077 m_normalization->Fill( x, y, norm );
00078 }
00079
00081 void XHistogram::fill( double x, double y, const std::vector<double> & weight, double norm, unsigned int colour )
00082 {
00083 check_weight( weight );
00084
00085 for (size_t h = 0; h < m_size; ++h)
00086 m_histograms[h]->Fill( x, y, weight[h] );
00087 m_normalization->Fill( x, y, norm );
00088 m_colormap->SetBinContent( m_colormap->FindBin(x, y), (float) colour );
00089 }
00090
00092 void XHistogram::fill( const Range& x, const Range& y, const std::vector<double> & weight, double norm )
00093 {
00094 check_weight( weight );
00095
00096 std::vector<position> v = splitSegment( x, y );
00097 for (size_t i = 0, s = v.size(); i < s; ++i) {
00098 for (size_t h = 0; h < m_size; ++h)
00099 m_histograms[h]->Fill( v[i].x, v[i].y, v[i].f * weight[h] );
00100 m_normalization->Fill( v[i].x, v[i].y, v[i].f * norm );
00101 }
00102 }
00103
00105 void XHistogram::fill( const Range& x, const Range& y, const std::vector<double> & weight, double norm, unsigned int colour )
00106 {
00107 check_weight( weight );
00108
00109 std::vector<position> v = splitSegment( x, y );
00110 for (size_t i = 0, s = v.size(); i < s; ++i) {
00111 for (size_t h = 0; h < m_size; ++h)
00112 m_histograms[h]->Fill( v[i].x, v[i].y, v[i].f * weight[h] );
00113 m_normalization->Fill( v[i].x, v[i].y, v[i].f * norm );
00114 m_colormap->SetBinContent( m_colormap->FindBin(v[i].x, v[i].y), (float) colour );
00115 }
00116 }
00117
00119 void XHistogram::normalize(void)
00120 {
00121 for (int i = 0; i < m_normalization->GetSize(); ++i) {
00122 if ((*m_normalization)[i] > 0.) {
00123 for (size_t h = 0; h < m_size; ++h)
00124 (*m_histograms[h])[i] /= (*m_normalization)[i];
00125 (*m_normalization)[i] = 1.;
00126 }
00127 }
00128 }