Add optional max distance between curve points in WBS plots

This commit is contained in:
Magne Sjaastad
2023-03-31 16:27:14 +02:00
committed by GitHub
parent cde96a39f6
commit b2e8cc1663
11 changed files with 278 additions and 102 deletions

View File

@@ -15,6 +15,7 @@
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RimWellBoreStabilityPlot.h"
#include "RiaDefines.h"

View File

@@ -106,6 +106,8 @@ RimWellLogCurveCommonDataSource::RimWellLogCurveCommonDataSource()
CAF_PDM_InitField( &m_wbsSmoothingThreshold, "WBSSmoothingThreshold", -1.0, "Smoothing Threshold" );
CAF_PDM_InitField( &m_maximumCurvePointInterval, "MaximumCurvePointInterval", std::make_pair( true, 10.0 ), "Maximum Curve Point Interval" );
CAF_PDM_InitFieldNoDefault( &m_rftTimeStep, "RftTimeStep", "RFT Time Step" );
CAF_PDM_InitFieldNoDefault( &m_rftWellName, "RftWellName", "RFT Well Name" );
CAF_PDM_InitFieldNoDefault( &m_rftSegmentBranchIndex, "SegmentBranchIndex", "RFT Branch" );
@@ -590,15 +592,20 @@ void RimWellLogCurveCommonDataSource::applyDataSourceChanges( const std::vector<
if ( !wbsSmoothingToApply().isPartiallyTrue() )
{
wbsCurve->setSmoothCurve( wbsSmoothingToApply().isTrue() );
updatedSomething = true;
}
if ( wbsSmoothingThreshold() != 1.0 )
{
wbsCurve->setSmoothingThreshold( wbsSmoothingThreshold() );
updatedSomething = true;
}
wbsCurve->enableMaximumCurvePointInterval( m_maximumCurvePointInterval().first );
wbsCurve->setMaximumCurvePointInterval( m_maximumCurvePointInterval().second );
// Always do an update for wbs plots
updatedSomething = true;
}
if ( updatedSomething )
{
RimWellLogPlot* parentPlot = nullptr;
@@ -1058,6 +1065,7 @@ void RimWellLogCurveCommonDataSource::defineUiOrdering( QString uiConfigName, ca
{
group->add( &m_wbsSmoothing );
group->add( &m_wbsSmoothingThreshold );
group->add( &m_maximumCurvePointInterval );
}
if ( !m_uniqueRftTimeSteps.empty() ) group->add( &m_rftTimeStep );
@@ -1110,7 +1118,7 @@ void RimWellLogCurveCommonDataSource::defineEditorAttribute( const caf::PdmField
}
}
auto* uiDisplayStringAttr = dynamic_cast<caf::PdmUiLineEditorAttributeUiDisplayString*>( attribute );
if ( uiDisplayStringAttr && wbsSmoothingThreshold() == -1.0 )
if ( uiDisplayStringAttr && ( wbsSmoothingThreshold() == -1.0 ) && ( field == &m_wbsSmoothingThreshold ) )
{
QString displayString = "Mixed";

View File

@@ -125,8 +125,10 @@ private:
caf::PdmField<int> m_branchIndex;
caf::PdmField<caf::Tristate> m_branchDetection;
caf::PdmField<int> m_timeStep;
caf::PdmField<caf::Tristate> m_wbsSmoothing;
caf::PdmField<double> m_wbsSmoothingThreshold;
caf::PdmField<caf::Tristate> m_wbsSmoothing;
caf::PdmField<double> m_wbsSmoothingThreshold;
caf::PdmField<std::pair<bool, double>> m_maximumCurvePointInterval;
caf::PdmField<QDateTime> m_rftTimeStep;
caf::PdmField<QString> m_rftWellName;

View File

@@ -421,13 +421,15 @@ void RimWellLogExtractionCurve::onLoadDataAndUpdate( bool updateParentPlot )
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::performDataExtraction( bool* isUsingPseudoLength )
{
extractData( isUsingPseudoLength );
extractData( isUsingPseudoLength, {}, {} );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogExtractionCurve::extractData( bool* isUsingPseudoLength, bool performDataSmoothing /*= false*/, double smoothingThreshold /*= -1.0 */ )
void RimWellLogExtractionCurve::extractData( bool* isUsingPseudoLength,
const std::optional<double>& smoothingThreshold,
const std::optional<double>& maxDistanceBetweenCurvePoints )
{
CAF_ASSERT( isUsingPseudoLength );
@@ -447,13 +449,15 @@ void RimWellLogExtractionCurve::extractData( bool* isUsingPseudoLength, bool per
}
else if ( geomCase && geomCase->geoMechData() )
{
curveData = extractGeomData( geomCase, isUsingPseudoLength, performDataSmoothing, smoothingThreshold );
curveData = extractGeomData( geomCase, isUsingPseudoLength, smoothingThreshold, maxDistanceBetweenCurvePoints );
}
if ( !curveData.values.empty() && !curveData.measuredDepthValues.empty() )
{
bool useLogarithmicScale = false;
bool performDataSmoothing = smoothingThreshold.has_value();
RimWellLogTrack* track = nullptr;
firstAncestorOfType( track );
if ( track )
@@ -592,17 +596,37 @@ RimWellLogExtractionCurve::WellLogExtractionCurveData RimWellLogExtractionCurve:
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogExtractionCurve::WellLogExtractionCurveData RimWellLogExtractionCurve::extractGeomData( RimGeoMechCase* geomCase,
bool* isUsingPseudoLength,
bool performDataSmoothing,
double smoothingThreshold )
RimWellLogExtractionCurve::WellLogExtractionCurveData
RimWellLogExtractionCurve::extractGeomData( RimGeoMechCase* geoMechCase,
bool* isUsingPseudoLength,
const std::optional<double>& smoothingThreshold,
const std::optional<double>& maxDistanceBetweenCurvePoints )
{
WellLogExtractionCurveData curveData;
RimWellLogPlotCollection* wellLogCollection = RimMainPlotCollection::current()->wellLogPlotCollection();
cvf::ref<RigGeoMechWellLogExtractor> wellExtractor = wellLogCollection->findOrCreateExtractor( m_wellPath, geomCase );
cvf::ref<RigGeoMechWellLogExtractor> refWellExtractor = wellLogCollection->findOrCreateExtractor( m_refWellPath, geomCase );
WellLogExtractionCurveData curveData;
RimWellLogPlotCollection* wellLogCollection = RimMainPlotCollection::current()->wellLogPlotCollection();
auto [timeStepIdx, frameIdx] = geomCase->geoMechData()->femPartResults()->stepListIndexToTimeStepAndDataFrameIndex( m_timeStep );
cvf::ref<RigGeoMechWellLogExtractor> wellExtractor;
if ( maxDistanceBetweenCurvePoints.has_value() && maxDistanceBetweenCurvePoints.value() > 0.0 )
{
RigGeoMechCaseData* caseData = geoMechCase->geoMechData();
auto wellPathGeometry = m_wellPath->wellPathGeometry();
if ( caseData && wellPathGeometry )
{
std::string errorIdName = ( m_wellPath->name() + " " + geoMechCase->caseUserDescription() ).toStdString();
wellExtractor = new RigGeoMechWellLogExtractor( caseData, wellPathGeometry, errorIdName );
// make sure the resampling of the well path is done before the extraction of the curve data
wellExtractor->resampleIntersections( maxDistanceBetweenCurvePoints.value() );
}
}
else
{
wellExtractor = wellLogCollection->findOrCreateExtractor( m_wellPath, geoMechCase );
}
cvf::ref<RigGeoMechWellLogExtractor> refWellExtractor = wellLogCollection->findOrCreateExtractor( m_refWellPath, geoMechCase );
auto [timeStepIdx, frameIdx] = geoMechCase->geoMechData()->femPartResults()->stepListIndexToTimeStepAndDataFrameIndex( m_timeStep );
if ( wellExtractor.notNull() )
{
@@ -659,26 +683,26 @@ RimWellLogExtractionCurve::WellLogExtractionCurveData RimWellLogExtractionCurve:
refWellPropertyValues,
refWellIndexKValues );
}
if ( performDataSmoothing )
if ( smoothingThreshold.has_value() )
{
refWellExtractor->performCurveDataSmoothing( timeStepIdx,
frameIdx,
&curveData.measuredDepthValues,
&curveData.tvDepthValues,
&curveData.values,
smoothingThreshold );
smoothingThreshold.value() );
}
return curveData;
}
if ( wellExtractor.notNull() && performDataSmoothing )
if ( wellExtractor.notNull() && smoothingThreshold.has_value() )
{
wellExtractor->performCurveDataSmoothing( timeStepIdx,
frameIdx,
&curveData.measuredDepthValues,
&curveData.tvDepthValues,
&curveData.values,
smoothingThreshold );
smoothingThreshold.value() );
}
return curveData;
}

View File

@@ -105,7 +105,9 @@ protected:
void connectCaseSignals( RimCase* rimCase );
virtual void performDataExtraction( bool* isUsingPseudoLength );
void extractData( bool* isUsingPseudoLength, bool performDataSmoothing = false, double smoothingThreshold = -1.0 );
void extractData( bool* isUsingPseudoLength,
const std::optional<double>& smoothingThreshold,
const std::optional<double>& maxDistanceBetweenCurvePoints );
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
@@ -154,16 +156,17 @@ private:
private:
WellLogExtractionCurveData extractEclipseData( RimEclipseCase* eclipseCase, bool* isUsingPseudoLength );
WellLogExtractionCurveData extractGeomData( RimGeoMechCase* geomCase,
bool* isUsingPseudoLength,
bool performDataSmoothing = false,
double smoothingThreshold = -1.0 );
void mapPropertyValuesFromReferenceWell( std::vector<double>& rMeasuredDepthValues,
std::vector<double>& rTvDepthValues,
std::vector<double>& rPropertyValues,
const std::vector<double>& indexKValues,
const std::vector<double>& refWellMeasuredDepthValues,
const std::vector<double>& refWellTvDepthValues,
const std::vector<double>& refWellPropertyValues,
const std::vector<double>& refWellIndexKValues );
WellLogExtractionCurveData extractGeomData( RimGeoMechCase* geoMechCase,
bool* isUsingPseudoLength,
const std::optional<double>& smoothingThreshold,
const std::optional<double>& maxDistanceBetweenCurvePoints );
void mapPropertyValuesFromReferenceWell( std::vector<double>& rMeasuredDepthValues,
std::vector<double>& rTvDepthValues,
std::vector<double>& rPropertyValues,
const std::vector<double>& indexKValues,
const std::vector<double>& refWellMeasuredDepthValues,
const std::vector<double>& refWellTvDepthValues,
const std::vector<double>& refWellPropertyValues,
const std::vector<double>& refWellIndexKValues );
};

