2017-02-13 01:37:31 -06:00
/////////////////////////////////////////////////////////////////////////////////
//
// 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"
2017-10-25 07:41:54 -05:00
# include "RiaApplication.h"
# include "RigEclipseCaseData.h"
# include "RigEclipseWellLogExtractor.h"
# include "RigFemPartResultsCollection.h"
# include "RigFemResultAddress.h"
# include "RigFormationNames.h"
# include "RigGeoMechCaseData.h"
# include "RigGeoMechWellLogExtractor.h"
# include "RigResultAccessorFactory.h"
# include "RigSimWellData.h"
# include "RigSimulationWellCenterLineCalculator.h"
# include "RigSimulationWellCoordsAndMD.h"
2017-02-13 01:37:31 -06:00
# include "RigStatisticsCalculator.h"
2017-02-24 07:14:29 -06:00
# include "RigWellLogCurveData.h"
2017-10-25 07:41:54 -05:00
# include "RigWellPath.h"
# include "RimCase.h"
# include "RimEclipseCase.h"
# include "RimGeoMechCase.h"
# include "RimMainPlotCollection.h"
# include "RimProject.h"
# include "RimTools.h"
2017-02-24 07:14:29 -06:00
# include "RimWellFlowRateCurve.h"
2017-02-13 01:37:31 -06:00
# include "RimWellLogCurve.h"
2017-02-24 07:14:29 -06:00
# include "RimWellLogPlot.h"
2017-10-25 07:41:54 -05:00
# include "RimWellLogPlotCollection.h"
# include "RimWellPath.h"
2017-11-03 07:22:51 -05:00
# include "RimWellRftPlot.h"
2017-02-13 01:37:31 -06:00
# include "RiuMainWindow.h"
2017-10-25 07:41:54 -05:00
# include "RiuPlotAnnotationTool.h"
2017-02-24 07:14:29 -06:00
# include "RiuWellLogPlot.h"
# include "RiuWellLogTrack.h"
2017-02-13 01:37:31 -06:00
# include "cvfAssert.h"
# include "qwt_scale_engine.h"
# define RI_LOGPLOTTRACK_MINX_DEFAULT -10.0
# define RI_LOGPLOTTRACK_MAXX_DEFAULT 100.0
CAF_PDM_SOURCE_INIT ( RimWellLogTrack , " WellLogPlotTrack " ) ;
2017-10-25 07:41:54 -05:00
namespace caf
{
template < >
void AppEnum < RimWellLogTrack : : TrajectoryType > : : setUp ( )
{
addItem ( RimWellLogTrack : : WELL_PATH , " WELL_PATH " , " Well Path " ) ;
addItem ( RimWellLogTrack : : SIMULATION_WELL , " SIMULATION_WELL " , " Simulation Well " ) ;
setDefault ( RimWellLogTrack : : WELL_PATH ) ;
}
}
2017-02-13 01:37:31 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack : : RimWellLogTrack ( )
{
CAF_PDM_InitObject ( " Track " , " :/WellLogTrack16x16.png " , " " , " " ) ;
CAF_PDM_InitFieldNoDefault ( & m_userName , " TrackDescription " , " Name " , " " , " " , " " ) ;
m_userName . uiCapability ( ) - > setUiReadOnly ( true ) ;
CAF_PDM_InitField ( & m_show , " Show " , true , " Show track " , " " , " " , " " ) ;
m_show . uiCapability ( ) - > setUiHidden ( true ) ;
CAF_PDM_InitFieldNoDefault ( & curves , " Curves " , " " , " " , " " , " " ) ;
curves . uiCapability ( ) - > setUiHidden ( true ) ;
CAF_PDM_InitField ( & m_visibleXRangeMin , " VisibleXRangeMin " , RI_LOGPLOTTRACK_MINX_DEFAULT , " Min " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_visibleXRangeMax , " VisibleXRangeMax " , RI_LOGPLOTTRACK_MAXX_DEFAULT , " Max " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_isAutoScaleXEnabled , " AutoScaleX " , true , " Auto Scale " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_isLogarithmicScaleEnabled , " LogarithmicScaleX " , false , " Logarithmic Scale " , " " , " " , " " ) ;
2017-10-25 07:41:54 -05:00
CAF_PDM_InitField ( & m_showFormations , " ShowFormations " , false , " Show Formations " , " " , " " , " " ) ;
CAF_PDM_InitFieldNoDefault ( & m_trajectoryType , " TrajectoryType " , " Trajectory " , " " , " " , " " ) ;
CAF_PDM_InitFieldNoDefault ( & m_wellPath , " CurveWellPath " , " " , " " , " " , " " ) ;
m_wellPath . uiCapability ( ) - > setUiTreeChildrenHidden ( true ) ;
CAF_PDM_InitField ( & m_simWellName , " SimulationWellName " , QString ( " None " ) , " " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_branchIndex , " Branch " , 0 , " " , " " , " " , " " ) ;
2017-11-03 07:22:51 -05:00
CAF_PDM_InitFieldNoDefault ( & m_formationCase , " CurveCase " , " Formation Case " , " " , " " , " " ) ;
m_formationCase . uiCapability ( ) - > setUiTreeChildrenHidden ( true ) ;
2017-10-26 03:18:42 -05:00
m_simulationWellChosen = false ;
2017-02-13 01:37:31 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogTrack : : ~ RimWellLogTrack ( )
{
curves . deleteAllChildObjects ( ) ;
if ( m_wellLogTrackPlotWidget )
{
m_wellLogTrackPlotWidget - > deleteLater ( ) ;
m_wellLogTrackPlotWidget = nullptr ;
}
2017-10-25 07:41:54 -05:00
2017-10-26 03:01:56 -05:00
clearGeneratedSimWellPaths ( & m_generatedSimulationWellPathBranches ) ;
2017-02-13 01:37:31 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : setDescription ( const QString & description )
{
m_userName = description ;
}
2017-10-26 03:01:56 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : simWellOptionItems ( QList < caf : : PdmOptionItemInfo > * options , RimCase * rimCase )
{
CVF_ASSERT ( options ) ;
if ( ! options ) return ;
std : : set < QString > sortedWellNames ;
RimEclipseCase * eclipseCase = dynamic_cast < RimEclipseCase * > ( rimCase ) ;
if ( eclipseCase & & eclipseCase - > eclipseCaseData ( ) )
{
sortedWellNames = eclipseCase - > eclipseCaseData ( ) - > findSortedWellNames ( ) ;
}
QIcon simWellIcon ( " :/Well.png " ) ;
for ( const QString & wname : sortedWellNames )
{
options - > push_back ( caf : : PdmOptionItemInfo ( wname , wname , false , simWellIcon ) ) ;
}
if ( options - > size ( ) = = 0 )
{
options - > push_front ( caf : : PdmOptionItemInfo ( " None " , " None " ) ) ;
}
}
2017-10-25 07:41:54 -05:00
//--------------------------------------------------------------------------------------------------
/// Clean up existing generated well paths
//--------------------------------------------------------------------------------------------------
2017-10-26 03:01:56 -05:00
void RimWellLogTrack : : clearGeneratedSimWellPaths ( cvf : : Collection < RigWellPath > * generatedSimulationWellPathBranches )
2017-10-25 07:41:54 -05:00
{
RimWellLogPlotCollection * wellLogCollection = nullptr ;
// Need to use this approach, and not firstAnchestor because the curve might not be inside the hierarchy when deleted.
RimProject * proj = RiaApplication : : instance ( ) - > project ( ) ;
if ( proj & & proj - > mainPlotCollection ( ) ) wellLogCollection = proj - > mainPlotCollection ( ) - > wellLogPlotCollection ( ) ;
if ( ! wellLogCollection ) return ;
2017-10-26 03:01:56 -05:00
for ( size_t wpIdx = 0 ; wpIdx < generatedSimulationWellPathBranches - > size ( ) ; + + wpIdx )
2017-10-25 07:41:54 -05:00
{
2017-10-26 03:01:56 -05:00
wellLogCollection - > removeExtractors ( generatedSimulationWellPathBranches - > at ( wpIdx ) ) ;
2017-10-25 07:41:54 -05:00
}
2017-10-26 03:01:56 -05:00
generatedSimulationWellPathBranches - > clear ( ) ;
2017-10-25 07:41:54 -05:00
}
2017-02-13 01:37:31 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : fieldChangedByUi ( const caf : : PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
if ( changedField = = & m_show )
{
if ( m_wellLogTrackPlotWidget )
{
m_wellLogTrackPlotWidget - > setVisible ( m_show ( ) ) ;
}
RimWellLogPlot * wellLogPlot ;
this - > firstAncestorOrThisOfType ( wellLogPlot ) ;
if ( wellLogPlot )
{
wellLogPlot - > calculateAvailableDepthRange ( ) ;
wellLogPlot - > updateDepthZoom ( ) ;
RiuWellLogPlot * wellLogPlotViewer = dynamic_cast < RiuWellLogPlot * > ( wellLogPlot - > viewWidget ( ) ) ;
if ( wellLogPlotViewer )
{
wellLogPlotViewer - > updateChildrenLayout ( ) ;
}
}
}
else if ( changedField = = & m_visibleXRangeMin | | changedField = = & m_visibleXRangeMax )
{
m_wellLogTrackPlotWidget - > setXRange ( m_visibleXRangeMin , m_visibleXRangeMax ) ;
m_wellLogTrackPlotWidget - > replot ( ) ;
m_isAutoScaleXEnabled = false ;
}
else if ( changedField = = & m_isAutoScaleXEnabled )
{
if ( m_isAutoScaleXEnabled ( ) )
{
this - > updateXZoom ( ) ;
computeAndSetXRangeMinForLogarithmicScale ( ) ;
if ( m_wellLogTrackPlotWidget ) m_wellLogTrackPlotWidget - > replot ( ) ;
}
}
else if ( changedField = = & m_isLogarithmicScaleEnabled )
{
updateAxisScaleEngine ( ) ;
this - > updateXZoom ( ) ;
computeAndSetXRangeMinForLogarithmicScale ( ) ;
m_wellLogTrackPlotWidget - > setXRange ( m_visibleXRangeMin , m_visibleXRangeMax ) ;
m_wellLogTrackPlotWidget - > replot ( ) ;
}
2017-10-25 07:41:54 -05:00
else if ( changedField = = & m_showFormations )
{
loadDataAndUpdate ( ) ;
2017-11-03 07:22:51 -05:00
RimWellRftPlot * rftPlot ;
this - > firstAncestorOrThisOfType ( rftPlot ) ;
if ( rftPlot )
{
rftPlot - > updateConnectedEditors ( ) ;
}
2017-10-25 07:41:54 -05:00
}
2017-11-03 07:22:51 -05:00
else if ( changedField = = & m_formationCase )
2017-10-25 07:41:54 -05:00
{
2017-10-26 03:01:56 -05:00
QList < caf : : PdmOptionItemInfo > options ;
2017-11-03 07:22:51 -05:00
RimWellLogTrack : : simWellOptionItems ( & options , m_formationCase ) ;
2017-10-25 07:41:54 -05:00
2017-10-26 03:01:56 -05:00
if ( options . isEmpty ( ) )
2017-10-25 07:41:54 -05:00
{
m_simWellName = QString ( " None " ) ;
}
2017-10-26 03:01:56 -05:00
clearGeneratedSimWellPaths ( & m_generatedSimulationWellPathBranches ) ;
2017-10-25 07:41:54 -05:00
loadDataAndUpdate ( ) ;
}
else if ( changedField = = & m_wellPath )
{
loadDataAndUpdate ( ) ;
}
else if ( changedField = = & m_simWellName )
{
2017-10-26 03:01:56 -05:00
clearGeneratedSimWellPaths ( & m_generatedSimulationWellPathBranches ) ;
2017-10-25 07:41:54 -05:00
loadDataAndUpdate ( ) ;
}
else if ( changedField = = & m_trajectoryType )
{
2017-10-26 03:01:56 -05:00
clearGeneratedSimWellPaths ( & m_generatedSimulationWellPathBranches ) ;
2017-10-26 03:18:42 -05:00
2017-10-25 07:41:54 -05:00
loadDataAndUpdate ( ) ;
}
else if ( changedField = = & m_branchIndex )
{
loadDataAndUpdate ( ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf : : PdmOptionItemInfo > RimWellLogTrack : : calculateValueOptions ( const caf : : PdmFieldHandle * fieldNeedingOptions , bool * useOptionsOnly )
{
QList < caf : : PdmOptionItemInfo > options ;
if ( options . size ( ) > 0 ) return options ;
if ( fieldNeedingOptions = = & m_wellPath )
{
RimTools : : wellPathOptionItems ( & options ) ;
options . push_front ( caf : : PdmOptionItemInfo ( " None " , nullptr ) ) ;
}
2017-11-03 07:22:51 -05:00
else if ( fieldNeedingOptions = = & m_formationCase )
2017-10-25 07:41:54 -05:00
{
RimTools : : caseOptionItems ( & options ) ;
options . push_front ( caf : : PdmOptionItemInfo ( " None " , nullptr ) ) ;
}
else if ( fieldNeedingOptions = = & m_simWellName )
{
2017-11-03 07:22:51 -05:00
RimWellLogTrack : : simWellOptionItems ( & options , m_formationCase ) ;
2017-10-25 07:41:54 -05:00
}
else if ( fieldNeedingOptions = = & m_branchIndex )
{
2017-11-03 07:22:51 -05:00
updateGeneratedSimulationWellpath ( & m_generatedSimulationWellPathBranches , m_simWellName ( ) , m_formationCase ) ;
2017-10-25 07:41:54 -05:00
size_t branchCount = m_generatedSimulationWellPathBranches . size ( ) ;
for ( int bIdx = 0 ; bIdx < static_cast < int > ( branchCount ) ; + + bIdx )
{
options . push_back ( caf : : PdmOptionItemInfo ( " Branch " + QString : : number ( bIdx + 1 ) , QVariant : : fromValue ( bIdx ) ) ) ;
}
if ( options . size ( ) = = 0 )
{
options . push_front ( caf : : PdmOptionItemInfo ( " None " , - 1 ) ) ;
}
}
return options ;
2017-02-13 01:37:31 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf : : PdmFieldHandle * RimWellLogTrack : : objectToggleField ( )
{
return & m_show ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf : : PdmFieldHandle * RimWellLogTrack : : userDescriptionField ( )
{
return & m_userName ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : addCurve ( RimWellLogCurve * curve )
{
curves . push_back ( curve ) ;
if ( m_wellLogTrackPlotWidget )
{
2017-09-23 01:47:04 -05:00
curve - > setParentQwtPlotAndReplot ( m_wellLogTrackPlotWidget ) ;
2017-02-13 01:37:31 -06:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : insertCurve ( RimWellLogCurve * curve , size_t index )
{
curves . insert ( index , curve ) ;
// Todo: Mark curve data to use either TVD or MD
if ( m_wellLogTrackPlotWidget )
{
2017-09-23 01:47:04 -05:00
curve - > setParentQwtPlotAndReplot ( m_wellLogTrackPlotWidget ) ;
2017-02-13 01:37:31 -06:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : removeCurve ( RimWellLogCurve * curve )
{
size_t index = curves . index ( curve ) ;
if ( index < curves . size ( ) )
{
curves [ index ] - > detachQwtCurve ( ) ;
curves . removeChildObject ( curve ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuWellLogTrack * RimWellLogTrack : : viewer ( )
{
return m_wellLogTrackPlotWidget ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : availableDepthRange ( double * minimumDepth , double * maximumDepth )
{
double minDepth = HUGE_VAL ;
double maxDepth = - HUGE_VAL ;
size_t curveCount = curves . size ( ) ;
for ( size_t cIdx = 0 ; cIdx < curveCount ; cIdx + + )
{
double minCurveDepth = HUGE_VAL ;
double maxCurveDepth = - HUGE_VAL ;
if ( curves [ cIdx ] - > isCurveVisible ( ) & & curves [ cIdx ] - > depthRange ( & minCurveDepth , & maxCurveDepth ) )
{
if ( minCurveDepth < minDepth )
{
minDepth = minCurveDepth ;
}
if ( maxCurveDepth > maxDepth )
{
maxDepth = maxCurveDepth ;
}
}
}
* minimumDepth = minDepth ;
* maximumDepth = maxDepth ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : loadDataAndUpdate ( )
{
RimWellLogPlot * wellLogPlot ;
firstAncestorOrThisOfType ( wellLogPlot ) ;
if ( wellLogPlot & & m_wellLogTrackPlotWidget )
{
m_wellLogTrackPlotWidget - > setDepthTitle ( wellLogPlot - > depthPlotTitle ( ) ) ;
m_wellLogTrackPlotWidget - > setXTitle ( m_xAxisTitle ) ;
}
for ( size_t cIdx = 0 ; cIdx < curves . size ( ) ; + + cIdx )
{
2017-09-23 01:47:04 -05:00
curves [ cIdx ] - > loadDataAndUpdate ( true ) ;
2017-02-13 01:37:31 -06:00
}
2017-10-25 07:41:54 -05:00
2017-10-26 03:18:42 -05:00
if ( m_trajectoryType = = RimWellLogTrack : : SIMULATION_WELL )
{
m_simulationWellChosen = true ;
}
2017-11-01 02:53:57 -05:00
if ( m_showFormations )
{
m_trajectoryType . uiCapability ( ) - > setUiReadOnly ( false ) ;
m_simWellName . uiCapability ( ) - > setUiReadOnly ( false ) ;
2017-11-03 07:22:51 -05:00
m_formationCase . uiCapability ( ) - > setUiReadOnly ( false ) ;
2017-11-01 02:53:57 -05:00
m_wellPath . uiCapability ( ) - > setUiReadOnly ( false ) ;
}
else
{
m_trajectoryType . uiCapability ( ) - > setUiReadOnly ( true ) ;
m_simWellName . uiCapability ( ) - > setUiReadOnly ( true ) ;
2017-11-03 07:22:51 -05:00
m_formationCase . uiCapability ( ) - > setUiReadOnly ( true ) ;
2017-11-01 02:53:57 -05:00
m_wellPath . uiCapability ( ) - > setUiReadOnly ( true ) ;
}
2017-10-25 07:41:54 -05:00
updateFormationNamesOnPlot ( ) ;
2017-02-13 01:37:31 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : setXAxisTitle ( const QString & text )
{
m_xAxisTitle = text ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : recreateViewer ( )
{
2017-10-25 07:41:54 -05:00
if ( m_wellLogTrackPlotWidget = = nullptr )
2017-02-13 01:37:31 -06:00
{
m_wellLogTrackPlotWidget = new RiuWellLogTrack ( this ) ;
updateAxisScaleEngine ( ) ;
for ( size_t cIdx = 0 ; cIdx < curves . size ( ) ; + + cIdx )
{
2017-09-23 01:47:04 -05:00
curves [ cIdx ] - > setParentQwtPlotNoReplot ( this - > m_wellLogTrackPlotWidget ) ;
2017-02-13 01:37:31 -06:00
}
2017-09-23 01:47:04 -05:00
this - > m_wellLogTrackPlotWidget - > replot ( ) ;
2017-02-13 01:37:31 -06:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : detachAllCurves ( )
{
for ( size_t cIdx = 0 ; cIdx < curves . size ( ) ; + + cIdx )
{
curves [ cIdx ] - > detachQwtCurve ( ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : updateXZoomAndParentPlotDepthZoom ( )
{
if ( m_wellLogTrackPlotWidget )
{
RimWellLogPlot * wellLogPlot ;
firstAncestorOrThisOfType ( wellLogPlot ) ;
if ( wellLogPlot )
{
wellLogPlot - > updateDepthZoom ( ) ;
}
updateXZoom ( ) ;
m_wellLogTrackPlotWidget - > replot ( ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : updateXZoom ( )
{
2017-10-27 08:17:24 -05:00
std : : map < int , std : : vector < RimWellFlowRateCurve * > > stackCurveGroups = visibleStackedCurves ( ) ;
for ( const std : : pair < int , std : : vector < RimWellFlowRateCurve * > > & curveGroup : stackCurveGroups )
{
for ( RimWellFlowRateCurve * stCurve : curveGroup . second ) stCurve - > updateStackedPlotData ( ) ;
}
2017-02-13 01:37:31 -06:00
if ( ! m_isAutoScaleXEnabled ( ) )
{
m_wellLogTrackPlotWidget - > setXRange ( m_visibleXRangeMin , m_visibleXRangeMax ) ;
m_wellLogTrackPlotWidget - > replot ( ) ;
return ;
}
double minValue = HUGE_VAL ;
double maxValue = - HUGE_VAL ;
for ( size_t cIdx = 0 ; cIdx < curves . size ( ) ; cIdx + + )
{
double minCurveValue = HUGE_VAL ;
double maxCurveValue = - HUGE_VAL ;
if ( curves [ cIdx ] - > isCurveVisible ( ) & & curves [ cIdx ] - > valueRange ( & minCurveValue , & maxCurveValue ) )
{
if ( minCurveValue < minValue )
{
minValue = minCurveValue ;
}
if ( maxCurveValue > maxValue )
{
maxValue = maxCurveValue ;
}
}
}
if ( minValue = = HUGE_VAL )
{
minValue = RI_LOGPLOTTRACK_MINX_DEFAULT ;
maxValue = RI_LOGPLOTTRACK_MAXX_DEFAULT ;
}
m_visibleXRangeMin = minValue ;
m_visibleXRangeMax = maxValue ;
computeAndSetXRangeMinForLogarithmicScale ( ) ;
if ( m_wellLogTrackPlotWidget ) m_wellLogTrackPlotWidget - > setXRange ( m_visibleXRangeMin , m_visibleXRangeMax ) ;
updateConnectedEditors ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogCurve * RimWellLogTrack : : curveDefinitionFromCurve ( const QwtPlotCurve * curve ) const
{
for ( size_t idx = 0 ; idx < curves . size ( ) ; idx + + )
{
if ( curves [ idx ] - > qwtPlotCurve ( ) = = curve )
{
return curves [ idx ] ;
}
}
2017-10-25 07:41:54 -05:00
return nullptr ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-26 03:01:56 -05:00
void RimWellLogTrack : : updateGeneratedSimulationWellpath ( cvf : : Collection < RigWellPath > * generatedSimulationWellPathBranches , const QString & simWellName , RimCase * rimCase )
2017-10-25 07:41:54 -05:00
{
2017-10-26 03:01:56 -05:00
if ( generatedSimulationWellPathBranches - > size ( ) ) return ; // Already created. Nothing to do
2017-10-25 07:41:54 -05:00
2017-10-26 03:01:56 -05:00
RimEclipseCase * eclipseCase = dynamic_cast < RimEclipseCase * > ( rimCase ) ;
2017-10-25 07:41:54 -05:00
2017-10-26 03:01:56 -05:00
if ( ! ( ! simWellName . isEmpty ( ) & & simWellName ! = QString ( " None " ) & & eclipseCase & & eclipseCase - > eclipseCaseData ( ) ) )
2017-10-25 07:41:54 -05:00
{
return ;
}
RigEclipseCaseData * eclCaseData = eclipseCase - > eclipseCaseData ( ) ;
2017-10-26 03:01:56 -05:00
const RigSimWellData * simWellData = eclCaseData - > findSimWellData ( simWellName ) ;
2017-10-25 07:41:54 -05:00
if ( ! simWellData ) return ;
std : : vector < std : : vector < cvf : : Vec3d > > pipeBranchesCLCoords ;
std : : vector < std : : vector < RigWellResultPoint > > pipeBranchesCellIds ;
RigSimulationWellCenterLineCalculator : : calculateWellPipeCenterlineFromWellFrame ( eclCaseData ,
simWellData ,
- 1 ,
true ,
true ,
pipeBranchesCLCoords ,
pipeBranchesCellIds ) ;
for ( size_t brIdx = 0 ; brIdx < pipeBranchesCLCoords . size ( ) ; + + brIdx )
{
auto wellMdCalculator = RigSimulationWellCoordsAndMD ( pipeBranchesCLCoords [ brIdx ] ) ; // Todo, branch index
cvf : : ref < RigWellPath > newWellPath = new RigWellPath ( ) ;
newWellPath - > m_measuredDepths = wellMdCalculator . measuredDepths ( ) ;
newWellPath - > m_wellPathPoints = wellMdCalculator . wellPathPoints ( ) ;
2017-10-26 03:01:56 -05:00
generatedSimulationWellPathBranches - > push_back ( newWellPath . p ( ) ) ;
2017-10-25 07:41:54 -05:00
}
2017-02-13 01:37:31 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : defineUiOrdering ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
uiOrdering . add ( & m_userName ) ;
2017-10-25 07:41:54 -05:00
caf : : PdmUiGroup * formationGroup = uiOrdering . addNewGroup ( " Formation Names Properties " ) ;
formationGroup - > add ( & m_showFormations ) ;
2017-11-03 07:22:51 -05:00
formationGroup - > add ( & m_formationCase ) ;
2017-10-25 07:41:54 -05:00
formationGroup - > add ( & m_trajectoryType ) ;
if ( m_trajectoryType ( ) = = WELL_PATH )
{
formationGroup - > add ( & m_wellPath ) ;
}
else
{
2017-11-03 07:22:51 -05:00
updateGeneratedSimulationWellpath ( & m_generatedSimulationWellPathBranches , m_simWellName ( ) , m_formationCase ) ;
2017-10-25 07:41:54 -05:00
formationGroup - > add ( & m_simWellName ) ;
if ( m_generatedSimulationWellPathBranches . size ( ) > 1 )
{
formationGroup - > add ( & m_branchIndex ) ;
}
}
2017-11-03 02:58:08 -05:00
uiOrderingForVisibleXRange ( uiConfigName , uiOrdering ) ;
2017-10-25 07:41:54 -05:00
uiOrdering . skipRemainingFields ( true ) ;
2017-02-13 01:37:31 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimWellLogTrack : : curveIndex ( RimWellLogCurve * curve )
{
return curves . index ( curve ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellLogTrack : : isVisible ( )
{
return m_show ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : updateAxisScaleEngine ( )
{
if ( m_isLogarithmicScaleEnabled )
{
m_wellLogTrackPlotWidget - > setAxisScaleEngine ( QwtPlot : : xTop , new QwtLogScaleEngine ) ;
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
m_wellLogTrackPlotWidget - > setAxisScaleEngine ( QwtPlot : : xBottom , new QwtLogScaleEngine ) ;
}
else
{
m_wellLogTrackPlotWidget - > setAxisScaleEngine ( QwtPlot : : xTop , new QwtLinearScaleEngine ) ;
// NB! Must assign scale engine to bottom in order to make QwtPlotGrid work
m_wellLogTrackPlotWidget - > setAxisScaleEngine ( QwtPlot : : xBottom , new QwtLinearScaleEngine ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : computeAndSetXRangeMinForLogarithmicScale ( )
{
if ( m_isAutoScaleXEnabled & & m_isLogarithmicScaleEnabled )
{
double pos = HUGE_VAL ;
double neg = - HUGE_VAL ;
for ( size_t cIdx = 0 ; cIdx < curves . size ( ) ; cIdx + + )
{
if ( curves [ cIdx ] - > isCurveVisible ( ) & & curves [ cIdx ] - > curveData ( ) )
{
RigStatisticsCalculator : : posNegClosestToZero ( curves [ cIdx ] - > curveData ( ) - > xPlotValues ( ) , pos , neg ) ;
}
}
if ( pos ! = HUGE_VAL )
{
m_visibleXRangeMin = pos ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : setLogarithmicScale ( bool enable )
{
m_isLogarithmicScaleEnabled = enable ;
updateAxisScaleEngine ( ) ;
computeAndSetXRangeMinForLogarithmicScale ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-27 08:17:24 -05:00
std : : map < int , std : : vector < RimWellFlowRateCurve * > > RimWellLogTrack : : visibleStackedCurves ( )
2017-02-13 01:37:31 -06:00
{
2017-10-27 08:17:24 -05:00
std : : map < int , std : : vector < RimWellFlowRateCurve * > > stackedCurves ;
2017-02-13 01:37:31 -06:00
for ( RimWellLogCurve * curve : curves )
{
if ( curve & & curve - > isCurveVisible ( ) )
{
RimWellFlowRateCurve * wfrCurve = dynamic_cast < RimWellFlowRateCurve * > ( curve ) ;
2017-10-27 08:17:24 -05:00
if ( wfrCurve ! = nullptr )
{
if ( stackedCurves . count ( wfrCurve - > groupId ( ) ) = = 0 )
{
stackedCurves . insert ( std : : make_pair ( wfrCurve - > groupId ( ) , std : : vector < RimWellFlowRateCurve * > ( ) ) ) ;
}
stackedCurves [ wfrCurve - > groupId ( ) ] . push_back ( wfrCurve ) ;
}
2017-02-13 01:37:31 -06:00
}
}
return stackedCurves ;
}
2017-03-09 07:27:41 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellLogTrack : : description ( )
{
return m_userName ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < RimWellLogCurve * > RimWellLogTrack : : curvesVector ( )
{
std : : vector < RimWellLogCurve * > curvesVector ;
for ( RimWellLogCurve * curve : curves )
{
curvesVector . push_back ( curve ) ;
}
return curvesVector ;
}
2017-11-03 02:58:08 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : uiOrderingForShowFormationNamesAndCase ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
2017-11-03 05:36:44 -05:00
caf : : PdmUiGroup * formationGroup = uiOrdering . addNewGroup ( " Formation Names " ) ;
2017-11-03 07:22:51 -05:00
formationGroup - > setCollapsedByDefault ( true ) ;
2017-11-03 02:58:08 -05:00
formationGroup - > add ( & m_showFormations ) ;
2017-11-03 07:22:51 -05:00
formationGroup - > add ( & m_formationCase ) ;
2017-11-03 02:58:08 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : uiOrderingForVisibleXRange ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
caf : : PdmUiGroup * gridGroup = uiOrdering . addNewGroup ( " Visible X Axis Range " ) ;
gridGroup - > add ( & m_isAutoScaleXEnabled ) ;
gridGroup - > add ( & m_isLogarithmicScaleEnabled ) ;
gridGroup - > add ( & m_visibleXRangeMin ) ;
gridGroup - > add ( & m_visibleXRangeMax ) ;
}
2017-10-25 07:41:54 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-27 04:41:19 -05:00
RigEclipseWellLogExtractor * RimWellLogTrack : : createSimWellExtractor ( RimWellLogPlotCollection * wellLogCollection , RimCase * rimCase , const QString & simWellName , int branchIndex )
2017-10-25 07:41:54 -05:00
{
2017-10-27 04:41:19 -05:00
if ( ! wellLogCollection ) return nullptr ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
RimEclipseCase * eclipseCase = dynamic_cast < RimEclipseCase * > ( rimCase ) ;
RimProject * proj = RiaApplication : : instance ( ) - > project ( ) ;
std : : vector < const RigWellPath * > wellPaths = proj - > simulationWellBranches ( simWellName ) ;
if ( wellPaths . size ( ) = = 0 ) return nullptr ;
return ( wellLogCollection - > findOrCreateSimWellExtractor ( simWellName , QString ( " Find or create sim well extractor " ) , wellPaths [ branchIndex ] , eclipseCase - > eclipseCaseData ( ) ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEclipseWellLogExtractor * RimWellLogTrack : : createWellPathExtractor ( RimWellLogPlotCollection * wellLogCollection , RimCase * rimCase , RimWellPath * wellPath )
{
if ( ! wellLogCollection ) return nullptr ;
RimEclipseCase * eclipseCase = dynamic_cast < RimEclipseCase * > ( rimCase ) ;
return ( wellLogCollection - > findOrCreateExtractor ( wellPath , eclipseCase ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigGeoMechWellLogExtractor * RimWellLogTrack : : createGeoMechExtractor ( RimWellLogPlotCollection * wellLogCollection , RimCase * rimCase , RimWellPath * wellPath )
{
RimGeoMechCase * geomCase = dynamic_cast < RimGeoMechCase * > ( rimCase ) ;
return ( wellLogCollection - > findOrCreateExtractor ( wellPath , geomCase ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CurveSamplingPointData RimWellLogTrack : : curveSamplingPointData ( RigEclipseWellLogExtractor * extractor , RigResultAccessor * resultAccessor )
{
CurveSamplingPointData curveData ;
curveData . md = extractor - > measuredDepth ( ) ;
curveData . tvd = extractor - > trueVerticalDepth ( ) ;
extractor - > curveData ( resultAccessor , & curveData . data ) ;
return curveData ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
CurveSamplingPointData RimWellLogTrack : : curveSamplingPointData ( RigGeoMechWellLogExtractor * extractor , const RigFemResultAddress & resultAddress )
{
CurveSamplingPointData curveData ;
curveData . md = extractor - > measuredDepth ( ) ;
curveData . tvd = extractor - > trueVerticalDepth ( ) ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
extractor - > curveData ( resultAddress , 0 , & curveData . data ) ;
return curveData ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < QString > RimWellLogTrack : : formationNameIndexToName ( RimCase * rimCase , const std : : vector < int > & formationNameInidces )
{
std : : vector < QString > availableFormationNames = RimWellLogTrack : : formationNamesVector ( rimCase ) ;
std : : vector < QString > formationNames ;
for ( int index : formationNameInidces )
2017-10-25 07:41:54 -05:00
{
2017-10-27 04:41:19 -05:00
formationNames . push_back ( availableFormationNames [ index ] ) ;
2017-10-25 07:41:54 -05:00
}
2017-10-27 04:41:19 -05:00
return formationNames ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : findFormationNamesToPlot ( const CurveSamplingPointData & curveData ,
const std : : vector < QString > & formationNamesVector ,
RimWellLogPlot : : DepthTypeEnum depthType ,
std : : vector < QString > * formationNamesToPlot ,
std : : vector < std : : pair < double , double > > * yValues )
{
2017-11-01 05:46:36 -05:00
if ( formationNamesVector . empty ( ) ) return ;
2017-10-27 04:41:19 -05:00
std : : vector < size_t > formationNameIndicesFromCurve ;
for ( double nameIdx : curveData . data )
2017-10-25 07:41:54 -05:00
{
2017-10-27 04:41:19 -05:00
formationNameIndicesFromCurve . push_back ( round ( nameIdx ) ) ;
2017-10-25 07:41:54 -05:00
}
2017-10-27 04:41:19 -05:00
if ( formationNameIndicesFromCurve . empty ( ) ) return ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
std : : vector < double > depthVector ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
if ( depthType = = RimWellLogPlot : : MEASURED_DEPTH )
{
depthVector = curveData . md ;
}
else
{
depthVector = curveData . tvd ;
}
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
if ( depthVector . empty ( ) ) return ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
double currentYStart = depthVector [ 0 ] ;
double prevNameIndex = formationNameIndicesFromCurve [ 0 ] ;
double currentNameIndex ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
for ( size_t i = 1 ; i < formationNameIndicesFromCurve . size ( ) ; i + + )
2017-10-25 07:41:54 -05:00
{
2017-10-27 04:41:19 -05:00
currentNameIndex = formationNameIndicesFromCurve [ i ] ;
if ( currentNameIndex ! = prevNameIndex )
2017-10-25 07:41:54 -05:00
{
2017-10-27 04:41:19 -05:00
if ( prevNameIndex < formationNamesVector . size ( ) )
{
formationNamesToPlot - > push_back ( formationNamesVector [ prevNameIndex ] ) ;
yValues - > push_back ( std : : make_pair ( currentYStart , depthVector [ i - 1 ] ) ) ;
}
currentYStart = depthVector [ i ] ;
prevNameIndex = currentNameIndex ;
2017-10-25 07:41:54 -05:00
}
2017-10-27 04:41:19 -05:00
}
size_t lastIdx = formationNameIndicesFromCurve . size ( ) - 1 ;
formationNamesToPlot - > push_back ( formationNamesVector [ formationNameIndicesFromCurve [ lastIdx ] ] ) ;
yValues - > push_back ( std : : make_pair ( currentYStart , depthVector [ lastIdx ] ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std : : vector < QString > RimWellLogTrack : : formationNamesVector ( RimCase * rimCase )
{
RimEclipseCase * eclipseCase = dynamic_cast < RimEclipseCase * > ( rimCase ) ;
RimGeoMechCase * geoMechCase = dynamic_cast < RimGeoMechCase * > ( rimCase ) ;
if ( eclipseCase )
{
2017-11-01 05:46:36 -05:00
if ( eclipseCase - > eclipseCaseData ( ) - > activeFormationNames ( ) )
{
return eclipseCase - > eclipseCaseData ( ) - > activeFormationNames ( ) - > formationNames ( ) ;
}
2017-10-27 04:41:19 -05:00
}
else if ( geoMechCase )
{
2017-11-01 05:46:36 -05:00
if ( geoMechCase - > geoMechData ( ) - > femPartResults ( ) - > activeFormationNames ( ) )
{
return geoMechCase - > geoMechData ( ) - > femPartResults ( ) - > activeFormationNames ( ) - > formationNames ( ) ;
}
2017-10-27 04:41:19 -05:00
}
2017-11-01 05:46:36 -05:00
return std : : vector < QString > ( ) ;
2017-10-27 04:41:19 -05:00
}
2017-10-26 03:18:42 -05:00
2017-10-27 04:41:19 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : updateFormationNamesOnPlot ( )
{
removeFormationNames ( ) ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
if ( m_showFormations = = false ) return ;
2017-10-25 07:41:54 -05:00
2017-11-03 07:22:51 -05:00
if ( ( m_simWellName = = QString ( " None " ) & & m_wellPath = = nullptr ) | | m_formationCase = = nullptr ) return ;
2017-10-27 04:41:19 -05:00
if ( m_annotationTool = = nullptr )
{
2017-11-03 05:36:44 -05:00
m_annotationTool = std : : unique_ptr < RiuPlotAnnotationTool > ( new RiuPlotAnnotationTool ( ) ) ;
2017-10-27 04:41:19 -05:00
}
RimMainPlotCollection * mainPlotCollection ;
this - > firstAncestorOrThisOfTypeAsserted ( mainPlotCollection ) ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
RimWellLogPlotCollection * wellLogCollection = mainPlotCollection - > wellLogPlotCollection ( ) ;
CurveSamplingPointData curveData ;
RigEclipseWellLogExtractor * eclWellLogExtractor ;
RigGeoMechWellLogExtractor * geoMechWellLogExtractor ;
if ( m_simulationWellChosen )
{
2017-11-03 07:22:51 -05:00
eclWellLogExtractor = RimWellLogTrack : : createSimWellExtractor ( wellLogCollection , m_formationCase , m_simWellName , m_branchIndex ) ;
2017-10-27 04:41:19 -05:00
}
else
{
2017-11-03 07:22:51 -05:00
eclWellLogExtractor = RimWellLogTrack : : createWellPathExtractor ( wellLogCollection , m_formationCase , m_wellPath ) ;
2017-10-27 04:41:19 -05:00
}
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
if ( eclWellLogExtractor )
{
2017-11-03 07:22:51 -05:00
RimEclipseCase * eclipseCase = dynamic_cast < RimEclipseCase * > ( m_formationCase ( ) ) ;
2017-10-25 07:41:54 -05:00
cvf : : ref < RigResultAccessor > resultAccessor = RigResultAccessorFactory : : createFromNameAndType ( eclipseCase - > eclipseCaseData ( ) ,
0 ,
RiaDefines : : PorosityModelType : : MATRIX_MODEL ,
0 ,
RiaDefines : : activeFormationNamesResultName ( ) ,
RiaDefines : : FORMATION_NAMES ) ;
2017-10-27 04:41:19 -05:00
curveData = RimWellLogTrack : : curveSamplingPointData ( eclWellLogExtractor , resultAccessor . p ( ) ) ;
2017-10-25 07:41:54 -05:00
}
2017-10-27 04:41:19 -05:00
else
2017-10-25 07:41:54 -05:00
{
2017-11-03 07:22:51 -05:00
geoMechWellLogExtractor = RimWellLogTrack : : createGeoMechExtractor ( wellLogCollection , m_formationCase , m_wellPath ) ;
2017-10-27 04:41:19 -05:00
if ( ! geoMechWellLogExtractor ) return ;
curveData = RimWellLogTrack : : curveSamplingPointData ( geoMechWellLogExtractor , RigFemResultAddress ( RIG_FORMATION_NAMES , RiaDefines : : activeFormationNamesResultName ( ) . toStdString ( ) , " " ) ) ;
2017-10-25 07:41:54 -05:00
}
2017-10-27 04:41:19 -05:00
RimWellLogPlot * plot ;
firstAncestorOrThisOfTypeAsserted ( plot ) ;
2017-10-25 07:41:54 -05:00
2017-11-03 07:22:51 -05:00
std : : vector < QString > formationNamesVector = RimWellLogTrack : : formationNamesVector ( m_formationCase ) ;
2017-10-27 04:41:19 -05:00
std : : vector < QString > formationNamesToPlot ;
std : : vector < std : : pair < double , double > > yValues ;
2017-10-25 07:41:54 -05:00
2017-10-27 04:41:19 -05:00
RimWellLogTrack : : findFormationNamesToPlot ( curveData ,
formationNamesVector ,
plot - > depthType ( ) ,
& formationNamesToPlot ,
& yValues ) ;
2017-10-25 07:41:54 -05:00
2017-11-03 05:36:44 -05:00
m_annotationTool - > attachFormationNames ( this - > viewer ( ) , formationNamesToPlot , yValues ) ;
2017-10-25 07:41:54 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogTrack : : removeFormationNames ( )
{
2017-10-26 03:01:56 -05:00
if ( m_annotationTool )
2017-10-25 07:41:54 -05:00
{
m_annotationTool - > detachAllAnnotations ( ) ;
}
}