mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 15:10:22 -05:00
Migrate all assert macros in ApplicationLibCode to CAF_ASSERT and remove every use of cvfAssert.h. CVF_ASSERT is replaced one to one. CVF_TIGHT_ASSERT is also replaced by CAF_ASSERT, which is semantically exact: CVF_ENABLE_TIGHT_ASSERTS is 1 only under _DEBUG, and that is what CAF_ASSERT now does. The two CVF_FAIL_MSG sites become CAF_ASSERT( false && "message" ), preserving the message with the idiom already used elsewhere in the code base. Counts before and after: CVF_ASSERT 1044 to 0, CVF_TIGHT_ASSERT 66 to 0, CVF_FAIL_MSG 2 to 0, cvfAssert.h references 154 to 0. Include handling: files that included cvfAssert.h directly now include cafAssert.h instead, includes left dead by the migration are removed, and files that were relying on cvfAssert.h transitively get an explicit cafAssert.h. Files that reach cafAssert.h through another caf header are left unchanged; a missing include here is a compile error, not a silently disabled assert. ResultStatisticsCache links only LibCore and therefore had no path to cafAssert.h. Add the cafPdmCore directory as a private include path rather than linking the library, since cafAssert.h is header only. Note that this stops these asserts from firing in Release and RelWithDebInfo, where CVF_ASSERT was previously active.
3237 lines
137 KiB
C++
3237 lines
137 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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 "RimWellLogTrack.h"
|
|
|
|
#include "RiaColorTables.h"
|
|
#include "RiaExtractionTools.h"
|
|
#include "RiaGuiApplication.h"
|
|
#include "RiaLogging.h"
|
|
#include "RiaPlotDefines.h"
|
|
#include "RiaPreferences.h"
|
|
#include "RiaResultNames.h"
|
|
#include "RiaSimWellBranchTools.h"
|
|
#include "RiaWellLogCurveMerger.h"
|
|
|
|
#include "RigEclipseCaseData.h"
|
|
#include "RigEclipseResultAddress.h"
|
|
#include "RigFemPartResultsCollection.h"
|
|
#include "RigFemResultAddress.h"
|
|
#include "RigFormationNames.h"
|
|
#include "RigGeoMechCaseData.h"
|
|
#include "RigResultAccessorFactory.h"
|
|
#include "RigStatisticsCalculator.h"
|
|
#include "Well/RigEclipseWellLogExtractor.h"
|
|
#include "Well/RigGeoMechWellLogExtractor.h"
|
|
#include "Well/RigSimWellData.h"
|
|
#include "Well/RigSimulationWellCenterLineCalculator.h"
|
|
#include "Well/RigSimulationWellCoordsAndMD.h"
|
|
#include "Well/RigWellLogCurveData.h"
|
|
#include "Well/RigWellPath.h"
|
|
#include "Well/RigWellPathFormations.h"
|
|
|
|
#include "Formations/RimFormationNames.h"
|
|
#include "RimCase.h"
|
|
#include "RimColorLegend.h"
|
|
#include "RimColorLegendCollection.h"
|
|
#include "RimColorLegendItem.h"
|
|
#include "RimEclipseCase.h"
|
|
#include "RimEclipseResultDefinition.h"
|
|
#include "RimEnsembleWellLogCurveSet.h"
|
|
#include "RimFishbones.h"
|
|
#include "RimFishbonesCollection.h"
|
|
#include "RimGeoMechCase.h"
|
|
#include "RimMainPlotCollection.h"
|
|
#include "RimPerforationCollection.h"
|
|
#include "RimPerforationInterval.h"
|
|
#include "RimProject.h"
|
|
#include "RimRftTopologyCurve.h"
|
|
#include "RimTools.h"
|
|
#include "RimWellAllocationPlot.h"
|
|
#include "RimWellBoreStabilityPlot.h"
|
|
#include "RimWellFlowRateCurve.h"
|
|
#include "RimWellLogCurve.h"
|
|
#include "RimWellLogCurveCommonDataSource.h"
|
|
#include "RimWellLogExtractionCurve.h"
|
|
#include "RimWellLogFormationSettings.h"
|
|
#include "RimWellLogPlotCollection.h"
|
|
#include "RimWellLogPropertyAxisSettings.h"
|
|
#include "RimWellLogRegionAnnotationSettings.h"
|
|
#include "RimWellLogWellPathAttributeSettings.h"
|
|
#include "RimWellPath.h"
|
|
#include "RimWellPathAttribute.h"
|
|
#include "RimWellPathAttributeCollection.h"
|
|
#include "RimWellPathCompletions.h"
|
|
#include "RimWellPathFracture.h"
|
|
#include "RimWellPathFractureCollection.h"
|
|
#include "RimWellPltPlot.h"
|
|
#include "RimWellRftPlot.h"
|
|
|
|
#include "RiuMainWindow.h"
|
|
#include "RiuPlotAnnotationTool.h"
|
|
#include "RiuPlotAxis.h"
|
|
#include "RiuPlotMainWindow.h"
|
|
#include "RiuPlotMainWindowTools.h"
|
|
#include "RiuQwtLinearScaleEngine.h"
|
|
#include "RiuQwtPlotWidget.h"
|
|
#include "RiuWellLogTrack.h"
|
|
#include "RiuWellPathComponentPlotItem.h"
|
|
|
|
#include "cafPdmFieldReorderCapability.h"
|
|
#include "cafPdmFieldScriptingCapability.h"
|
|
#include "cafPdmObjectScriptingCapability.h"
|
|
#include "cafPdmUiDoubleValueEditor.h"
|
|
#include "cafPdmUiSliderEditor.h"
|
|
#include "cafSelectionManager.h"
|
|
|
|
#include "caf.h"
|
|
#include "cafAssert.h"
|
|
|
|
#include "qwt_scale_map.h"
|
|
|
|
#include <QWheelEvent>
|
|
|
|
#include <algorithm>
|
|
#include <map>
|
|
#include <memory>
|
|
#include <set>
|
|
|
|
#define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0
|
|
#define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0
|
|
#define RI_SCROLLWHEEL_ZOOMFACTOR 1.1
|
|
#define RI_SCROLLWHEEL_PANFACTOR 0.1
|
|
|
|
CAF_PDM_SOURCE_INIT( RimWellLogTrack, "WellLogPlotTrack" );
|
|
|
|
namespace internal
|
|
{
|
|
void setColorShadingLegendFromFormationCase( RimWellLogRegionAnnotationSettings* settings, RimCase* rimCase )
|
|
{
|
|
if ( !settings || !rimCase ) return;
|
|
|
|
auto* formationNames = rimCase->activeFormationNames();
|
|
if ( !formationNames ) return;
|
|
|
|
QString legendName = formationNames->shortName();
|
|
auto* legend = RimProject::current()->colorLegendCollection->findByName( legendName );
|
|
if ( legend ) settings->setColorShadingLegend( legend );
|
|
}
|
|
} // namespace internal
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellLogTrack::RimWellLogTrack()
|
|
: m_availablePropertyValueRangeMin( RI_LOGPLOTTRACK_MINX_DEFAULT )
|
|
, m_availablePropertyValueRangeMax( RI_LOGPLOTTRACK_MAXX_DEFAULT )
|
|
, m_availableDepthRangeMin( RI_LOGPLOTTRACK_MINX_DEFAULT )
|
|
, m_availableDepthRangeMax( RI_LOGPLOTTRACK_MAXX_DEFAULT )
|
|
|
|
{
|
|
CAF_PDM_InitScriptableObject( "Track", ":/WellLogTrack16x16.png" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_description, "TrackDescription", "Name" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_curves, "Curves", "Curves" );
|
|
auto reorderability = caf::PdmFieldReorderCapability::addToField( &m_curves );
|
|
reorderability->orderChanged.connect( this, &RimWellLogTrack::curveDataChanged );
|
|
|
|
// Property axis settings
|
|
CAF_PDM_InitFieldNoDefault( &m_propertyAxisSettings, "PropertyAxisSettings", "" );
|
|
m_propertyAxisSettings = new RimWellLogPropertyAxisSettings();
|
|
m_propertyAxisSettings.uiCapability()->setUiTreeChildrenHidden( true );
|
|
|
|
// OBSOLETE property axis fields - kept for migration from older project files
|
|
CAF_PDM_InitField( &m_visiblePropertyValueRangeMin_OBSOLETE, "VisibleXRangeMin", RI_LOGPLOTTRACK_MINX_DEFAULT, "Min" );
|
|
m_visiblePropertyValueRangeMin_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitField( &m_visiblePropertyValueRangeMax_OBSOLETE, "VisibleXRangeMax", RI_LOGPLOTTRACK_MAXX_DEFAULT, "Max" );
|
|
m_visiblePropertyValueRangeMax_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_visibleDepthRangeMin, "VisibleYRangeMin", RI_LOGPLOTTRACK_MINX_DEFAULT, "Min" );
|
|
CAF_PDM_InitField( &m_visibleDepthRangeMax, "VisibleYRangeMax", RI_LOGPLOTTRACK_MAXX_DEFAULT, "Max" );
|
|
m_visibleDepthRangeMin.uiCapability()->setUiHidden( true );
|
|
m_visibleDepthRangeMin.xmlCapability()->disableIO();
|
|
m_visibleDepthRangeMax.uiCapability()->setUiHidden( true );
|
|
m_visibleDepthRangeMax.xmlCapability()->disableIO();
|
|
|
|
CAF_PDM_InitField( &m_isAutoScalePropertyValuesEnabled_OBSOLETE, "AutoScaleX", true, "Auto Scale" );
|
|
m_isAutoScalePropertyValuesEnabled_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_isPropertyLogarithmicScaleEnabled_OBSOLETE, "LogarithmicScaleX", false, "Logarithmic Scale" );
|
|
m_isPropertyLogarithmicScaleEnabled_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitField( &m_invertPropertyValueAxis_OBSOLETE, "InvertPropertyValueAxis", false, "Invert Axis Range" );
|
|
m_invertPropertyValueAxis_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitField( &m_isPropertyAxisEnabled_OBSOLETE, "IsPropertyAxisEnabled", true, "Show Axis" );
|
|
m_isPropertyAxisEnabled_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_propertyValueAxisGridVisibility_OBSOLETE, "ShowXGridLines", "Show Grid Lines" );
|
|
m_propertyValueAxisGridVisibility_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_explicitTickIntervalsPropertyValueAxis_OBSOLETE, "ExplicitTickIntervals", false, "Manually Set Tick Intervals" );
|
|
m_explicitTickIntervalsPropertyValueAxis_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitField( &m_propertyAxisMinAndMaxTicksOnly_OBSOLETE, "MinAndMaxTicksOnly", false, "Show Ticks at Min and Max" );
|
|
m_propertyAxisMinAndMaxTicksOnly_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitField( &m_majorTickIntervalPropertyAxis_OBSOLETE, "MajorTickIntervals", 0.0, "Major Tick Interval" );
|
|
m_majorTickIntervalPropertyAxis_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
CAF_PDM_InitField( &m_minorTickIntervalPropertyAxis_OBSOLETE, "MinorTickIntervals", 0.0, "Minor Tick Interval" );
|
|
m_minorTickIntervalPropertyAxis_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_axisFontSize, "AxisFontSize", "Axis Font Size" );
|
|
|
|
// Region annotation settings
|
|
CAF_PDM_InitFieldNoDefault( &m_regionAnnotationSettings, "RegionAnnotationSettings", "" );
|
|
m_regionAnnotationSettings = new RimWellLogRegionAnnotationSettings();
|
|
m_regionAnnotationSettings.uiCapability()->setUiTreeChildrenHidden( true );
|
|
|
|
// OBSOLETE region annotation fields
|
|
CAF_PDM_InitFieldNoDefault( &m_regionAnnotationType_OBSOLETE, "AnnotationType", "Region Annotations" );
|
|
m_regionAnnotationType_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_regionAnnotationDisplay_OBSOLETE, "RegionDisplay", "Region Display" );
|
|
m_regionAnnotationDisplay_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_colorShadingLegend_OBSOLETE, "ColorShadingLegend", "Colors" );
|
|
m_colorShadingLegend_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_colorShadingTransparency_OBSOLETE, "ColorShadingTransparency", 50, "Color Transparency" );
|
|
m_colorShadingTransparency_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_showRegionLabels_OBSOLETE, "ShowFormationLabels", true, "Show Labels" );
|
|
m_showRegionLabels_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
caf::FontTools::RelativeSizeEnum regionLabelFontSizeDefault = caf::FontTools::RelativeSize::Small;
|
|
CAF_PDM_InitField( &m_regionLabelFontSize_OBSOLETE, "RegionLabelFontSize", regionLabelFontSizeDefault, "Font Size" );
|
|
m_regionLabelFontSize_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
// Formation settings
|
|
CAF_PDM_InitFieldNoDefault( &m_formationSettings, "FormationSettings", "" );
|
|
m_formationSettings = new RimWellLogFormationSettings();
|
|
m_formationSettings.uiCapability()->setUiTreeChildrenHidden( true );
|
|
|
|
// OBSOLETE formation fields
|
|
CAF_PDM_InitFieldNoDefault( &m_formationSource_OBSOLETE, "FormationSource", "Source" );
|
|
m_formationSource_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_formationTrajectoryType_OBSOLETE, "FormationTrajectoryType", "Trajectory" );
|
|
m_formationTrajectoryType_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_formationWellPathForSourceCase_OBSOLETE, "FormationWellPath", "Well Path" );
|
|
m_formationWellPathForSourceCase_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_formationWellPathForSourceWellPath_OBSOLETE, "FormationWellPathForSourceWellPath", "Well Path" );
|
|
m_formationWellPathForSourceWellPath_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_formationSimWellName_OBSOLETE, "FormationSimulationWellName", QString( "None" ), "Simulation Well" );
|
|
m_formationSimWellName_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_formationBranchIndex_OBSOLETE, "FormationBranchIndex", 0, " " );
|
|
m_formationBranchIndex_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_formationBranchDetection_OBSOLETE, "FormationBranchDetection", true, "Branch Detection" );
|
|
m_formationBranchDetection_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_formationCase_OBSOLETE, "FormationCase", "Formation Case" );
|
|
m_formationCase_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_formationLevel_OBSOLETE, "FormationLevel", "Well Pick Filter" );
|
|
m_formationLevel_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_showformationFluids_OBSOLETE, "ShowFormationFluids", false, "Show Fluids" );
|
|
m_showformationFluids_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
// Well path attribute settings
|
|
CAF_PDM_InitFieldNoDefault( &m_wellPathAttributeSettings, "WellPathAttributeSettings", "" );
|
|
m_wellPathAttributeSettings = new RimWellLogWellPathAttributeSettings();
|
|
m_wellPathAttributeSettings.uiCapability()->setUiTreeChildrenHidden( true );
|
|
|
|
// OBSOLETE well path attribute fields
|
|
CAF_PDM_InitField( &m_showWellPathAttributes_OBSOLETE, "ShowWellPathAttributes", false, "Show Well Attributes" );
|
|
m_showWellPathAttributes_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_wellPathAttributesInLegend_OBSOLETE, "WellPathAttributesInLegend", true, "Attributes in Legend" );
|
|
m_wellPathAttributesInLegend_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_showWellPathCompletions_OBSOLETE, "ShowWellPathCompletions", true, "Show Well Completions" );
|
|
m_showWellPathCompletions_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_wellPathCompletionsInLegend_OBSOLETE, "WellPathCompletionsInLegend", true, "Completions in Legend" );
|
|
m_wellPathCompletionsInLegend_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_showWellPathComponentsBothSides_OBSOLETE, "ShowWellPathAttrBothSides", true, "Show Both Sides" );
|
|
m_showWellPathComponentsBothSides_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_showWellPathComponentLabels_OBSOLETE, "ShowWellPathAttrLabels", false, "Show Labels" );
|
|
m_showWellPathComponentLabels_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_wellPathComponentSource_OBSOLETE, "AttributesWellPathSource", "Well Path" );
|
|
m_wellPathComponentSource_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_wellPathAttributeCollection_OBSOLETE, "AttributesCollection", "Well Attributes" );
|
|
m_wellPathAttributeCollection_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_overburdenHeight_OBSOLETE, "OverburdenHeight", 0.0, "Overburden Height" );
|
|
m_overburdenHeight_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_underburdenHeight_OBSOLETE, "UnderburdenHeight", 0.0, "Underburden Height" );
|
|
m_underburdenHeight_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
|
|
CAF_PDM_InitField( &m_autoCheckStateBasedOnCurveData, "AutoCheckStateBasedOnCurveData", false, "Hide Track if No Curve Data" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_resultDefinition, "ResultDefinition", "Result Definition" );
|
|
m_resultDefinition.uiCapability()->setUiTreeChildrenHidden( true );
|
|
m_resultDefinition = new RimEclipseResultDefinition;
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_ensembleWellLogCurveSet, "EnsembleWellLogCurveSet", "Ensemble Well Logs Curve Set" );
|
|
|
|
m_formationsForCaseWithSimWellOnly = false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellLogTrack::~RimWellLogTrack()
|
|
{
|
|
m_curves.deleteChildren();
|
|
|
|
deleteViewWidget();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellLogTrack::description() const
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setDescription( const QString& description )
|
|
{
|
|
m_description = description;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::simWellOptionItems( QList<caf::PdmOptionItemInfo>* options, RimCase* rimCase )
|
|
{
|
|
CAF_ASSERT( options );
|
|
if ( !options ) return;
|
|
|
|
std::set<QString> sortedWellNames;
|
|
|
|
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase );
|
|
|
|
if ( eclipseCase && eclipseCase->eclipseCaseData() )
|
|
{
|
|
sortedWellNames = eclipseCase->eclipseCaseData()->findSortedWellNames();
|
|
}
|
|
|
|
caf::IconProvider simWellIcon( ":/Well.svg" );
|
|
for ( const QString& wname : sortedWellNames )
|
|
{
|
|
options->push_back( caf::PdmOptionItemInfo( wname, wname, false, simWellIcon ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::cleanupBeforeClose()
|
|
{
|
|
detachAllPlotItems();
|
|
if ( m_plotWidget )
|
|
{
|
|
m_plotWidget->deleteLater();
|
|
m_plotWidget = nullptr;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::detachAllPlotItems()
|
|
{
|
|
for ( RimPlotCurve* curve : m_curves )
|
|
{
|
|
curve->detach();
|
|
}
|
|
for ( auto& plotObjects : m_wellPathAttributePlotObjects )
|
|
{
|
|
plotObjects->detachFromQwt();
|
|
}
|
|
if ( m_ensembleWellLogCurveSet )
|
|
{
|
|
m_ensembleWellLogCurveSet->detachPlotCurves();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::calculatePropertyValueZoomRange()
|
|
{
|
|
updateStackedCurveData();
|
|
|
|
double minValue = HUGE_VAL;
|
|
double maxValue = -HUGE_VAL;
|
|
|
|
size_t topologyCurveCount = 0;
|
|
for ( const auto& curve : m_curves )
|
|
{
|
|
double minCurveValue = HUGE_VAL;
|
|
double maxCurveValue = -HUGE_VAL;
|
|
|
|
if ( curve->isChecked() )
|
|
{
|
|
if ( curve->propertyValueRangeInData( &minCurveValue, &maxCurveValue ) )
|
|
{
|
|
if ( minCurveValue < minValue )
|
|
{
|
|
minValue = minCurveValue;
|
|
}
|
|
|
|
if ( maxCurveValue > maxValue )
|
|
{
|
|
maxValue = maxCurveValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( dynamic_cast<RimRftTopologyCurve*>( curve.p() ) ) topologyCurveCount++;
|
|
}
|
|
|
|
if ( topologyCurveCount == m_curves.size() )
|
|
{
|
|
// The topology track is quite narrow, and to be able to show the curves we add extra space for min/max values
|
|
const double range = maxValue - minValue;
|
|
maxValue += range * 0.5;
|
|
minValue -= range * 0.5;
|
|
}
|
|
|
|
if ( minValue == HUGE_VAL )
|
|
{
|
|
// Empty axis when there are no sensible visible curves
|
|
minValue = 0;
|
|
maxValue = 0;
|
|
}
|
|
else if ( m_propertyAxisSettings->minorTickInterval() != 0.0 )
|
|
{
|
|
std::tie( minValue, maxValue ) = adjustXRange( minValue, maxValue, m_propertyAxisSettings->minorTickInterval() );
|
|
}
|
|
else
|
|
{
|
|
double adjustmentFactor = 0.1;
|
|
auto [adjustedMin, adjustedMax] = extendMinMaxRange( minValue, maxValue, adjustmentFactor );
|
|
|
|
minValue = adjustedMin;
|
|
maxValue = adjustedMax;
|
|
}
|
|
|
|
m_availablePropertyValueRangeMin = minValue;
|
|
m_availablePropertyValueRangeMax = maxValue;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::calculateDepthZoomRange()
|
|
{
|
|
double minDepth = HUGE_VAL;
|
|
double maxDepth = -HUGE_VAL;
|
|
|
|
for ( RimWellLogCurve* curve : m_curves )
|
|
{
|
|
double minCurveDepth = HUGE_VAL;
|
|
double maxCurveDepth = -HUGE_VAL;
|
|
|
|
if ( curve->isChecked() && curve->depthValueRangeInData( &minCurveDepth, &maxCurveDepth ) )
|
|
{
|
|
if ( minCurveDepth < minDepth )
|
|
{
|
|
minDepth = minCurveDepth;
|
|
}
|
|
|
|
if ( maxCurveDepth > maxDepth )
|
|
{
|
|
maxDepth = maxCurveDepth;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( m_wellPathAttributeSettings->showWellPathAttributes() || m_wellPathAttributeSettings->showWellPathCompletions() )
|
|
{
|
|
for ( const std::unique_ptr<RiuWellPathComponentPlotItem>& plotObject : m_wellPathAttributePlotObjects )
|
|
{
|
|
double minObjectDepth = HUGE_VAL;
|
|
double maxObjectDepth = -HUGE_VAL;
|
|
if ( plotObject->depthValueRange( &minObjectDepth, &maxObjectDepth ) )
|
|
{
|
|
if ( minObjectDepth < minDepth )
|
|
{
|
|
minDepth = minObjectDepth;
|
|
}
|
|
|
|
if ( maxObjectDepth > maxDepth )
|
|
{
|
|
maxDepth = maxObjectDepth;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
double adjustmentFactor = 0.02;
|
|
auto [adjustedMin, adjustedMax] = extendMinMaxRange( minDepth, maxDepth, adjustmentFactor );
|
|
|
|
m_availableDepthRangeMin = adjustedMin;
|
|
m_availableDepthRangeMax = adjustedMax;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updatePropertyValueZoom()
|
|
{
|
|
if ( !m_plotWidget ) return;
|
|
|
|
calculatePropertyValueZoomRange();
|
|
|
|
if ( m_propertyAxisSettings->isAutoScaleEnabled() )
|
|
{
|
|
double rangeMin = m_availablePropertyValueRangeMin;
|
|
double rangeMax = m_availablePropertyValueRangeMax;
|
|
|
|
if ( !visibleStackedCurves().empty() && !m_propertyAxisSettings->isLogarithmicScaleEnabled() )
|
|
{
|
|
// Try to ensure we include the base line whether the values are negative or positive.
|
|
rangeMin = std::min( rangeMin, 0.0 );
|
|
rangeMax = std::max( rangeMax, 0.0 );
|
|
}
|
|
m_propertyAxisSettings->setVisibleRange( rangeMin, rangeMax );
|
|
computeAndSetPropertyValueRangeMinForLogarithmicScale();
|
|
updateEditors();
|
|
}
|
|
|
|
updatePropertyValueAxisAndGridTickIntervals();
|
|
|
|
// Attribute range. Fixed range where well components are positioned [-1, 1].
|
|
// Set an extended range here to allow for some label space.
|
|
double componentRangeMax = 2.0 / ( static_cast<double>( colSpan() ) );
|
|
double componentRangeMin = -0.25;
|
|
if ( m_wellPathAttributeSettings->showBothSides() )
|
|
{
|
|
componentRangeMin = -1.5;
|
|
componentRangeMax *= 2.0;
|
|
}
|
|
if ( m_wellPathAttributeSettings->showComponentLabels() )
|
|
{
|
|
componentRangeMax *= 1.5;
|
|
}
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
// Attribute components use the opposite axis to the property values
|
|
if ( wellLogPlot->depthOrientation() == RiaDefines::Orientation::VERTICAL )
|
|
{
|
|
m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), componentRangeMin, componentRangeMax );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->setAxisRange( RiuPlotAxis::defaultRight(), componentRangeMin, componentRangeMax );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateDepthZoom()
|
|
{
|
|
if ( !m_plotWidget ) return;
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
if ( wellLogPlot->depthOrientation() == RiaDefines::Orientation::VERTICAL )
|
|
{
|
|
m_plotWidget->setAxisRange( depthAxis(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->setAxisRange( RiuPlotAxis::defaultTop(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() );
|
|
m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), m_visibleDepthRangeMin(), m_visibleDepthRangeMax() );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimWellLogTrack::axisFontSize() const
|
|
{
|
|
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisFontSize() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
|
{
|
|
RimPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
|
|
|
if ( changedField == &m_showWindow )
|
|
{
|
|
if ( m_plotWidget )
|
|
{
|
|
m_plotWidget->setVisible( m_showWindow );
|
|
}
|
|
|
|
updateParentLayout();
|
|
|
|
RimDepthTrackPlot* depthTrackPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
depthTrackPlot->updateDepthAxisVisibility();
|
|
}
|
|
else if ( changedField == &m_description )
|
|
{
|
|
updateParentLayout();
|
|
}
|
|
else if ( changedField == &m_autoCheckStateBasedOnCurveData )
|
|
{
|
|
updateCheckStateBasedOnCurveData();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::curveDataChanged( const caf::SignalEmitter* emitter )
|
|
{
|
|
for ( auto curve : m_curves )
|
|
{
|
|
if ( curve->isStacked() )
|
|
{
|
|
updateStackedCurveData();
|
|
break;
|
|
}
|
|
}
|
|
loadDataAndUpdate();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::curveVisibilityChanged( const caf::SignalEmitter* emitter, bool visible )
|
|
{
|
|
const RimWellLogCurve* curve = dynamic_cast<const RimWellLogCurve*>( emitter );
|
|
if ( curve->isStacked() )
|
|
{
|
|
updateStackedCurveData();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::curveAppearanceChanged( const caf::SignalEmitter* emitter )
|
|
{
|
|
if ( m_plotWidget )
|
|
{
|
|
m_plotWidget->scheduleReplot();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::curveStackingChanged( const caf::SignalEmitter* emitter, bool stacked )
|
|
{
|
|
updateStackedCurveData();
|
|
|
|
m_propertyAxisSettings->setAutoScaleEnabled( true );
|
|
updatePropertyValueZoom();
|
|
m_plotWidget->scheduleReplot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updatePropertyValueAxisAndGridTickIntervals()
|
|
{
|
|
if ( !m_plotWidget ) return;
|
|
|
|
bool emptyRange = isEmptyVisiblePropertyRange();
|
|
if ( emptyRange )
|
|
{
|
|
m_plotWidget->enableGridLines( valueAxis(), false, false );
|
|
m_plotWidget->setAxisRange( valueAxis(), 0.0, 1.0 );
|
|
m_plotWidget->setAxisLabelsAndTicksEnabled( valueAxis(), false, false );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->setAxisLabelsAndTicksEnabled( valueAxis(), true, true );
|
|
|
|
auto rangeBoundaryA = m_propertyAxisSettings->visibleRangeMin();
|
|
auto rangeBoundaryB = m_propertyAxisSettings->visibleRangeMax();
|
|
if ( m_propertyAxisSettings->isAxisInverted() ) std::swap( rangeBoundaryA, rangeBoundaryB );
|
|
|
|
if ( m_propertyAxisSettings->isMinAndMaxTicksOnly() )
|
|
{
|
|
auto roundToDigits = []( double value, int numberOfDigits, bool useFloor )
|
|
{
|
|
if ( value == 0.0 ) return 0.0;
|
|
|
|
double factor = std::pow( 10.0, numberOfDigits - std::ceil( std::log10( std::fabs( value ) ) ) );
|
|
|
|
if ( useFloor )
|
|
{
|
|
// Use floor for maximum value to ensure we get a value inside the complete range
|
|
return std::floor( value * factor ) / factor;
|
|
}
|
|
|
|
// Use ceil for minimum value to ensure we get a value inside the complete range
|
|
return std::ceil( value * factor ) / factor;
|
|
};
|
|
|
|
auto div = QwtScaleDiv( rangeBoundaryA, rangeBoundaryB );
|
|
|
|
QList<double> majorTicks;
|
|
|
|
auto min = roundToDigits( rangeBoundaryA, 2, false );
|
|
auto max = roundToDigits( rangeBoundaryB, 2, true );
|
|
if ( min == max )
|
|
{
|
|
min = roundToDigits( rangeBoundaryA, 3, false );
|
|
max = roundToDigits( rangeBoundaryB, 3, true );
|
|
}
|
|
|
|
majorTicks.push_back( min );
|
|
majorTicks.push_back( max );
|
|
|
|
div.setTicks( QwtScaleDiv::TickType::MajorTick, majorTicks );
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
if ( wellLogPlot->depthOrientation() == RiaDefines::Orientation::VERTICAL )
|
|
{
|
|
m_plotWidget->qwtPlot()->setAxisScaleDiv( QwtAxis::XTop, div );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->qwtPlot()->setAxisScaleDiv( QwtAxis::YLeft, div );
|
|
}
|
|
}
|
|
else if ( m_propertyAxisSettings->isExplicitTickIntervals() )
|
|
{
|
|
m_plotWidget->setMajorAndMinorTickIntervals( valueAxis(),
|
|
m_propertyAxisSettings->majorTickInterval(),
|
|
m_propertyAxisSettings->minorTickInterval(),
|
|
rangeBoundaryA,
|
|
rangeBoundaryB );
|
|
}
|
|
else
|
|
{
|
|
int majorTickIntervals = 5;
|
|
int minorTickIntervals = 10;
|
|
m_plotWidget->setAutoTickIntervalCounts( valueAxis(), majorTickIntervals, minorTickIntervals );
|
|
m_plotWidget->setAxisRange( valueAxis(), rangeBoundaryA, rangeBoundaryB );
|
|
}
|
|
|
|
m_plotWidget->enableGridLines( valueAxis(),
|
|
m_propertyAxisSettings->gridVisibility() & RimWellLogPlot::AXIS_GRID_MAJOR,
|
|
m_propertyAxisSettings->gridVisibility() & RimWellLogPlot::AXIS_GRID_MINOR );
|
|
}
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
if ( wellLogPlot )
|
|
{
|
|
m_plotWidget->enableGridLines( depthAxis(),
|
|
wellLogPlot->depthAxisGridLinesEnabled() & RimWellLogPlot::AXIS_GRID_MAJOR,
|
|
wellLogPlot->depthAxisGridLinesEnabled() & RimWellLogPlot::AXIS_GRID_MINOR );
|
|
}
|
|
|
|
m_plotWidget->enableAxisNumberLabels( valueAxis(), m_propertyAxisSettings->isEnabled() );
|
|
|
|
m_plotWidget->scheduleReplot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateLegend()
|
|
{
|
|
reattachAllCurves();
|
|
if ( m_plotWidget )
|
|
{
|
|
m_plotWidget->updateLegend();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellLogTrack::asciiDataForPlotExport() const
|
|
{
|
|
QString out = "\n" + description() + "\n";
|
|
|
|
std::vector<QString> curveNames;
|
|
std::vector<double> curveDepths;
|
|
std::vector<std::vector<double>> curvesPlotXValues;
|
|
|
|
auto depthType = parentWellLogPlot()->depthType();
|
|
auto depthUnit = parentWellLogPlot()->depthUnit();
|
|
bool isWellAllocInflowPlot = false;
|
|
{
|
|
auto wapl = parentWellLogPlot()->firstAncestorOfType<RimWellAllocationPlot>();
|
|
if ( wapl )
|
|
{
|
|
isWellAllocInflowPlot = ( wapl->flowType() == RimWellAllocationPlot::INFLOW );
|
|
}
|
|
}
|
|
|
|
RiaWellLogCurveMerger curveMerger;
|
|
bool foundNonMatchingDepths = false;
|
|
|
|
for ( RimWellLogCurve* curve : m_curves() )
|
|
{
|
|
if ( !curve->isChecked() ) continue;
|
|
|
|
const RigWellLogCurveData& curveData = curve->curveData();
|
|
curveNames.push_back( curve->curveName() );
|
|
|
|
if ( curveNames.size() == 1 )
|
|
{
|
|
curveDepths = curveData.depthValuesByIntervals( depthType, depthUnit );
|
|
}
|
|
|
|
std::vector<double> xPlotValues = curveData.propertyValuesByIntervals();
|
|
if ( xPlotValues.empty() )
|
|
{
|
|
curveNames.pop_back();
|
|
|
|
if ( curveNames.empty() )
|
|
{
|
|
curveDepths.clear();
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if ( curveDepths.size() != xPlotValues.size() )
|
|
{
|
|
foundNonMatchingDepths = true;
|
|
}
|
|
|
|
std::vector<double> depths = curveData.depthValuesByIntervals( depthType, depthUnit );
|
|
curveMerger.addCurveData( depths, xPlotValues );
|
|
|
|
curvesPlotXValues.push_back( xPlotValues );
|
|
}
|
|
|
|
// Header
|
|
|
|
if ( depthType == RiaDefines::DepthType::CONNECTION_NUMBER )
|
|
{
|
|
out += "Connection";
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::MEASURED_DEPTH )
|
|
{
|
|
out += "MD ";
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::PSEUDO_LENGTH )
|
|
{
|
|
out += "PL ";
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH )
|
|
{
|
|
out += "TVDMSL ";
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
|
|
{
|
|
out += "TVDRKB ";
|
|
}
|
|
|
|
for ( QString name : curveNames )
|
|
{
|
|
out += " \t" + name;
|
|
}
|
|
out += "\n";
|
|
|
|
// Resample when curves have different depth
|
|
if ( foundNonMatchingDepths )
|
|
{
|
|
curvesPlotXValues.clear();
|
|
curveDepths.clear();
|
|
|
|
curveMerger.computeLookupValues();
|
|
|
|
const std::vector<double>& allDepths = curveMerger.allXValues();
|
|
curveDepths = allDepths;
|
|
for ( size_t curveIdx = 0; curveIdx < curveMerger.curveCount(); ++curveIdx )
|
|
{
|
|
const std::vector<double>& curveValues = curveMerger.lookupYValuesForAllXValues( curveIdx );
|
|
curvesPlotXValues.push_back( curveValues );
|
|
}
|
|
}
|
|
|
|
for ( size_t dIdx = 0; dIdx < curveDepths.size(); ++dIdx )
|
|
{
|
|
size_t i = dIdx;
|
|
double curveDepth = curveDepths[i];
|
|
|
|
if ( depthType == RiaDefines::DepthType::CONNECTION_NUMBER )
|
|
{
|
|
if ( dIdx == 0 )
|
|
continue; // Skip the first line. (shallow depth, which is last)
|
|
// as it is a fictitious value added to make
|
|
// the plot easier to read
|
|
|
|
i = curveDepths.size() - 1 - dIdx; // Reverse the order, since the connections are coming bottom to top
|
|
|
|
if ( i == 0 )
|
|
{
|
|
if ( curveDepths.size() > 1 && curveDepths[i] == curveDepths[i + 1] )
|
|
{
|
|
continue; // Skip double depth at last connection
|
|
}
|
|
}
|
|
|
|
curveDepth = curveDepths[i];
|
|
|
|
if ( isWellAllocInflowPlot )
|
|
{
|
|
curveDepth -= 0.5; // To shift the values that was shifted to get the numbers between the changes
|
|
}
|
|
}
|
|
|
|
out += QString::number( curveDepth, 'f', 3 );
|
|
for ( std::vector<double> plotVector : curvesPlotXValues )
|
|
{
|
|
out += QString( " \t%1" ).arg( QString::number( plotVector[i], 'f', 3 ), 12 );
|
|
}
|
|
out += "\n";
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateAxisRangesFromPlotWidget()
|
|
{
|
|
auto [xIntervalMin, xIntervalMax] = m_plotWidget->axisRange( valueAxis() );
|
|
auto [depthIntervalMin, depthIntervalMax] = m_plotWidget->axisRange( depthAxis() );
|
|
|
|
m_propertyAxisSettings->setVisibleRange( xIntervalMin, xIntervalMax );
|
|
m_visibleDepthRangeMin = depthIntervalMin;
|
|
m_visibleDepthRangeMax = depthIntervalMax;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::onAxisSelected( RiuPlotAxis axis, bool toggle )
|
|
{
|
|
RiuPlotMainWindowTools::selectOrToggleObject( this, toggle );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateAxes()
|
|
{
|
|
updatePropertyValueZoom();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QList<caf::PdmOptionItemInfo> RimWellLogTrack::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
|
|
{
|
|
QList<caf::PdmOptionItemInfo> options;
|
|
|
|
// Formation field options are now handled by RimWellLogFormationSettings
|
|
// Region annotation field options are now handled by RimWellLogRegionAnnotationSettings
|
|
// Well path attribute field options are now handled by RimWellLogWellPathAttributeSettings
|
|
|
|
if ( fieldNeedingOptions == &m_ensembleWellLogCurveSet )
|
|
{
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::addCurve( RimWellLogCurve* curve )
|
|
{
|
|
m_curves.push_back( curve );
|
|
connectCurveSignals( curve );
|
|
|
|
if ( m_plotWidget )
|
|
{
|
|
curve->setParentPlotAndReplot( m_plotWidget );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::insertCurve( RimWellLogCurve* curve, size_t index )
|
|
{
|
|
if ( index >= m_curves.size() )
|
|
{
|
|
addCurve( curve );
|
|
}
|
|
else
|
|
{
|
|
m_curves.insert( index, curve );
|
|
connectCurveSignals( curve );
|
|
// Todo: Mark curve data to use either TVD or MD
|
|
|
|
if ( m_plotWidget )
|
|
{
|
|
curve->setParentPlotAndReplot( m_plotWidget );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::removeCurve( RimWellLogCurve* curve )
|
|
{
|
|
size_t index = m_curves.indexOf( curve );
|
|
if ( index < m_curves.size() )
|
|
{
|
|
m_curves[index]->detach();
|
|
m_curves.removeChild( curve );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::deleteAllCurves()
|
|
{
|
|
m_curves.deleteChildren();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::availablePropertyValueRange( double* minX, double* maxX )
|
|
{
|
|
calculatePropertyValueZoomRange();
|
|
*minX = m_availablePropertyValueRangeMin;
|
|
*maxX = m_availablePropertyValueRangeMax;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::availableDepthRange( double* minimumDepth, double* maximumDepth )
|
|
{
|
|
calculateDepthZoomRange();
|
|
*minimumDepth = m_availableDepthRangeMin;
|
|
*maximumDepth = m_availableDepthRangeMax;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::visiblePropertyValueRange( double* minX, double* maxX )
|
|
{
|
|
CAF_ASSERT( minX && maxX );
|
|
*minX = m_propertyAxisSettings->visibleRangeMin();
|
|
*maxX = m_propertyAxisSettings->visibleRangeMax();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::visibleDepthRange( double* minDepth, double* maxDepth )
|
|
{
|
|
CAF_ASSERT( minDepth && maxDepth );
|
|
*minDepth = m_visibleDepthRangeMin;
|
|
*maxDepth = m_visibleDepthRangeMax;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimWellLogTrack::isEmptyVisiblePropertyRange() const
|
|
{
|
|
return std::abs( m_propertyAxisSettings->visibleRangeMax() - m_propertyAxisSettings->visibleRangeMin() ) <
|
|
1.0e-6 * std::max( 1.0, std::max( m_propertyAxisSettings->visibleRangeMax(), m_propertyAxisSettings->visibleRangeMin() ) );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAutoCheckStateBasedOnCurveData( bool enable )
|
|
{
|
|
m_autoCheckStateBasedOnCurveData = enable;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateCheckStateBasedOnCurveData()
|
|
{
|
|
bool curveDataPresent = false;
|
|
for ( const auto& curve : curves() )
|
|
{
|
|
curve->updateCheckStateBasedOnCurveData();
|
|
curve->updateCurveVisibility();
|
|
|
|
if ( curve->isAnyCurveDataPresent() ) curveDataPresent = true;
|
|
}
|
|
|
|
// As the visibility of a curve might have changed, update the legend
|
|
updateLegend();
|
|
|
|
if ( !m_autoCheckStateBasedOnCurveData ) return;
|
|
|
|
setShowWindow( curveDataPresent );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateAxesVisibility( RiaDefines::Orientation orientation, bool isFirstTrack, bool isLastTrack )
|
|
{
|
|
if ( !m_plotWidget ) return;
|
|
|
|
auto setAxisVisible = [this]( QwtAxis::Position axis, bool enable )
|
|
{
|
|
auto plot = m_plotWidget->qwtPlot();
|
|
if ( !plot ) return false;
|
|
|
|
bool isCurrentlyEnabled = plot->isAxisVisible( axis );
|
|
if ( enable == isCurrentlyEnabled ) return false;
|
|
|
|
m_plotWidget->setAxisEnabled( axis, enable );
|
|
return true;
|
|
};
|
|
|
|
bool needUpdate = false;
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
bool showFirstTrack = wellLogPlot->depthAxisVisibility() == RiaDefines::MultiPlotAxisVisibility::ALL_VISIBLE ||
|
|
( isFirstTrack && wellLogPlot->depthAxisVisibility() == RiaDefines::MultiPlotAxisVisibility::ONE_VISIBLE );
|
|
|
|
bool showLastTrack = wellLogPlot->depthAxisVisibility() == RiaDefines::MultiPlotAxisVisibility::ALL_VISIBLE ||
|
|
( isLastTrack && wellLogPlot->depthAxisVisibility() == RiaDefines::MultiPlotAxisVisibility::ONE_VISIBLE );
|
|
|
|
if ( orientation == RiaDefines::Orientation::VERTICAL )
|
|
{
|
|
// Show depth axis only for the first track (on the left side)
|
|
needUpdate |= setAxisVisible( QwtAxis::XBottom, false );
|
|
needUpdate |= setAxisVisible( QwtAxis::XTop, true );
|
|
needUpdate |= setAxisVisible( QwtAxis::YLeft, showFirstTrack );
|
|
needUpdate |= setAxisVisible( QwtAxis::YRight, false );
|
|
}
|
|
else
|
|
{
|
|
// Show depth axis only for the last track (on the bottom side)
|
|
needUpdate |= setAxisVisible( QwtAxis::XTop, false );
|
|
needUpdate |= setAxisVisible( QwtAxis::XBottom, showLastTrack );
|
|
needUpdate |= setAxisVisible( QwtAxis::YLeft, true );
|
|
needUpdate |= setAxisVisible( QwtAxis::YRight, false );
|
|
}
|
|
|
|
if ( needUpdate ) onLoadDataAndUpdate();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::onChildrenUpdated( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& updatedObjects )
|
|
{
|
|
if ( childArray == &m_curves )
|
|
{
|
|
// If multiple curves are unchecked, we need to attach/reattach to make sure the unchecked curves are not visible
|
|
detachAllCurves();
|
|
reattachAllCurves();
|
|
|
|
loadDataAndUpdate();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateDepthMarkerLine()
|
|
{
|
|
if ( m_plotWidget )
|
|
{
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
if ( wellLogPlot->isDepthMarkerLineEnabled() )
|
|
{
|
|
m_plotWidget->createAnnotationsInPlot( wellLogPlot->depthAxisAnnotations() );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->createAnnotationsInPlot( {} );
|
|
}
|
|
|
|
m_plotWidget->scheduleReplot();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::onLoadDataAndUpdate()
|
|
{
|
|
auto wellLogPlot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
|
|
if ( wellLogPlot && m_plotWidget )
|
|
{
|
|
m_plotWidget->setAxisTitleText( valueAxis(), m_propertyValueAxisTitle );
|
|
m_plotWidget->setAxisTitleText( depthAxis(), wellLogPlot->depthAxisTitle() );
|
|
}
|
|
|
|
for ( size_t cIdx = 0; cIdx < m_curves.size(); ++cIdx )
|
|
{
|
|
m_curves[cIdx]->loadDataAndUpdate( false );
|
|
}
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::FORMATION_ANNOTATIONS ||
|
|
m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::RESULT_PROPERTY_ANNOTATIONS )
|
|
{
|
|
m_resultDefinition->loadDataAndUpdate();
|
|
}
|
|
|
|
if ( m_plotWidget )
|
|
{
|
|
updateWellPathAttributesCollection();
|
|
updateWellPathAttributesOnPlot();
|
|
m_plotWidget->updateLegend();
|
|
|
|
updateAxisScaleEngine();
|
|
updateRegionAnnotationsOnPlot();
|
|
updatePropertyValueZoom();
|
|
}
|
|
|
|
updatePropertyValueAxisAndGridTickIntervals();
|
|
updateDepthZoom();
|
|
|
|
updateLegend();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAndUpdateWellPathFormationNamesData( RimCase* rimCase, RimWellPath* wellPath )
|
|
{
|
|
m_formationSettings->setFormationCase( rimCase );
|
|
m_formationSettings->setTrajectoryType( RiaDefines::WellLogTrackTrajectoryType::WELL_PATH );
|
|
m_formationSettings->setWellPathForSourceCase( wellPath );
|
|
m_formationSettings->setSimWellName( "" );
|
|
m_formationSettings->setBranchIndex( -1 );
|
|
|
|
internal::setColorShadingLegendFromFormationCase( m_regionAnnotationSettings, rimCase );
|
|
updateConnectedEditors();
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() != RiaDefines::RegionAnnotationType::NO_ANNOTATIONS )
|
|
{
|
|
updateRegionAnnotationsOnPlot();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAndUpdateSimWellFormationNamesAndBranchData( RimCase* rimCase,
|
|
const QString& simWellName,
|
|
int branchIndex,
|
|
bool useBranchDetection )
|
|
{
|
|
m_formationSettings->setBranchIndex( branchIndex );
|
|
m_formationSettings->setBranchDetection( useBranchDetection );
|
|
|
|
setAndUpdateSimWellFormationNamesData( rimCase, simWellName );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAndUpdateSimWellFormationNamesData( RimCase* rimCase, const QString& simWellName )
|
|
{
|
|
m_formationSettings->setFormationCase( rimCase );
|
|
m_formationSettings->setTrajectoryType( RiaDefines::WellLogTrackTrajectoryType::SIMULATION_WELL );
|
|
m_formationSettings->setWellPathForSourceCase( nullptr );
|
|
m_formationSettings->setSimWellName( simWellName );
|
|
|
|
internal::setColorShadingLegendFromFormationCase( m_regionAnnotationSettings, rimCase );
|
|
updateConnectedEditors();
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() != RiaDefines::RegionAnnotationType::NO_ANNOTATIONS )
|
|
{
|
|
updateRegionAnnotationsOnPlot();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAutoScaleXEnabled( bool enabled )
|
|
{
|
|
CAF_ASSERT( "A well log track can be both vertical and horizontal, use setAutoScalePropertyValuesEnabled " );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAutoScaleYEnabled( bool enabled )
|
|
{
|
|
CAF_ASSERT( "A well log track can be both vertical and horizontal, use setAutoScaleDepthValuesEnabled " );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAutoScalePropertyValuesEnabled( bool enabled )
|
|
{
|
|
m_propertyAxisSettings->setAutoScaleEnabled( enabled );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAutoScaleDepthValuesEnabled( bool enabled )
|
|
{
|
|
if ( enabled )
|
|
{
|
|
m_visibleDepthRangeMin = m_availableDepthRangeMin;
|
|
m_visibleDepthRangeMax = m_availableDepthRangeMax;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAutoScalePropertyValuesIfNecessary()
|
|
{
|
|
// Avoid resetting if visible range has set to empty by user
|
|
bool emptyRange = isEmptyVisiblePropertyRange();
|
|
if ( !m_propertyAxisSettings->isAutoScaleEnabled() && emptyRange ) return;
|
|
|
|
const double eps = 1.0e-8;
|
|
calculatePropertyValueZoomRange();
|
|
|
|
double maxRange = std::max( m_propertyAxisSettings->visibleRangeMax() - m_propertyAxisSettings->visibleRangeMin(),
|
|
m_availablePropertyValueRangeMax - m_availablePropertyValueRangeMin );
|
|
|
|
double maxLow = std::max( m_propertyAxisSettings->visibleRangeMin(), m_availablePropertyValueRangeMin );
|
|
double minHigh = std::min( m_propertyAxisSettings->visibleRangeMax(), m_availablePropertyValueRangeMax );
|
|
double overlap = minHigh - maxLow;
|
|
|
|
if ( maxRange < eps || overlap < eps * maxRange )
|
|
{
|
|
setAutoScalePropertyValuesEnabled( true );
|
|
}
|
|
|
|
updatePropertyValueZoom();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setPropertyValueAxisTitle( const QString& text )
|
|
{
|
|
m_propertyValueAxisTitle = text;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellLogTrack::depthAxisTitle() const
|
|
{
|
|
RimDepthTrackPlot* parent = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
if ( parent )
|
|
{
|
|
return parent->depthAxisTitle();
|
|
}
|
|
return "";
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationWellPath( RimWellPath* wellPath )
|
|
{
|
|
m_formationSettings->setWellPathForSourceCase( wellPath );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellPath* RimWellLogTrack::formationWellPath() const
|
|
{
|
|
return m_formationSettings->wellPathForSourceCase();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationSimWellName( const QString& simWellName )
|
|
{
|
|
m_formationSettings->setSimWellName( simWellName );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimWellLogTrack::formationSimWellName() const
|
|
{
|
|
return m_formationSettings->simWellName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationBranchDetection( bool branchDetection )
|
|
{
|
|
m_formationSettings->setBranchDetection( branchDetection );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimWellLogTrack::formationBranchDetection() const
|
|
{
|
|
return m_formationSettings->branchDetection();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationBranchIndex( int branchIndex )
|
|
{
|
|
m_formationSettings->setBranchIndex( branchIndex );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimWellLogTrack::formationBranchIndex() const
|
|
{
|
|
return m_formationSettings->branchIndex();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationCase( RimCase* rimCase )
|
|
{
|
|
m_formationSettings->setFormationCase( rimCase );
|
|
m_resultDefinition->setEclipseCase( dynamic_cast<RimEclipseCase*>( rimCase ) );
|
|
m_resultDefinition->setPorosityModel( RiaDefines::PorosityModelType::MATRIX_MODEL );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setRegionPropertyResultType( RiaDefines::ResultCatType resultCatType, const QString& resultVariable )
|
|
{
|
|
m_resultDefinition->setResultType( resultCatType );
|
|
m_resultDefinition->setResultVariable( resultVariable );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimCase* RimWellLogTrack::formationCase() const
|
|
{
|
|
return m_formationSettings->formationCase();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationTrajectoryType( RiaDefines::WellLogTrackTrajectoryType trajectoryType )
|
|
{
|
|
m_formationSettings->setTrajectoryType( trajectoryType );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiaDefines::WellLogTrackTrajectoryType RimWellLogTrack::formationTrajectoryType() const
|
|
{
|
|
return m_formationSettings->trajectoryType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuPlotWidget* RimWellLogTrack::doCreatePlotViewWidget( QWidget* mainWindowParent )
|
|
{
|
|
if ( m_plotWidget == nullptr )
|
|
{
|
|
m_plotWidget = new RiuWellLogTrack( this, mainWindowParent );
|
|
updateAxisScaleEngine();
|
|
|
|
for ( size_t cIdx = 0; cIdx < m_curves.size(); ++cIdx )
|
|
{
|
|
m_curves[cIdx]->setParentPlotNoReplot( m_plotWidget );
|
|
}
|
|
}
|
|
return m_plotWidget;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::deleteViewWidget()
|
|
{
|
|
cleanupBeforeClose();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::detachAllCurves()
|
|
{
|
|
detachAllPlotItems();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::reattachAllCurves()
|
|
{
|
|
for ( RimPlotCurve* curve : m_curves )
|
|
{
|
|
curve->reattach();
|
|
}
|
|
|
|
for ( auto& plotObjects : m_wellPathAttributePlotObjects )
|
|
{
|
|
plotObjects->reattachToQwt();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateParentPlotZoom()
|
|
{
|
|
if ( m_plotWidget )
|
|
{
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
if ( wellLogPlot )
|
|
{
|
|
wellLogPlot->updateZoom();
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateEditors()
|
|
{
|
|
updateConnectedEditors();
|
|
RimPlotWindow* plotWindow = firstAncestorOrThisOfTypeAsserted<RimPlotWindow>();
|
|
plotWindow->updateConnectedEditors();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setVisiblePropertyValueRange( double minValue, double maxValue )
|
|
{
|
|
setAutoScalePropertyValuesEnabled( false );
|
|
m_propertyAxisSettings->setVisibleRange( minValue, maxValue );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setVisibleDepthRange( double minValue, double maxValue )
|
|
{
|
|
m_visibleDepthRangeMin = minValue;
|
|
m_visibleDepthRangeMax = maxValue;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updatePlotWidgetFromAxisRanges()
|
|
{
|
|
updatePropertyValueZoom();
|
|
updateDepthZoom();
|
|
m_plotWidget->scheduleReplot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setTickIntervals( double majorTickInterval, double minorTickInterval )
|
|
{
|
|
m_propertyAxisSettings->setTickIntervals( majorTickInterval, minorTickInterval );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setMinAndMaxTicksOnly( bool enable )
|
|
{
|
|
m_propertyAxisSettings->setMinAndMaxTicksOnly( enable );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setPropertyValueAxisGridVisibility( RimWellLogPlot::AxisGridVisibility gridLines )
|
|
{
|
|
m_propertyAxisSettings->setGridVisibility( gridLines );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setColorShadingLegend( RimColorLegend* colorLegend )
|
|
{
|
|
m_regionAnnotationSettings->setColorShadingLegend( colorLegend );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAnnotationType( RiaDefines::RegionAnnotationType annotationType )
|
|
{
|
|
m_regionAnnotationSettings->setAnnotationType( annotationType );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAnnotationDisplay( RiaDefines::RegionDisplay annotationDisplay )
|
|
{
|
|
m_regionAnnotationSettings->setAnnotationDisplay( annotationDisplay );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setAnnotationTransparency( int percent )
|
|
{
|
|
m_regionAnnotationSettings->setColorShadingTransparency( percent );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiaDefines::RegionAnnotationType RimWellLogTrack::annotationType() const
|
|
{
|
|
return m_regionAnnotationSettings->annotationType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiaDefines::RegionDisplay RimWellLogTrack::annotationDisplay() const
|
|
{
|
|
return m_regionAnnotationSettings->annotationDisplay();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimWellLogTrack::showFormations() const
|
|
{
|
|
return m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::FORMATION_ANNOTATIONS;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setShowRegionLabels( bool on )
|
|
{
|
|
m_regionAnnotationSettings->setShowRegionLabels( on );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimWellLogTrack::showWellPathAttributes() const
|
|
{
|
|
return m_wellPathAttributeSettings->showWellPathAttributes();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setShowWellPathAttributes( bool on )
|
|
{
|
|
m_wellPathAttributeSettings->setShowWellPathAttributes( on );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setShowWellPathAttributesInLegend( bool on )
|
|
{
|
|
m_wellPathAttributeSettings->setShowAttributesInLegend( on );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setShowWellPathCompletionsInLegend( bool on )
|
|
{
|
|
m_wellPathAttributeSettings->setShowCompletionsInLegend( on );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setShowBothSidesOfWell( bool on )
|
|
{
|
|
m_wellPathAttributeSettings->setShowBothSides( on );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setWellPathAttributesSource( RimWellPath* wellPath )
|
|
{
|
|
m_wellPathAttributeSettings->setWellPathComponentSource( wellPath );
|
|
updateWellPathAttributesCollection();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimWellPath* RimWellLogTrack::wellPathAttributeSource() const
|
|
{
|
|
return m_wellPathAttributeSettings->wellPathComponentSource();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QWidget* RimWellLogTrack::viewWidget()
|
|
{
|
|
return m_plotWidget;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuQwtPlotWidget* RimWellLogTrack::viewer()
|
|
{
|
|
return m_plotWidget;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuPlotWidget* RimWellLogTrack::plotWidget()
|
|
{
|
|
return m_plotWidget;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::zoomAll()
|
|
{
|
|
RimDepthTrackPlot* plot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
|
|
if ( plot ) plot->zoomAll();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
uiOrdering.add( &m_description );
|
|
|
|
RimDepthTrackPlot* plot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
bool isHorizontal = plot && plot->depthOrientation() == RiaDefines::Orientation::HORIZONTAL;
|
|
if ( isHorizontal )
|
|
uiOrdering.add( &m_rowSpan );
|
|
else
|
|
uiOrdering.add( &m_colSpan );
|
|
|
|
caf::PdmUiGroup* automationGroup = uiOrdering.addNewGroup( "Automation" );
|
|
automationGroup->setCollapsedByDefault();
|
|
automationGroup->add( &m_autoCheckStateBasedOnCurveData );
|
|
|
|
caf::PdmUiGroup* annotationGroup = uiOrdering.addNewGroup( "Regions/Annotations" );
|
|
m_regionAnnotationSettings->uiOrdering( uiConfigName, *annotationGroup );
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::FORMATION_ANNOTATIONS )
|
|
{
|
|
m_formationSettings->uiOrdering( uiConfigName, *annotationGroup, m_formationsForCaseWithSimWellOnly );
|
|
}
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::RESULT_PROPERTY_ANNOTATIONS )
|
|
{
|
|
m_resultDefinition->uiOrdering( uiConfigName, *annotationGroup );
|
|
}
|
|
|
|
caf::PdmUiGroup* componentGroup = uiOrdering.addNewGroup( "Well Path Components" );
|
|
componentGroup->setCollapsedByDefault();
|
|
m_wellPathAttributeSettings->uiOrdering( uiConfigName, *componentGroup );
|
|
|
|
uiOrdering.add( &m_ensembleWellLogCurveSet );
|
|
|
|
uiOrderingForPropertyAxisSettings( uiOrdering );
|
|
|
|
uiOrdering.skipRemainingFields( true );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::initAfterRead()
|
|
{
|
|
if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::RESULT_PROPERTY_ANNOTATIONS )
|
|
{
|
|
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_formationSettings->formationCase() );
|
|
m_resultDefinition->setEclipseCase( dynamic_cast<RimEclipseCase*>( eclipseCase ) );
|
|
}
|
|
|
|
// Migrate property axis settings from obsolete fields (pre-2025.12.0)
|
|
if ( RimProject::current()->isProjectFileVersionEqualOrOlderThan( "2025.12.0" ) )
|
|
{
|
|
m_propertyAxisSettings->setEnabled( m_isPropertyAxisEnabled_OBSOLETE() );
|
|
m_propertyAxisSettings->setVisibleRange( m_visiblePropertyValueRangeMin_OBSOLETE(), m_visiblePropertyValueRangeMax_OBSOLETE() );
|
|
m_propertyAxisSettings->setAutoScaleEnabled( m_isAutoScalePropertyValuesEnabled_OBSOLETE() );
|
|
m_propertyAxisSettings->setLogarithmicScaleEnabled( m_isPropertyLogarithmicScaleEnabled_OBSOLETE() );
|
|
m_propertyAxisSettings->setAxisInverted( m_invertPropertyValueAxis_OBSOLETE() );
|
|
|
|
auto gridVisibility = m_propertyValueAxisGridVisibility_OBSOLETE();
|
|
if ( gridVisibility == RimWellLogPlot::AXIS_GRID_MINOR )
|
|
{
|
|
gridVisibility = RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR;
|
|
}
|
|
m_propertyAxisSettings->setGridVisibility( gridVisibility );
|
|
|
|
m_propertyAxisSettings->setMinAndMaxTicksOnly( m_propertyAxisMinAndMaxTicksOnly_OBSOLETE() );
|
|
m_propertyAxisSettings->setExplicitTickIntervals( m_explicitTickIntervalsPropertyValueAxis_OBSOLETE() );
|
|
if ( m_explicitTickIntervalsPropertyValueAxis_OBSOLETE() )
|
|
{
|
|
m_propertyAxisSettings->setTickIntervals( m_majorTickIntervalPropertyAxis_OBSOLETE(), m_minorTickIntervalPropertyAxis_OBSOLETE() );
|
|
}
|
|
|
|
// Migrate formation settings from obsolete fields
|
|
m_formationSettings->setFormationSource( m_formationSource_OBSOLETE() );
|
|
m_formationSettings->setFormationCase( m_formationCase_OBSOLETE() );
|
|
m_formationSettings->setTrajectoryType( m_formationTrajectoryType_OBSOLETE() );
|
|
m_formationSettings->setWellPathForSourceCase( m_formationWellPathForSourceCase_OBSOLETE() );
|
|
m_formationSettings->setWellPathForSourceWellPath( m_formationWellPathForSourceWellPath_OBSOLETE() );
|
|
m_formationSettings->setSimWellName( m_formationSimWellName_OBSOLETE() );
|
|
m_formationSettings->setBranchIndex( m_formationBranchIndex_OBSOLETE() );
|
|
m_formationSettings->setBranchDetection( m_formationBranchDetection_OBSOLETE() );
|
|
m_formationSettings->setFormationLevel( m_formationLevel_OBSOLETE() );
|
|
m_formationSettings->setShowFormationFluids( m_showformationFluids_OBSOLETE() );
|
|
|
|
// Migrate region annotation settings from obsolete fields
|
|
m_regionAnnotationSettings->setAnnotationType( m_regionAnnotationType_OBSOLETE() );
|
|
m_regionAnnotationSettings->setAnnotationDisplay( m_regionAnnotationDisplay_OBSOLETE() );
|
|
m_regionAnnotationSettings->setColorShadingLegend( m_colorShadingLegend_OBSOLETE() );
|
|
m_regionAnnotationSettings->setColorShadingTransparency( m_colorShadingTransparency_OBSOLETE() );
|
|
m_regionAnnotationSettings->setShowRegionLabels( m_showRegionLabels_OBSOLETE() );
|
|
m_regionAnnotationSettings->setRegionLabelFontSize( m_regionLabelFontSize_OBSOLETE() );
|
|
|
|
// Migrate well path attribute settings from obsolete fields
|
|
m_wellPathAttributeSettings->setShowWellPathAttributes( m_showWellPathAttributes_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setShowWellPathCompletions( m_showWellPathCompletions_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setShowBothSides( m_showWellPathComponentsBothSides_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setShowComponentLabels( m_showWellPathComponentLabels_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setShowAttributesInLegend( m_wellPathAttributesInLegend_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setShowCompletionsInLegend( m_wellPathCompletionsInLegend_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setWellPathComponentSource( m_wellPathComponentSource_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setWellPathAttributeCollection( m_wellPathAttributeCollection_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setOverburdenHeight( m_overburdenHeight_OBSOLETE() );
|
|
m_wellPathAttributeSettings->setUnderburdenHeight( m_underburdenHeight_OBSOLETE() );
|
|
}
|
|
|
|
for ( auto curve : m_curves )
|
|
{
|
|
connectCurveSignals( curve );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::PdmFieldHandle* RimWellLogTrack::userDescriptionField()
|
|
{
|
|
return &m_description;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
size_t RimWellLogTrack::curveIndex( RimWellLogCurve* curve )
|
|
{
|
|
return m_curves.indexOf( curve );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateAxisScaleEngine()
|
|
{
|
|
if ( !m_plotWidget ) return;
|
|
|
|
auto wellLogPlot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
if ( wellLogPlot )
|
|
{
|
|
if ( wellLogPlot->depthOrientation() == RiaDefines::Orientation::VERTICAL )
|
|
{
|
|
m_plotWidget->setAxisInverted( RiuPlotAxis::defaultLeft(), true );
|
|
|
|
if ( m_propertyAxisSettings->isLogarithmicScaleEnabled() )
|
|
{
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::XTop, new QwtLogScaleEngine );
|
|
|
|
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::XBottom, new QwtLogScaleEngine );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::XTop, new RiuQwtLinearScaleEngine );
|
|
|
|
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::XBottom, new RiuQwtLinearScaleEngine );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->setAxisInverted( RiuPlotAxis::defaultLeft(), false );
|
|
|
|
if ( m_propertyAxisSettings->isLogarithmicScaleEnabled() )
|
|
{
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::YLeft, new QwtLogScaleEngine );
|
|
|
|
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::YRight, new QwtLogScaleEngine );
|
|
}
|
|
else
|
|
{
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::YLeft, new RiuQwtLinearScaleEngine );
|
|
|
|
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
|
|
m_plotWidget->qwtPlot()->setAxisScaleEngine( QwtAxis::YRight, new RiuQwtLinearScaleEngine );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::pair<double, double> RimWellLogTrack::adjustXRange( double minValue, double maxValue, double tickInterval )
|
|
{
|
|
double minRemainder = std::fmod( minValue, tickInterval );
|
|
double maxRemainder = std::fmod( maxValue, tickInterval );
|
|
double adjustedMin = minValue - minRemainder;
|
|
double adjustedMax = maxValue + ( tickInterval - maxRemainder );
|
|
return std::make_pair( adjustedMin, adjustedMax );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::pair<double, double> RimWellLogTrack::extendMinMaxRange( double minValue, double maxValue, double factor )
|
|
{
|
|
if ( minValue == std::numeric_limits<double>::infinity() || maxValue == std::numeric_limits<double>::infinity() )
|
|
{
|
|
return { minValue, maxValue };
|
|
}
|
|
|
|
auto modifiedMin = minValue;
|
|
auto modifiedMax = maxValue;
|
|
|
|
auto range = std::fabs( maxValue - minValue );
|
|
if ( range < 1e-6 )
|
|
{
|
|
// If min and max are equal, the curve is not visible. Make sure the range is larger than zero.
|
|
if ( maxValue != 0.0 )
|
|
{
|
|
range = maxValue * 0.01;
|
|
}
|
|
else
|
|
{
|
|
range = 1.0;
|
|
}
|
|
}
|
|
|
|
modifiedMax += factor * range;
|
|
|
|
auto candidateMinValue = minValue - factor * range;
|
|
if ( std::signbit( minValue ) == std::signbit( candidateMinValue ) )
|
|
{
|
|
modifiedMin = candidateMinValue;
|
|
}
|
|
else
|
|
{
|
|
// If the sign of the adjusted minimum changes, set minimum to zero to make sure that zero is located properly
|
|
modifiedMin = 0.0;
|
|
}
|
|
|
|
return { modifiedMin, modifiedMax };
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateWellPathAttributesCollection()
|
|
{
|
|
m_wellPathAttributeSettings->setWellPathAttributeCollection( nullptr );
|
|
if ( m_wellPathAttributeSettings->wellPathComponentSource() )
|
|
{
|
|
std::vector<RimWellPathAttributeCollection*> attributeCollection =
|
|
m_wellPathAttributeSettings->wellPathComponentSource()->descendantsIncludingThisOfType<RimWellPathAttributeCollection>();
|
|
if ( !attributeCollection.empty() )
|
|
{
|
|
m_wellPathAttributeSettings->setWellPathAttributeCollection( attributeCollection.front() );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimDepthTrackPlot* RimWellLogTrack::parentWellLogPlot() const
|
|
{
|
|
return firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::handleWheelEvent( QWheelEvent* wheelEvent )
|
|
{
|
|
auto wellLogPlot = firstAncestorOrThisOfType<RimDepthTrackPlot>();
|
|
if ( wellLogPlot )
|
|
{
|
|
if ( wheelEvent->modifiers() & Qt::ControlModifier )
|
|
{
|
|
double zoomCenter = 0.0;
|
|
auto position = caf::position( wheelEvent );
|
|
|
|
if ( wellLogPlot->depthOrientation() == RiaDefines::Orientation::VERTICAL )
|
|
{
|
|
QwtScaleMap scaleMap = m_plotWidget->qwtPlot()->canvasMap( QwtAxis::YLeft );
|
|
zoomCenter = scaleMap.invTransform( position.y() );
|
|
}
|
|
else
|
|
{
|
|
QwtScaleMap scaleMap = m_plotWidget->qwtPlot()->canvasMap( QwtAxis::XTop );
|
|
zoomCenter = scaleMap.invTransform( position.x() );
|
|
}
|
|
|
|
if ( wheelEvent->angleDelta().y() > 0 )
|
|
{
|
|
wellLogPlot->setDepthAxisRangeByFactorAndCenter( RI_SCROLLWHEEL_ZOOMFACTOR, zoomCenter );
|
|
}
|
|
else
|
|
{
|
|
wellLogPlot->setDepthAxisRangeByFactorAndCenter( 1.0 / RI_SCROLLWHEEL_ZOOMFACTOR, zoomCenter );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wellLogPlot->setDepthAxisRangeByPanDepth( wheelEvent->angleDelta().y() < 0 ? RI_SCROLLWHEEL_PANFACTOR : -RI_SCROLLWHEEL_PANFACTOR );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<std::pair<double, double>> RimWellLogTrack::waterAndRockRegions( RiaDefines::DepthType depthType,
|
|
const RigGeoMechWellLogExtractor* extractor ) const
|
|
{
|
|
double waterEndTVD = extractor->waterDepth();
|
|
if ( waterEndTVD == std::numeric_limits<double>::infinity() )
|
|
{
|
|
waterEndTVD = extractor->estimateWaterDepth();
|
|
}
|
|
|
|
if ( depthType == RiaDefines::DepthType::MEASURED_DEPTH )
|
|
{
|
|
double waterStartMD = 0.0;
|
|
if ( extractor->wellPathGeometry()->rkbDiff() != std::numeric_limits<double>::infinity() )
|
|
{
|
|
waterStartMD += extractor->wellPathGeometry()->rkbDiff();
|
|
}
|
|
double waterEndMD = extractor->cellIntersectionMDs().front();
|
|
double rockEndMD = extractor->cellIntersectionMDs().back();
|
|
return { { waterStartMD, waterEndMD }, { waterEndMD, rockEndMD } };
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH )
|
|
{
|
|
double waterStartTVD = 0.0;
|
|
double rockEndTVD = extractor->cellIntersectionTVDs().back();
|
|
return { { waterStartTVD, waterEndTVD }, { waterEndTVD, rockEndTVD } };
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
|
|
{
|
|
double waterStartTVDRKB = extractor->wellPathGeometry()->rkbDiff();
|
|
double waterEndTVDRKB = waterEndTVD + extractor->wellPathGeometry()->rkbDiff();
|
|
double rockEndTVDRKB = extractor->cellIntersectionTVDs().back() + extractor->wellPathGeometry()->rkbDiff();
|
|
return { { waterStartTVDRKB, waterEndTVDRKB }, { waterEndTVDRKB, rockEndTVDRKB } };
|
|
}
|
|
return {};
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::connectCurveSignals( RimWellLogCurve* curve )
|
|
{
|
|
curve->dataChanged.connect( this, &RimWellLogTrack::curveDataChanged );
|
|
curve->visibilityChanged.connect( this, &RimWellLogTrack::curveVisibilityChanged );
|
|
curve->appearanceChanged.connect( this, &RimWellLogTrack::curveAppearanceChanged );
|
|
curve->stackingChanged.connect( this, &RimWellLogTrack::curveStackingChanged );
|
|
curve->stackingColorsChanged.connect( this, &RimWellLogTrack::curveStackingChanged );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::computeAndSetPropertyValueRangeMinForLogarithmicScale()
|
|
{
|
|
if ( m_propertyAxisSettings->isAutoScaleEnabled() && m_propertyAxisSettings->isLogarithmicScaleEnabled() )
|
|
{
|
|
double pos = HUGE_VAL;
|
|
double neg = -HUGE_VAL;
|
|
|
|
for ( const auto& curve : m_curves )
|
|
{
|
|
if ( curve->isChecked() )
|
|
{
|
|
RigStatisticsCalculator::posNegClosestToZero( curve->curveData().propertyValuesByIntervals(), pos, neg );
|
|
}
|
|
}
|
|
|
|
if ( pos != HUGE_VAL )
|
|
{
|
|
m_propertyAxisSettings->setVisibleRange( pos, m_propertyAxisSettings->visibleRangeMax() );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setLogarithmicScale( bool enable )
|
|
{
|
|
m_propertyAxisSettings->setLogarithmicScaleEnabled( enable );
|
|
|
|
updateAxisScaleEngine();
|
|
computeAndSetPropertyValueRangeMinForLogarithmicScale();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimWellLogTrack::isLogarithmicScale() const
|
|
{
|
|
return m_propertyAxisSettings->isLogarithmicScaleEnabled();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::map<int, std::vector<RimWellLogCurve*>> RimWellLogTrack::visibleStackedCurves()
|
|
{
|
|
std::map<int, std::vector<RimWellLogCurve*>> stackedCurves;
|
|
for ( RimWellLogCurve* curve : m_curves )
|
|
{
|
|
if ( curve && curve->isChecked() )
|
|
{
|
|
RimWellFlowRateCurve* wfrCurve = dynamic_cast<RimWellFlowRateCurve*>( curve );
|
|
if ( wfrCurve != nullptr ) // Flow rate curves are always stacked
|
|
{
|
|
stackedCurves[wfrCurve->groupId()].push_back( wfrCurve );
|
|
}
|
|
else if ( curve->isStacked() )
|
|
{
|
|
stackedCurves[-1].push_back( curve );
|
|
}
|
|
}
|
|
}
|
|
|
|
return stackedCurves;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<RimWellLogCurve*> RimWellLogTrack::curves() const
|
|
{
|
|
return m_curves.childrenByType();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<RimWellLogCurve*> RimWellLogTrack::visibleCurves() const
|
|
{
|
|
std::vector<RimWellLogCurve*> curvesVector;
|
|
|
|
for ( RimWellLogCurve* curve : m_curves.childrenByType() )
|
|
{
|
|
if ( curve->isChecked() )
|
|
{
|
|
curvesVector.push_back( curve );
|
|
}
|
|
}
|
|
|
|
return curvesVector;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::uiOrderingForRftPltFormations( caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
caf::PdmUiGroup* formationGroup = uiOrdering.addNewGroup( "Zonation/Formation Names" );
|
|
formationGroup->setCollapsedByDefault();
|
|
|
|
// Region annotation settings UI ordering
|
|
m_regionAnnotationSettings->uiOrdering( "", *formationGroup );
|
|
|
|
// Delegate to formation settings for formation-related fields
|
|
m_formationSettings->uiOrdering( "", *formationGroup, m_formationsForCaseWithSimWellOnly );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::uiOrderingForPropertyAxisSettings( caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
m_propertyAxisSettings->uiOrdering( "", uiOrdering );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::enablePropertyAxis( bool enable )
|
|
{
|
|
m_propertyAxisSettings->setEnabled( enable );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimWellLogTrack::isPropertyAxisEnabled() const
|
|
{
|
|
return m_propertyAxisSettings->isEnabled();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setFormationsForCaseWithSimWellOnly( bool caseWithSimWellOnly )
|
|
{
|
|
m_formationsForCaseWithSimWellOnly = caseWithSimWellOnly;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RigEclipseWellLogExtractor* RimWellLogTrack::createSimWellExtractor( RimWellLogPlotCollection* wellLogCollection,
|
|
RimCase* rimCase,
|
|
const QString& simWellName,
|
|
int branchIndex,
|
|
bool useBranchDetection )
|
|
{
|
|
if ( !wellLogCollection ) return nullptr;
|
|
|
|
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase );
|
|
if ( !eclipseCase ) return nullptr;
|
|
|
|
std::vector<const RigWellPath*> wellPaths = RiaSimWellBranchTools::simulationWellBranches( simWellName, useBranchDetection );
|
|
|
|
if ( wellPaths.empty() ) return nullptr;
|
|
|
|
CAF_ASSERT( branchIndex >= 0 && branchIndex < static_cast<int>( wellPaths.size() ) );
|
|
|
|
return ( wellLogCollection->findOrCreateSimWellExtractor( simWellName,
|
|
QString( "Find or create sim well extractor" ),
|
|
wellPaths[branchIndex],
|
|
eclipseCase->eclipseCaseData() ) );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
CurveSamplingPointData RimWellLogTrack::curveSamplingPointData( RigEclipseWellLogExtractor* extractor, RigResultAccessor* resultAccessor )
|
|
{
|
|
CurveSamplingPointData curveData;
|
|
|
|
curveData.md = extractor->cellIntersectionMDs();
|
|
curveData.tvd = extractor->cellIntersectionTVDs();
|
|
curveData.rkbDiff = extractor->wellPathGeometry()->rkbDiff();
|
|
|
|
extractor->curveData( resultAccessor, &curveData.data );
|
|
|
|
return curveData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
CurveSamplingPointData RimWellLogTrack::curveSamplingPointData( RigGeoMechWellLogExtractor* extractor, const RigFemResultAddress& resultAddress )
|
|
{
|
|
CurveSamplingPointData curveData;
|
|
|
|
curveData.md = extractor->cellIntersectionMDs();
|
|
curveData.tvd = extractor->cellIntersectionTVDs();
|
|
curveData.rkbDiff = extractor->wellPathGeometry()->rkbDiff();
|
|
|
|
extractor->curveData( resultAddress, 0, 0, &curveData.data );
|
|
return curveData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::findRegionNamesToPlot( const CurveSamplingPointData& curveData,
|
|
const std::vector<QString>& regionNamesVector,
|
|
RimWellLogPlot::DepthTypeEnum depthType,
|
|
std::vector<QString>* regionNamesToPlot,
|
|
std::vector<std::pair<double, double>>* yValues )
|
|
{
|
|
if ( regionNamesVector.empty() ) return;
|
|
|
|
std::vector<size_t> regionNameIndicesFromCurve;
|
|
|
|
for ( double nameIdx : curveData.data )
|
|
{
|
|
if ( nameIdx != std::numeric_limits<double>::infinity() )
|
|
{
|
|
regionNameIndicesFromCurve.push_back( static_cast<size_t>( round( nameIdx ) ) );
|
|
}
|
|
else
|
|
{
|
|
regionNameIndicesFromCurve.push_back( std::numeric_limits<size_t>::max() );
|
|
}
|
|
}
|
|
|
|
if ( regionNameIndicesFromCurve.empty() ) return;
|
|
|
|
std::vector<double> depthVector;
|
|
|
|
if ( depthType == RiaDefines::DepthType::MEASURED_DEPTH || depthType == RiaDefines::DepthType::PSEUDO_LENGTH )
|
|
{
|
|
depthVector = curveData.md;
|
|
}
|
|
else if ( depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH || depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
|
|
{
|
|
depthVector = curveData.tvd;
|
|
if ( depthType == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
|
|
{
|
|
for ( double& depthValue : depthVector )
|
|
{
|
|
depthValue += curveData.rkbDiff;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( depthVector.empty() ) return;
|
|
|
|
double currentYStart = depthVector[0];
|
|
size_t prevNameIndex = regionNameIndicesFromCurve[0];
|
|
size_t currentNameIndex;
|
|
|
|
for ( size_t i = 1; i < regionNameIndicesFromCurve.size(); i++ )
|
|
{
|
|
currentNameIndex = regionNameIndicesFromCurve[i];
|
|
if ( currentNameIndex != std::numeric_limits<size_t>::max() && currentNameIndex != prevNameIndex )
|
|
{
|
|
if ( prevNameIndex < regionNamesVector.size() )
|
|
{
|
|
regionNamesToPlot->push_back( regionNamesVector[prevNameIndex] );
|
|
yValues->push_back( std::make_pair( currentYStart, depthVector[i - 1] ) );
|
|
}
|
|
|
|
currentYStart = depthVector[i];
|
|
prevNameIndex = currentNameIndex;
|
|
}
|
|
}
|
|
|
|
size_t lastFormationIdx = regionNameIndicesFromCurve.back();
|
|
if ( lastFormationIdx < regionNamesVector.size() )
|
|
{
|
|
regionNamesToPlot->push_back( regionNamesVector[lastFormationIdx] );
|
|
yValues->push_back( std::make_pair( currentYStart, depthVector.back() ) );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::vector<QString> RimWellLogTrack::formationNamesVector( RimCase* rimCase )
|
|
{
|
|
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( rimCase );
|
|
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>( rimCase );
|
|
|
|
if ( eclipseCase )
|
|
{
|
|
return eclipseCase->eclipseCaseData()->formationNames();
|
|
}
|
|
else if ( geoMechCase )
|
|
{
|
|
return geoMechCase->geoMechData()->femPartResults()->formationNames();
|
|
}
|
|
|
|
return std::vector<QString>();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateStackedCurveData()
|
|
{
|
|
// See RimSummaryPlot::updateStackedCurveDataForAxis() horizontal plots
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
RimWellLogPlot::DepthTypeEnum depthType = wellLogPlot->depthType();
|
|
RiaDefines::DepthUnitType displayUnit = wellLogPlot->depthUnit();
|
|
if ( depthType == RiaDefines::DepthType::CONNECTION_NUMBER )
|
|
{
|
|
displayUnit = RiaDefines::DepthUnitType::UNIT_NONE;
|
|
}
|
|
|
|
std::map<RiaDefines::PhaseType, size_t> curvePhaseCount;
|
|
|
|
// Stack the curves that are meant to be stacked
|
|
std::map<int, std::vector<RimWellLogCurve*>> stackedCurves = visibleStackedCurves();
|
|
|
|
// Reset all stacked curves
|
|
for ( auto groupCurvePair : stackedCurves )
|
|
{
|
|
const std::vector<RimWellLogCurve*>& stackedCurvesInGroup = groupCurvePair.second;
|
|
for ( auto curve : stackedCurvesInGroup )
|
|
{
|
|
curve->loadDataAndUpdate( false );
|
|
curvePhaseCount[curve->phaseType()]++;
|
|
}
|
|
}
|
|
|
|
for ( auto groupCurvePair : stackedCurves )
|
|
{
|
|
int groupId = groupCurvePair.first;
|
|
const std::vector<RimWellLogCurve*>& stackedCurvesInGroup = groupCurvePair.second;
|
|
if ( stackedCurvesInGroup.empty() ) continue;
|
|
|
|
// Z-position of curve, to draw them in correct order
|
|
double zPos = -10000.0 + 100.0 * static_cast<double>( groupId );
|
|
|
|
// We use the depths from the curve with the largest depth range.
|
|
// Trying to merge them is difficult since they may not be in order.
|
|
std::pair<double, double> maxDepthRange;
|
|
std::vector<double> allDepthValues;
|
|
|
|
for ( auto curve : stackedCurvesInGroup )
|
|
{
|
|
auto depths = curve->curveData().depths( depthType );
|
|
if ( depths.empty() ) continue;
|
|
|
|
if ( allDepthValues.empty() )
|
|
{
|
|
auto minmaxit = std::minmax_element( depths.begin(), depths.end() );
|
|
maxDepthRange = std::make_pair( *minmaxit.first, *minmaxit.second );
|
|
allDepthValues.insert( allDepthValues.end(), depths.begin(), depths.end() );
|
|
}
|
|
else
|
|
{
|
|
auto minmaxit = std::minmax_element( depths.begin(), depths.end() );
|
|
std::pair<double, double> depthRange = std::make_pair( *minmaxit.first, *minmaxit.second );
|
|
if ( std::fabs( depthRange.second - depthRange.first ) > std::fabs( maxDepthRange.second - maxDepthRange.first ) )
|
|
{
|
|
maxDepthRange = depthRange;
|
|
allDepthValues = depths;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( allDepthValues.empty() ) continue;
|
|
|
|
size_t stackIndex = 0u;
|
|
std::vector<double> allStackedValues( allDepthValues.size(), 0.0 );
|
|
for ( auto curve : stackedCurvesInGroup )
|
|
{
|
|
auto interpolatedCurveValues = curve->curveData().calculateResampledCurveData( depthType, allDepthValues );
|
|
auto xValues = interpolatedCurveValues.propertyValues();
|
|
for ( size_t i = 0; i < xValues.size(); ++i )
|
|
{
|
|
if ( xValues[i] != HUGE_VAL )
|
|
{
|
|
allStackedValues[i] += xValues[i];
|
|
}
|
|
}
|
|
|
|
RigWellLogCurveData tempCurveData;
|
|
tempCurveData.setValuesAndDepths( allStackedValues,
|
|
allDepthValues,
|
|
depthType,
|
|
0.0,
|
|
displayUnit,
|
|
false,
|
|
m_propertyAxisSettings->isLogarithmicScaleEnabled() );
|
|
|
|
auto plotDepthValues = tempCurveData.depths( depthType );
|
|
auto polyLineStartStopIndices = tempCurveData.polylineStartStopIndices();
|
|
|
|
curve->setOverrideCurveData( allStackedValues, plotDepthValues, polyLineStartStopIndices );
|
|
curve->setZOrder( zPos );
|
|
|
|
if ( !dynamic_cast<RimWellFlowRateCurve*>( curve ) )
|
|
{
|
|
// Apply a area filled style if it isn't already set
|
|
if ( curve->fillStyle() == Qt::NoBrush )
|
|
{
|
|
curve->setFillStyle( Qt::SolidPattern );
|
|
}
|
|
|
|
if ( curve->isStackedWithPhaseColors() )
|
|
{
|
|
curve->assignStackColor( stackIndex, curvePhaseCount[curve->phaseType()] );
|
|
}
|
|
}
|
|
zPos -= 1.0;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateRegionAnnotationsOnPlot()
|
|
{
|
|
removeRegionAnnotations();
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::NO_ANNOTATIONS ) return;
|
|
|
|
if ( m_annotationTool == nullptr )
|
|
{
|
|
m_annotationTool = std::make_unique<RiuPlotAnnotationTool>();
|
|
}
|
|
|
|
if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::FORMATION_ANNOTATIONS )
|
|
{
|
|
updateFormationNamesOnPlot();
|
|
}
|
|
else if ( m_regionAnnotationSettings->annotationType() == RiaDefines::RegionAnnotationType::RESULT_PROPERTY_ANNOTATIONS )
|
|
{
|
|
updateResultPropertyNamesOnPlot();
|
|
}
|
|
else
|
|
{
|
|
updateCurveDataRegionsOnPlot();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateFormationNamesOnPlot()
|
|
{
|
|
RimDepthTrackPlot* plot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
RiaDefines::DepthUnitType fromDepthUnit = plot->caseDepthUnit();
|
|
RiaDefines::DepthUnitType toDepthUnit = plot->depthUnit();
|
|
|
|
auto orientation = plot->depthOrientation();
|
|
|
|
if ( m_formationSettings->formationSource() == RiaDefines::WellLogTrackFormationSource::WELL_PICK_FILTER )
|
|
{
|
|
if ( m_formationSettings->wellPathForSourceWellPath() == nullptr ) return;
|
|
|
|
if ( plot->depthType() != RiaDefines::DepthType::MEASURED_DEPTH && plot->depthType() != RiaDefines::DepthType::TRUE_VERTICAL_DEPTH &&
|
|
plot->depthType() != RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::vector<double> yValues;
|
|
|
|
const RigWellPathFormations* formations = m_formationSettings->wellPathForSourceWellPath()->formationsGeometry();
|
|
if ( !formations ) return;
|
|
|
|
std::vector<QString> formationNamesToPlot;
|
|
auto formationLevel = static_cast<RigWellPathFormations::FormationLevel>( m_formationSettings->formationLevel() );
|
|
formations->depthAndFormationNamesUpToLevel( formationLevel,
|
|
&formationNamesToPlot,
|
|
&yValues,
|
|
m_formationSettings->showFormationFluids(),
|
|
plot->depthType() );
|
|
|
|
if ( plot->depthType() == RiaDefines::DepthType::TRUE_VERTICAL_DEPTH_RKB )
|
|
{
|
|
for ( double& depthValue : yValues )
|
|
{
|
|
depthValue += m_formationSettings->wellPathForSourceWellPath()->wellPathGeometry()->rkbDiff();
|
|
}
|
|
}
|
|
|
|
std::vector<double> convertedYValues = RiaWellLogUnitTools<double>::convertDepths( yValues, fromDepthUnit, toDepthUnit );
|
|
|
|
m_annotationTool->attachWellPicks( m_plotWidget->qwtPlot(), formationNamesToPlot, convertedYValues );
|
|
}
|
|
else
|
|
{
|
|
RimMainPlotCollection* mainPlotCollection = firstAncestorOrThisOfTypeAsserted<RimMainPlotCollection>();
|
|
|
|
RimWellLogPlotCollection* wellLogCollection = mainPlotCollection->wellLogPlotCollection();
|
|
|
|
CurveSamplingPointData curveData;
|
|
|
|
RigEclipseWellLogExtractor* eclWellLogExtractor = nullptr;
|
|
RigGeoMechWellLogExtractor* geoMechWellLogExtractor = nullptr;
|
|
|
|
if ( m_formationSettings->trajectoryType() == RiaDefines::WellLogTrackTrajectoryType::SIMULATION_WELL )
|
|
{
|
|
eclWellLogExtractor = RimWellLogTrack::createSimWellExtractor( wellLogCollection,
|
|
m_formationSettings->formationCase(),
|
|
m_formationSettings->simWellName(),
|
|
m_formationSettings->branchIndex(),
|
|
m_formationSettings->branchDetection() );
|
|
}
|
|
else
|
|
{
|
|
eclWellLogExtractor =
|
|
RiaExtractionTools::findOrCreateWellLogExtractor( m_formationSettings->wellPathForSourceCase(),
|
|
dynamic_cast<RimEclipseCase*>( m_formationSettings->formationCase() ) );
|
|
}
|
|
|
|
if ( eclWellLogExtractor )
|
|
{
|
|
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_formationSettings->formationCase() );
|
|
cvf::ref<RigResultAccessor> resultAccessor =
|
|
RigResultAccessorFactory::createFromResultAddress( eclipseCase->eclipseCaseData(),
|
|
0,
|
|
RiaDefines::PorosityModelType::MATRIX_MODEL,
|
|
0,
|
|
RigEclipseResultAddress( RiaDefines::ResultCatType::FORMATION_NAMES,
|
|
RiaResultNames::activeFormationNamesResultName() ) );
|
|
|
|
if ( resultAccessor.notNull() )
|
|
{
|
|
curveData = RimWellLogTrack::curveSamplingPointData( eclWellLogExtractor, resultAccessor.p() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
geoMechWellLogExtractor =
|
|
RiaExtractionTools::findOrCreateWellLogExtractor( m_formationSettings->wellPathForSourceCase(),
|
|
dynamic_cast<RimGeoMechCase*>( m_formationSettings->formationCase() ) );
|
|
if ( !geoMechWellLogExtractor ) return;
|
|
|
|
std::string activeFormationNamesResultName = RiaResultNames::activeFormationNamesResultName().toStdString();
|
|
curveData =
|
|
RimWellLogTrack::curveSamplingPointData( geoMechWellLogExtractor,
|
|
RigFemResultAddress( RIG_FORMATION_NAMES, activeFormationNamesResultName, "" ) );
|
|
}
|
|
|
|
if ( geoMechWellLogExtractor )
|
|
{
|
|
// Attach water and rock base formations
|
|
|
|
const caf::ColorTable waterAndRockColors = RiaColorTables::waterAndRockPaletteColors();
|
|
const std::vector<std::pair<double, double>> waterAndRockIntervals =
|
|
waterAndRockRegions( plot->depthType(), geoMechWellLogExtractor );
|
|
|
|
const std::vector<std::pair<double, double>> convertedYValues =
|
|
RiaWellLogUnitTools<double>::convertDepths( waterAndRockIntervals, fromDepthUnit, toDepthUnit );
|
|
|
|
m_annotationTool->attachNamedRegions( m_plotWidget->qwtPlot(),
|
|
{ "Sea Level", "" },
|
|
orientation,
|
|
convertedYValues,
|
|
m_regionAnnotationSettings->annotationDisplay(),
|
|
waterAndRockColors,
|
|
( ( 100 - m_regionAnnotationSettings->colorShadingTransparency() ) * 255 ) / 100,
|
|
m_regionAnnotationSettings->showRegionLabels(),
|
|
RiaDefines::TrackSpan::LEFT_COLUMN,
|
|
{ Qt::SolidPattern, Qt::Dense6Pattern } );
|
|
}
|
|
|
|
if ( m_formationSettings->formationSource() == RiaDefines::WellLogTrackFormationSource::CASE && m_plotWidget )
|
|
{
|
|
if ( ( m_formationSettings->simWellName() == QString( "None" ) && m_formationSettings->wellPathForSourceCase() == nullptr ) ||
|
|
m_formationSettings->formationCase() == nullptr )
|
|
return;
|
|
|
|
std::vector<QString> formationNamesVector = RimWellLogTrack::formationNamesVector( m_formationSettings->formationCase() );
|
|
|
|
if ( m_wellPathAttributeSettings->overburdenHeight() > 0.0 )
|
|
{
|
|
addOverburden( formationNamesVector, curveData, m_wellPathAttributeSettings->overburdenHeight() );
|
|
}
|
|
|
|
if ( m_wellPathAttributeSettings->underburdenHeight() > 0.0 )
|
|
{
|
|
addUnderburden( formationNamesVector, curveData, m_wellPathAttributeSettings->underburdenHeight() );
|
|
}
|
|
|
|
std::vector<std::pair<double, double>> yValues;
|
|
|
|
std::vector<QString> formationNamesToPlot;
|
|
RimWellLogTrack::findRegionNamesToPlot( curveData, formationNamesVector, plot->depthType(), &formationNamesToPlot, &yValues );
|
|
|
|
std::vector<std::pair<double, double>> convertedYValues =
|
|
RiaWellLogUnitTools<double>::convertDepths( yValues, fromDepthUnit, toDepthUnit );
|
|
|
|
// Build color table ordered by formation name to ensure correct color mapping
|
|
// when using a legend based on a LYR-file. Falls back to palette index for
|
|
// formations not found in the legend (e.g., when using a generic color palette).
|
|
// Related to https://github.com/OPM/ResInsight/issues/12974
|
|
RimColorLegend* legend = m_regionAnnotationSettings->colorShadingLegend();
|
|
if ( !legend ) legend = RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::NORMAL );
|
|
|
|
if ( legend && !formationNamesToPlot.empty() )
|
|
{
|
|
std::map<QString, cvf::Color3ub> nameToColor;
|
|
for ( auto* item : legend->colorLegendItems() )
|
|
{
|
|
nameToColor[item->categoryName()] = cvf::Color3ub( item->color() );
|
|
}
|
|
|
|
cvf::Color3ubArray paletteColors = legend->colorArray();
|
|
size_t colorCount = std::max( size_t( 2 ), formationNamesToPlot.size() );
|
|
cvf::Color3ubArray orderedColors( colorCount );
|
|
orderedColors.setAll( cvf::Color3ub::GRAY );
|
|
|
|
for ( size_t i = 0; i < formationNamesToPlot.size(); i++ )
|
|
{
|
|
auto it = nameToColor.find( formationNamesToPlot[i] );
|
|
if ( it != nameToColor.end() )
|
|
{
|
|
orderedColors.set( i, it->second );
|
|
}
|
|
else if ( paletteColors.size() > 0 )
|
|
{
|
|
orderedColors.set( i, paletteColors[i % paletteColors.size()] );
|
|
}
|
|
}
|
|
|
|
caf::ColorTable colorTable( orderedColors );
|
|
|
|
m_annotationTool->attachNamedRegions( m_plotWidget->qwtPlot(),
|
|
formationNamesToPlot,
|
|
orientation,
|
|
convertedYValues,
|
|
m_regionAnnotationSettings->annotationDisplay(),
|
|
colorTable,
|
|
( ( 100 - m_regionAnnotationSettings->colorShadingTransparency() ) * 255 ) / 100,
|
|
m_regionAnnotationSettings->showRegionLabels() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateResultPropertyNamesOnPlot()
|
|
{
|
|
RimDepthTrackPlot* plot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
RiaDefines::DepthUnitType fromDepthUnit = plot->caseDepthUnit();
|
|
RiaDefines::DepthUnitType toDepthUnit = plot->depthUnit();
|
|
|
|
auto orientation = plot->depthOrientation();
|
|
|
|
RigEclipseWellLogExtractor* eclWellLogExtractor =
|
|
RiaExtractionTools::findOrCreateWellLogExtractor( m_formationSettings->wellPathForSourceCase(),
|
|
dynamic_cast<RimEclipseCase*>( m_formationSettings->formationCase() ) );
|
|
|
|
if ( !eclWellLogExtractor )
|
|
{
|
|
RiaLogging::error( "No well log extractor found for case." );
|
|
return;
|
|
}
|
|
|
|
RimEclipseCase* eclipseCase = dynamic_cast<RimEclipseCase*>( m_formationSettings->formationCase() );
|
|
|
|
m_resultDefinition->loadResult();
|
|
|
|
size_t m_timeStep = 0;
|
|
cvf::ref<RigResultAccessor> resultAccessor =
|
|
RigResultAccessorFactory::createFromResultDefinition( eclipseCase->eclipseCaseData(), 0, m_timeStep, m_resultDefinition );
|
|
if ( !resultAccessor.notNull() )
|
|
{
|
|
QString resultTypeStr = caf::AppEnum<RiaDefines::ResultCatType>( m_resultDefinition->resultType() ).uiText();
|
|
RiaLogging::error( QString( "Unable to find result for region annotation for '%1' track. Tried '%2' (%3) on case: '%4'" )
|
|
.arg( m_description() )
|
|
.arg( m_resultDefinition->resultVariable() )
|
|
.arg( resultTypeStr )
|
|
.arg( eclipseCase->caseUserDescription() )
|
|
.toStdString() );
|
|
return;
|
|
}
|
|
|
|
CurveSamplingPointData curveData = RimWellLogTrack::curveSamplingPointData( eclWellLogExtractor, resultAccessor.p() );
|
|
|
|
// Attach water and rock base formations
|
|
|
|
if ( m_formationSettings->formationSource() == RiaDefines::WellLogTrackFormationSource::CASE )
|
|
{
|
|
if ( ( m_formationSettings->simWellName() == QString( "None" ) && m_formationSettings->wellPathForSourceCase() == nullptr ) ||
|
|
m_formationSettings->formationCase() == nullptr )
|
|
return;
|
|
|
|
std::vector<cvf::Color3ub> colors;
|
|
|
|
// Find the largest category number.
|
|
int maxCategoryValue = std::numeric_limits<int>::min();
|
|
for ( RimColorLegendItem* legendItem : m_regionAnnotationSettings->colorShadingLegend()->colorLegendItems() )
|
|
{
|
|
maxCategoryValue = std::max( maxCategoryValue, legendItem->categoryValue() );
|
|
}
|
|
|
|
// Insert each name at index matching the category number.
|
|
std::vector<QString> namesVector( maxCategoryValue + 1 );
|
|
for ( RimColorLegendItem* legendItem : m_regionAnnotationSettings->colorShadingLegend()->colorLegendItems() )
|
|
{
|
|
namesVector[legendItem->categoryValue()] = legendItem->categoryName();
|
|
}
|
|
|
|
if ( m_wellPathAttributeSettings->overburdenHeight() > 0.0 )
|
|
{
|
|
addOverburden( namesVector, curveData, m_wellPathAttributeSettings->overburdenHeight() );
|
|
}
|
|
|
|
if ( m_wellPathAttributeSettings->underburdenHeight() > 0.0 )
|
|
{
|
|
addUnderburden( namesVector, curveData, m_wellPathAttributeSettings->underburdenHeight() );
|
|
}
|
|
|
|
std::vector<QString> namesToPlot;
|
|
std::vector<std::pair<double, double>> yValues;
|
|
RimWellLogTrack::findRegionNamesToPlot( curveData, namesVector, plot->depthType(), &namesToPlot, &yValues );
|
|
|
|
// convert to plot depth unit
|
|
std::vector<std::pair<double, double>> convertedYValues =
|
|
RiaWellLogUnitTools<double>::convertDepths( yValues, fromDepthUnit, toDepthUnit );
|
|
|
|
// TODO: unnecessarily messy!
|
|
// Need to map colors to names (since a category can be used several times)
|
|
for ( QString nameToPlot : namesToPlot )
|
|
{
|
|
bool isFound = false;
|
|
for ( RimColorLegendItem* legendItem : m_regionAnnotationSettings->colorShadingLegend()->colorLegendItems() )
|
|
{
|
|
if ( legendItem->categoryName() == nameToPlot )
|
|
{
|
|
colors.push_back( cvf::Color3ub( legendItem->color() ) );
|
|
isFound = true;
|
|
}
|
|
}
|
|
|
|
if ( !isFound )
|
|
{
|
|
colors.push_back( cvf::Color3ub( RiaColorTables::undefinedCellColor() ) );
|
|
}
|
|
}
|
|
|
|
if ( colors.empty() )
|
|
{
|
|
RiaLogging::error( "No colors found." );
|
|
return;
|
|
}
|
|
|
|
caf::ColorTable colorTable( colors );
|
|
|
|
int fontSize = caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(),
|
|
m_regionAnnotationSettings->regionLabelFontSize() );
|
|
|
|
m_annotationTool->attachNamedRegions( m_plotWidget->qwtPlot(),
|
|
namesToPlot,
|
|
orientation,
|
|
convertedYValues,
|
|
m_regionAnnotationSettings->annotationDisplay(),
|
|
colorTable,
|
|
( ( 100 - m_regionAnnotationSettings->colorShadingTransparency() ) * 255 ) / 100,
|
|
m_regionAnnotationSettings->showRegionLabels(),
|
|
RiaDefines::TrackSpan::FULL_WIDTH,
|
|
{},
|
|
fontSize );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateCurveDataRegionsOnPlot()
|
|
{
|
|
RimWellBoreStabilityPlot* wellBoreStabilityPlot = firstAncestorOrThisOfType<RimWellBoreStabilityPlot>();
|
|
if ( wellBoreStabilityPlot )
|
|
{
|
|
RiaDefines::DepthUnitType fromDepthUnit = wellBoreStabilityPlot->caseDepthUnit();
|
|
RiaDefines::DepthUnitType toDepthUnit = wellBoreStabilityPlot->depthUnit();
|
|
|
|
auto orientation = wellBoreStabilityPlot->depthOrientation();
|
|
|
|
wellBoreStabilityPlot->updateCommonDataSource();
|
|
RimGeoMechCase* geoMechCase = dynamic_cast<RimGeoMechCase*>( wellBoreStabilityPlot->commonDataSource()->caseToApply() );
|
|
RimWellPath* wellPath = wellBoreStabilityPlot->commonDataSource()->wellPathToApply();
|
|
int timeStep = wellBoreStabilityPlot->commonDataSource()->timeStepToApply();
|
|
if ( geoMechCase && wellPath && timeStep >= 0 )
|
|
{
|
|
auto [stepIdx, frameIdx] = geoMechCase->geoMechData()->femPartResults()->stepListIndexToTimeStepAndDataFrameIndex( timeStep );
|
|
|
|
RigGeoMechWellLogExtractor* geoMechWellLogExtractor = nullptr;
|
|
geoMechWellLogExtractor =
|
|
RiaExtractionTools::findOrCreateWellLogExtractor( wellPath, dynamic_cast<RimGeoMechCase*>( geoMechCase ) );
|
|
if ( !geoMechWellLogExtractor ) return;
|
|
|
|
CurveSamplingPointData curveData;
|
|
curveData.md = geoMechWellLogExtractor->cellIntersectionMDs();
|
|
curveData.tvd = geoMechWellLogExtractor->cellIntersectionTVDs();
|
|
|
|
RimWellLogExtractionCurve::findAndLoadWbsParametersFromFiles( wellPath, geoMechWellLogExtractor );
|
|
RimWellBoreStabilityPlot* wbsPlot = firstAncestorOrThisOfType<RimWellBoreStabilityPlot>();
|
|
if ( wbsPlot )
|
|
{
|
|
wbsPlot->applyWbsParametersToExtractor( geoMechWellLogExtractor );
|
|
}
|
|
|
|
std::vector<double> ppSourceRegions = geoMechWellLogExtractor->porePressureSourceRegions( stepIdx, frameIdx );
|
|
std::vector<double> poissonSourceRegions = geoMechWellLogExtractor->poissonSourceRegions( stepIdx, frameIdx );
|
|
std::vector<double> ucsSourceRegions = geoMechWellLogExtractor->ucsSourceRegions( stepIdx, frameIdx );
|
|
|
|
{
|
|
caf::ColorTable colorTable( m_regionAnnotationSettings->colorShadingLegend()->colorArray() );
|
|
|
|
std::vector<QString> sourceNames =
|
|
RigWbsParameter::PP_Reservoir().allSourceUiLabels( "\n", wbsPlot->userDefinedValue( RigWbsParameter::PP_NonReservoir() ) );
|
|
curveData.data = ppSourceRegions;
|
|
|
|
std::vector<QString> sourceNamesToPlot;
|
|
std::vector<std::pair<double, double>> yValues;
|
|
RimWellLogTrack::findRegionNamesToPlot( curveData, sourceNames, wellBoreStabilityPlot->depthType(), &sourceNamesToPlot, &yValues );
|
|
|
|
// convert to plot depth unit
|
|
std::vector<std::pair<double, double>> convertedYValues =
|
|
RiaWellLogUnitTools<double>::convertDepths( yValues, fromDepthUnit, toDepthUnit );
|
|
|
|
m_annotationTool->attachNamedRegions( m_plotWidget->qwtPlot(),
|
|
sourceNamesToPlot,
|
|
orientation,
|
|
convertedYValues,
|
|
m_regionAnnotationSettings->annotationDisplay(),
|
|
colorTable,
|
|
( ( ( 100 - m_regionAnnotationSettings->colorShadingTransparency() ) * 255 ) / 100 ) / 3,
|
|
m_regionAnnotationSettings->showRegionLabels(),
|
|
RiaDefines::TrackSpan::LEFT_COLUMN );
|
|
}
|
|
{
|
|
caf::ColorTable colorTable( m_regionAnnotationSettings->colorShadingLegend()->colorArray() );
|
|
|
|
std::vector<QString> sourceNames =
|
|
RigWbsParameter::poissonRatio().allSourceUiLabels( "\n", wbsPlot->userDefinedValue( RigWbsParameter::poissonRatio() ) );
|
|
curveData.data = poissonSourceRegions;
|
|
|
|
std::vector<QString> sourceNamesToPlot;
|
|
std::vector<std::pair<double, double>> yValues;
|
|
RimWellLogTrack::findRegionNamesToPlot( curveData, sourceNames, wellBoreStabilityPlot->depthType(), &sourceNamesToPlot, &yValues );
|
|
|
|
// convert to plot depth unit
|
|
std::vector<std::pair<double, double>> convertedYValues =
|
|
RiaWellLogUnitTools<double>::convertDepths( yValues, fromDepthUnit, toDepthUnit );
|
|
|
|
m_annotationTool->attachNamedRegions( m_plotWidget->qwtPlot(),
|
|
sourceNamesToPlot,
|
|
orientation,
|
|
convertedYValues,
|
|
m_regionAnnotationSettings->annotationDisplay(),
|
|
colorTable,
|
|
( ( ( 100 - m_regionAnnotationSettings->colorShadingTransparency() ) * 255 ) / 100 ) / 3,
|
|
m_regionAnnotationSettings->showRegionLabels(),
|
|
RiaDefines::TrackSpan::CENTRE_COLUMN );
|
|
}
|
|
{
|
|
caf::ColorTable colorTable( m_regionAnnotationSettings->colorShadingLegend()->colorArray() );
|
|
|
|
std::vector<QString> sourceNames =
|
|
RigWbsParameter::UCS().allSourceUiLabels( "\n", wbsPlot->userDefinedValue( RigWbsParameter::UCS() ) );
|
|
|
|
curveData.data = ucsSourceRegions;
|
|
|
|
std::vector<QString> sourceNamesToPlot;
|
|
std::vector<std::pair<double, double>> yValues;
|
|
RimWellLogTrack::findRegionNamesToPlot( curveData, sourceNames, wellBoreStabilityPlot->depthType(), &sourceNamesToPlot, &yValues );
|
|
|
|
// convert to plot depth unit
|
|
std::vector<std::pair<double, double>> convertedYValues =
|
|
RiaWellLogUnitTools<double>::convertDepths( yValues, fromDepthUnit, toDepthUnit );
|
|
|
|
m_annotationTool->attachNamedRegions( m_plotWidget->qwtPlot(),
|
|
sourceNamesToPlot,
|
|
orientation,
|
|
convertedYValues,
|
|
m_regionAnnotationSettings->annotationDisplay(),
|
|
colorTable,
|
|
( ( ( 100 - m_regionAnnotationSettings->colorShadingTransparency() ) * 255 ) / 100 ) / 3,
|
|
m_regionAnnotationSettings->showRegionLabels(),
|
|
RiaDefines::TrackSpan::RIGHT_COLUMN );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::updateWellPathAttributesOnPlot()
|
|
{
|
|
m_wellPathAttributePlotObjects.clear();
|
|
|
|
if ( wellPathAttributeSource() )
|
|
{
|
|
std::vector<const RimWellPathComponentInterface*> allWellPathComponents;
|
|
|
|
if ( wellPathAttributeSource()->wellPathGeometry() &&
|
|
( m_wellPathAttributeSettings->showWellPathAttributes() || m_wellPathAttributeSettings->showWellPathCompletions() ) )
|
|
{
|
|
m_wellPathAttributePlotObjects.push_back( std::make_unique<RiuWellPathComponentPlotItem>( wellPathAttributeSource() ) );
|
|
}
|
|
|
|
if ( m_wellPathAttributeSettings->showWellPathAttributes() )
|
|
{
|
|
if ( m_wellPathAttributeSettings->wellPathAttributeCollection() )
|
|
{
|
|
std::vector<RimWellPathAttribute*> attributes = m_wellPathAttributeSettings->wellPathAttributeCollection()->attributes();
|
|
for ( const RimWellPathAttribute* attribute : attributes )
|
|
{
|
|
if ( attribute->isEnabled() )
|
|
{
|
|
allWellPathComponents.push_back( attribute );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( m_wellPathAttributeSettings->showWellPathCompletions() )
|
|
{
|
|
const RimWellPathCompletions* completionsCollection = wellPathAttributeSource()->completions();
|
|
std::vector<const RimWellPathComponentInterface*> allCompletions = completionsCollection->allCompletions();
|
|
|
|
for ( const RimWellPathComponentInterface* completion : allCompletions )
|
|
{
|
|
if ( completion->isEnabled() )
|
|
{
|
|
allWellPathComponents.push_back( completion );
|
|
}
|
|
}
|
|
}
|
|
|
|
const std::map<RiaDefines::WellPathComponentType, int> sortIndices = { { RiaDefines::WellPathComponentType::WELL_PATH, 0 },
|
|
{ RiaDefines::WellPathComponentType::CASING, 1 },
|
|
{ RiaDefines::WellPathComponentType::LINER, 2 },
|
|
{ RiaDefines::WellPathComponentType::PERFORATION_INTERVAL, 3 },
|
|
{ RiaDefines::WellPathComponentType::FISHBONES, 4 },
|
|
{ RiaDefines::WellPathComponentType::FRACTURE, 5 },
|
|
{ RiaDefines::WellPathComponentType::PACKER, 6 },
|
|
{ RiaDefines::WellPathComponentType::ICD, 7 },
|
|
{ RiaDefines::WellPathComponentType::AICD, 8 },
|
|
{ RiaDefines::WellPathComponentType::ICV, 9 },
|
|
{ RiaDefines::WellPathComponentType::MSW_SEGMENT, 10 },
|
|
{ RiaDefines::WellPathComponentType::SICD, 11 },
|
|
{ RiaDefines::WellPathComponentType::UNDEFINED_COMPONENT, 12 } };
|
|
|
|
std::stable_sort( allWellPathComponents.begin(),
|
|
allWellPathComponents.end(),
|
|
[&sortIndices]( const RimWellPathComponentInterface* lhs, const RimWellPathComponentInterface* rhs )
|
|
{ return sortIndices.at( lhs->componentType() ) < sortIndices.at( rhs->componentType() ); } );
|
|
|
|
std::set<QString> completionsAssignedToLegend;
|
|
for ( const RimWellPathComponentInterface* component : allWellPathComponents )
|
|
{
|
|
if ( component->componentType() == RiaDefines::WellPathComponentType::UNDEFINED_COMPONENT )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
std::unique_ptr<RiuWellPathComponentPlotItem> plotItem( new RiuWellPathComponentPlotItem( wellPathAttributeSource(), component ) );
|
|
QString legendTitle = plotItem->legendTitle();
|
|
bool contributeToLegend = m_wellPathAttributeSettings->showCompletionsInLegend() &&
|
|
!completionsAssignedToLegend.count( legendTitle );
|
|
plotItem->setContributeToLegend( contributeToLegend );
|
|
m_wellPathAttributePlotObjects.push_back( std::move( plotItem ) );
|
|
completionsAssignedToLegend.insert( legendTitle );
|
|
}
|
|
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
RimWellLogPlot::DepthTypeEnum depthType = wellLogPlot->depthType();
|
|
auto depthOrientation = wellLogPlot->depthOrientation();
|
|
|
|
for ( auto& attributePlotObject : m_wellPathAttributePlotObjects )
|
|
{
|
|
attributePlotObject->setDepthType( depthType );
|
|
attributePlotObject->setDepthOrientation( depthOrientation );
|
|
attributePlotObject->setShowLabel( m_wellPathAttributeSettings->showComponentLabels() );
|
|
attributePlotObject->loadDataAndUpdate( false );
|
|
attributePlotObject->setParentPlotNoReplot( m_plotWidget->qwtPlot() );
|
|
}
|
|
}
|
|
updatePropertyValueZoom();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::removeRegionAnnotations()
|
|
{
|
|
if ( m_annotationTool )
|
|
{
|
|
m_annotationTool->detachAllAnnotations();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::doUpdateLayout()
|
|
{
|
|
updateFonts();
|
|
m_plotWidget->scheduleReplot();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector<caf::PdmObjectHandle*>& referringObjects )
|
|
{
|
|
setAutoScalePropertyValuesEnabled( true );
|
|
updatePlotWidgetFromAxisRanges();
|
|
RiuPlotMainWindow* mainPlotWindow = RiaGuiApplication::instance()->mainPlotWindow();
|
|
mainPlotWindow->updateWellLogPlotToolBar();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setOverburdenHeight( double overburdenHeight )
|
|
{
|
|
m_wellPathAttributeSettings->setOverburdenHeight( overburdenHeight );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setUnderburdenHeight( double underburdenHeight )
|
|
{
|
|
m_wellPathAttributeSettings->setUnderburdenHeight( underburdenHeight );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::addOverburden( std::vector<QString>& namesVector, CurveSamplingPointData& curveData, double height )
|
|
{
|
|
if ( !curveData.data.empty() )
|
|
{
|
|
namesVector.push_back( "Overburden" );
|
|
|
|
// Prepend the new "fake" depth for start of overburden
|
|
double tvdTop = curveData.tvd[0];
|
|
curveData.tvd.insert( curveData.tvd.begin(), tvdTop );
|
|
curveData.tvd.insert( curveData.tvd.begin(), tvdTop - height );
|
|
|
|
// TODO: this is not always correct
|
|
double mdTop = curveData.md[0];
|
|
curveData.md.insert( curveData.md.begin(), mdTop );
|
|
curveData.md.insert( curveData.md.begin(), mdTop - height );
|
|
|
|
curveData.data.insert( curveData.data.begin(), namesVector.size() - 1 );
|
|
curveData.data.insert( curveData.data.begin(), namesVector.size() - 1 );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::addUnderburden( std::vector<QString>& namesVector, CurveSamplingPointData& curveData, double height )
|
|
{
|
|
if ( !curveData.data.empty() )
|
|
{
|
|
namesVector.push_back( "Underburden" );
|
|
|
|
size_t lastIndex = curveData.tvd.size() - 1;
|
|
|
|
// Append the new "fake" depth for start of underburden
|
|
double tvdBottom = curveData.tvd[lastIndex];
|
|
curveData.tvd.push_back( tvdBottom );
|
|
curveData.tvd.push_back( tvdBottom + height );
|
|
|
|
// TODO: this is not always correct
|
|
double mdBottom = curveData.md[lastIndex];
|
|
curveData.md.push_back( mdBottom );
|
|
curveData.md.push_back( mdBottom + height );
|
|
|
|
curveData.data.push_back( namesVector.size() - 1 );
|
|
curveData.data.push_back( namesVector.size() - 1 );
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setCurvesTreeVisibility( bool isVisible )
|
|
{
|
|
m_curves.uiCapability()->setUiTreeChildrenHidden( !isVisible );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimWellLogTrack::setEnsembleWellLogCurveSet( RimEnsembleWellLogCurveSet* curveSet )
|
|
{
|
|
m_ensembleWellLogCurveSet = curveSet;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuPlotAxis RimWellLogTrack::depthAxis() const
|
|
{
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
return wellLogPlot->depthAxis();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RiuPlotAxis RimWellLogTrack::valueAxis() const
|
|
{
|
|
RimDepthTrackPlot* wellLogPlot = firstAncestorOrThisOfTypeAsserted<RimDepthTrackPlot>();
|
|
|
|
return wellLogPlot->valueAxis();
|
|
}
|