Skip to content

Commit

Permalink
Refs #3882 color scale on SliceViewer
Browse files Browse the repository at this point in the history
Also showing a NAN color in the color map
  • Loading branch information
Janik Zikovsky committed Nov 9, 2011
1 parent bd95540 commit bf2b4d2
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 69 deletions.
4 changes: 2 additions & 2 deletions Code/Mantid/MantidPlot/src/Mantid/MantidApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bool MantidApplication::notify( QObject * receiver, QEvent * event )
//std::cout << "MantidApplication::notify( event.type() == " << event->type() << ")\n";
res = QApplication::notify(receiver,event);
}
catch(std::exception& e)
catch(std::exception& e)
{

if (MantidQt::API::MantidDialog::handle(receiver,e))
Expand All @@ -51,7 +51,7 @@ bool MantidApplication::notify( QObject * receiver, QEvent * event )
}else
g_log.fatal("Continue working.");
}
catch(...)
catch(...)
{

g_log.fatal()<<"Unknown exception\n";
Expand Down
35 changes: 12 additions & 23 deletions Code/Mantid/MantidQt/API/inc/MantidQtAPI/MantidColorMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,50 +38,36 @@ class EXPORT_OPT_MANTIDQT_API MantidColorMap : public QwtColorMap
{

public:
/// Default constructor
MantidColorMap();

/// Constructor with a type parameter
explicit MantidColorMap(const QString & filename, GraphOptions::ScaleType type);

/// (virtual) Destructor
virtual ~MantidColorMap();

/// Create a clone of the color map
QwtColorMap* copy() const;

/// Change the scale type
void changeScaleType(GraphOptions::ScaleType type);

/**
* Retrieve the scale type
* @returns the current scale type
*/
GraphOptions::ScaleType getScaleType() const
{
return m_scale_type;
}

/// Load a color map file
bool loadMap(const QString & filename);

void setNanColor(int r, int g, int b);

/// Setup a default color map. This is used if a file is not available
void setupDefaultMap();

/// Compute an rgb value for the given data value and interval
QRgb rgb(const QwtDoubleInterval & interval, double value) const;

/// Compute fraction for the given value and range using the current scale type
double normalize(const QwtDoubleInterval &interval, double value) const;

/// Compute a color index for the given data value and interval
unsigned char colorIndex (const QwtDoubleInterval &interval, double value) const;

/// Compute a lookup table
QVector<QRgb> colorTable(const QwtDoubleInterval & interval) const;

/**
* Retrieve the scale type
* @returns the current scale type
*/
GraphOptions::ScaleType getScaleType() const
{
return m_scale_type;
}

/**
* Get the number of colors in this map
*/
Expand Down Expand Up @@ -114,6 +100,9 @@ class EXPORT_OPT_MANTIDQT_API MantidColorMap : public QwtColorMap
/// Color to show for not-a-number
QRgb m_nan_color;

/// Cached NAN value
double m_nan;

};


Expand Down
58 changes: 34 additions & 24 deletions Code/Mantid/MantidQt/API/src/MantidColorMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <iostream>
#include <QRgb>
#include <limits>

//--------------------------------------
// Public member functions
Expand All @@ -21,9 +22,12 @@
MantidColorMap::MantidColorMap() : QwtColorMap(QwtColorMap::Indexed), m_scale_type(GraphOptions::Log10),
m_colors(0), m_num_colors(0)
{
m_nan = std::numeric_limits<double>::quiet_NaN();
this->setNanColor(255,255,255);
setupDefaultMap();
}

//-------------------------------------------------------------------------------------------------
/**
* Constructor with filename and type
* @param
Expand All @@ -32,20 +36,24 @@ MantidColorMap::MantidColorMap() : QwtColorMap(QwtColorMap::Indexed), m_scale_ty
MantidColorMap::MantidColorMap(const QString & filename, GraphOptions::ScaleType type) :
QwtColorMap(QwtColorMap::Indexed), m_scale_type(type), m_colors(0), m_num_colors(0)
{
m_nan = std::numeric_limits<double>::quiet_NaN();
this->setNanColor(255,255,255);
// Check and load default if this doesn't work
if( !loadMap(filename) )
{
setupDefaultMap();
}
}

//-------------------------------------------------------------------------------------------------
/**
* Destructor
*/
MantidColorMap::~MantidColorMap()
{
}

//-------------------------------------------------------------------------------------------------
/**
* Create a clone of the color map
*/
Expand All @@ -57,6 +65,7 @@ QwtColorMap* MantidColorMap::copy() const
return map;
}

