Improved logarithmic color legends for zero and negative values

p4#: 21804
This commit is contained in:
Magne Sjaastad 2013-06-03 13:08:11 +02:00
parent 1d3d13c927
commit 0021e2f861
7 changed files with 222 additions and 2 deletions

View File

@ -334,3 +334,29 @@ void RimCellEdgeResultSlot::minMaxCellEdgeValues(double& min, double& max)
max = globalMax;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCellEdgeResultSlot::posNegClosestToZero(double& pos, double& neg)
{
pos = HUGE_VAL;
neg = -HUGE_VAL;
size_t resultIndices[6];
this->gridScalarIndices(resultIndices);
size_t idx;
for (idx = 0; idx < 6; idx++)
{
if (resultIndices[idx] == cvf::UNDEFINED_SIZE_T) continue;
{
double localPos, localNeg;
m_reservoirView->currentGridCellResults()->cellResults()->posNegClosestToZero(resultIndices[idx], localPos, localNeg);
if (localPos > 0 && localPos < pos) pos = localPos;
if (localNeg < 0 && localNeg > neg) neg = localNeg;
}
}
}

View File

@ -75,6 +75,7 @@ public:
bool hasResult() const;
void minMaxCellEdgeValues(double& min, double& max);
void posNegClosestToZero(double& pos, double& neg);
protected:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);

View File

@ -97,7 +97,11 @@ RimLegendConfig::RimLegendConfig()
: m_globalAutoMax(cvf::UNDEFINED_DOUBLE),
m_globalAutoMin(cvf::UNDEFINED_DOUBLE),
m_localAutoMax(cvf::UNDEFINED_DOUBLE),
m_localAutoMin(cvf::UNDEFINED_DOUBLE)
m_localAutoMin(cvf::UNDEFINED_DOUBLE),
m_globalAutoPosClosestToZero(0),
m_globalAutoNegClosestToZero(0),
m_localAutoPosClosestToZero(0),
m_localAutoNegClosestToZero(0)
{
CAF_PDM_InitObject("Legend Definition", ":/Legend.png", "", "");
CAF_PDM_InitField(&m_numLevels, "NumberOfLevels", 8, "Number of levels", "", "","");
@ -174,28 +178,78 @@ void RimLegendConfig::updateLegend()
{
double adjustedMin = cvf::UNDEFINED_DOUBLE;
double adjustedMax = cvf::UNDEFINED_DOUBLE;
double posClosestToZero = cvf::UNDEFINED_DOUBLE;
double negClosestToZero = cvf::UNDEFINED_DOUBLE;
if (m_rangeMode == AUTOMATIC_ALLTIMESTEPS)
{
adjustedMin = adjust(m_globalAutoMin, m_precision);
adjustedMax = adjust(m_globalAutoMax, m_precision);
posClosestToZero = m_globalAutoPosClosestToZero;
negClosestToZero = m_globalAutoNegClosestToZero;
}
else if (m_rangeMode == AUTOMATIC_CURRENT_TIMESTEP)
{
adjustedMin = adjust(m_localAutoMin, m_precision);
adjustedMax = adjust(m_localAutoMax, m_precision);
posClosestToZero = m_localAutoPosClosestToZero;
negClosestToZero = m_localAutoNegClosestToZero;
}
else
{
adjustedMin = adjust(m_userDefinedMinValue, m_precision);
adjustedMax = adjust(m_userDefinedMaxValue, m_precision);
posClosestToZero = m_globalAutoPosClosestToZero;
negClosestToZero = m_globalAutoNegClosestToZero;
}
m_linDiscreteScalarMapper->setRange(adjustedMin, adjustedMax);
m_linSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
if (m_mappingMode == LOG10_CONTINUOUS || m_mappingMode == LOG10_DISCRETE)
{
if (adjustedMin != adjustedMax)
{
if (adjustedMin == 0)
{
if (adjustedMax > adjustedMin)
{
adjustedMin = posClosestToZero;
}
else
{
adjustedMin = negClosestToZero;
}
}
else if (adjustedMax == 0)
{
if (adjustedMin > adjustedMax)
{
adjustedMax = posClosestToZero;
}
else
{
adjustedMax = negClosestToZero;
}
}
else if (adjustedMin < 0 && adjustedMax > 0)
{
adjustedMin = posClosestToZero;
}
else if (adjustedMax < 0 && adjustedMin > 0)
{
adjustedMin = negClosestToZero;
}
}
}
m_logDiscreteScalarMapper->setRange(adjustedMin, adjustedMax);
m_logSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
m_linSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
cvf::Color3ubArray legendColors;
switch (m_colorRangeMode())
@ -455,3 +509,21 @@ double RimLegendConfig::adjust(double domainValue, double precision)
return newDomainValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimLegendConfig::setClosestToZeroValues(double globalPosClosestToZero, double globalNegClosestToZero, double localPosClosestToZero, double localNegClosestToZero)
{
m_globalAutoPosClosestToZero = globalPosClosestToZero;
m_globalAutoNegClosestToZero = globalNegClosestToZero;
m_localAutoPosClosestToZero = localPosClosestToZero;
m_localAutoNegClosestToZero = localNegClosestToZero;
if (m_globalAutoPosClosestToZero == HUGE_VAL) m_globalAutoPosClosestToZero = 0;
if (m_globalAutoNegClosestToZero == -HUGE_VAL) m_globalAutoNegClosestToZero = 0;
if (m_localAutoPosClosestToZero == HUGE_VAL) m_localAutoPosClosestToZero = 0;
if (m_localAutoNegClosestToZero == -HUGE_VAL) m_localAutoNegClosestToZero = 0;
updateLegend();
}

View File

@ -86,6 +86,7 @@ public:
void recreateLegend();
void setColorRangeMode(ColorRangesType colorMode);
void setAutomaticRanges(double globalMin, double globalMax, double localMin, double localMax);
void setClosestToZeroValues(double globalPosClosestToZero, double globalNegClosestToZero, double localPosClosestToZero, double localNegClosestToZero);
void setPosition(cvf::Vec2ui position);
cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); }
@ -116,6 +117,11 @@ private:
double m_localAutoMax;
double m_localAutoMin;
double m_globalAutoPosClosestToZero;
double m_globalAutoNegClosestToZero;
double m_localAutoPosClosestToZero;
double m_localAutoNegClosestToZero;
cvf::Vec2ui m_position;
// Fields

