mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 15:10:22 -05:00
Add BinningMode (Linear/Logarithmic) and OutOfRangeHandling (Exclude/Include in Boundary Bins) to RigHistogramCalculator, with defaulted constructor arguments so existing callers are unaffected. All four histogram plot data sources get shared options for binning mode and an optional user-defined bin range through new PDM fields on RimHistogramDataSource. The grid statistics data source computes non-default histograms through a new non-caching RigStatisticsDataCache::computeHistogram() pass-through, leaving the cached statistics used by the 3D overlay and the P10/P90/mean annotation lines untouched. Selecting logarithmic binning enables logarithmic scale on the plot X axis once, via a new signal handled by RimHistogramCurve. Also fix the bin index computation to use uniform bins of width range/nBins, consistent with calculatePercentil() and the bin edges drawn by the plots. The previous divisor (nBins - 1) shifted counts by up to one bin width relative to the drawn bars and slightly biased histogram-based percentile estimates.
620 lines
30 KiB
C++
620 lines
30 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2020 Equinor ASA
|
|
//
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RimHistogramCalculator.h"
|
|
|
|
#include "RiaResultNames.h"
|
|
|
|
#include "ContourMap/RigContourMapProjection.h"
|
|
#include "RigEclipseMultiPropertyStatCalc.h"
|
|
#include "RigEclipseNativeVisibleCellsStatCalc.h"
|
|
#include "RigFemNativeVisibleCellsStatCalc.h"
|
|
#include "RigFemPartResultsCollection.h"
|
|
#include "RigFemResultAddress.h"
|
|
#include "RigFlowDiagResults.h"
|
|
#include "RigFlowDiagVisibleCellsStatCalc.h"
|
|
#include "RigGeoMechCaseData.h"
|
|
#include "RigStatisticsMath.h"
|
|
|
|
#include <limits>
|
|
|
|
#include "ContourMap/RimEclipseContourMapProjection.h"
|
|
#include "ContourMap/RimEclipseContourMapView.h"
|
|
#include "RimEclipseCellColors.h"
|
|
#include "RimEclipseView.h"
|
|
#include "RimGeoMechCase.h"
|
|
#include "RimGeoMechContourMapView.h"
|
|
#include "RimGeoMechResultDefinition.h"
|
|
#include "RimGeoMechView.h"
|
|
|
|
#include "cafAssert.h"
|
|
|
|
namespace caf
|
|
{
|
|
template <>
|
|
void caf::AppEnum<RimHistogramCalculator::StatisticsTimeRangeType>::setUp()
|
|
{
|
|
addItem( RimHistogramCalculator::StatisticsTimeRangeType::ALL_TIMESTEPS, "ALL_TIMESTEPS", "All Time Steps" );
|
|
addItem( RimHistogramCalculator::StatisticsTimeRangeType::CURRENT_TIMESTEP, "CURRENT_TIMESTEP", "Current Time Step" );
|
|
setDefault( RimHistogramCalculator::StatisticsTimeRangeType::ALL_TIMESTEPS );
|
|
}
|
|
} // namespace caf
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
namespace caf
|
|
{
|
|
template <>
|
|
void caf::AppEnum<RimHistogramCalculator::StatisticsCellRangeType>::setUp()
|
|
{
|
|
addItem( RimHistogramCalculator::StatisticsCellRangeType::ALL_CELLS, "ALL_CELLS", "All Active Cells" );
|
|
addItem( RimHistogramCalculator::StatisticsCellRangeType::VISIBLE_CELLS, "VISIBLE_CELLS", "Visible Cells" );
|
|
setDefault( RimHistogramCalculator::StatisticsCellRangeType::ALL_CELLS );
|
|
}
|
|
} // namespace caf
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimHistogramCalculator::RimHistogramCalculator()
|
|
: m_isVisCellStatUpToDate( false )
|
|
, m_numBins( RigStatisticsDataCache::defaultNumBins() )
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimHistogramCalculator::setNumBins( size_t numBins )
|
|
{
|
|
m_numBins = numBins;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimHistogramCalculator::setBinningParameters( RigHistogramCalculator::BinningMode binningMode,
|
|
RigHistogramCalculator::OutOfRangeHandling outOfRangeHandling,
|
|
std::optional<std::pair<double, double>> customBinRange )
|
|
{
|
|
m_binningMode = binningMode;
|
|
m_outOfRangeHandling = outOfRangeHandling;
|
|
m_customBinRange = customBinRange;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Recompute the histogram with non-default binning (logarithmic and/or a custom bin range) directly
|
|
/// from the underlying data. The statistics cached for other consumers are left untouched.
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimHistogramCalculator::applyCustomBinning( RigStatisticsDataCache* statisticsCache,
|
|
std::optional<size_t> timeStepIndex,
|
|
RigHistogramData& histData )
|
|
{
|
|
const bool useCustomBinning = ( m_binningMode != RigHistogramCalculator::BinningMode::LINEAR ) || m_customBinRange.has_value();
|
|
if ( !useCustomBinning || !statisticsCache ) return;
|
|
|
|
double binMin = m_customBinRange ? m_customBinRange->first : histData.min;
|
|
double binMax = m_customBinRange ? m_customBinRange->second : histData.max;
|
|
|
|
if ( m_binningMode == RigHistogramCalculator::BinningMode::LOGARITHMIC && binMin <= 0.0 )
|
|
{
|
|
// Use the smallest positive value as the logarithmic range minimum. HUGE_VAL when there are none.
|
|
double pos = HUGE_VAL;
|
|
double neg = -HUGE_VAL;
|
|
if ( timeStepIndex.has_value() )
|
|
statisticsCache->posNegClosestToZero( *timeStepIndex, pos, neg );
|
|
else
|
|
statisticsCache->posNegClosestToZero( pos, neg );
|
|
|
|
binMin = pos;
|
|
}
|
|
|
|
histData.histogram.clear();
|
|
|
|
if ( binMin <= binMax && RigStatisticsTools::isValidNumber( binMin ) && RigStatisticsTools::isValidNumber( binMax ) )
|
|
{
|
|
RigHistogramCalculator histCalc( binMin, binMax, m_numBins, &histData.histogram, m_binningMode, m_outOfRangeHandling );
|
|
if ( timeStepIndex.has_value() )
|
|
statisticsCache->computeHistogram( *timeStepIndex, histCalc );
|
|
else
|
|
statisticsCache->computeHistogram( histCalc );
|
|
|
|
// Let the plot draw bin edges that match the histogram
|
|
histData.min = binMin;
|
|
histData.max = binMax;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimHistogramCalculator::invalidateVisibleCellsCache()
|
|
{
|
|
m_isVisCellStatUpToDate = false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigHistogramData RimHistogramCalculator::histogramData( RimEclipseContourMapView* contourMap )
|
|
{
|
|
RigHistogramData histData;
|
|
|
|
if ( contourMap && contourMap->contourMapProjection() && contourMap->contourMapProjection()->mapProjection() )
|
|
{
|
|
auto mapProjection = contourMap->contourMapProjection()->mapProjection();
|
|
bool isResultsInfoRelevant = mapProjection->numberOfValidCells() > 0u;
|
|
|
|
if ( isResultsInfoRelevant )
|
|
{
|
|
histData.min = mapProjection->minValue();
|
|
histData.max = mapProjection->maxValue();
|
|
histData.mean = mapProjection->meanValue();
|
|
histData.sum = mapProjection->sumAllValues();
|
|
|
|
RigHistogramCalculator histCalc( histData.min, histData.max, m_numBins, &histData.histogram );
|
|
for ( double value : mapProjection->aggregatedResults() )
|
|
{
|
|
if ( value != std::numeric_limits<double>::infinity() ) histCalc.addValue( value );
|
|
}
|
|
}
|
|
}
|
|
return histData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigHistogramData RimHistogramCalculator::histogramData( RimGeoMechContourMapView* contourMap )
|
|
{
|
|
RigHistogramData histData;
|
|
|
|
if ( contourMap && contourMap->contourMapProjection() && contourMap->contourMapProjection()->mapProjection() )
|
|
{
|
|
auto mapProjection = contourMap->contourMapProjection()->mapProjection();
|
|
bool isResultsInfoRelevant = mapProjection->numberOfValidCells() > 0u;
|
|
|
|
if ( isResultsInfoRelevant )
|
|
{
|
|
histData.min = mapProjection->minValue();
|
|
histData.max = mapProjection->maxValue();
|
|
histData.mean = mapProjection->meanValue();
|
|
histData.sum = mapProjection->sumAllValues();
|
|
|
|
RigHistogramCalculator histCalc( histData.min, histData.max, m_numBins, &histData.histogram );
|
|
for ( double value : mapProjection->aggregatedResults() )
|
|
{
|
|
if ( value != std::numeric_limits<double>::infinity() ) histCalc.addValue( value );
|
|
}
|
|
}
|
|
}
|
|
return histData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigHistogramData
|
|
RimHistogramCalculator::histogramData( RimEclipseView* eclipseView, StatisticsCellRangeType cellRange, StatisticsTimeRangeType timeRange )
|
|
{
|
|
if ( eclipseView )
|
|
{
|
|
RimEclipseResultDefinition* eclResultDefinition = eclipseView->cellResult();
|
|
bool isResultsInfoRelevant = eclResultDefinition->hasResult();
|
|
|
|
if ( isResultsInfoRelevant )
|
|
{
|
|
RigEclipseResultAddress eclResAddr = eclResultDefinition->eclipseResultAddress();
|
|
|
|
if ( eclResAddr.isValid() )
|
|
{
|
|
int currentTimeStep = eclipseView->currentTimeStep();
|
|
if ( eclipseView->cellResult()->hasStaticResult() )
|
|
{
|
|
currentTimeStep = 0;
|
|
}
|
|
|
|
return histogramData( eclipseView, eclResultDefinition, cellRange, timeRange, currentTimeStep );
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
RigHistogramData data;
|
|
return data;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigHistogramData RimHistogramCalculator::histogramData( RimEclipseView* eclipseView,
|
|
RimEclipseResultDefinition* eclResultDefinition,
|
|
StatisticsCellRangeType cellRange,
|
|
StatisticsTimeRangeType timeRange,
|
|
int timeStep )
|
|
{
|
|
CAF_ASSERT( eclResultDefinition );
|
|
|
|
RigHistogramData histData;
|
|
|
|
RigStatisticsDataCache* statisticsCache = nullptr;
|
|
std::optional<size_t> timeStepContext;
|
|
|
|
eclResultDefinition->loadResult();
|
|
|
|
if ( eclResultDefinition->isFlowDiagOrInjectionFlooding() )
|
|
{
|
|
if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP )
|
|
{
|
|
if ( cellRange == StatisticsCellRangeType::ALL_CELLS )
|
|
{
|
|
RigFlowDiagResults* fldResults = eclResultDefinition->flowDiagSolution()->flowDiagResults();
|
|
RigFlowDiagResultAddress resAddr = eclResultDefinition->flowDiagResAddress();
|
|
|
|
fldResults->setStatisticsDataCacheNumBins( resAddr, m_numBins );
|
|
fldResults->minMaxScalarValues( resAddr, timeStep, &histData.min, &histData.max );
|
|
fldResults->p10p90ScalarValues( resAddr, timeStep, &histData.p10, &histData.p90 );
|
|
fldResults->meanScalarValue( resAddr, timeStep, &histData.mean );
|
|
fldResults->sumScalarValue( resAddr, timeStep, &histData.sum );
|
|
fldResults->mobileVolumeWeightedMean( resAddr, timeStep, &histData.weightedMean );
|
|
|
|
histData.histogram = fldResults->scalarValuesHistogram( resAddr, timeStep );
|
|
|
|
statisticsCache = fldResults->statistics( resAddr );
|
|
timeStepContext = static_cast<size_t>( timeStep );
|
|
}
|
|
else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS )
|
|
{
|
|
CAF_ASSERT( eclipseView );
|
|
|
|
updateVisCellStatsIfNeeded( eclipseView, eclResultDefinition );
|
|
|
|
m_visibleCellStatistics->setNumBins( m_numBins );
|
|
m_visibleCellStatistics->meanCellScalarValues( timeStep, histData.mean );
|
|
m_visibleCellStatistics->minMaxCellScalarValues( timeStep, histData.min, histData.max );
|
|
m_visibleCellStatistics->p10p90CellScalarValues( timeStep, histData.p10, histData.p90 );
|
|
m_visibleCellStatistics->sumCellScalarValues( timeStep, histData.sum );
|
|
m_visibleCellStatistics->mobileVolumeWeightedMean( timeStep, histData.weightedMean );
|
|
|
|
histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram( timeStep );
|
|
|
|
statisticsCache = m_visibleCellStatistics.p();
|
|
timeStepContext = static_cast<size_t>( timeStep );
|
|
}
|
|
}
|
|
else if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS )
|
|
{
|
|
if ( cellRange == StatisticsCellRangeType::ALL_CELLS )
|
|
{
|
|
RigFlowDiagResults* fldResults = eclResultDefinition->flowDiagSolution()->flowDiagResults();
|
|
RigFlowDiagResultAddress resAddr = eclResultDefinition->flowDiagResAddress();
|
|
|
|
fldResults->setStatisticsDataCacheNumBins( resAddr, m_numBins );
|
|
fldResults->minMaxScalarValues( resAddr, &histData.min, &histData.max );
|
|
fldResults->p10p90ScalarValues( resAddr, &histData.p10, &histData.p90 );
|
|
fldResults->meanScalarValue( resAddr, &histData.mean );
|
|
fldResults->sumScalarValue( resAddr, &histData.sum );
|
|
fldResults->mobileVolumeWeightedMean( resAddr, &histData.weightedMean );
|
|
|
|
histData.histogram = fldResults->scalarValuesHistogram( resAddr );
|
|
|
|
statisticsCache = fldResults->statistics( resAddr );
|
|
}
|
|
else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS )
|
|
{
|
|
CAF_ASSERT( eclipseView );
|
|
|
|
updateVisCellStatsIfNeeded( eclipseView, eclResultDefinition );
|
|
|
|
m_visibleCellStatistics->setNumBins( m_numBins );
|
|
m_visibleCellStatistics->meanCellScalarValues( histData.mean );
|
|
m_visibleCellStatistics->minMaxCellScalarValues( histData.min, histData.max );
|
|
m_visibleCellStatistics->p10p90CellScalarValues( histData.p10, histData.p90 );
|
|
m_visibleCellStatistics->sumCellScalarValues( histData.sum );
|
|
m_visibleCellStatistics->mobileVolumeWeightedMean( histData.weightedMean );
|
|
|
|
histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram();
|
|
|
|
statisticsCache = m_visibleCellStatistics.p();
|
|
}
|
|
}
|
|
}
|
|
else if ( cellRange == StatisticsCellRangeType::ALL_CELLS )
|
|
{
|
|
RigEclipseResultAddress eclResAddr = eclResultDefinition->eclipseResultAddress();
|
|
RigCaseCellResultsData* cellResults = eclResultDefinition->currentGridCellResults();
|
|
if ( cellResults && eclResAddr.isValid() && cellResults->hasResultEntry( eclResAddr ) )
|
|
{
|
|
if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS )
|
|
{
|
|
cellResults->setStatisticsDataCacheNumBins( eclResAddr, m_numBins );
|
|
cellResults->minMaxCellScalarValues( eclResAddr, histData.min, histData.max );
|
|
cellResults->p10p90CellScalarValues( eclResAddr, histData.p10, histData.p90 );
|
|
cellResults->meanCellScalarValues( eclResAddr, histData.mean );
|
|
cellResults->sumCellScalarValues( eclResAddr, histData.sum );
|
|
cellResults->mobileVolumeWeightedMean( eclResAddr, histData.weightedMean );
|
|
histData.histogram = cellResults->cellScalarValuesHistogram( eclResAddr );
|
|
|
|
statisticsCache = cellResults->statistics( eclResAddr );
|
|
}
|
|
else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP )
|
|
{
|
|
cellResults->setStatisticsDataCacheNumBins( eclResAddr, m_numBins );
|
|
cellResults->minMaxCellScalarValues( eclResAddr, timeStep, histData.min, histData.max );
|
|
cellResults->p10p90CellScalarValues( eclResAddr, timeStep, histData.p10, histData.p90 );
|
|
cellResults->meanCellScalarValues( eclResAddr, timeStep, histData.mean );
|
|
cellResults->sumCellScalarValues( eclResAddr, timeStep, histData.sum );
|
|
cellResults->mobileVolumeWeightedMean( eclResAddr, timeStep, histData.weightedMean );
|
|
histData.histogram = cellResults->cellScalarValuesHistogram( eclResAddr, timeStep );
|
|
|
|
statisticsCache = cellResults->statistics( eclResAddr );
|
|
timeStepContext = static_cast<size_t>( timeStep );
|
|
}
|
|
}
|
|
}
|
|
else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS )
|
|
{
|
|
CAF_ASSERT( eclipseView );
|
|
updateVisCellStatsIfNeeded( eclipseView, eclResultDefinition );
|
|
if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS )
|
|
{
|
|
// TODO: Only valid if we have no dynamic property filter
|
|
m_visibleCellStatistics->setNumBins( m_numBins );
|
|
m_visibleCellStatistics->meanCellScalarValues( histData.mean );
|
|
m_visibleCellStatistics->minMaxCellScalarValues( histData.min, histData.max );
|
|
m_visibleCellStatistics->p10p90CellScalarValues( histData.p10, histData.p90 );
|
|
m_visibleCellStatistics->sumCellScalarValues( histData.sum );
|
|
m_visibleCellStatistics->mobileVolumeWeightedMean( histData.weightedMean );
|
|
|
|
histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram();
|
|
|
|
statisticsCache = m_visibleCellStatistics.p();
|
|
}
|
|
else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP )
|
|
{
|
|
m_visibleCellStatistics->setNumBins( m_numBins );
|
|
m_visibleCellStatistics->meanCellScalarValues( timeStep, histData.mean );
|
|
m_visibleCellStatistics->minMaxCellScalarValues( timeStep, histData.min, histData.max );
|
|
m_visibleCellStatistics->p10p90CellScalarValues( timeStep, histData.p10, histData.p90 );
|
|
m_visibleCellStatistics->sumCellScalarValues( timeStep, histData.sum );
|
|
m_visibleCellStatistics->mobileVolumeWeightedMean( timeStep, histData.weightedMean );
|
|
|
|
histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram( timeStep );
|
|
|
|
statisticsCache = m_visibleCellStatistics.p();
|
|
timeStepContext = static_cast<size_t>( timeStep );
|
|
}
|
|
}
|
|
|
|
applyCustomBinning( statisticsCache, timeStepContext, histData );
|
|
|
|
return histData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigHistogramData
|
|
RimHistogramCalculator::histogramData( RimGeoMechView* geoMechView, StatisticsCellRangeType cellRange, StatisticsTimeRangeType timeRange )
|
|
{
|
|
RigHistogramData histData;
|
|
|
|
if ( geoMechView )
|
|
{
|
|
RimGeoMechCase* geoMechCase = geoMechView->geoMechCase();
|
|
RigGeoMechCaseData* caseData = geoMechCase ? geoMechCase->geoMechData() : nullptr;
|
|
bool isResultsInfoRelevant = caseData && geoMechView->cellResultResultDefinition()->hasResult();
|
|
|
|
if ( isResultsInfoRelevant )
|
|
{
|
|
RigFemResultAddress resAddress = geoMechView->cellResultResultDefinition()->resultAddress();
|
|
if ( cellRange == StatisticsCellRangeType::ALL_CELLS )
|
|
{
|
|
if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS )
|
|
{
|
|
caseData->femPartResults()->meanScalarValue( resAddress, &histData.mean );
|
|
caseData->femPartResults()->minMaxScalarValues( resAddress, &histData.min, &histData.max );
|
|
caseData->femPartResults()->p10p90ScalarValues( resAddress, &histData.p10, &histData.p90 );
|
|
caseData->femPartResults()->sumScalarValue( resAddress, &histData.sum );
|
|
|
|
histData.histogram = caseData->femPartResults()->scalarValuesHistogram( resAddress );
|
|
}
|
|
else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP )
|
|
{
|
|
auto [timeStepIdx, frameIdx] = geoMechView->currentStepAndDataFrame();
|
|
caseData->femPartResults()->meanScalarValue( resAddress, timeStepIdx, frameIdx, &histData.mean );
|
|
caseData->femPartResults()->minMaxScalarValues( resAddress, timeStepIdx, frameIdx, &histData.min, &histData.max );
|
|
caseData->femPartResults()->p10p90ScalarValues( resAddress, timeStepIdx, frameIdx, &histData.p10, &histData.p90 );
|
|
caseData->femPartResults()->sumScalarValue( resAddress, timeStepIdx, frameIdx, &histData.sum );
|
|
|
|
histData.histogram = caseData->femPartResults()->scalarValuesHistogram( resAddress, timeStepIdx, frameIdx );
|
|
}
|
|
}
|
|
else if ( cellRange == StatisticsCellRangeType::VISIBLE_CELLS )
|
|
{
|
|
updateVisCellStatsIfNeeded( geoMechView );
|
|
|
|
if ( timeRange == StatisticsTimeRangeType::ALL_TIMESTEPS )
|
|
{
|
|
// TODO: Only valid if we have no dynamic property filter
|
|
m_visibleCellStatistics->meanCellScalarValues( histData.mean );
|
|
m_visibleCellStatistics->minMaxCellScalarValues( histData.min, histData.max );
|
|
m_visibleCellStatistics->p10p90CellScalarValues( histData.p10, histData.p90 );
|
|
m_visibleCellStatistics->sumCellScalarValues( histData.sum );
|
|
|
|
histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram();
|
|
}
|
|
else if ( timeRange == StatisticsTimeRangeType::CURRENT_TIMESTEP )
|
|
{
|
|
int timeStepIdx = geoMechView->currentTimeStep();
|
|
m_visibleCellStatistics->meanCellScalarValues( timeStepIdx, histData.mean );
|
|
m_visibleCellStatistics->minMaxCellScalarValues( timeStepIdx, histData.min, histData.max );
|
|
m_visibleCellStatistics->p10p90CellScalarValues( timeStepIdx, histData.p10, histData.p90 );
|
|
m_visibleCellStatistics->sumCellScalarValues( timeStepIdx, histData.sum );
|
|
|
|
histData.histogram = m_visibleCellStatistics->cellScalarValuesHistogram( timeStepIdx );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return histData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimHistogramCalculator::updateVisCellStatsIfNeeded( RimGeoMechView* geoMechView )
|
|
{
|
|
if ( m_isVisCellStatUpToDate ) return;
|
|
|
|
cvf::ref<RigStatisticsCalculator> calc;
|
|
if ( geoMechView )
|
|
{
|
|
RigFemResultAddress resAddress = geoMechView->cellResultResultDefinition()->resultAddress();
|
|
calc = new RigFemNativeVisibleCellsStatCalc( geoMechView->geoMechCase()->geoMechData(),
|
|
resAddress,
|
|
geoMechView->currentTotalCellVisibility().p() );
|
|
}
|
|
|
|
m_visibleCellStatistics = new RigStatisticsDataCache( calc.p() );
|
|
m_isVisCellStatUpToDate = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimHistogramCalculator::updateVisCellStatsIfNeeded( RimEclipseView* eclipseView, RimEclipseResultDefinition* eclResultDefinition )
|
|
{
|
|
CAF_ASSERT( eclipseView );
|
|
CAF_ASSERT( eclResultDefinition );
|
|
|
|
if ( m_isVisCellStatUpToDate ) return;
|
|
|
|
eclipseView->cellResult()->loadResult();
|
|
|
|
cvf::ref<RigStatisticsCalculator> calc;
|
|
|
|
if ( eclResultDefinition->isFlowDiagOrInjectionFlooding() )
|
|
{
|
|
RigFlowDiagResultAddress resAddr = eclResultDefinition->flowDiagResAddress();
|
|
RigFlowDiagResults* fldResults = eclResultDefinition->flowDiagSolution()->flowDiagResults();
|
|
calc = new RigFlowDiagVisibleCellsStatCalc( fldResults, resAddr, eclipseView->currentTotalCellVisibility().p() );
|
|
}
|
|
else
|
|
{
|
|
RigEclipseResultAddress resAddr = eclResultDefinition->eclipseResultAddress();
|
|
|
|
QString resultName = resAddr.resultName();
|
|
|
|
std::vector<RigEclipseResultAddress> addresses = sourcesForMultiPropertyResults( resultName );
|
|
if ( !addresses.empty() )
|
|
{
|
|
cvf::ref<RigEclipseMultiPropertyStatCalc> multicalc = new RigEclipseMultiPropertyStatCalc();
|
|
|
|
for ( RigEclipseResultAddress& compResAddr : addresses )
|
|
{
|
|
cvf::ref<RigEclipseNativeVisibleCellsStatCalc> singleCalc =
|
|
new RigEclipseNativeVisibleCellsStatCalc( eclResultDefinition->currentGridCellResults(),
|
|
compResAddr,
|
|
eclipseView->currentTotalCellVisibility().p() );
|
|
multicalc->addStatisticsCalculator( singleCalc.p() );
|
|
}
|
|
|
|
calc = multicalc;
|
|
}
|
|
else
|
|
{
|
|
calc = new RigEclipseNativeVisibleCellsStatCalc( eclResultDefinition->currentGridCellResults(),
|
|
resAddr,
|
|
eclipseView->currentTotalCellVisibility().p() );
|
|
}
|
|
}
|
|
|
|
m_visibleCellStatistics = new RigStatisticsDataCache( calc.p() );
|
|
m_isVisCellStatUpToDate = true;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<RigEclipseResultAddress> RimHistogramCalculator::sourcesForMultiPropertyResults( const QString& resultName )
|
|
{
|
|
static const std::map<QString, std::vector<RigEclipseResultAddress>> resultsWithMultiPropertySource =
|
|
{ { RiaResultNames::combinedTransmissibilityResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANX" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANY" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "TRANZ" ) } },
|
|
{ RiaResultNames::combinedMultResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTX-" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTY-" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, "MULTZ-" ) } },
|
|
{ RiaResultNames::combinedRiTranResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranXResultName() ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranYResultName() ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riTranZResultName() ) } },
|
|
{ RiaResultNames::combinedRiMultResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultXResultName() ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultYResultName() ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riMultZResultName() ) } },
|
|
{ RiaResultNames::combinedRiAreaNormTranResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranXResultName() ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranYResultName() ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::STATIC_NATIVE, RiaResultNames::riAreaNormTranZResultName() ) } },
|
|
{ RiaResultNames::combinedWaterFluxResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATI+" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATJ+" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRWATK+" ) } },
|
|
{ RiaResultNames::combinedOilFluxResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILI+" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILJ+" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLROILK+" ) } },
|
|
{ RiaResultNames::combinedGasFluxResultName(),
|
|
{ RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASI+" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASJ+" ),
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::DYNAMIC_NATIVE, "FLRGASK+" ) } } };
|
|
|
|
auto resNameResultAddrsPairIt = resultsWithMultiPropertySource.find( resultName );
|
|
|
|
if ( resNameResultAddrsPairIt != resultsWithMultiPropertySource.end() )
|
|
{
|
|
return resNameResultAddrsPairIt->second;
|
|
}
|
|
else if ( resultName.endsWith( "IJK" ) )
|
|
{
|
|
std::vector<RigEclipseResultAddress> resultAddrs;
|
|
|
|
QString baseName = resultName.left( resultName.size() - 3 );
|
|
QStringList endings = { "I", "J", "K" };
|
|
|
|
for ( QString ending : endings )
|
|
{
|
|
resultAddrs.emplace_back( RigEclipseResultAddress( RiaDefines::ResultCatType::GENERATED, baseName + ending ) );
|
|
}
|
|
|
|
return resultAddrs;
|
|
}
|
|
else
|
|
{
|
|
return std::vector<RigEclipseResultAddress>();
|
|
}
|
|
}
|