mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
parent
2f580a0c52
commit
414ee77aa8
@ -39,6 +39,8 @@
|
||||
#include "RimWellLogPlot.h"
|
||||
#include "RimWellLogTrack.h"
|
||||
|
||||
#include "RigWellLogIndexDepthOffset.h"
|
||||
|
||||
#include "RiuAbstractLegendFrame.h"
|
||||
#include "RiuDraggableOverlayFrame.h"
|
||||
#include "RiuPlotMainWindow.h"
|
||||
@ -49,6 +51,8 @@
|
||||
#include "cafPdmUiItem.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include "qwt_plot_curve.h"
|
||||
#include "qwt_symbol.h"
|
||||
|
||||
@ -97,6 +101,7 @@ RimEnsembleWellLogCurveSet::RimEnsembleWellLogCurveSet()
|
||||
CAF_PDM_InitFieldNoDefault( &m_wellLogChannelName, "WellLogChannelName", "Well Log Channel Name", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_ensembleCurveSet, "FilterEnsembleCurveSet", "Filter by Ensemble Curve Set", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_depthEqualization, "DepthEqualization", "Depth Equalization", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_colorMode, "ColorMode", caf::AppEnum<ColorMode>( ColorMode::SINGLE_COLOR ), "Coloring Mode", "", "", "" );
|
||||
|
||||
@ -397,6 +402,11 @@ void RimEnsembleWellLogCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* ch
|
||||
updateAllCurves();
|
||||
updateTextInPlot = true;
|
||||
}
|
||||
else if ( changedField == &m_depthEqualization )
|
||||
{
|
||||
updateAllCurves();
|
||||
updateTextInPlot = true;
|
||||
}
|
||||
else if ( changedField == &m_color )
|
||||
{
|
||||
updateCurveColors();
|
||||
@ -437,6 +447,7 @@ void RimEnsembleWellLogCurveSet::defineUiOrdering( QString uiConfigName, caf::Pd
|
||||
uiOrdering.add( &m_ensembleWellLogs );
|
||||
uiOrdering.add( &m_wellLogChannelName );
|
||||
uiOrdering.add( &m_ensembleCurveSet );
|
||||
uiOrdering.add( &m_depthEqualization );
|
||||
|
||||
appendColorGroup( uiOrdering );
|
||||
|
||||
@ -734,6 +745,12 @@ void RimEnsembleWellLogCurveSet::updateEnsembleCurves( const std::vector<RimWell
|
||||
|
||||
if ( m_statistics->hideEnsembleCurves() ) return;
|
||||
|
||||
cvf::ref<RigWellLogIndexDepthOffset> offsets;
|
||||
if ( m_depthEqualization() == RimEnsembleWellLogStatistics::DepthEqualization::K_LAYER )
|
||||
{
|
||||
offsets = RimEnsembleWellLogStatistics::calculateIndexDepthOffset( sumCases );
|
||||
}
|
||||
|
||||
m_qwtPlotCurveForLegendText->attach( plotTrack->viewer() );
|
||||
|
||||
QString wellLogChannelName = m_wellLogChannelName();
|
||||
@ -771,6 +788,7 @@ void RimEnsembleWellLogCurveSet::updateEnsembleCurves( const std::vector<RimWell
|
||||
curve->setWellLogChannelName( wellLogChannelName );
|
||||
curve->setWellLogFile( wellLogFile );
|
||||
|
||||
if ( !offsets.isNull() ) curve->setIndexDepthOffsets( offsets );
|
||||
curve->loadDataAndUpdate( true );
|
||||
|
||||
curve->updateCurveVisibility();
|
||||
@ -814,7 +832,7 @@ void RimEnsembleWellLogCurveSet::updateStatistics( const std::vector<RimWellLogF
|
||||
wellLogFiles = ensembleWellLogs->wellLogFiles();
|
||||
}
|
||||
|
||||
m_ensembleWellLogStatistics->calculate( wellLogFiles, wellLogChannelName );
|
||||
m_ensembleWellLogStatistics->calculate( wellLogFiles, wellLogChannelName, m_depthEqualization() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -898,6 +916,14 @@ void RimEnsembleWellLogCurveSet::showCurves( bool show )
|
||||
m_showCurves = show;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEnsembleWellLogStatistics::DepthEqualization RimEnsembleWellLogCurveSet::depthEqualization() const
|
||||
{
|
||||
return m_depthEqualization();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "RimEnsembleCurveSetColorManager.h"
|
||||
#include "RimEnsembleCurveSetInterface.h"
|
||||
#include "RimEnsembleWellLogStatistics.h"
|
||||
|
||||
#include "RigEnsembleParameter.h"
|
||||
|
||||
@ -45,7 +46,6 @@ class RimEnsembleStatisticsCase;
|
||||
class RimWellLogCurve;
|
||||
class RimWellLogFileCurve;
|
||||
class RimWellLogFile;
|
||||
class RimEnsembleWellLogStatistics;
|
||||
|
||||
class RiuDraggableOverlayFrame;
|
||||
|
||||
@ -112,7 +112,8 @@ public:
|
||||
|
||||
void updateFilterLegend();
|
||||
|
||||
const RimEnsembleWellLogStatistics* ensembleWellLogStatistics() const;
|
||||
const RimEnsembleWellLogStatistics* ensembleWellLogStatistics() const;
|
||||
RimEnsembleWellLogStatistics::DepthEqualization depthEqualization() const;
|
||||
|
||||
void updateStatistics();
|
||||
|
||||
@ -147,8 +148,9 @@ private:
|
||||
private:
|
||||
caf::PdmField<bool> m_showCurves;
|
||||
|
||||
caf::PdmPtrArrayField<RimWellLogCurve*> m_curves;
|
||||
caf::PdmPointer<RimWellLogCurve> m_currentWellLogCurve;
|
||||
caf::PdmPtrArrayField<RimWellLogCurve*> m_curves;
|
||||
caf::PdmPointer<RimWellLogCurve> m_currentWellLogCurve;
|
||||
caf::PdmField<caf::AppEnum<RimEnsembleWellLogStatistics::DepthEqualization>> m_depthEqualization;
|
||||
|
||||
caf::PdmField<caf::AppEnum<ColorMode>> m_colorMode;
|
||||
caf::PdmField<cvf::Color3f> m_color;
|
||||
|
@ -21,11 +21,13 @@
|
||||
#include "RiaCurveMerger.h"
|
||||
#include "RiaDefines.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaResultNames.h"
|
||||
#include "RiaWeightedMeanCalculator.h"
|
||||
#include "RiaWellLogUnitTools.h"
|
||||
|
||||
#include "RigStatisticsMath.h"
|
||||
#include "RigWellLogFile.h"
|
||||
#include "RigWellLogIndexDepthOffset.h"
|
||||
|
||||
#include "RimWellLogFile.h"
|
||||
|
||||
@ -43,6 +45,16 @@ void caf::AppEnum<RimEnsembleWellLogStatistics::StatisticsType>::setUp()
|
||||
|
||||
setDefault( RimEnsembleWellLogStatistics::StatisticsType::MEAN );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimEnsembleWellLogStatistics::DepthEqualization>::setUp()
|
||||
{
|
||||
addItem( RimEnsembleWellLogStatistics::DepthEqualization::K_LAYER, "K_LAYER", "By K-Layer" );
|
||||
addItem( RimEnsembleWellLogStatistics::DepthEqualization::NONE, "NONE", "None" );
|
||||
|
||||
setDefault( RimEnsembleWellLogStatistics::DepthEqualization::NONE );
|
||||
}
|
||||
|
||||
}; // namespace caf
|
||||
|
||||
RimEnsembleWellLogStatistics::RimEnsembleWellLogStatistics()
|
||||
@ -51,6 +63,23 @@ RimEnsembleWellLogStatistics::RimEnsembleWellLogStatistics()
|
||||
m_logChannelUnitString = RiaWellLogUnitTools<double>::noUnitString();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleWellLogStatistics::calculate( const std::vector<RimWellLogFile*>& wellLogFiles,
|
||||
const QString& wellLogChannelName,
|
||||
DepthEqualization depthEqualization )
|
||||
{
|
||||
if ( depthEqualization == DepthEqualization::NONE )
|
||||
{
|
||||
calculate( wellLogFiles, wellLogChannelName );
|
||||
}
|
||||
else if ( depthEqualization == DepthEqualization::K_LAYER )
|
||||
{
|
||||
calculateByKLayer( wellLogFiles, wellLogChannelName );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -127,6 +156,196 @@ void RimEnsembleWellLogStatistics::calculate( const std::vector<RimWellLogFile*>
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleWellLogStatistics::calculateByKLayer( const std::vector<RimWellLogFile*>& wellLogFiles,
|
||||
const QString& wellLogChannelName )
|
||||
{
|
||||
cvf::ref<RigWellLogIndexDepthOffset> offsets = RimEnsembleWellLogStatistics::calculateIndexDepthOffset( wellLogFiles );
|
||||
|
||||
std::map<int, std::vector<double>> topValues;
|
||||
std::map<int, std::vector<double>> bottomValues;
|
||||
|
||||
for ( RimWellLogFile* wellLogFile : wellLogFiles )
|
||||
{
|
||||
QString errorMessage;
|
||||
if ( wellLogFile->readFile( &errorMessage ) )
|
||||
{
|
||||
RigWellLogFile* fileData = wellLogFile->wellLogFileData();
|
||||
|
||||
std::vector<double> kIndexValues = fileData->values( RiaResultNames::indexKResultName() );
|
||||
std::vector<double> values = fileData->values( wellLogChannelName );
|
||||
|
||||
CAF_ASSERT( values.size() == kIndexValues.size() );
|
||||
|
||||
std::set<int> seenTopIndexes;
|
||||
std::set<int> seenBottomIndexes;
|
||||
|
||||
for ( size_t i = 0; i < values.size(); i++ )
|
||||
{
|
||||
int kLayer = static_cast<int>( kIndexValues[i] );
|
||||
if ( seenTopIndexes.count( kLayer ) == 0 )
|
||||
{
|
||||
seenTopIndexes.insert( kLayer );
|
||||
topValues[kLayer].push_back( values[i] );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = static_cast<int>( values.size() ) - 1; i >= 0; i-- )
|
||||
{
|
||||
int kLayer = static_cast<int>( kIndexValues[i] );
|
||||
if ( seenBottomIndexes.count( kLayer ) == 0 )
|
||||
{
|
||||
seenBottomIndexes.insert( kLayer );
|
||||
bottomValues[kLayer].push_back( values[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearData();
|
||||
|
||||
std::vector<int> kIndexes = offsets->sortedIndexes();
|
||||
for ( auto kIndex : kIndexes )
|
||||
{
|
||||
double topMean = -1.0;
|
||||
double bottomMean = -2.3;
|
||||
// Top first
|
||||
{
|
||||
std::vector<double> valuesAtDepth = topValues[kIndex];
|
||||
double p10, p50, p90, mean;
|
||||
RigStatisticsMath::calculateStatisticsCurves( valuesAtDepth, &p10, &p50, &p90, &mean );
|
||||
m_measuredDepths.push_back( offsets->getTopDepth( kIndex ) );
|
||||
m_p10Data.push_back( p10 );
|
||||
m_p50Data.push_back( p50 );
|
||||
m_p90Data.push_back( p90 );
|
||||
m_meanData.push_back( mean );
|
||||
|
||||
topMean = mean;
|
||||
}
|
||||
|
||||
// Then bottom of k-layer
|
||||
{
|
||||
std::vector<double> valuesAtDepth = bottomValues[kIndex];
|
||||
double p10, p50, p90, mean;
|
||||
RigStatisticsMath::calculateStatisticsCurves( valuesAtDepth, &p10, &p50, &p90, &mean );
|
||||
m_measuredDepths.push_back( offsets->getBottomDepth( kIndex ) );
|
||||
m_p10Data.push_back( p10 );
|
||||
m_p50Data.push_back( p50 );
|
||||
m_p90Data.push_back( p90 );
|
||||
m_meanData.push_back( mean );
|
||||
|
||||
bottomMean = mean;
|
||||
}
|
||||
|
||||
RiaLogging::debug( QString( "[%1] top: %2 bttom: %3 %4 %5" )
|
||||
.arg( kIndex )
|
||||
.arg( offsets->getTopDepth( kIndex ) )
|
||||
.arg( offsets->getBottomDepth( kIndex ) )
|
||||
.arg( topMean )
|
||||
.arg( bottomMean ) );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::ref<RigWellLogIndexDepthOffset>
|
||||
RimEnsembleWellLogStatistics::calculateIndexDepthOffset( const std::vector<RimWellLogFile*>& wellLogFiles )
|
||||
{
|
||||
int hack = 1000;
|
||||
std::vector<double> sumTopDepths( hack, 0.0 );
|
||||
std::vector<int> numTopDepths( hack, 0 );
|
||||
|
||||
std::vector<double> sumBottomDepths( hack, 0.0 );
|
||||
std::vector<int> numBottomDepths( hack, 0 );
|
||||
|
||||
int minLayerK = std::numeric_limits<int>::max();
|
||||
int maxLayerK = -std::numeric_limits<int>::max();
|
||||
|
||||
std::vector<std::vector<double>> topValues;
|
||||
|
||||
for ( RimWellLogFile* wellLogFile : wellLogFiles )
|
||||
{
|
||||
QString errorMessage;
|
||||
if ( wellLogFile->readFile( &errorMessage ) )
|
||||
{
|
||||
RigWellLogFile* fileData = wellLogFile->wellLogFileData();
|
||||
|
||||
std::vector<double> depths = fileData->depthValues();
|
||||
std::vector<double> kIndexValues = fileData->values( RiaResultNames::indexKResultName() );
|
||||
|
||||
std::set<int> seenTopIndexes;
|
||||
std::set<int> seenBottomIndexes;
|
||||
if ( !depths.empty() && !kIndexValues.empty() )
|
||||
{
|
||||
// Find top indexes
|
||||
for ( size_t i = 0; i < kIndexValues.size(); i++ )
|
||||
{
|
||||
int kLayer = static_cast<int>( kIndexValues[i] );
|
||||
if ( seenTopIndexes.count( kLayer ) == 0 )
|
||||
{
|
||||
// Only use the first value encountered per index per file.
|
||||
// This is depth of the top of the index since the file is
|
||||
// sorted by increasing depth.
|
||||
seenTopIndexes.insert( kLayer );
|
||||
sumTopDepths[kLayer] += depths[i];
|
||||
numTopDepths[kLayer] += 1;
|
||||
minLayerK = std::min( minLayerK, kLayer );
|
||||
maxLayerK = std::max( maxLayerK, kLayer );
|
||||
}
|
||||
}
|
||||
|
||||
// Find bottom indexes
|
||||
for ( int i = static_cast<int>( kIndexValues.size() ) - 1; i >= 0; i-- )
|
||||
{
|
||||
int kLayer = static_cast<int>( kIndexValues[i] );
|
||||
if ( seenBottomIndexes.count( kLayer ) == 0 )
|
||||
{
|
||||
// Only use the last value encountered per index per file.
|
||||
// This is depth of the bottom of the index since the file is
|
||||
// sorted by increasing depth.
|
||||
seenBottomIndexes.insert( kLayer );
|
||||
sumBottomDepths[kLayer] += depths[i];
|
||||
numBottomDepths[kLayer] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::error( errorMessage );
|
||||
}
|
||||
}
|
||||
|
||||
if ( minLayerK > maxLayerK )
|
||||
{
|
||||
RiaLogging::error(
|
||||
QString( "Invalid K layers found. Minimum: %1 > Maximum : %2" ).arg( minLayerK ).arg( maxLayerK ) );
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cvf::ref<RigWellLogIndexDepthOffset> offset = cvf::make_ref<RigWellLogIndexDepthOffset>();
|
||||
for ( int kLayer = minLayerK; kLayer <= maxLayerK; kLayer++ )
|
||||
{
|
||||
if ( numTopDepths[kLayer] > 0 && numBottomDepths[kLayer] > 0 )
|
||||
{
|
||||
double topDepth = sumTopDepths[kLayer] / numTopDepths[kLayer];
|
||||
double bottomDepth = sumBottomDepths[kLayer] / numBottomDepths[kLayer];
|
||||
RiaLogging::debug( QString( "K: %1 mean depth range: %2 - %3 Samples: %4 - %5" )
|
||||
.arg( kLayer )
|
||||
.arg( topDepth )
|
||||
.arg( bottomDepth )
|
||||
.arg( numTopDepths[kLayer] )
|
||||
.arg( numBottomDepths[kLayer] ) );
|
||||
offset->setIndexOffsetDepth( kLayer, topDepth, bottomDepth );
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -20,12 +20,16 @@
|
||||
|
||||
#include "RiaDefines.h"
|
||||
|
||||
#include <cvfObject.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class QString;
|
||||
|
||||
class RimWellLogFile;
|
||||
|
||||
class RigWellLogIndexDepthOffset;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
@ -40,6 +44,12 @@ public:
|
||||
MEAN
|
||||
};
|
||||
|
||||
enum class DepthEqualization
|
||||
{
|
||||
K_LAYER,
|
||||
NONE
|
||||
};
|
||||
|
||||
RimEnsembleWellLogStatistics();
|
||||
|
||||
const std::vector<double>& measuredDepths() const;
|
||||
@ -56,9 +66,17 @@ public:
|
||||
bool hasP90Data() const;
|
||||
bool hasMeanData() const;
|
||||
|
||||
void calculate( const std::vector<RimWellLogFile*>& sumCases, const QString& wellLogChannelName );
|
||||
void calculate( const std::vector<RimWellLogFile*>& sumCases,
|
||||
const QString& wellLogChannelName,
|
||||
DepthEqualization depthEqualization );
|
||||
|
||||
static cvf::ref<RigWellLogIndexDepthOffset>
|
||||
calculateIndexDepthOffset( const std::vector<RimWellLogFile*>& wellLogFiles );
|
||||
|
||||
private:
|
||||
void calculate( const std::vector<RimWellLogFile*>& sumCases, const QString& wellLogChannelName );
|
||||
void calculateByKLayer( const std::vector<RimWellLogFile*>& sumCases, const QString& wellLogChannelName );
|
||||
|
||||
void clearData();
|
||||
|
||||
QString m_logChannelUnitString;
|
||||
|
@ -128,7 +128,8 @@ void RimEnsembleWellLogStatisticsCurve::performDataExtraction( bool* isUsingPseu
|
||||
bool performDataSmoothing = false;
|
||||
if ( !values.empty() && !measuredDepthValues.empty() && measuredDepthValues.size() == values.size() )
|
||||
{
|
||||
addDatapointsForBottomOfSegment( measuredDepthValues, values );
|
||||
if ( m_ensembleWellLogCurveSet->depthEqualization() == RimEnsembleWellLogStatistics::DepthEqualization::NONE )
|
||||
addDatapointsForBottomOfSegment( measuredDepthValues, values );
|
||||
|
||||
this->setValuesAndDepths( values,
|
||||
measuredDepthValues,
|
||||
|
@ -22,7 +22,9 @@
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaPreferences.h"
|
||||
|
||||
#include "RiaResultNames.h"
|
||||
#include "RigWellLogCurveData.h"
|
||||
#include "RigWellLogIndexDepthOffset.h"
|
||||
#include "RigWellPath.h"
|
||||
|
||||
#include "RimProject.h"
|
||||
@ -94,6 +96,17 @@ void RimWellLogFileCurve::onLoadDataAndUpdate( bool updateParentPlot )
|
||||
|
||||
bool rkbDiff = m_wellPath->wellPathGeometry() ? m_wellPath->wellPathGeometry()->rkbDiff() : 0.0;
|
||||
|
||||
if ( !m_indexDepthOffsets.isNull() )
|
||||
{
|
||||
// Adjust depths by reassigning depths for top and bottom of layer for each K layer
|
||||
std::vector<double> kIndexValues = wellLogFile->values( RiaResultNames::indexKResultName() );
|
||||
auto [valuesAdjusted, measuredDepthValuesAdjusted] =
|
||||
adjustByIndexDepthOffsets( measuredDepthValues, values, kIndexValues );
|
||||
|
||||
values = valuesAdjusted;
|
||||
measuredDepthValues = measuredDepthValuesAdjusted;
|
||||
}
|
||||
|
||||
if ( tvdMslValues.size() != values.size() )
|
||||
{
|
||||
RigWellPath* rigWellPath = m_wellPath->wellPathGeometry();
|
||||
@ -192,6 +205,55 @@ void RimWellLogFileCurve::onLoadDataAndUpdate( bool updateParentPlot )
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<std::vector<double>, std::vector<double>>
|
||||
RimWellLogFileCurve::adjustByIndexDepthOffsets( const std::vector<double>& measuredDepthValues,
|
||||
const std::vector<double>& values,
|
||||
const std::vector<double>& kIndexValues ) const
|
||||
{
|
||||
CAF_ASSERT( values.size() == kIndexValues.size() );
|
||||
|
||||
auto findFirstIndex = []( int kLayer, const std::vector<double>& vals ) {
|
||||
for ( size_t i = 0; i < vals.size(); i++ )
|
||||
if ( kLayer == static_cast<int>( vals[i] ) ) return i;
|
||||
|
||||
return vals.size();
|
||||
};
|
||||
|
||||
auto findLastIndex = []( int kLayer, const std::vector<double>& vals ) {
|
||||
for ( int i = static_cast<int>( vals.size() ) - 1; i >= 0; i-- )
|
||||
if ( kLayer == static_cast<int>( vals[i] ) ) return static_cast<size_t>( i );
|
||||
|
||||
return vals.size();
|
||||
};
|
||||
|
||||
std::vector<int> kIndexes = m_indexDepthOffsets->sortedIndexes();
|
||||
|
||||
std::vector<double> valuesAdjusted;
|
||||
std::vector<double> measuredDepthValuesAdjusted;
|
||||
|
||||
for ( int kLayer : kIndexes )
|
||||
{
|
||||
size_t firstIndex = findFirstIndex( kLayer, kIndexValues );
|
||||
size_t lastIndex = findLastIndex( kLayer, kIndexValues );
|
||||
|
||||
if ( firstIndex != kIndexValues.size() && lastIndex != kIndexValues.size() )
|
||||
{
|
||||
// Add top
|
||||
measuredDepthValuesAdjusted.push_back( m_indexDepthOffsets->getTopDepth( kLayer ) );
|
||||
valuesAdjusted.push_back( values[firstIndex] );
|
||||
|
||||
// Add bottom of layer
|
||||
measuredDepthValuesAdjusted.push_back( m_indexDepthOffsets->getBottomDepth( kLayer ) );
|
||||
valuesAdjusted.push_back( values[lastIndex] );
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair( valuesAdjusted, measuredDepthValuesAdjusted );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -224,6 +286,14 @@ void RimWellLogFileCurve::setWellLogFile( RimWellLogFile* wellLogFile )
|
||||
m_wellLogFile = wellLogFile;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimWellLogFileCurve::setIndexDepthOffsets( cvf::ref<RigWellLogIndexDepthOffset> depthOffsets )
|
||||
{
|
||||
m_indexDepthOffsets = depthOffsets;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -29,6 +29,7 @@
|
||||
class RimWellPath;
|
||||
class RimWellLogFileChannel;
|
||||
class RimWellLogFile;
|
||||
class RigWellLogIndexDepthOffset;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -46,6 +47,7 @@ public:
|
||||
RimWellPath* wellPath() const;
|
||||
void setWellLogChannelName( const QString& name );
|
||||
void setWellLogFile( RimWellLogFile* wellLogFile );
|
||||
void setIndexDepthOffsets( cvf::ref<RigWellLogIndexDepthOffset> depthOffsets );
|
||||
|
||||
// Overrides from RimWellLogPlotCurve
|
||||
QString wellName() const override;
|
||||
@ -69,9 +71,16 @@ protected:
|
||||
|
||||
bool isRftPlotChild() const;
|
||||
|
||||
std::pair<std::vector<double>, std::vector<double>>
|
||||
adjustByIndexDepthOffsets( const std::vector<double>& measuredDepthValues,
|
||||
const std::vector<double>& values,
|
||||
const std::vector<double>& kIndexValues ) const;
|
||||
|
||||
protected:
|
||||
caf::PdmPtrField<RimWellPath*> m_wellPath;
|
||||
caf::PdmPtrField<RimWellLogFile*> m_wellLogFile;
|
||||
caf::PdmField<QString> m_wellLogChannelName;
|
||||
caf::PdmField<QString> m_wellLogChannnelUnit;
|
||||
|
||||
cvf::ref<RigWellLogIndexDepthOffset> m_indexDepthOffsets;
|
||||
};
|
||||
|
@ -89,7 +89,8 @@ set(SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSlice2D.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleParameter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceResampler.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceStatisticsCalculator.h)
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceStatisticsCalculator.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigWellLogIndexDepthOffset.h)
|
||||
|
||||
set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigActiveCellInfo.cpp
|
||||
@ -175,7 +176,8 @@ set(SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSlice2D.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleParameter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceResampler.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceStatisticsCalculator.cpp)
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigSurfaceStatisticsCalculator.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigWellLogIndexDepthOffset.cpp)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021- 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 "RigWellLogIndexDepthOffset.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigWellLogIndexDepthOffset::setIndexOffsetDepth( int kIndex, double topDepth, double bottomDepth )
|
||||
{
|
||||
m_depthOffsets[kIndex] = std::pair<double, double>( topDepth, bottomDepth );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigWellLogIndexDepthOffset::getTopDepth( int kIndex ) const
|
||||
{
|
||||
auto hit = m_depthOffsets.find( kIndex );
|
||||
if ( hit != m_depthOffsets.end() )
|
||||
{
|
||||
return hit->second.first;
|
||||
}
|
||||
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RigWellLogIndexDepthOffset::getBottomDepth( int kIndex ) const
|
||||
{
|
||||
auto hit = m_depthOffsets.find( kIndex );
|
||||
if ( hit != m_depthOffsets.end() )
|
||||
{
|
||||
return hit->second.second;
|
||||
}
|
||||
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<int> RigWellLogIndexDepthOffset::sortedIndexes() const
|
||||
{
|
||||
std::vector<int> indexes;
|
||||
for ( auto m : m_depthOffsets )
|
||||
{
|
||||
indexes.push_back( m.first );
|
||||
}
|
||||
|
||||
std::sort( indexes.begin(), indexes.end() );
|
||||
return indexes;
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021- 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "cvfObject.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class RigWellLogIndexDepthOffset : public cvf::Object
|
||||
{
|
||||
public:
|
||||
RigWellLogIndexDepthOffset() = default;
|
||||
~RigWellLogIndexDepthOffset() override = default;
|
||||
|
||||
void setIndexOffsetDepth( int kIndex, double topDepth, double bottomDepth );
|
||||
double getTopDepth( int kIndex ) const;
|
||||
double getBottomDepth( int kIndex ) const;
|
||||
std::vector<int> sortedIndexes() const;
|
||||
|
||||
private:
|
||||
std::map<int, std::pair<double, double>> m_depthOffsets;
|
||||
};
|
@ -11,7 +11,11 @@ resinsight = rips.Instance.find()
|
||||
home_dir = expanduser("~")
|
||||
|
||||
|
||||
properties = [("STATIC_NATIVE", "PORO", 0), ("DYNAMIC_NATIVE", "PRESSURE", 0)]
|
||||
properties = [
|
||||
("STATIC_NATIVE", "PORO", 0),
|
||||
("DYNAMIC_NATIVE", "PRESSURE", 0),
|
||||
("STATIC_NATIVE", "INDEX_K", 0),
|
||||
]
|
||||
|
||||
export_folder = tempfile.mkdtemp()
|
||||
|
||||
@ -77,3 +81,5 @@ for path in case_file_paths:
|
||||
|
||||
export_folder = export_folder_path.as_posix()
|
||||
well_log_plot.export_data_as_las(export_folder=export_folder)
|
||||
|
||||
resinsight.project.close()
|
||||
|
Loading…
Reference in New Issue
Block a user