#5001 Add measurements to WBS plot.

This commit is contained in:
Kristian Bendiksen 2019-11-19 11:07:51 +01:00
parent e380168f13
commit 18c2350bdf
6 changed files with 503 additions and 0 deletions

View File

@ -33,6 +33,7 @@
#include "RimWellLogRftCurve.h"
#include "RimWellLogTrack.h"
#include "RimWellLogWbsCurve.h"
#include "RimWellMeasurementCurve.h"
#include "RimWellPath.h"
#include "RifReaderEclipseRft.h"
@ -410,3 +411,33 @@ RimWellLogWbsCurve* RicWellLogTools::addWellLogWbsCurve( RimWellLogTrack* plotTr
useBranchDetection,
showPlotWindow );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellMeasurementCurve* RicWellLogTools::addWellMeasurementCurve( RimWellLogTrack* plotTrack,
RimWellPath* wellPath,
const QString& measurementKind,
bool showPlotWindow )
{
CVF_ASSERT( plotTrack );
RimWellMeasurementCurve* curve = new RimWellMeasurementCurve;
curve->setWellPath( wellPath );
curve->setMeasurementKind( measurementKind );
plotTrack->addCurve( curve );
plotTrack->updateConnectedEditors();
RiaApplication::instance()->project()->updateConnectedEditors();
RiaGuiApplication::instance()->getOrCreateMainPlotWindow();
RiuPlotMainWindowTools::selectAsCurrentItem( curve );
if ( showPlotWindow )
{
// Make sure the summary plot window is visible
RiuPlotMainWindowTools::showPlotMainWindow();
}
return curve;
}

View File

@ -33,6 +33,7 @@ class RimWellLogRftCurve;
class RimWellLogTrack;
class RimWellLogWbsCurve;
class RimWellPath;
class RimWellMeasurementCurve;
//--------------------------------------------------------------------------------------------------
///
@ -66,6 +67,10 @@ public:
int branchIndex,
bool useBranchDetection,
bool showPlotWindow = true );
static RimWellMeasurementCurve* addWellMeasurementCurve( RimWellLogTrack* plotTrack,
RimWellPath* wellPath,
const QString& measurementName,
bool showPlotWindow = true );
private:
template <typename ExtractionCurveType>

View File

@ -321,6 +321,14 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore
curve->setSmoothCurve( true );
curve->setSmoothingThreshold( 0.002 );
}
std::vector<QString> measurementNames;
measurementNames.push_back( "XLOT" );
for ( size_t i = 0; i < measurementNames.size(); i++ )
{
RicWellLogTools::addWellMeasurementCurve( stabilityCurvesTrack, wellPath, measurementNames[i] );
}
stabilityCurvesTrack->setAutoScaleXEnabled( true );
}

View File