//-------------------------------------------------------------------------------------------------
/**
* Change the scale type
* @param type :: The new scale type
Expand Down Expand Up @@ -109,6 +118,8 @@ bool MantidColorMap::loadMap(const QString & filename)
{
m_num_colors = count;
m_colors = new_colormap;
if (m_num_colors > 1)
m_colors[0] = m_nan_color;
}
return is_success;
}
Expand All @@ -123,6 +134,8 @@ bool MantidColorMap::loadMap(const QString & filename)
void MantidColorMap::setNanColor(int r, int g, int b)
{
m_nan_color = qRgb(r,g,b);
if (m_num_colors > 1)
m_colors[0] = m_nan_color;
}

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -175,6 +188,7 @@ void MantidColorMap::setupDefaultMap()
}


//-------------------------------------------------------------------------------------------------
/**
* Normalize the value to the range[0,1]
* @param interval :: The data range
Expand All @@ -183,21 +197,17 @@ void MantidColorMap::setupDefaultMap()
*/
double MantidColorMap::normalize(const QwtDoubleInterval &interval, double value) const
{
if( interval.isNull() || m_num_colors == 0 )
{
return -1.0;
}
// nan numbers have the property that nan != nan, treat nan as being invalid
if( interval.isNull() || m_num_colors == 0 || value != value )
return m_nan;

const double width = interval.width();
if( width <= 0.0 || value <= interval.minValue() )
{
return 0.0;
}
// nan numbers have the property that nan != nan, treat nan as being the maximum
if ( value >= interval.maxValue() || value != value )
{

if ( value >= interval.maxValue())
return 1.0;
}

double ratio(0.0);
if( m_scale_type == GraphOptions::Linear)
{
Expand All @@ -217,32 +227,25 @@ double MantidColorMap::normalize(const QwtDoubleInterval &interval, double value
}


//-------------------------------------------------------------------------------------------------
/**
* Compute an rgb value for the given data value and interval
* @param interval :: The data range
* @param value :: Compute an RGB color for this data value
*/
QRgb MantidColorMap::rgb(const QwtDoubleInterval & interval, double value) const
{
// Special case for NAN which is != NAN
if (value != value)
return m_nan_color;

short ci = static_cast<short>(colorIndex(interval, value));
if( ci >= 0 && ci < m_num_colors )
{
return m_colors[ci];
}
// Return black
return QRgb();

// QRgb col = getColor();
// float r(0.0f), g(0.0f), b(0.0f), a(0.0f);
// col.get(r,g,b,a);
// return qRgb(int(r*255),int(g*255),int(b*255));
}


//-------------------------------------------------------------------------------------------------
/**
* Compute a color index
* @param interval :: The data range
Expand All @@ -253,21 +256,26 @@ QRgb MantidColorMap::rgb(const QwtDoubleInterval & interval, double value) const
unsigned char MantidColorMap::colorIndex (const QwtDoubleInterval &interval, double value) const
{
double fraction = normalize(interval, value);
if( fraction < 0.0 )return static_cast<unsigned char>(0);
// NAN: return index 0
if (fraction != fraction) return static_cast<unsigned char>(0);
// Below minimum: return index 1
if( fraction < 0.0 ) return static_cast<unsigned char>(1);

short index = short(std::floor(fraction * m_num_colors));
// If the ratio gives back 1 then we need to adjust the index down 1
if( index >= m_num_colors )
{
index = short(m_num_colors - 1);
}
if( index < 0 )
if( index < 1 )
{
index = 0;
index = 1;
}
return static_cast<unsigned char>(index);
}


//-------------------------------------------------------------------------------------------------
/**
* Compute a lookup table
* @param interval :: The interval for the table to cover
Expand All @@ -279,14 +287,16 @@ QVector<QRgb> MantidColorMap::colorTable(const QwtDoubleInterval & interval) con
m_scale_type = GraphOptions::Linear;

short table_size = (m_num_colors > 1) ? m_num_colors : 2;
QVector<QRgb> rgbtable(table_size);
QVector<QRgb> rgbtable(table_size+1);
if( interval.isValid() )
{
const double step = interval.width() / table_size;
for( short i = 0; i < table_size; ++i )
{
rgbtable[i] = rgb(interval, interval.minValue() + step*i);
rgbtable[i+1] = rgb(interval, interval.minValue() + step*i);
}
// Special NAN at index 0
rgbtable[0] = rgb(interval, m_nan);
}

//Restore scaling type
Expand Down
36 changes: 34 additions & 2 deletions Code/Mantid/MantidQt/API/test/MantidColorMapTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,52 @@ class MantidColorMapTest : public CxxTest::TestSuite
MantidColorMap map;
QRgb col;
col = map.rgb( QwtDoubleInterval( 0.0, 1.0 ), 0.0);
TSM_ASSERT_EQUALS("Default min color.", col, qRgb(0, 172, 252) );
TSM_ASSERT_EQUALS("Default min color.", col, qRgb(0, 170, 252) );
col = map.rgb( QwtDoubleInterval( 0.0, 1.0 ), 1.0);
TSM_ASSERT_EQUALS("Default max color.", col, qRgb(255,255,255) );
TSM_ASSERT_EQUALS("Default map is linear", map.getScaleType(), GraphOptions::Log10 );
}

void test_normalize_linear()
{
MantidColorMap map;
QwtDoubleInterval range(10.0, 20.0);
map.changeScaleType( GraphOptions::Linear );
TS_ASSERT_DELTA( map.normalize(range, 15.), 0.5, 1e-5);
}

void test_normalize_log()
{
MantidColorMap map;
QwtDoubleInterval range(1.0, 10000.0);
map.changeScaleType( GraphOptions::Log10 );
TS_ASSERT_DELTA( map.normalize(range, 1000.), 0.75, 1e-5);
}

/// Setting a NAN color
void test_nan_color()
{
MantidColorMap map;
map.setNanColor(123, 23, 34);
QRgb col;
QwtDoubleInterval range(10.0, 20.0);
double nan = std::numeric_limits<double>::quiet_NaN();
col = map.rgb( QwtDoubleInterval( 0.0, 1.0 ), nan);
col = map.rgb( range, nan);
TSM_ASSERT_EQUALS("Passing NAN to rgb returns the set color.", col, qRgb(123, 23, 34) );
}

void test_colorIndex()
{
MantidColorMap map;
QwtDoubleInterval range(10.0, 20.0);
double nan = std::numeric_limits<double>::quiet_NaN();
TSM_ASSERT_EQUALS("Color index is 0 for NAN", map.colorIndex(range, nan), 0);
TSM_ASSERT_EQUALS("Color index is 1 for small numbers", map.colorIndex(range, -123.0), 1);
TSM_ASSERT_EQUALS("Color index is 255 for large numbers", map.colorIndex(range, +123.0), 255);
}



};


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public slots:
void setSpinBoxesSteps();
void mouseDoubleClickEvent(QMouseEvent * event);
void updateMinMaxGUI();
void resizeEvent(QResizeEvent * event);

/// Auto-gen UI classes
Ui::ColorBarWidgetClass ui;
Expand All @@ -104,6 +105,9 @@ public slots:

/// Min value being displayed
double m_max;

/// Show the value tooltip (off by default)
bool m_showTooltip;
};

#endif // COLORBARWIDGET_H

0 comments on commit bf2b4d2

Please sign in to comment.