View File

@ -1156,19 +1156,27 @@ void RimReservoirView::updateLegends()
if (this->cellResult()->hasResult())
{
double globalMin, globalMax;
double globalPosClosestToZero, globalNegClosestToZero;
results->minMaxCellScalarValues(this->cellResult()->gridScalarIndex(), globalMin, globalMax);
results->posNegClosestToZero(this->cellResult()->gridScalarIndex(), globalPosClosestToZero, globalNegClosestToZero);
double localMin, localMax;
double localPosClosestToZero, localNegClosestToZero;
if (this->cellResult()->hasDynamicResult())
{
results->minMaxCellScalarValues(this->cellResult()->gridScalarIndex(), m_currentTimeStep, localMin, localMax);
results->posNegClosestToZero(this->cellResult()->gridScalarIndex(), m_currentTimeStep, localPosClosestToZero, localNegClosestToZero);
}
else
{
localMin = globalMin;
localMax = globalMax;
localPosClosestToZero = globalPosClosestToZero;
localNegClosestToZero = globalNegClosestToZero;
}
this->cellResult()->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, localPosClosestToZero, localNegClosestToZero);
this->cellResult()->legendConfig->setAutomaticRanges(globalMin, globalMax, localMin, localMax);
m_viewer->setColorLegend1(this->cellResult()->legendConfig->legend());
@ -1176,6 +1184,7 @@ void RimReservoirView::updateLegends()
}
else
{
this->cellResult()->legendConfig->setClosestToZeroValues(0, 0, 0, 0);
this->cellResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE);
m_viewer->setColorLegend1(NULL);
}
@ -1183,8 +1192,13 @@ void RimReservoirView::updateLegends()
if (this->cellEdgeResult()->hasResult())
{
double globalMin, globalMax;
double globalPosClosestToZero, globalNegClosestToZero;
this->cellEdgeResult()->minMaxCellEdgeValues(globalMin, globalMax);
this->cellEdgeResult()->posNegClosestToZero(globalPosClosestToZero, globalNegClosestToZero);
this->cellEdgeResult()->legendConfig->setClosestToZeroValues(globalPosClosestToZero, globalNegClosestToZero, globalPosClosestToZero, globalNegClosestToZero);
this->cellEdgeResult()->legendConfig->setAutomaticRanges(globalMin, globalMax, globalMin, globalMax);
m_viewer->setColorLegend2(this->cellEdgeResult()->legendConfig->legend());
this->cellEdgeResult()->legendConfig->legend()->setTitle(cvfqt::Utils::fromQString(QString("Edge Results: \n") + this->cellEdgeResult()->resultVariable));
@ -1192,6 +1206,7 @@ void RimReservoirView::updateLegends()
else
{
m_viewer->setColorLegend2(NULL);
this->cellEdgeResult()->legendConfig->setClosestToZeroValues(0, 0, 0, 0);
this->cellEdgeResult()->legendConfig->setAutomaticRanges(cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE, cvf::UNDEFINED_DOUBLE);
}
}