View File

@@ -16,6 +16,8 @@ RimWellLogWbsCurve::RimWellLogWbsCurve()
CAF_PDM_InitField( &m_smoothCurve, "SmoothCurve", false, "Smooth Curve" );
CAF_PDM_InitField( &m_smoothingThreshold, "SmoothingThreshold", 0.002, "Smoothing Threshold" );
CAF_PDM_InitField( &m_maximumCurvePointInterval, "MaximumCurvePointInterval", std::make_pair( false, 10.0 ), "Maximum Curve Point Interval" );
}
//--------------------------------------------------------------------------------------------------
@@ -50,12 +52,31 @@ void RimWellLogWbsCurve::setSmoothingThreshold( double threshold )
m_smoothingThreshold = threshold;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogWbsCurve::enableMaximumCurvePointInterval( bool enable )
{
m_maximumCurvePointInterval.v().first = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogWbsCurve::setMaximumCurvePointInterval( double interval )
{
m_maximumCurvePointInterval.v().second = interval;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogWbsCurve::performDataExtraction( bool* isUsingPseudoLength )
{
extractData( isUsingPseudoLength, m_smoothCurve(), m_smoothingThreshold() );
auto smoothingThreshold = createOptional( m_smoothCurve(), m_smoothingThreshold() );
auto maxDistanceBetweenPoints = createOptional( m_maximumCurvePointInterval() );
extractData( isUsingPseudoLength, smoothingThreshold, maxDistanceBetweenPoints );
}
//--------------------------------------------------------------------------------------------------
@@ -68,6 +89,7 @@ void RimWellLogWbsCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
caf::PdmUiGroup* dataGroup = uiOrdering.findGroup( dataSourceGroupKeyword() );
dataGroup->add( &m_smoothCurve );
dataGroup->add( &m_smoothingThreshold );
dataGroup->add( &m_maximumCurvePointInterval );
}
//--------------------------------------------------------------------------------------------------
@@ -77,7 +99,7 @@ void RimWellLogWbsCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedFie
{
RimWellLogExtractionCurve::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_smoothCurve || changedField == &m_smoothingThreshold )
if ( changedField == &m_smoothCurve || changedField == &m_smoothingThreshold || changedField == &m_maximumCurvePointInterval )
{
this->loadDataAndUpdate( true );
}

View File

@@ -19,6 +19,23 @@
#include "RimWellLogExtractionCurve.h"
//==================================================================================================
/// Helpers for creating optional values, move to stdOptionalTools when used in more places
//==================================================================================================
template <typename T>
std::optional<T> createOptional( bool enable, const T& value )
{
if ( !enable ) return {};
return std::optional<T>( value );
}
template <typename T>
std::optional<T> createOptional( const std::pair<bool, T>& value )
{
return createOptional( value.first, value.second );
}
//==================================================================================================
///
///
@@ -36,12 +53,17 @@ public:
void setSmoothCurve( bool smooth );
void setSmoothingThreshold( double threshold );
void enableMaximumCurvePointInterval( bool enable );
void setMaximumCurvePointInterval( double interval );
protected:
void performDataExtraction( bool* isUsingPseudoLength ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
protected:
caf::PdmField<std::pair<bool, double>> m_maximumCurvePointInterval;
caf::PdmField<bool> m_smoothCurve;
caf::PdmField<double> m_smoothingThreshold;
};