LCOV - code coverage report
Current view: top level - render - Histogram.cpp (source / functions) Hit Total Coverage
Test: Lexis Lines: 49 80 61.2 %
Date: 2017-10-26 03:19:55 Functions: 7 14 50.0 %

          Line data    Source code
       1             : /* Copyright (c) 2016-2017, Human Brain Project
       2             :  *                          Ahmet.Bilgili@epfl.ch
       3             :  */
       4             : 
       5             : #include "Histogram.h"
       6             : 
       7             : #include <vmmlib/vector.hpp>
       8             : 
       9             : namespace lexis
      10             : {
      11             : namespace render
      12             : {
      13             : 
      14           5 : Histogram::Histogram()
      15             : {
      16           5 :     setMin( std::numeric_limits<float>::infinity( ));
      17           5 :     setMax( -std::numeric_limits<float>::infinity( ));
      18           5 : }
      19             : 
      20           1 : Histogram& Histogram::operator+=( const Histogram& histogram )
      21             : {
      22           1 :     if( histogram.getBins().empty( ))
      23           0 :         return *this;
      24             : 
      25           1 :     if( getBins().empty( ))
      26             :     {
      27           0 :         *this = histogram;
      28           0 :         return *this;
      29             :     }
      30             : 
      31           1 :     if( histogram.getBins().size() != getBins().size( ))
      32           0 :         throw std::runtime_error( "Addition of incompatible histograms" );
      33             : 
      34           1 :     const uint64_t* srcBins = histogram.getBins().data();
      35             : 
      36           1 :     uint64_t* bins = getBins().data();
      37           5 :     for( size_t i = 0; i < getBins().size(); ++i )
      38           4 :         bins[ i ] += srcBins[ i ];
      39             : 
      40           1 :     setMin( std::min( getMin(), histogram.getMin()));
      41           1 :     setMax( std::max( getMax(), histogram.getMax()));
      42             : 
      43           1 :     return *this;
      44             : }
      45             : 
      46           7 : bool Histogram::operator==( const Histogram& rhs ) const
      47             : {
      48           7 :     if( this == &rhs )
      49           1 :         return true;
      50             : 
      51          12 :     return getMin() == rhs.getMin() &&
      52          11 :            getMax() == rhs.getMax() &&
      53          14 :            getBins().size() == rhs.getBins().size() &&
      54           3 :            memcmp( getBins().data(), rhs.getBins().data(),
      55           9 :                    getBins().size() * sizeof( uint64_t ) ) == 0;
      56             : }
      57             : 
      58           0 : bool Histogram::operator!=( const Histogram& rhs ) const
      59             : {
      60           0 :     return !(*this == rhs);
      61             : }
      62             : 
      63           0 : size_t Histogram::getMinIndex() const
      64             : {
      65           0 :     const uint64_t* bins = getBins().data();
      66           0 :     return std::distance( bins, std::min_element( bins, bins + getBins().size( )));
      67             : }
      68             : 
      69           0 : size_t Histogram::getMaxIndex() const
      70             : {
      71           0 :     const uint64_t* bins = getBins().data();
      72           0 :     return std::distance( bins, std::max_element( bins, bins + getBins().size( )));
      73             : }
      74             : 
      75           4 : bool Histogram::isEmpty() const
      76             : {
      77           4 :     const uint64_t* bins = getBins().data();
      78           4 :     for( size_t i = 0; i < getBins().size(); ++i )
      79             :     {
      80           3 :         if( bins[ i ] > 0 )
      81           3 :             return false;
      82             :     }
      83           1 :     return true;
      84             : }
      85             : 
      86           0 : uint64_t Histogram::getSum() const
      87             : {
      88           0 :     const uint64_t* bins = getBins().data();
      89           0 :     uint64_t sum = 0;
      90           0 :     for( size_t i = 0; i < getBins().size(); ++i )
      91           0 :         sum +=  bins[ i ];
      92             : 
      93           0 :     return sum;
      94             : }
      95             : 
      96           0 : vmml::Vector2f Histogram::getRange() const
      97             : {
      98           0 :     return { getMin(), getMax() };
      99             : }
     100             : 
     101           0 : double Histogram::getRatio( const size_t index ) const
     102             : {
     103           0 :     if( index >= getBins().size( ))
     104           0 :         return 0.0f;
     105             : 
     106           0 :     const uint64_t sum = getSum();
     107           0 :     if( sum == 0 )
     108           0 :         return 0.0f;
     109             : 
     110           0 :     const uint64_t* bins = getBins().data();
     111           0 :     return (double)bins[ index ] / (double)sum;
     112             : }
     113             : 
     114           0 : void Histogram::resize( size_t newSize )
     115             : {
     116           0 :     getBins().resize( newSize );
     117           0 : }
     118             : 
     119             : std::vector< vmml::Vector2f >
     120           4 : Histogram::sampleCurve( const bool logScale, const vmml::Vector2f& range ) const
     121             : {
     122           4 :     if( isEmpty( ))
     123           1 :         return {};
     124             : 
     125           3 :     const auto* bins = getBins().data();
     126           3 :     const auto maxIndex = std::distance( bins,
     127           6 :                    std::max_element( bins, bins + getBins().size() ));
     128           3 :     const auto heightMax = bins[maxIndex];
     129           3 :     const float scale = 1.f/ (logScale ? std::log(heightMax) : heightMax);
     130             : 
     131           3 :     const size_t nbBins = std::ceil(getBins().size() * (range[1] - range[0]));
     132           3 :     const size_t offset( std::floor(getBins().size() * range[0] ));
     133             : 
     134           6 :     std::vector< vmml::Vector2f > points;
     135           3 :     points.reserve( nbBins );
     136          13 :     for( size_t i = 0; i < nbBins; ++i )
     137             :     {
     138          10 :         float value = bins[offset + i];
     139          10 :         if( logScale && value <= 1.0f )
     140           1 :             value = 1.0f;
     141          40 :         points.push_back( { float(i)/nbBins,
     142          30 :                             1.f - scale * (logScale ? std::log(value) : value) });
     143             :     }
     144           3 :     return points;
     145             : }
     146             : 
     147             : }
     148          12 : }

Generated by: LCOV version 1.11