View File

@ -576,3 +576,99 @@ void RigCaseCellResultsData::setMustBeCalculated(size_t scalarResultIndex)
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg)
{
pos = HUGE_VAL;
neg = -HUGE_VAL;
CVF_ASSERT(scalarResultIndex < resultCount());
// Extend array and cache vars
if (scalarResultIndex >= m_posNegClosestToZero.size() )
{
m_posNegClosestToZero.resize(scalarResultIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL));
}
if (m_posNegClosestToZero[scalarResultIndex].first != HUGE_VAL)
{
pos = m_posNegClosestToZero[scalarResultIndex].first;
neg = m_posNegClosestToZero[scalarResultIndex].second;
return;
}
size_t i;
for (i = 0; i < timeStepCount(scalarResultIndex); i++)
{
double tsNeg, tsPos;
posNegClosestToZero(scalarResultIndex, i, tsPos, tsNeg);
if (tsNeg > neg && tsNeg < 0) neg = tsNeg;
if (tsPos < pos && tsPos > 0) pos = tsPos;
}
m_posNegClosestToZero[scalarResultIndex].first = pos;
m_posNegClosestToZero[scalarResultIndex].second= neg;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigCaseCellResultsData::posNegClosestToZero(size_t scalarResultIndex, size_t timeStepIndex, double& pos, double& neg)
{
pos = HUGE_VAL;
neg = -HUGE_VAL;
CVF_ASSERT(scalarResultIndex < resultCount());
if (timeStepIndex >= m_cellScalarResults[scalarResultIndex].size())
{
return;
}
if (scalarResultIndex >= m_posNegClosestToZeroPrTs.size())
{
m_posNegClosestToZeroPrTs.resize(scalarResultIndex+1);
}
if (timeStepIndex >= m_posNegClosestToZeroPrTs[scalarResultIndex].size())
{
m_posNegClosestToZeroPrTs[scalarResultIndex].resize(timeStepIndex+1, std::make_pair(HUGE_VAL, -HUGE_VAL));
}
if (m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].first != HUGE_VAL)
{
pos = m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].first;
neg = m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].second;
return;
}
std::vector<double>& values = m_cellScalarResults[scalarResultIndex][timeStepIndex];
size_t i;
for (i = 0; i < values.size(); i++)
{
if (values[i] == HUGE_VAL)
{
continue;
}
if (values[i] < pos && values[i] > 0)
{
pos = values[i];
}
if (values[i] > neg && values[i] < 0)
{
neg = values[i];
}
}
m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].first = pos;
m_posNegClosestToZeroPrTs[scalarResultIndex][timeStepIndex].second= neg;
}

View File

@ -41,6 +41,8 @@ public:
void recalculateMinMax(size_t scalarResultIndex);
void minMaxCellScalarValues(size_t scalarResultIndex, double& min, double& max);
void minMaxCellScalarValues(size_t scalarResultIndex, size_t timeStepIndex, double& min, double& max);
void posNegClosestToZero(size_t scalarResultIndex, double& pos, double& neg);
void posNegClosestToZero(size_t scalarResultIndex, size_t timeStepIndex, double& pos, double& neg);
const std::vector<size_t>& cellScalarValuesHistogram(size_t scalarResultIndex);
void p10p90CellScalarValues(size_t scalarResultIndex, double& p10, double& p90);
void meanCellScalarValues(size_t scalarResultIndex, double& meanValue);
@ -107,11 +109,13 @@ public:
private:
std::vector< std::vector< std::vector<double> > > m_cellScalarResults; ///< Scalar results on the complete reservoir for each Result index (ResultVariable) and timestep
std::vector< std::pair<double, double> > m_maxMinValues; ///< Max min values for each Result index
std::vector< std::pair<double, double> > m_posNegClosestToZero;
std::vector< std::vector<size_t> > m_histograms; ///< Histogram for each Result Index
std::vector< std::pair<double, double> > m_p10p90; ///< P10 and p90 values for each Result Index
std::vector< double > m_meanValues; ///< Mean value for each Result Index
std::vector< std::vector< std::pair<double, double> > > m_maxMinValuesPrTs; ///< Max min values for each Result index and timestep
std::vector< std::vector< std::pair<double, double> > > m_posNegClosestToZeroPrTs;