From f5b10b4d7083705be6d34897c633abcbf4d6e3f8 Mon Sep 17 00:00:00 2001 From: Gaute Lindkvist Date: Thu, 3 Oct 2019 14:41:37 +0200 Subject: [PATCH] #4800 WBS: Add parameter track which is off by default (#4816) * Initial WIP * Identical results with spreadsheet * Improved and more robust smoothing by filtering points first * Improved smoothing and more GUI * Include mixed-label for smoothing threshold * Implement WBS parameters track * Much better alignment of tracks without flickering * Don't replace user description when dragging and dropping tracks * Fix missing OBG and SH curves * Fix curve and track D&D * Make sure parameter curves aren't WBS curves --- ApplicationCode/Application/RiaDefines.cpp | 46 ++++-- ApplicationCode/Application/RiaDefines.h | 17 ++- .../RicDeleteWellLogPlotTrackFeature.cpp | 2 +- .../RicNewWellBoreStabilityPlotFeature.cpp | 53 ++++++- .../RicNewWellBoreStabilityPlotFeature.h | 3 +- .../RicNewWellLogPlotTrackFeature.cpp | 2 +- .../RicWellLogPlotTrackFeatureImpl.cpp | 4 +- .../RimGeoMechResultDefinition.cpp | 5 +- .../RimWellLogExtractionCurve.cpp | 13 ++ .../RimWellLogExtractionCurve.h | 2 + .../ProjectDataModel/RimWellLogPlot.cpp | 21 ++- .../ProjectDataModel/RimWellLogPlot.h | 1 + .../ProjectDataModel/RimWellLogTrack.cpp | 26 ++++ .../ProjectDataModel/RimWellLogTrack.h | 2 + .../RigGeoMechWellLogExtractor.cpp | 68 ++++++++- .../RigGeoMechWellLogExtractor.h | 2 +- ApplicationCode/UserInterface/RiuDragDrop.cpp | 37 ++++- ApplicationCode/UserInterface/RiuDragDrop.h | 8 +- .../UserInterface/RiuPlotMainWindow.cpp | 3 +- .../UserInterface/RiuWellLogPlot.cpp | 143 ++++++++---------- .../UserInterface/RiuWellLogPlot.h | 7 +- .../UserInterface/RiuWellLogTrack.cpp | 3 + 22 files changed, 330 insertions(+), 138 deletions(-) diff --git a/ApplicationCode/Application/RiaDefines.cpp b/ApplicationCode/Application/RiaDefines.cpp index 258f4f209d..47c3d44339 100644 --- a/ApplicationCode/Application/RiaDefines.cpp +++ b/ApplicationCode/Application/RiaDefines.cpp @@ -400,7 +400,7 @@ QString RiaDefines::activeFormationNamesResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathAzimuthResultName() +QString RiaDefines::wbsAzimuthResultName() { return "Azimuth"; } @@ -408,7 +408,7 @@ QString RiaDefines::wellPathAzimuthResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathInclinationResultName() +QString RiaDefines::wbsInclinationResultName() { return "Inclination"; } @@ -416,7 +416,7 @@ QString RiaDefines::wellPathInclinationResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathPPResultName() +QString RiaDefines::wbsPPResultName() { return "PP"; } @@ -424,7 +424,7 @@ QString RiaDefines::wellPathPPResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathSHResultName() +QString RiaDefines::wbsSHResultName() { return "SH"; } @@ -432,7 +432,7 @@ QString RiaDefines::wellPathSHResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathOBGResultName() +QString RiaDefines::wbsOBGResultName() { return "OBG"; } @@ -440,7 +440,7 @@ QString RiaDefines::wellPathOBGResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathFGResultName() +QString RiaDefines::wbsFGResultName() { return "FG"; } @@ -448,17 +448,33 @@ QString RiaDefines::wellPathFGResultName() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RiaDefines::wellPathSFGResultName() +QString RiaDefines::wbsSFGResultName() { return "SFG"; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::wbsPoissonParameterName() +{ + return "RATIO"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RiaDefines::wbsUCSParameterName() +{ + return "UCS"; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RiaDefines::wellPathAngleResultNames() { - return {RiaDefines::wellPathAzimuthResultName(), RiaDefines::wellPathInclinationResultName()}; + return {wbsAzimuthResultName(), wbsInclinationResultName()}; } //-------------------------------------------------------------------------------------------------- @@ -466,11 +482,15 @@ std::vector RiaDefines::wellPathAngleResultNames() //-------------------------------------------------------------------------------------------------- std::vector RiaDefines::wellPathStabilityResultNames() { - return {RiaDefines::wellPathFGResultName(), - RiaDefines::wellPathOBGResultName(), - RiaDefines::wellPathPPResultName(), - RiaDefines::wellPathSFGResultName(), - RiaDefines::wellPathSHResultName()}; + return {wbsFGResultName(), wbsOBGResultName(), wbsPPResultName(), wbsSFGResultName(), wbsSHResultName()}; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RiaDefines::wellPathStabilityParameterNames() +{ + return {wbsPoissonParameterName(), wbsUCSParameterName()}; } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/Application/RiaDefines.h b/ApplicationCode/Application/RiaDefines.h index 8958091ae2..dc808d9d25 100644 --- a/ApplicationCode/Application/RiaDefines.h +++ b/ApplicationCode/Application/RiaDefines.h @@ -114,17 +114,20 @@ QString mockModelBasicInputCase(); QString activeFormationNamesResultName(); // Well path derived results -QString wellPathAzimuthResultName(); -QString wellPathInclinationResultName(); -QString wellPathPPResultName(); -QString wellPathSHResultName(); -QString wellPathOBGResultName(); -QString wellPathFGResultName(); -QString wellPathSFGResultName(); +QString wbsAzimuthResultName(); +QString wbsInclinationResultName(); +QString wbsPPResultName(); +QString wbsSHResultName(); +QString wbsOBGResultName(); +QString wbsFGResultName(); +QString wbsSFGResultName(); +QString wbsPoissonParameterName(); +QString wbsUCSParameterName(); // List of well path derived results std::vector wellPathAngleResultNames(); std::vector wellPathStabilityResultNames(); +std::vector wellPathStabilityParameterNames(); // Units and conversions enum DepthUnitType diff --git a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp index 2d8e500ede..9d2f054fe4 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicDeleteWellLogPlotTrackFeature.cpp @@ -89,7 +89,7 @@ void RicDeleteWellLogPlotTrackFeature::onActionTriggered( bool isChecked ) for ( RimWellLogPlot* wellLogPlot : alteredWellLogPlots ) { RiuWellLogPlot* viewWidget = dynamic_cast( wellLogPlot->viewWidget() ); - plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() ); + plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() ); wellLogPlot->calculateAvailableDepthRange(); wellLogPlot->updateDepthZoom(); wellLogPlot->uiCapability()->updateConnectedEditors(); diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp index 1e335637e3..3a8cc563b6 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.cpp @@ -120,7 +120,12 @@ void RicNewWellBoreStabilityPlotFeature::onActionTriggered( bool isChecked ) } { - auto task = progInfo.task( "Creating stability curves track", 75 ); + auto task = progInfo.task( "Creating parameters track", 15 ); + createParametersTrack( plot, wellPath, geoMechView ); + } + + { + auto task = progInfo.task( "Creating stability curves track", 60 ); createStabilityCurvesTrack( plot, wellPath, geoMechView ); } @@ -193,6 +198,50 @@ void RicNewWellBoreStabilityPlotFeature::createCasingShoeTrack( RimWellBoreStabi casingShoeTrack->loadDataAndUpdate(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RicNewWellBoreStabilityPlotFeature::createParametersTrack( RimWellBoreStabilityPlot* plot, + RimWellPath* wellPath, + RimGeoMechView* geoMechView ) +{ + RimWellLogTrack* paramCurvesTrack = RicNewWellLogPlotFeatureImpl::createWellLogPlotTrack( false, + "WBS Parameters", + plot ); + paramCurvesTrack->setWidthScaleFactor( RimWellLogTrack::WIDE_TRACK ); + paramCurvesTrack->setAutoScaleXEnabled( true ); + paramCurvesTrack->setTickIntervals( 0.5, 0.05 ); + paramCurvesTrack->setXAxisGridVisibility( RimWellLogPlot::AXIS_GRID_MAJOR_AND_MINOR ); + paramCurvesTrack->setFormationWellPath( wellPath ); + paramCurvesTrack->setFormationCase( geoMechView->geoMechCase() ); + paramCurvesTrack->setAnnotationType( RiuPlotAnnotationTool::CURVE_ANNOTATIONS ); + paramCurvesTrack->setShowRegionLabels( true ); + paramCurvesTrack->setVisible( false ); + std::vector resultNames = RiaDefines::wellPathStabilityParameterNames(); + + std::vector colors = {cvf::Color3f::CRIMSON, cvf::Color3f::DARK_YELLOW}; + + for ( size_t i = 0; i < resultNames.size(); ++i ) + { + const QString& resultName = resultNames[i]; + RigFemResultAddress resAddr( RIG_WELLPATH_DERIVED, resultName.toStdString(), "" ); + RimWellLogExtractionCurve* curve = RicWellLogTools::addWellLogExtractionCurve( paramCurvesTrack, + geoMechView, + wellPath, + nullptr, + -1, + false, + false ); + curve->setGeoMechResultAddress( resAddr ); + curve->setCurrentTimeStep( geoMechView->currentTimeStep() ); + curve->setColor( colors[i % colors.size()] ); + curve->setLineThickness( 2 ); + curve->loadDataAndUpdate( false ); + curve->setAutoNameComponents( false, true, false, false, false ); + } + paramCurvesTrack->calculateXZoomRangeAndUpdateQwt(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -233,7 +282,7 @@ void RicNewWellBoreStabilityPlotFeature::createStabilityCurvesTrack( RimWellBore false ); curve->setGeoMechResultAddress( resAddr ); curve->setCurrentTimeStep( geoMechView->currentTimeStep() ); - curve->setCustomName( resultName ); + curve->setAutoNameComponents( false, true, false, false, false ); curve->setColor( colors[i % colors.size()] ); curve->setLineThickness( 2 ); curve->loadDataAndUpdate( false ); diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h index 9b103a1052..9004a72ae6 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellBoreStabilityPlotFeature.h @@ -41,6 +41,7 @@ protected: private: void createFormationTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase ); void createCasingShoeTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechCase* geoMechCase ); - void createStabilityCurvesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechCase ); + void createParametersTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView ); + void createStabilityCurvesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView ); void createAnglesTrack( RimWellBoreStabilityPlot* plot, RimWellPath* wellPath, RimGeoMechView* geoMechView ); }; diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp index beea79a0f7..0fa6df48e1 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogPlotTrackFeature.cpp @@ -68,7 +68,7 @@ void RicNewWellLogPlotTrackFeature::onActionTriggered( bool isChecked ) RiuWellLogPlot* viewWidget = dynamic_cast( wellLogPlot->viewWidget() ); RicWellLogTools::addWellLogExtractionCurve( plotTrack, nullptr, nullptr, nullptr, -1, true ); - plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() ); + plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() ); wellLogPlot->updateConnectedEditors(); wellLogPlot->loadDataAndUpdate(); } diff --git a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp index e163347a93..1d41d28108 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicWellLogPlotTrackFeatureImpl.cpp @@ -114,7 +114,7 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( RimWellLogPlot* for ( std::set::iterator pIt = srcPlots.begin(); pIt != srcPlots.end(); ++pIt ) { RiuWellLogPlot* viewWidget = dynamic_cast( ( *pIt )->viewWidget() ); - plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() ); + plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() ); ( *pIt )->calculateAvailableDepthRange(); ( *pIt )->updateTrackNames(); @@ -130,7 +130,7 @@ void RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( RimWellLogPlot* dstWellLogPlot->insertTrack( tracksToMove[tIdx], insertionStartIndex + tIdx ); } RiuWellLogPlot* viewWidget = dynamic_cast( dstWellLogPlot->viewWidget() ); - plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredSize().width() ); + plotWindow->setWidthOfMdiWindow( viewWidget, viewWidget->preferredWidth() ); dstWellLogPlot->updateTrackNames(); dstWellLogPlot->updateTracks(); diff --git a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp index d601c5f882..d3a2cc04b1 100644 --- a/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp +++ b/ApplicationCode/ProjectDataModel/RimGeoMechResultDefinition.cpp @@ -468,8 +468,8 @@ void RimGeoMechResultDefinition::loadResult() { if ( m_geomCase && m_geomCase->geoMechData() ) { - if ( this->resultAddress().fieldName == RiaDefines::wellPathFGResultName().toStdString() || - this->resultAddress().fieldName == RiaDefines::wellPathSFGResultName().toStdString() ) + if ( this->resultAddress().fieldName == RiaDefines::wbsFGResultName().toStdString() || + this->resultAddress().fieldName == RiaDefines::wbsSFGResultName().toStdString() ) { RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, std::string( "ST" ), "" ); RigFemResultAddress porBarResAddr( RIG_ELEMENT_NODAL, std::string( "POR-Bar" ), "" ); @@ -625,6 +625,7 @@ QString RimGeoMechResultDefinition::convertToUiResultFieldName( QString resultFi if ( resultFieldName == "POR-Bar" ) newName = "POR"; // POR-Bar appear as POR if ( resultFieldName == "MODULUS" ) newName = "Young's Modulus"; if ( resultFieldName == "RATIO" ) newName = "Poisson's Ratio"; + if ( resultFieldName == "UCS" ) newName = "UCS bar/ 100"; return newName; } diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp index 8378badc2f..fec94d0ff1 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.cpp @@ -563,6 +563,19 @@ void RimWellLogExtractionCurve::findAndLoadWbsParametersFromLasFiles( const RimW } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogExtractionCurve::setAutoNameComponents( + bool addCaseName, bool addProperty, bool addWellname, bool addTimeStep, bool addDate ) +{ + m_addCaseNameToCurveName = addCaseName; + m_addPropertyToCurveName = addProperty; + m_addWellNameToCurveName = addWellname; + m_addTimestepToCurveName = addTimeStep; + m_addDateToCurveName = addDate; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h index 3cf99396a7..ce6097f424 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogExtractionCurve.h @@ -86,6 +86,8 @@ public: static void findAndLoadWbsParametersFromLasFiles( const RimWellPath* wellPath, RigGeoMechWellLogExtractor* geomExtractor ); + void setAutoNameComponents( bool addCaseName, bool addProperty, bool addWellname, bool addTimeStep, bool addDate ); + protected: QString createCurveAutoName() override; void onLoadDataAndUpdate( bool updateParentPlot ) override; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp index 9f3fd695e6..69c85c735f 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp @@ -362,6 +362,22 @@ std::vector RimWellLogPlot::tracks() const return m_tracks.childObjects(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellLogPlot::visibleTracks() const +{ + std::vector tracks; + for ( RimWellLogTrack* track : m_tracks() ) + { + if ( track->isVisible() ) + { + tracks.push_back( track ); + } + } + return tracks; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -835,7 +851,10 @@ void RimWellLogPlot::updateTrackNames() { for ( size_t tIdx = 0; tIdx < m_tracks.size(); tIdx++ ) { - m_tracks[tIdx]->setDescription( QString( "Track %1" ).arg( tIdx + 1 ) ); + QString description = m_tracks[tIdx]->description(); + QRegularExpression regexp( "Track \\d+" ); + description.replace( regexp, QString( "Track %1" ).arg( tIdx + 1 ) ); + m_tracks[tIdx]->setDescription( description ); } } diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h index ac52b68a78..221c5d561c 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h @@ -105,6 +105,7 @@ public: RimWellLogTrack* trackByIndex( size_t index ) const; size_t firstVisibleTrackIndex() const; std::vector tracks() const; + std::vector visibleTracks() const; void updateTracks( bool autoScaleXAxis = false ); void updateTrackNames(); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp index f9ae2fa73f..b5d076aac9 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp @@ -1534,6 +1534,14 @@ bool RimWellLogTrack::isVisible() return m_show; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogTrack::setVisible( bool visible ) +{ + m_show = visible; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1675,6 +1683,24 @@ std::vector RimWellLogTrack::curvesVector() return curvesVector; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellLogTrack::visibleCurvesVector() +{ + std::vector curvesVector; + + for ( RimWellLogCurve* curve : curves ) + { + if ( curve->isCurveVisible() ) + { + curvesVector.push_back( curve ); + } + } + + return curvesVector; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h index 7c0fd1ec08..efc9b12f96 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.h @@ -96,6 +96,7 @@ public: void setDescription( const QString& description ); bool isVisible(); + void setVisible( bool visible ); void addCurve( RimWellLogCurve* curve ); void insertCurve( RimWellLogCurve* curve, size_t index ); void takeOutCurve( RimWellLogCurve* curve ); @@ -175,6 +176,7 @@ public: QString description(); std::vector curvesVector(); + std::vector visibleCurvesVector(); void uiOrderingForRftPltFormations( caf::PdmUiOrdering& uiOrdering ); void uiOrderingForXAxisSettings( caf::PdmUiOrdering& uiOrdering ); diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp index ac10817887..7f9132408d 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.cpp @@ -114,18 +114,26 @@ void RigGeoMechWellLogExtractor::curveData( const RigFemResultAddress& resAddr, if ( resAddr.resultPosType == RIG_WELLPATH_DERIVED ) { - if ( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() || - resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() ) + if ( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() || + resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() ) { wellBoreWallCurveData( resAddr, frameIndex, values ); return; } - else if ( resAddr.fieldName == "PP" || resAddr.fieldName == "OBG" || resAddr.fieldName == "SH" ) + else if ( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() || + resAddr.fieldName == RiaDefines::wbsUCSParameterName().toStdString() ) + { + wellPathParameters( resAddr, frameIndex, values ); + } + else if ( resAddr.fieldName == RiaDefines::wbsPPResultName().toStdString() || + resAddr.fieldName == RiaDefines::wbsOBGResultName().toStdString() || + resAddr.fieldName == RiaDefines::wbsSHResultName().toStdString() ) { wellPathScaledCurveData( resAddr, frameIndex, values ); return; } - else if ( resAddr.fieldName == "Azimuth" || resAddr.fieldName == "Inclination" ) + else if ( resAddr.fieldName == RiaDefines::wbsAzimuthResultName().toStdString() || + resAddr.fieldName == RiaDefines::wbsInclinationResultName().toStdString() ) { wellPathAngles( resAddr, values ); return; @@ -401,6 +409,13 @@ void RigGeoMechWellLogExtractor::wellPathScaledCurveData( const RigFemResultAddr averageUnscaledValue = ppSourcePair.first; } } + else + { + averageIntersectionValuesToSegmentValue( intersectionIdx, + interpolatedInterfaceValues, + std::numeric_limits::infinity(), + &averageUnscaledValue ); + } ( *values )[intersectionIdx] = static_cast( averageUnscaledValue ) / hydroStaticPorePressureBar; } @@ -419,8 +434,8 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres std::vector* values ) { CVF_ASSERT( values ); - CVF_ASSERT( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() || - resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() ); + CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() || + resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() ); // The result addresses needed RigFemResultAddress stressResAddr( RIG_ELEMENT_NODAL, "ST", "" ); @@ -499,7 +514,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres RigGeoMechBoreHoleStressCalculator sigmaCalculator( wellPathStressDouble, porePressureBar, poissonRatio, ucsBar, 32 ); double resultValue = std::numeric_limits::infinity(); - if ( resAddr.fieldName == RiaDefines::wellPathFGResultName().toStdString() ) + if ( resAddr.fieldName == RiaDefines::wbsFGResultName().toStdString() ) { if ( isFGregion && validSegmentStress ) { @@ -508,7 +523,7 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres } else { - CVF_ASSERT( resAddr.fieldName == RiaDefines::wellPathSFGResultName().toStdString() ); + CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsSFGResultName().toStdString() ); if ( !isFGregion && validSegmentStress ) { resultValue = sigmaCalculator.solveStassiDalia(); @@ -525,6 +540,43 @@ void RigGeoMechWellLogExtractor::wellBoreWallCurveData( const RigFemResultAddres } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RigGeoMechWellLogExtractor::wellPathParameters( const RigFemResultAddress& resAddr, + int frameIndex, + std::vector* values ) +{ + CVF_ASSERT( values ); + CVF_ASSERT( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() || + resAddr.fieldName == RiaDefines::wbsUCSParameterName().toStdString() ); + + RigFemPartResultsCollection* resultCollection = m_caseData->femPartResults(); + + // Check for element property values + RigFemResultAddress elmResAddr( RIG_ELEMENT, resAddr.fieldName, "" ); + std::vector elmPropertyValues = resultCollection->resultValues( elmResAddr, 0, frameIndex ); + + values->resize( m_intersections.size(), 0.0f ); + + if ( resAddr.fieldName == RiaDefines::wbsPoissonParameterName().toStdString() ) + { +#pragma omp parallel for + for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx ) + { + ( *values )[intersectionIdx] = calculatePoissonRatioInSegment( intersectionIdx, elmPropertyValues ).first; + } + } + else + { +#pragma omp parallel for + for ( int64_t intersectionIdx = 0; intersectionIdx < (int64_t)m_intersections.size(); ++intersectionIdx ) + { + ( *values )[intersectionIdx] = calculateUcsInSegment( intersectionIdx, elmPropertyValues ).first / 100.0; + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h index d2a6159df7..5665674e5f 100644 --- a/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h +++ b/ApplicationCode/ReservoirDataModel/RigGeoMechWellLogExtractor.h @@ -113,7 +113,7 @@ private: void wellPathAngles( const RigFemResultAddress& resAddr, std::vector* values ); void wellPathScaledCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector* values ); void wellBoreWallCurveData( const RigFemResultAddress& resAddr, int frameIndex, std::vector* values ); - + void wellPathParameters( const RigFemResultAddress& resAddr, int frameIndex, std::vector* values ); template T interpolateGridResultValue( RigFemResultPosEnum resultPosType, const std::vector& gridResultValues, diff --git a/ApplicationCode/UserInterface/RiuDragDrop.cpp b/ApplicationCode/UserInterface/RiuDragDrop.cpp index 96dc20202d..f92af40e87 100644 --- a/ApplicationCode/UserInterface/RiuDragDrop.cpp +++ b/ApplicationCode/UserInterface/RiuDragDrop.cpp @@ -281,14 +281,14 @@ bool RiuDragDrop::dropMimeData( const QMimeData* data, Qt::DropAction action, in dropTarget->firstAncestorOrThisOfType( wellLogPlotTrack ); if ( wellLogPlotTrack ) { - return handleWellLogPlotTrackDrop( action, draggedObjects, wellLogPlotTrack ); + return handleWellLogPlotTrackDrop( action, draggedObjects, wellLogPlotTrack, row ); } RimWellLogPlot* wellLogPlot; dropTarget->firstAncestorOrThisOfType( wellLogPlot ); if ( wellLogPlot ) { - return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot ); + return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot, row ); } RimSummaryCaseCollection* summaryCaseCollection; @@ -381,7 +381,8 @@ bool RiuDragDrop::handleGridCaseGroupDrop( Qt::DropAction action, //-------------------------------------------------------------------------------------------------- bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action, caf::PdmObjectGroup& draggedObjects, - RimWellLogTrack* trackTarget ) + RimWellLogTrack* trackTarget, + int insertAtPosition ) { std::vector wellLogFileChannels = RiuTypedPdmObjects::typedObjectsFromGroup( draggedObjects ); @@ -400,7 +401,17 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action, { if ( action == Qt::MoveAction ) { - RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack( trackTarget, wellLogPlotCurves, nullptr ); + RimWellLogCurve* insertAfter = nullptr; + if ( insertAtPosition > 0 ) + { + auto visibleCurves = trackTarget->visibleCurvesVector(); + if ( !visibleCurves.empty() ) + { + int insertAfterPosition = std::min( insertAtPosition - 1, (int)visibleCurves.size() - 1 ); + insertAfter = visibleCurves[insertAfterPosition]; + } + } + RicWellLogPlotTrackFeatureImpl::moveCurvesToWellLogPlotTrack( trackTarget, wellLogPlotCurves, insertAfter ); return true; } } @@ -413,8 +424,7 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action, { RimWellLogPlot* wellLogPlot; trackTarget->firstAncestorOrThisOfType( wellLogPlot ); - RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlot, wellLogPlotTracks, trackTarget ); - return true; + return handleWellLogPlotDrop( action, draggedObjects, wellLogPlot, insertAtPosition ); } } @@ -426,7 +436,8 @@ bool RiuDragDrop::handleWellLogPlotTrackDrop( Qt::DropAction action, //-------------------------------------------------------------------------------------------------- bool RiuDragDrop::handleWellLogPlotDrop( Qt::DropAction action, caf::PdmObjectGroup& draggedObjects, - RimWellLogPlot* wellLogPlotTarget ) + RimWellLogPlot* wellLogPlotTarget, + int insertAtPosition ) { std::vector wellLogPlotTracks = RiuTypedPdmObjects::typedObjectsFromGroup( draggedObjects ); @@ -434,7 +445,17 @@ bool RiuDragDrop::handleWellLogPlotDrop( Qt::DropAction action, { if ( action == Qt::MoveAction ) { - RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlotTarget, wellLogPlotTracks, nullptr ); + RimWellLogTrack* insertAfter = nullptr; + if ( insertAtPosition > 0 ) + { + auto visibleTracks = wellLogPlotTarget->visibleTracks(); + if ( !visibleTracks.empty() ) + { + int insertAfterPosition = std::min( insertAtPosition - 1, (int)visibleTracks.size() - 1 ); + insertAfter = visibleTracks[insertAfterPosition]; + } + } + RicWellLogPlotTrackFeatureImpl::moveTracksToWellLogPlot( wellLogPlotTarget, wellLogPlotTracks, insertAfter ); return true; } } diff --git a/ApplicationCode/UserInterface/RiuDragDrop.h b/ApplicationCode/UserInterface/RiuDragDrop.h index 19775b3c38..972f31d20b 100644 --- a/ApplicationCode/UserInterface/RiuDragDrop.h +++ b/ApplicationCode/UserInterface/RiuDragDrop.h @@ -62,8 +62,12 @@ private: RimIdenticalGridCaseGroup* gridCaseGroup ); bool handleWellLogPlotTrackDrop( Qt::DropAction action, caf::PdmObjectGroup& objectGroup, - RimWellLogTrack* wellLogPlotTrack ); - bool handleWellLogPlotDrop( Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimWellLogPlot* wellLogPlot ); + RimWellLogTrack* wellLogPlotTrack, + int insertAtPosition ); + bool handleWellLogPlotDrop( Qt::DropAction action, + caf::PdmObjectGroup& objectGroup, + RimWellLogPlot* wellLogPlot, + int insertAtPosition ); bool handleWellLogPlotCurveDrop( Qt::DropAction action, caf::PdmObjectGroup& objectGroup, RimWellLogCurve* wellLogPlotCurve ); diff --git a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp index f35bafc051..df2366a875 100644 --- a/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp +++ b/ApplicationCode/UserInterface/RiuPlotMainWindow.cpp @@ -626,8 +626,7 @@ void RiuPlotMainWindow::addViewer( QWidget* viewer, const RimMdiWindowGeometry& RiuWellLogPlot* wellLogPlot = dynamic_cast( viewer ); if ( wellLogPlot ) { - QSize preferredSize = wellLogPlot->preferredSize(); - subWindowSize = QSize( preferredSize.width(), m_mdiArea->height() ); + subWindowSize = QSize( wellLogPlot->preferredWidth(), m_mdiArea->height() ); } else { diff --git a/ApplicationCode/UserInterface/RiuWellLogPlot.cpp b/ApplicationCode/UserInterface/RiuWellLogPlot.cpp index 48efc5dea0..2e2da505f0 100644 --- a/ApplicationCode/UserInterface/RiuWellLogPlot.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogPlot.cpp @@ -37,6 +37,7 @@ #include "qwt_legend.h" #include "qwt_plot_layout.h" +#include "qwt_scale_draw.h" #include #include @@ -142,17 +143,6 @@ void RiuWellLogPlot::insertTrackPlot( RiuWellLogTrack* trackPlot, size_t index ) legend->contentsWidget()->layout()->setAlignment( Qt::AlignBottom | Qt::AlignHCenter ); m_legends.insert( static_cast( index ), legend ); - trackPlot->updateLegend(); - - if ( trackPlot->isRimTrackVisible() ) - { - trackPlot->show(); - } - else - { - trackPlot->hide(); - } - updateChildrenLayout(); } @@ -202,24 +192,23 @@ void RiuWellLogPlot::setPlotTitle( const QString& plotTitle ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QSize RiuWellLogPlot::preferredSize() const +int RiuWellLogPlot::preferredWidth() const { - int titleWidth = 0; - int titleHeight = 0; + int titleWidth = 0; if ( m_plotTitle && m_plotTitle->isVisible() ) { - titleWidth = m_plotTitle->width(); - titleHeight = m_plotTitle->height() + 10; + titleWidth = m_plotTitle->width(); } - int sumTrackWidth = 0; - int maxTrackHeight = 0; + int sumTrackWidth = 0; for ( QPointer track : m_trackPlots ) { - sumTrackWidth += track->width(); - maxTrackHeight = std::max( maxTrackHeight, track->height() ); + if ( track->isVisible() ) + { + sumTrackWidth += track->width(); + } } - return QSize( std::max( titleWidth, sumTrackWidth ), titleHeight + maxTrackHeight ); + return std::max( titleWidth, sumTrackWidth ); } //-------------------------------------------------------------------------------------------------- @@ -237,34 +226,7 @@ void RiuWellLogPlot::setTitleVisible( bool visible ) void RiuWellLogPlot::updateChildrenLayout() { reinsertTracks(); - - int trackCount = m_trackPlots.size(); - int numTracksAlreadyShown = 0; - for ( int tIdx = 0; tIdx < trackCount; ++tIdx ) - { - if ( m_plotDefinition->areTrackLegendsVisible() && m_trackPlots[tIdx]->isVisible() ) - { - int legendColumns = 1; - if ( m_plotDefinition->areTrackLegendsHorizontal() ) - { - legendColumns = 0; // unlimited - } - m_legends[tIdx]->setMaxColumns( legendColumns ); - m_legends[tIdx]->show(); - - m_trackPlots[tIdx]->enableDepthAxisLabelsAndTitle( numTracksAlreadyShown == 0 ); - numTracksAlreadyShown++; - } - else - { - m_legends[tIdx]->hide(); - } - RiuWellLogTrack* riuTrack = m_trackPlots[tIdx]; - m_trackLayout->setColumnStretch( tIdx, riuTrack->widthScaleFactor() ); - } alignCanvasTops(); - this->update(); - this->repaint(); } //-------------------------------------------------------------------------------------------------- @@ -375,49 +337,23 @@ void RiuWellLogPlot::alignCanvasTops() { CVF_ASSERT( m_legends.size() == m_trackPlots.size() ); - int maxCanvasOffset = 0; + double maxExtent = 0.0; for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx ) { if ( m_trackPlots[tIdx]->isVisible() ) { - // Hack to align QWT plots. See below. - QRectF canvasRect = m_trackPlots[tIdx]->plotLayout()->canvasRect(); - int canvasMargins = m_trackPlots[tIdx]->plotLayout()->canvasMargin( QwtPlot::xTop ); - maxCanvasOffset = std::max( maxCanvasOffset, static_cast( canvasRect.top() + canvasMargins ) ); + QFont font = m_trackPlots[tIdx]->axisFont( QwtPlot::xTop ); + maxExtent = std::max( maxExtent, m_trackPlots[tIdx]->axisScaleDraw( QwtPlot::xTop )->extent( font ) ); } } - int legendHeight = 0; - for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx ) { if ( m_trackPlots[tIdx]->isVisible() ) { - // Hack to align QWT plots which doesn't have an x-axis with the other tracks. - // Since they are missing the axis, QWT will shift them upwards. - // So we shift the plot downwards and resize to match the others. - // TODO: Look into subclassing QwtPlotLayout instead. - QRectF canvasRect = m_trackPlots[tIdx]->plotLayout()->canvasRect(); - int canvasMargins = m_trackPlots[tIdx]->plotLayout()->canvasMargin( QwtPlot::xTop ); - int myCanvasOffset = static_cast( canvasRect.top() ) + canvasMargins; - int canvasShift = std::max( 0, maxCanvasOffset - myCanvasOffset ); - - QMargins margins = m_trackPlots[tIdx]->contentsMargins(); - margins.setTop( margins.top() + canvasShift ); - m_trackPlots[tIdx]->setContentsMargins( margins ); - - if ( m_legends[tIdx]->isVisible() ) - { - legendHeight = std::max( legendHeight, m_legends[tIdx]->heightForWidth( canvasRect.width() ) ); - } + m_trackPlots[tIdx]->axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( maxExtent ); } } - - if ( m_plotDefinition->areTrackLegendsVisible() && m_trackLayout->columnCount() > 0 && m_trackLayout->rowCount() > 0 ) - { - m_scrollBarLayout->setContentsMargins( 0, legendHeight, 0, 0 ); - m_trackLayout->setRowMinimumHeight( 0, legendHeight ); - } } //-------------------------------------------------------------------------------------------------- @@ -425,21 +361,60 @@ void RiuWellLogPlot::alignCanvasTops() //-------------------------------------------------------------------------------------------------- void RiuWellLogPlot::reinsertTracks() { + clearTrackLayout(); + int visibleIndex = 0; for ( int tIdx = 0; tIdx < m_trackPlots.size(); ++tIdx ) { - if ( m_trackPlots[tIdx]->isVisible() ) + if ( m_trackPlots[tIdx]->isRimTrackVisible() ) { - m_trackLayout->addWidget( m_legends[tIdx], 0, static_cast( visibleIndex ) ); - m_trackLayout->addWidget( m_trackPlots[tIdx], 1, static_cast( visibleIndex ) ); - m_trackLayout->setRowStretch( 1, 1 ); - - if ( !m_plotDefinition->areTrackLegendsVisible() ) + if ( m_plotDefinition->areTrackLegendsVisible() ) + { + m_trackPlots[tIdx]->updateLegend(); + int legendColumns = 1; + if ( m_plotDefinition->areTrackLegendsHorizontal() ) + { + legendColumns = 0; // unlimited + } + m_legends[tIdx]->setMaxColumns( legendColumns ); + m_legends[tIdx]->show(); + } + else { m_legends[tIdx]->hide(); } + + m_trackPlots[tIdx]->enableDepthAxisLabelsAndTitle( visibleIndex == 0 ); + m_trackPlots[tIdx]->show(); + + m_trackLayout->addWidget( m_legends[tIdx], 0, static_cast( visibleIndex ) ); + m_trackLayout->addWidget( m_trackPlots[tIdx], 1, static_cast( visibleIndex ) ); + + m_trackLayout->setColumnStretch( visibleIndex++, m_trackPlots[tIdx]->widthScaleFactor() ); + m_trackLayout->setRowStretch( 1, 1 ); visibleIndex++; } + else + { + m_trackPlots[tIdx]->hide(); + m_legends[tIdx]->hide(); + } + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellLogPlot::clearTrackLayout() +{ + if ( m_trackLayout ) + { + QLayoutItem* item; + while ( ( item = m_trackLayout->takeAt( 0 ) ) != 0 ) + { + } + QWidget().setLayout( m_trackLayout ); + m_trackLayout = new QGridLayout( m_plotFrame ); } } diff --git a/ApplicationCode/UserInterface/RiuWellLogPlot.h b/ApplicationCode/UserInterface/RiuWellLogPlot.h index 38bcd88f16..7026f77c78 100644 --- a/ApplicationCode/UserInterface/RiuWellLogPlot.h +++ b/ApplicationCode/UserInterface/RiuWellLogPlot.h @@ -61,9 +61,9 @@ public: void insertTrackPlot( RiuWellLogTrack* trackPlot, size_t index ); void removeTrackPlot( RiuWellLogTrack* trackPlot ); - void setDepthZoomAndReplot( double minDepth, double maxDepth ); - void setPlotTitle( const QString& plotTitle ); - virtual QSize preferredSize() const; + void setDepthZoomAndReplot( double minDepth, double maxDepth ); + void setPlotTitle( const QString& plotTitle ); + int preferredWidth() const; void setTitleVisible( bool visible ); @@ -85,6 +85,7 @@ private: void updateScrollBar( double minDepth, double maxDepth ); void alignCanvasTops(); void reinsertTracks(); + void clearTrackLayout(); private slots: void slotSetMinDepth( int value ); diff --git a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp index 50e289ce30..d7fbdb4839 100644 --- a/ApplicationCode/UserInterface/RiuWellLogTrack.cpp +++ b/ApplicationCode/UserInterface/RiuWellLogTrack.cpp @@ -87,6 +87,9 @@ void RiuWellLogTrack::setDefaults() axisScaleEngine( QwtPlot::yLeft )->setAttribute( QwtScaleEngine::Floating, true ); setAxisScale( QwtPlot::yLeft, 1000, 0 ); setXRange( 0, 100 ); + QFont font = axisFont( QwtPlot::xTop ); + int lineHeight = QFontMetrics( font ).height() + axisScaleDraw( QwtPlot::xTop )->tickLength( QwtScaleDiv::MajorTick ); + axisScaleDraw( QwtPlot::xTop )->setMinimumExtent( lineHeight ); } //--------------------------------------------------------------------------------------------------