@ -143,6 +143,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimPlotAxisAnnotation.h
${CMAKE_CURRENT_LIST_DIR}/RimObservedDataCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimObservedFmuRftData.h
${CMAKE_CURRENT_LIST_DIR}/RimMultiPlotCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCurve.h
)
@ -290,6 +291,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimPlotAxisAnnotation.cpp
${CMAKE_CURRENT_LIST_DIR}/RimObservedDataCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimObservedFmuRftData.cpp
${CMAKE_CURRENT_LIST_DIR}/RimMultiPlotCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimWellMeasurementCurve.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,381 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimWellMeasurementCurve.h"
#include "RigWellLogCurveData.h"
#include "RigWellPath.h"
#include "RimProject.h"
#include "RimTools.h"
#include "RimWellLogFile.h"
#include "RimWellLogPlot.h"
#include "RimWellLogTrack.h"
#include "RimWellMeasurement.h"
#include "RimWellMeasurementCollection.h"
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimWellPlotTools.h"
#include "RimWellRftPlot.h"
#include "RiuQwtPlotCurve.h"
#include "RiuQwtPlotWidget.h"
#include "RiaApplication.h"
#include "RiaPreferences.h"
#include "cafPdmUiTreeOrdering.h"
#include <QFileInfo>
#include <QMessageBox>
CAF_PDM_SOURCE_INIT( RimWellMeasurementCurve, "WellMeasurementCurve" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellMeasurementCurve::RimWellMeasurementCurve()
{
CAF_PDM_InitObject( "Well Measurement Curve", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_wellPath, "CurveWellPath", "Well Path", "", "", "" );
m_wellPath.uiCapability()->setUiTreeChildrenHidden( true );
CAF_PDM_InitFieldNoDefault( &m_measurementKind, "CurveMeasurementKind", "Measurement Kind", "", "", "" );
m_measurementKind.uiCapability()->setUiTreeChildrenHidden( true );
m_wellPath = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellMeasurementCurve::~RimWellMeasurementCurve() {}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::onLoadDataAndUpdate( bool updateParentPlot )
{
this->RimPlotCurve::updateCurvePresentation( updateParentPlot );
if ( isCurveVisible() )
{
RimWellLogPlot* wellLogPlot;
firstAncestorOrThisOfType( wellLogPlot );
CVF_ASSERT( wellLogPlot );
if ( m_wellPath && !m_measurementKind().isEmpty() && m_wellPath->measurementCollection() )
{
const RimWellMeasurementCollection* measurementCollection = m_wellPath->measurementCollection();
// Extract the values for this measurement kind
std::vector<double> values;
std::vector<double> measuredDepthValues;
for ( auto& measurement : measurementCollection->measurements() )
{
if ( measurement->kind() == measurementKind() )
{
values.push_back( measurement->value() );
measuredDepthValues.push_back( measurement->MD() );
}
}
if ( values.size() == measuredDepthValues.size() )
{
this->setValuesAndDepths( values,
measuredDepthValues,
RiaDefines::MEASURED_DEPTH,
RiaDefines::UNIT_METER,
false );
RigWellPath* rigWellPath = m_wellPath->wellPathGeometry();
if ( rigWellPath )
{
std::vector<double> trueVerticalDepthValues;
for ( double measuredDepthValue : measuredDepthValues )
{
trueVerticalDepthValues.push_back(
-rigWellPath->interpolatedPointAlongWellPath( measuredDepthValue ).z() );
}
this->setValuesAndDepths( values,
measuredDepthValues,
RiaDefines::TRUE_VERTICAL_DEPTH,
RiaDefines::UNIT_METER,
false );
}
}
if ( m_isUsingAutoName )
{
m_qwtPlotCurve->setTitle( createCurveAutoName() );
}
setSymbol( getSymbolForMeasurementKind( m_measurementKind() ) );
setColor( getColorForMeasurementKind( measurementKind() ) );
setLineStyle( RiuQwtPlotCurve::STYLE_NONE );
RiaDefines::DepthUnitType displayUnit = RiaDefines::UNIT_METER;
if ( wellLogPlot )
{
displayUnit = wellLogPlot->depthUnit();
}
if ( wellLogPlot && wellLogPlot->depthType() == RiaDefines::TRUE_VERTICAL_DEPTH &&
this->curveData()->availableDepthTypes().count( RiaDefines::TRUE_VERTICAL_DEPTH ) )
{
m_qwtPlotCurve->setSamples( this->curveData()->xPlotValues().data(),
this->curveData()
->depthPlotValues( RiaDefines::TRUE_VERTICAL_DEPTH, displayUnit )
.data(),
static_cast<int>( this->curveData()->xPlotValues().size() ) );
}
else
{
m_qwtPlotCurve
->setSamples( this->curveData()->xPlotValues().data(),
this->curveData()->depthPlotValues( RiaDefines::MEASURED_DEPTH, displayUnit ).data(),
static_cast<int>( this->curveData()->xPlotValues().size() ) );
}
m_qwtPlotCurve->setLineSegmentStartStopIndices( this->curveData()->polylineStartStopIndices() );
}
if ( updateParentPlot )
{
updateZoomInParentPlot();
}
if ( m_parentQwtPlot )
{
m_parentQwtPlot->replot();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::setWellPath( RimWellPath* wellPath )
{
m_wellPath = wellPath;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellMeasurementCurve::wellPath() const
{
return m_wellPath;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue )
{
RimWellLogCurve::fieldChangedByUi( changedField, oldValue, newValue );
if ( changedField == &m_wellPath || changedField == &m_measurementKind )
{
this->loadDataAndUpdate( true );
}
if ( m_parentQwtPlot ) m_parentQwtPlot->replot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
RimPlotCurve::updateOptionSensitivity();
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Curve Data" );
curveDataGroup->add( &m_wellPath );
curveDataGroup->add( &m_measurementKind );
caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup( "Appearance" );
RimPlotCurve::appearanceUiOrdering( *appearanceGroup );
caf::PdmUiGroup* nameGroup = uiOrdering.addNewGroup( "Curve Name" );
nameGroup->add( &m_showLegend );
RimPlotCurve::curveNameUiOrdering( *nameGroup );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/ )
{
uiTreeOrdering.skipRemainingChildren( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RimWellMeasurementCurve::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
{
QList<caf::PdmOptionItemInfo> options;
options = RimWellLogCurve::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
if ( options.size() > 0 ) return options;
if ( fieldNeedingOptions == &m_wellPath )
{
auto wellPathColl = RimTools::wellPathCollection();
if ( wellPathColl )
{
caf::PdmChildArrayField<RimWellPath*>& wellPaths = wellPathColl->wellPaths;
for ( size_t i = 0; i < wellPaths.size(); i++ )
{
options.push_back( caf::PdmOptionItemInfo( wellPaths[i]->name(), wellPaths[i] ) );
}
if ( options.size() > 0 )
{
options.push_front( caf::PdmOptionItemInfo( "None", nullptr ) );
}
}
}
if ( fieldNeedingOptions == &m_measurementKind )
{
if ( m_wellPath() )
{
// TODO: take all options from somewhere and filter based on
// what the current well path has set.
options.push_back( caf::PdmOptionItemInfo( "XLOT", "XLOT" ) );
options.push_back( caf::PdmOptionItemInfo( "LOT", "LOT" ) );
options.push_back( caf::PdmOptionItemInfo( "FIT", "FIT" ) );
options.push_back( caf::PdmOptionItemInfo( "DP", "DP" ) );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::initAfterRead()
{
if ( !m_wellPath ) return;
// TODO: do something here?
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellMeasurementCurve::createCurveAutoName()
{
if ( m_wellPath )
{
QStringList name;
name.push_back( wellName() );
name.push_back( measurementKind() );
return name.join( ", " );
}
return "Empty curve";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellMeasurementCurve::wellLogChannelName() const
{
// Does not really make sense for measurement curve.
return QString( "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellMeasurementCurve::wellName() const
{
if ( m_wellPath )
{
return m_wellPath->name();
}
return QString( "" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellMeasurementCurve::measurementKind() const
{
if ( !m_measurementKind().isEmpty() )
{
return m_measurementKind();
}
return QString( "None" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellMeasurementCurve::setMeasurementKind( const QString& measurementKind )
{
m_measurementKind = measurementKind;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtSymbol::PointSymbolEnum RimWellMeasurementCurve::getSymbolForMeasurementKind( const QString& measurementKind )
{
std::map<QString, RiuQwtSymbol::PointSymbolEnum> symbolTable;
symbolTable["XLOT"] = RiuQwtSymbol::SYMBOL_RECT;
symbolTable["LOT"] = RiuQwtSymbol::SYMBOL_TRIANGLE;
symbolTable["FIT"] = RiuQwtSymbol::SYMBOL_DIAMOND;
symbolTable["MCF"] = RiuQwtSymbol::SYMBOL_ELLIPSE;
symbolTable["MNF"] = RiuQwtSymbol::SYMBOL_ELLIPSE;
symbolTable["TH"] = RiuQwtSymbol::SYMBOL_STAR1;
symbolTable["LE"] = RiuQwtSymbol::SYMBOL_STAR2;
symbolTable["BA"] = RiuQwtSymbol::SYMBOL_STAR1;
symbolTable["CORE"] = RiuQwtSymbol::SYMBOL_RECT;
symbolTable["PPG"] = RiuQwtSymbol::SYMBOL_RECT;
auto it = symbolTable.find( measurementKind );
if ( it != symbolTable.end() )
return it->second;
else
return RiuQwtSymbol::SYMBOL_CROSS;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Color3f RimWellMeasurementCurve::getColorForMeasurementKind( const QString& measurementKind )
{
if ( measurementKind == "TH" ) return cvf::Color3f::RED;
if ( measurementKind == "LE" ) return cvf::Color3f::BLUE;
if ( measurementKind == "BA" ) return cvf::Color3f::GREEN;
if ( measurementKind == "CORE" ) return cvf::Color3f::BLACK;
return cvf::Color3f::CRIMSON;
}

View File

@ -0,0 +1,76 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2015- Statoil ASA
// Copyright (C) 2015- Ceetron Solutions AS
//
// 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 "RimWellLogCurve.h"
#include "RiuQwtSymbol.h"
#include "cafPdmField.h"
#include "cafPdmPtrField.h"
#include <vector>
class RimWellPath;
class RimWellMeasurement;
//==================================================================================================
///
///
//==================================================================================================
class RimWellMeasurementCurve : public RimWellLogCurve
{
CAF_PDM_HEADER_INIT;
public:
RimWellMeasurementCurve();
~RimWellMeasurementCurve() override;
void setWellPath( RimWellPath* wellPath );
RimWellPath* wellPath() const;
void setMeasurementKind( const QString& measurementKind );
QString measurementKind() const;
// Overrides from RimWellLogPlotCurve
QString wellName() const override;
QString wellLogChannelName() const override;
protected:
// Overrides from RimWellLogCurve
QString createCurveAutoName() override;
void onLoadDataAndUpdate( bool updateParentPlot ) override;
// Pdm overrrides
void fieldChangedByUi( const caf::PdmFieldHandle* changedField,
const QVariant& oldValue,
const QVariant& newValue ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly ) override;
void initAfterRead() override;
RiuQwtSymbol::PointSymbolEnum getSymbolForMeasurementKind( const QString& measurementKind );
cvf::Color3f getColorForMeasurementKind( const QString& measurementKind );
protected:
caf::PdmPtrField<RimWellPath*> m_wellPath;
caf::PdmField<QString> m_measurementKind;
};