2017-10-23 06:57:01 -05:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 Statoil ASA
//
// 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 "RimWellPltPlot.h"
# include "RiaApplication.h"
# include "RiaColorTables.h"
# include "RiaDateStringParser.h"
2017-11-08 09:35:58 -06:00
# include "RiaWellNameComparer.h"
2017-11-13 03:21:24 -06:00
2017-10-23 06:57:01 -05:00
# include "RifReaderEclipseRft.h"
2017-11-13 03:21:24 -06:00
# include "RigAccWellFlowCalculator.h"
2017-10-23 06:57:01 -05:00
# include "RigCaseCellResultsData.h"
# include "RigEclipseCaseData.h"
2017-11-13 03:21:24 -06:00
# include "RigEclipseWellLogExtractor.h"
# include "RigMainGrid.h"
2017-10-23 06:57:01 -05:00
# include "RigSimWellData.h"
2017-11-13 03:21:24 -06:00
# include "RigWellLogExtractor.h"
2017-10-23 06:57:01 -05:00
# include "RigWellPath.h"
2017-11-13 03:21:24 -06:00
2017-10-23 06:57:01 -05:00
# include "RimEclipseCase.h"
# include "RimEclipseCaseCollection.h"
# include "RimEclipseResultCase.h"
# include "RimEclipseResultDefinition.h"
2017-11-13 03:21:24 -06:00
# include "RimMainPlotCollection.h"
2017-10-23 06:57:01 -05:00
# include "RimOilField.h"
# include "RimProject.h"
2017-11-13 03:21:24 -06:00
# include "RimSummaryCurveAppearanceCalculator.h"
2017-10-23 06:57:01 -05:00
# include "RimTools.h"
2017-11-13 03:21:24 -06:00
# include "RimWellFlowRateCurve.h"
2017-10-23 06:57:01 -05:00
# include "RimWellLogExtractionCurve.h"
# include "RimWellLogFile.h"
# include "RimWellLogFileChannel.h"
# include "RimWellLogFileCurve.h"
# include "RimWellLogPlot.h"
2017-11-13 03:21:24 -06:00
# include "RimWellLogPlotCollection.h"
2017-10-23 06:57:01 -05:00
# include "RimWellLogRftCurve.h"
# include "RimWellLogTrack.h"
# include "RimWellPath.h"
# include "RimWellPathCollection.h"
2017-11-09 03:03:32 -06:00
# include "RimWellPlotTools.h"
2017-11-13 03:21:24 -06:00
2017-10-23 06:57:01 -05:00
# include "RiuWellPltPlot.h"
2017-11-13 03:21:24 -06:00
# include "cafPdmUiTreeOrdering.h"
2017-10-23 06:57:01 -05:00
# include "cafPdmUiTreeSelectionEditor.h"
2017-11-13 03:21:24 -06:00
# include "cafVecIjk.h"
2017-10-23 06:57:01 -05:00
# include <algorithm>
# include <iterator>
2017-11-13 03:21:24 -06:00
# include <tuple>
2017-11-15 09:17:55 -06:00
# include "QMessageBox"
2017-11-13 03:21:24 -06:00
2017-10-23 06:57:01 -05:00
2017-11-08 09:35:58 -06:00
2017-10-23 06:57:01 -05:00
CAF_PDM_SOURCE_INIT ( RimWellPltPlot , " WellPltPlot " ) ;
2017-10-25 12:44:04 -05:00
namespace caf
{
2017-10-25 07:43:17 -05:00
template < >
2017-11-09 03:03:32 -06:00
void caf : : AppEnum < FlowType > : : setUp ( )
2017-10-25 07:43:17 -05:00
{
2017-11-09 03:03:32 -06:00
addItem ( FLOW_TYPE_PHASE_SPLIT , " PHASE_SPLIT " , " Phase Split " ) ;
2017-11-17 08:35:07 -06:00
addItem ( FLOW_TYPE_TOTAL , " TOTAL " , " Total Flow " ) ;
setDefault ( FLOW_TYPE_PHASE_SPLIT ) ;
2017-10-25 07:43:17 -05:00
}
template < >
2017-11-09 03:03:32 -06:00
void caf : : AppEnum < FlowPhase > : : setUp ( )
2017-10-25 07:43:17 -05:00
{
2017-11-09 03:03:32 -06:00
addItem ( FLOW_PHASE_OIL , " PHASE_OIL " , " Oil " ) ;
addItem ( FLOW_PHASE_GAS , " PHASE_GAS " , " Gas " ) ;
addItem ( FLOW_PHASE_WATER , " PHASE_WATER " , " Water " ) ;
2017-11-23 08:11:07 -06:00
addItem ( FLOW_PHASE_TOTAL , " PHASE_TOTAL " , " Total " ) ;
2017-10-25 07:43:17 -05:00
}
2017-10-25 12:44:04 -05:00
}
2017-10-25 07:43:17 -05:00
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-27 02:17:05 -05:00
const char RimWellPltPlot : : PLOT_NAME_QFORMAT_STRING [ ] = " PLT: %1 " ;
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPltPlot : : RimWellPltPlot ( )
{
CAF_PDM_InitObject ( " Well Allocation Plot " , " :/WellAllocPlot16x16.png " , " " , " " ) ;
2017-10-27 02:17:05 -05:00
CAF_PDM_InitField ( & m_userName , " PlotDescription " , QString ( " PLT Plot " ) , " Name " , " " , " " , " " ) ;
2017-10-23 06:57:01 -05:00
m_userName . uiCapability ( ) - > setUiReadOnly ( true ) ;
CAF_PDM_InitField ( & m_showPlotTitle , " ShowPlotTitle " , true , " Show Plot Title " , " " , " " , " " ) ;
CAF_PDM_InitFieldNoDefault ( & m_wellLogPlot , " WellLog " , " WellLog " , " " , " " , " " ) ;
m_wellLogPlot . uiCapability ( ) - > setUiHidden ( true ) ;
m_wellLogPlot = new RimWellLogPlot ( ) ;
2017-10-25 07:43:17 -05:00
m_wellLogPlot - > setDepthType ( RimWellLogPlot : : MEASURED_DEPTH ) ;
2017-10-23 06:57:01 -05:00
2017-11-30 06:44:18 -06:00
CAF_PDM_InitFieldNoDefault ( & m_wellPathName , " WellName " , " Well Name " , " " , " " , " " ) ;
2017-10-23 06:57:01 -05:00
2017-11-30 06:44:18 -06:00
CAF_PDM_InitFieldNoDefault ( & m_selectedSources , " SourcesInternal " , " Sources Internal " , " " , " " , " " ) ;
2017-10-23 06:57:01 -05:00
m_selectedSources . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiTreeSelectionEditor : : uiEditorTypeName ( ) ) ;
m_selectedSources . uiCapability ( ) - > setUiLabelPosition ( caf : : PdmUiItemInfo : : HIDDEN ) ;
m_selectedSources . uiCapability ( ) - > setAutoAddingOptionFromValue ( false ) ;
2017-10-27 02:38:24 -05:00
m_selectedSources . xmlCapability ( ) - > disableIO ( ) ;
CAF_PDM_InitFieldNoDefault ( & m_selectedSourcesForIo , " Sources " , " Sources " , " " , " " , " " ) ;
m_selectedSourcesForIo . uiCapability ( ) - > setUiHidden ( true ) ;
2017-10-23 06:57:01 -05:00
2017-11-30 06:44:18 -06:00
CAF_PDM_InitFieldNoDefault ( & m_selectedTimeSteps , " TimeSteps " , " Time Steps " , " " , " " , " " ) ;
2017-10-23 06:57:01 -05:00
m_selectedTimeSteps . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiTreeSelectionEditor : : uiEditorTypeName ( ) ) ;
m_selectedTimeSteps . uiCapability ( ) - > setUiLabelPosition ( caf : : PdmUiItemInfo : : HIDDEN ) ;
m_selectedTimeSteps . uiCapability ( ) - > setAutoAddingOptionFromValue ( false ) ;
2017-12-15 08:11:08 -06:00
CAF_PDM_InitField ( & m_useStandardConditionCurves , " UseStandardConditionCurves " , true , " Standard Volume " , " " , " " , " " ) ;
CAF_PDM_InitField ( & m_useReservoirConditionCurves , " UseReservoirConditionCurves " , true , " Reservoir Volume " , " " , " " , " " ) ;
2017-10-25 07:43:17 -05:00
CAF_PDM_InitFieldNoDefault ( & m_phases , " Phases " , " Phases " , " " , " " , " " ) ;
m_phases . uiCapability ( ) - > setUiEditorTypeName ( caf : : PdmUiTreeSelectionEditor : : uiEditorTypeName ( ) ) ;
2017-11-09 03:03:32 -06:00
m_phases = std : : vector < caf : : AppEnum < FlowPhase > > ( { FLOW_PHASE_OIL , FLOW_PHASE_GAS , FLOW_PHASE_WATER } ) ;
2017-11-23 08:11:07 -06:00
m_phases . uiCapability ( ) - > setUiLabelPosition ( caf : : PdmUiItemInfo : : HIDDEN ) ;
2017-10-25 07:43:17 -05:00
2017-10-23 06:57:01 -05:00
this - > setAsPlotMdiWindow ( ) ;
2017-10-27 02:38:24 -05:00
m_doInitAfterLoad = false ;
2017-11-13 01:56:22 -06:00
m_isOnLoad = true ;
2017-10-23 06:57:01 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPltPlot : : ~ RimWellPltPlot ( )
{
removeMdiWindowFromMdiArea ( ) ;
deleteViewWidget ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : deleteViewWidget ( )
{
if ( m_wellLogPlotWidget )
{
m_wellLogPlotWidget - > deleteLater ( ) ;
m_wellLogPlotWidget = nullptr ;
}
}
2017-10-25 07:43:17 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : setPlotXAxisTitles ( RimWellLogTrack * plotTrack )
{
2017-11-15 09:17:55 -06:00
std : : set < RiaEclipseUnitTools : : UnitSystem > presentUnitSystems ;
for ( const RifDataSourceForRftPlt & source : m_selectedSources . v ( ) )
2017-10-23 06:57:01 -05:00
{
2017-11-15 09:17:55 -06:00
if ( source . eclCase ( ) ) presentUnitSystems . insert ( source . eclCase ( ) - > eclipseCaseData ( ) - > unitsType ( ) ) ;
if ( source . wellLogFile ( ) )
{
if ( source . wellLogFile ( ) - > wellLogFileData ( ) )
{
// Todo: Handle different units in the relevant las channels
switch ( source . wellLogFile ( ) - > wellLogFileData ( ) - > depthUnit ( ) )
{
case RiaDefines : : UNIT_METER : presentUnitSystems . insert ( RiaEclipseUnitTools : : UNITS_METRIC ) ;
case RiaDefines : : UNIT_FEET : presentUnitSystems . insert ( RiaEclipseUnitTools : : UNITS_FIELD ) ;
case RiaDefines : : UNIT_NONE : presentUnitSystems . insert ( RiaEclipseUnitTools : : UNITS_UNKNOWN ) ;
}
}
}
2017-10-25 07:43:17 -05:00
}
2017-10-23 06:57:01 -05:00
2017-11-15 09:17:55 -06:00
if ( presentUnitSystems . size ( ) > 1 ) { QMessageBox : : warning ( nullptr , " ResInsight PLT Plot " , " Inconsistent units in PLT plot " ) ; }
2017-11-23 09:10:39 -06:00
if ( presentUnitSystems . size ( ) < = 0 ) return ;
RiaEclipseUnitTools : : UnitSystem unitSet = * presentUnitSystems . begin ( ) ;
QString axisTitle ;
if ( m_useReservoirConditionCurves ) axisTitle + = RimWellPlotTools : : flowPlotAxisTitle ( RimWellLogFile : : WELL_FLOW_COND_RESERVOIR , unitSet ) ;
if ( m_useReservoirConditionCurves & & m_useStandardConditionCurves ) axisTitle + = " | " ;
if ( m_useStandardConditionCurves ) axisTitle + = RimWellPlotTools : : flowPlotAxisTitle ( RimWellLogFile : : WELL_FLOW_COND_STANDARD , unitSet ) ;
plotTrack - > setXAxisTitle ( axisTitle ) ;
#if 0
2017-11-15 09:17:55 -06:00
QString unitText ;
for ( auto unitSet : presentUnitSystems )
2017-10-23 06:57:01 -05:00
{
2017-11-15 09:17:55 -06:00
switch ( unitSet )
2017-10-23 06:57:01 -05:00
{
2017-11-15 09:17:55 -06:00
case RiaEclipseUnitTools : : UNITS_METRIC :
unitText + = " [Liquid Sm<sup>3</sup>/day], [Gas kSm<sup>3</sup>/day] " ;
break ;
case RiaEclipseUnitTools : : UNITS_FIELD :
unitText + = " [Liquid BBL/day], [Gas BOE/day] " ;
break ;
case RiaEclipseUnitTools : : UNITS_LAB :
unitText + = " [cm<sup>3</sup>/hr] " ;
break ;
default :
unitText + = " (unknown unit) " ;
break ;
2017-10-25 07:43:17 -05:00
}
2017-10-23 06:57:01 -05:00
}
2017-11-15 09:17:55 -06:00
plotTrack - > setXAxisTitle ( " Surface Flow Rate " + unitText ) ;
2017-11-23 09:10:39 -06:00
# endif
2017-10-25 07:43:17 -05:00
}
2017-10-23 06:57:01 -05:00
2017-11-06 07:40:26 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-11-07 03:38:05 -06:00
void RimWellPltPlot : : updateFormationsOnPlot ( ) const
2017-11-06 07:40:26 -06:00
{
2017-11-12 07:45:06 -06:00
if ( m_wellLogPlot - > trackCount ( ) > 0 )
2017-11-06 07:40:26 -06:00
{
2017-11-12 07:45:06 -06:00
RimProject * proj = RiaApplication : : instance ( ) - > project ( ) ;
RimWellPath * wellPath = proj - > wellPathByName ( m_wellPathName ) ;
2017-11-06 07:40:26 -06:00
2017-11-12 07:45:06 -06:00
RimCase * formationNamesCase = m_wellLogPlot - > trackByIndex ( 0 ) - > formationNamesCase ( ) ;
2017-11-06 07:40:26 -06:00
2017-11-12 07:45:06 -06:00
if ( ! formationNamesCase )
{
/// Set default case. Todo : Use the first of the selected cases in the plot
std : : vector < RimCase * > cases ;
proj - > allCases ( cases ) ;
2017-11-06 07:40:26 -06:00
2017-11-12 07:45:06 -06:00
if ( ! cases . empty ( ) )
{
formationNamesCase = cases [ 0 ] ;
}
}
m_wellLogPlot - > trackByIndex ( 0 ) - > setAndUpdateWellPathFormationNamesData ( formationNamesCase , wellPath ) ;
2017-11-06 07:40:26 -06:00
}
}
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : updateWidgetTitleWindowTitle ( )
{
updateMdiWindowTitle ( ) ;
if ( m_wellLogPlotWidget )
{
if ( m_showPlotTitle )
{
m_wellLogPlotWidget - > showTitle ( m_userName ) ;
}
else
{
m_wellLogPlotWidget - > hideTitle ( ) ;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-11-15 10:08:09 -06:00
std : : set < RiaRftPltCurveDefinition > RimWellPltPlot : : selectedCurveDefs ( ) const
2017-11-16 09:17:54 -06:00
{
2017-11-16 09:35:55 -06:00
return RimWellPlotTools : : curveDefsFromTimesteps ( RimWellPlotTools : : simWellName ( m_wellPathName ) ,
m_selectedTimeSteps . v ( ) ,
2017-12-07 09:24:28 -06:00
false ,
2017-11-16 09:35:55 -06:00
selectedSourcesExpanded ( ) ) ;
2017-11-16 09:17:54 -06:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-11-07 07:40:36 -06:00
class RigResultPointCalculator
{
public :
RigResultPointCalculator ( ) { }
virtual ~ RigResultPointCalculator ( ) { }
const std : : vector < cvf : : Vec3d > & pipeBranchCLCoords ( ) { return m_pipeBranchCLCoords ; }
const std : : vector < RigWellResultPoint > & pipeBranchWellResultPoints ( ) { return m_pipeBranchWellResultPoints ; }
const std : : vector < double > & pipeBranchMeasuredDepths ( ) { return m_pipeBranchMeasuredDepths ; }
protected :
2017-11-08 09:35:58 -06:00
RigEclipseWellLogExtractor * findWellLogExtractor ( const QString & wellPathName ,
2017-11-07 07:40:36 -06:00
RimEclipseResultCase * eclCase )
{
RimProject * proj = RiaApplication : : instance ( ) - > project ( ) ;
2017-11-08 09:35:58 -06:00
RimWellPath * wellPath = proj - > wellPathByName ( wellPathName ) ;
2017-11-07 07:40:36 -06:00
RimWellLogPlotCollection * wellLogCollection = proj - > mainPlotCollection ( ) - > wellLogPlotCollection ( ) ;
RigEclipseWellLogExtractor * eclExtractor = wellLogCollection - > findOrCreateExtractor ( wellPath , eclCase ) ;
2017-10-23 06:57:01 -05:00
2017-11-07 07:40:36 -06:00
return eclExtractor ;
}
2017-11-06 15:23:54 -06:00
2017-11-07 07:40:36 -06:00
std : : vector < cvf : : Vec3d > m_pipeBranchCLCoords ;
std : : vector < RigWellResultPoint > m_pipeBranchWellResultPoints ;
std : : vector < double > m_pipeBranchMeasuredDepths ;
} ;
2017-11-06 15:23:54 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-11-07 07:40:36 -06:00
class RigRftResultPointCalculator : public RigResultPointCalculator
2017-11-06 15:23:54 -06:00
{
public :
2017-11-08 09:35:58 -06:00
RigRftResultPointCalculator ( const QString & wellPathName ,
2017-11-06 15:23:54 -06:00
RimEclipseResultCase * eclCase ,
QDateTime m_timeStep )
{
2017-11-09 03:03:32 -06:00
RifEclipseRftAddress gasRateAddress ( RimWellPlotTools : : simWellName ( wellPathName ) , m_timeStep , RifEclipseRftAddress : : GRAT ) ;
RifEclipseRftAddress oilRateAddress ( RimWellPlotTools : : simWellName ( wellPathName ) , m_timeStep , RifEclipseRftAddress : : ORAT ) ;
RifEclipseRftAddress watRateAddress ( RimWellPlotTools : : simWellName ( wellPathName ) , m_timeStep , RifEclipseRftAddress : : WRAT ) ;
2017-11-06 15:23:54 -06:00
std : : vector < caf : : VecIjk > rftIndices ;
eclCase - > rftReader ( ) - > cellIndices ( gasRateAddress , & rftIndices ) ;
if ( rftIndices . empty ( ) ) eclCase - > rftReader ( ) - > cellIndices ( oilRateAddress , & rftIndices ) ;
if ( rftIndices . empty ( ) ) eclCase - > rftReader ( ) - > cellIndices ( watRateAddress , & rftIndices ) ;
if ( rftIndices . empty ( ) ) return ;
std : : vector < double > gasRates ;
std : : vector < double > oilRates ;
std : : vector < double > watRates ;
eclCase - > rftReader ( ) - > values ( gasRateAddress , & gasRates ) ;
eclCase - > rftReader ( ) - > values ( oilRateAddress , & oilRates ) ;
eclCase - > rftReader ( ) - > values ( watRateAddress , & watRates ) ;
std : : map < size_t , size_t > globCellIdxToIdxInRftFile ;
2017-11-07 07:40:36 -06:00
const RigMainGrid * mainGrid = eclCase - > eclipseCaseData ( ) - > mainGrid ( ) ;
2017-11-06 15:23:54 -06:00
for ( size_t rftCellIdx = 0 ; rftCellIdx < rftIndices . size ( ) ; rftCellIdx + + )
{
caf : : VecIjk ijkIndex = rftIndices [ rftCellIdx ] ;
size_t globalCellIndex = mainGrid - > cellIndexFromIJK ( ijkIndex . i ( ) , ijkIndex . j ( ) , ijkIndex . k ( ) ) ;
globCellIdxToIdxInRftFile [ globalCellIndex ] = rftCellIdx ;
}
2017-11-08 09:35:58 -06:00
RigEclipseWellLogExtractor * eclExtractor = findWellLogExtractor ( wellPathName , eclCase ) ;
2017-11-07 07:40:36 -06:00
if ( ! eclExtractor ) return ;
2017-12-12 09:32:57 -06:00
std : : vector < WellPathCellIntersectionInfo > intersections = eclExtractor - > cellIntersectionInfosAlongWellPath ( ) ;
2017-11-07 07:40:36 -06:00
2017-11-06 15:23:54 -06:00
for ( size_t wpExIdx = 0 ; wpExIdx < intersections . size ( ) ; wpExIdx + + )
{
size_t globCellIdx = intersections [ wpExIdx ] . globCellIndex ;
auto it = globCellIdxToIdxInRftFile . find ( globCellIdx ) ;
2017-11-08 04:58:14 -06:00
if ( it = = globCellIdxToIdxInRftFile . end ( ) )
{
2017-12-04 11:58:52 -06:00
if ( ! m_pipeBranchWellResultPoints . empty ( ) & & wpExIdx = = ( intersections . size ( ) - 1 ) )
2017-11-08 04:58:14 -06:00
{
m_pipeBranchWellResultPoints . pop_back ( ) ;
}
continue ;
}
2017-11-06 15:23:54 -06:00
m_pipeBranchCLCoords . push_back ( intersections [ wpExIdx ] . startPoint ) ;
m_pipeBranchMeasuredDepths . push_back ( intersections [ wpExIdx ] . startMD ) ;
m_pipeBranchCLCoords . push_back ( intersections [ wpExIdx ] . endPoint ) ;
m_pipeBranchMeasuredDepths . push_back ( intersections [ wpExIdx ] . endMD ) ;
RigWellResultPoint resPoint ;
2017-11-07 11:35:34 -06:00
resPoint . m_isOpen = true ;
2017-11-09 06:47:00 -06:00
resPoint . m_gridIndex = 0 ; // Always main grid
2017-11-06 15:23:54 -06:00
resPoint . m_gridCellIndex = globCellIdx ; // Shortcut, since we only have main grid results from RFT
2017-11-09 06:47:00 -06:00
resPoint . m_gasRate = RiaEclipseUnitTools : : convertSurfaceGasFlowRateToOilEquivalents ( eclCase - > eclipseCaseData ( ) - > unitsType ( ) ,
gasRates [ it - > second ] ) ;
resPoint . m_oilRate = oilRates [ it - > second ] ;
2017-11-06 15:23:54 -06:00
resPoint . m_waterRate = watRates [ it - > second ] ;
m_pipeBranchWellResultPoints . push_back ( resPoint ) ;
2017-11-07 11:35:34 -06:00
if ( wpExIdx < intersections . size ( ) - 1 )
{
m_pipeBranchWellResultPoints . push_back ( RigWellResultPoint ( ) ) ; // Invalid res point describing the "line" between the cells
}
2017-11-06 15:23:54 -06:00
}
}
} ;
2017-11-07 07:40:36 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class RigSimWellResultPointCalculator : public RigResultPointCalculator
{
public :
2017-11-08 09:35:58 -06:00
RigSimWellResultPointCalculator ( const QString & wellPathName ,
2017-11-07 07:40:36 -06:00
RimEclipseResultCase * eclCase ,
QDateTime m_timeStep )
{
// Find timestep index from qdatetime
const std : : vector < QDateTime > timeSteps = eclCase - > eclipseCaseData ( ) - > results ( RiaDefines : : MATRIX_MODEL ) - > timeStepDates ( ) ;
size_t tsIdx = timeSteps . size ( ) ;
for ( tsIdx = 0 ; tsIdx < timeSteps . size ( ) ; + + tsIdx ) { if ( timeSteps [ tsIdx ] = = m_timeStep ) break ; }
if ( tsIdx > = timeSteps . size ( ) ) return ;
// Build search map into simulation well data
std : : map < size_t , std : : pair < size_t , size_t > > globCellIdxToIdxInSimWellBranch ;
2017-11-09 03:03:32 -06:00
const RimWellPath * wellPath = RimWellPlotTools : : wellPathByWellPathNameOrSimWellName ( wellPathName ) ;
2017-11-17 08:35:07 -06:00
const RigSimWellData * simWell = wellPath ! = nullptr ? eclCase - > eclipseCaseData ( ) - > findSimWellData ( wellPath - > associatedSimulationWellName ( ) ) : nullptr ;
2017-11-07 07:40:36 -06:00
if ( ! simWell ) return ;
if ( ! simWell - > hasWellResult ( tsIdx ) ) return ;
const RigWellResultFrame & resFrame = simWell - > wellResultFrame ( tsIdx ) ;
const RigMainGrid * mainGrid = eclCase - > eclipseCaseData ( ) - > mainGrid ( ) ;
for ( size_t brIdx = 0 ; brIdx < resFrame . m_wellResultBranches . size ( ) ; + + brIdx )
{
const std : : vector < RigWellResultPoint > & branchResPoints = resFrame . m_wellResultBranches [ brIdx ] . m_branchResultPoints ;
for ( size_t wrpIdx = 0 ; wrpIdx < branchResPoints . size ( ) ; wrpIdx + + )
{
const RigGridBase * grid = mainGrid - > gridByIndex ( branchResPoints [ wrpIdx ] . m_gridIndex ) ;
size_t globalCellIndex = grid - > reservoirCellIndex ( branchResPoints [ wrpIdx ] . m_gridCellIndex ) ;
globCellIdxToIdxInSimWellBranch [ globalCellIndex ] = std : : make_pair ( brIdx , wrpIdx ) ;
}
}
2017-11-08 09:35:58 -06:00
RigEclipseWellLogExtractor * eclExtractor = findWellLogExtractor ( wellPathName , eclCase ) ;
2017-11-07 07:40:36 -06:00
if ( ! eclExtractor ) return ;
2017-12-12 09:32:57 -06:00
std : : vector < WellPathCellIntersectionInfo > intersections = eclExtractor - > cellIntersectionInfosAlongWellPath ( ) ;
2017-11-07 07:40:36 -06:00
for ( size_t wpExIdx = 0 ; wpExIdx < intersections . size ( ) ; wpExIdx + + )
{
size_t globCellIdx = intersections [ wpExIdx ] . globCellIndex ;
auto it = globCellIdxToIdxInSimWellBranch . find ( globCellIdx ) ;
2017-11-08 04:58:14 -06:00
if ( it = = globCellIdxToIdxInSimWellBranch . end ( ) )
{
2017-12-04 11:58:52 -06:00
if ( ! m_pipeBranchWellResultPoints . empty ( ) & & wpExIdx = = ( intersections . size ( ) - 1 ) )
2017-11-08 04:58:14 -06:00
{
m_pipeBranchWellResultPoints . pop_back ( ) ;
}
continue ;
}
2017-11-07 07:40:36 -06:00
m_pipeBranchCLCoords . push_back ( intersections [ wpExIdx ] . startPoint ) ;
m_pipeBranchMeasuredDepths . push_back ( intersections [ wpExIdx ] . startMD ) ;
m_pipeBranchCLCoords . push_back ( intersections [ wpExIdx ] . endPoint ) ;
m_pipeBranchMeasuredDepths . push_back ( intersections [ wpExIdx ] . endMD ) ;
const RigWellResultPoint & resPoint = resFrame . m_wellResultBranches [ it - > second . first ] . m_branchResultPoints [ it - > second . second ] ;
m_pipeBranchWellResultPoints . push_back ( resPoint ) ;
2017-11-07 11:35:34 -06:00
if ( wpExIdx < intersections . size ( ) - 1 )
{
m_pipeBranchWellResultPoints . push_back ( RigWellResultPoint ( ) ) ; // Invalid res point describing the "line" between the cells
}
2017-11-07 07:40:36 -06:00
}
}
} ;
2017-11-06 15:23:54 -06:00
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-31 06:49:14 -05:00
void RimWellPltPlot : : syncCurvesFromUiSelection ( )
2017-10-23 06:57:01 -05:00
{
2017-10-31 06:49:14 -05:00
RimWellLogTrack * plotTrack = m_wellLogPlot - > trackByIndex ( 0 ) ;
2017-11-15 10:08:09 -06:00
const std : : set < RiaRftPltCurveDefinition > & curveDefs = selectedCurveDefs ( ) ;
2017-10-23 06:57:01 -05:00
2017-10-25 07:43:17 -05:00
setPlotXAxisTitles ( plotTrack ) ;
// Delete existing curves
2017-11-15 04:31:35 -06:00
plotTrack - > deleteAllCurves ( ) ;
2017-10-23 06:57:01 -05:00
2017-10-27 08:17:24 -05:00
int curveGroupId = 0 ;
2017-11-06 15:23:54 -06:00
RimProject * proj = RiaApplication : : instance ( ) - > project ( ) ;
2017-11-09 03:03:32 -06:00
RimWellPath * wellPath = RimWellPlotTools : : wellPathByWellPathNameOrSimWellName ( m_wellPathName ) ;
2017-11-06 15:23:54 -06:00
2017-11-23 08:11:07 -06:00
QString dateFormatString ;
{
std : : vector < QDateTime > allTimeSteps ;
for ( const RiaRftPltCurveDefinition & curveDefToAdd : curveDefs )
{
allTimeSteps . push_back ( curveDefToAdd . timeStep ( ) ) ;
}
dateFormatString = RimTools : : createTimeFormatStringFromDates ( allTimeSteps ) ;
}
2017-10-25 07:43:17 -05:00
// Add curves
2017-11-15 10:08:09 -06:00
for ( const RiaRftPltCurveDefinition & curveDefToAdd : curveDefs )
2017-10-23 06:57:01 -05:00
{
2017-11-23 08:11:07 -06:00
std : : set < FlowPhase > selectedPhases = std : : set < FlowPhase > ( m_phases ( ) . begin ( ) , m_phases ( ) . end ( ) ) ;
2017-11-15 10:08:09 -06:00
RifDataSourceForRftPlt sourceDef = curveDefToAdd . address ( ) ;
QDateTime timeStep = curveDefToAdd . timeStep ( ) ;
2017-10-27 08:17:24 -05:00
2017-11-07 07:40:36 -06:00
std : : unique_ptr < RigResultPointCalculator > resultPointCalc ;
2017-11-12 16:46:12 -06:00
2017-11-08 04:22:16 -06:00
QString curveName ;
2017-12-05 02:45:41 -06:00
2017-11-12 16:46:12 -06:00
{
2017-11-23 08:11:07 -06:00
curveName + = sourceDef . eclCase ( ) ? sourceDef . eclCase ( ) - > caseUserDescription ( ) : " " ;
2017-11-12 16:46:12 -06:00
curveName + = sourceDef . wellLogFile ( ) ? sourceDef . wellLogFile ( ) - > name ( ) : " " ;
2017-11-13 04:10:27 -06:00
if ( sourceDef . sourceType ( ) = = RifDataSourceForRftPlt : : RFT ) curveName + = " , RFT " ;
2017-11-23 08:11:07 -06:00
curveName + = " , " + timeStep . toString ( dateFormatString ) ;
2017-11-12 16:46:12 -06:00
}
2017-11-07 07:40:36 -06:00
2017-12-05 02:45:41 -06:00
RimEclipseResultCase * rimEclipseResultCase = dynamic_cast < RimEclipseResultCase * > ( sourceDef . eclCase ( ) ) ;
2017-11-13 04:10:27 -06:00
if ( sourceDef . sourceType ( ) = = RifDataSourceForRftPlt : : RFT )
2017-11-07 07:40:36 -06:00
{
2017-11-08 09:35:58 -06:00
resultPointCalc . reset ( new RigRftResultPointCalculator ( m_wellPathName ,
2017-12-05 02:45:41 -06:00
rimEclipseResultCase ,
2017-11-08 04:22:16 -06:00
timeStep ) ) ;
2017-11-07 07:40:36 -06:00
}
2017-11-13 04:10:27 -06:00
else if ( sourceDef . sourceType ( ) = = RifDataSourceForRftPlt : : GRID )
2017-11-07 07:40:36 -06:00
{
2017-11-08 09:35:58 -06:00
resultPointCalc . reset ( new RigSimWellResultPointCalculator ( m_wellPathName ,
2017-12-05 02:45:41 -06:00
rimEclipseResultCase ,
2017-11-08 04:22:16 -06:00
timeStep ) ) ;
2017-11-07 07:40:36 -06:00
}
2017-12-05 02:45:41 -06:00
RiaEclipseUnitTools : : UnitSystem unitSet = RiaEclipseUnitTools : : UNITS_UNKNOWN ;
if ( rimEclipseResultCase )
{
unitSet = rimEclipseResultCase - > eclipseCaseData ( ) - > unitsType ( ) ;
}
2017-11-07 07:40:36 -06:00
if ( resultPointCalc ! = nullptr )
2017-11-06 15:23:54 -06:00
{
2017-11-07 07:40:36 -06:00
if ( resultPointCalc - > pipeBranchCLCoords ( ) . size ( ) )
2017-11-06 15:23:54 -06:00
{
2017-12-05 02:45:41 -06:00
2017-11-23 08:11:07 -06:00
if ( selectedPhases . count ( FLOW_PHASE_TOTAL )
& & m_useReservoirConditionCurves ( )
& & sourceDef . sourceType ( ) = = RifDataSourceForRftPlt : : GRID )
{
RigAccWellFlowCalculator wfTotalAccumulator ( resultPointCalc - > pipeBranchCLCoords ( ) ,
resultPointCalc - > pipeBranchWellResultPoints ( ) ,
resultPointCalc - > pipeBranchMeasuredDepths ( ) ,
true ) ;
const std : : vector < double > & depthValues = wfTotalAccumulator . pseudoLengthFromTop ( 0 ) ;
2017-12-05 02:45:41 -06:00
QString curveUnitText = RimWellPlotTools : : flowUnitText ( RimWellLogFile : : WELL_FLOW_COND_RESERVOIR , unitSet ) ;
2017-11-23 08:11:07 -06:00
const std : : vector < double > accFlow = wfTotalAccumulator . accumulatedTracerFlowPrPseudoLength ( RIG_FLOW_TOTAL_NAME , 0 ) ;
2017-12-05 02:45:41 -06:00
addStackedCurve ( curveName + " , " + RIG_FLOW_TOTAL_NAME + " " + curveUnitText ,
2017-11-23 08:11:07 -06:00
depthValues ,
accFlow ,
plotTrack ,
cvf : : Color3f : : DARK_GRAY ,
curveGroupId ,
false ) ;
curveGroupId + + ;
}
if ( m_useStandardConditionCurves ( ) )
2017-11-06 15:23:54 -06:00
{
2017-11-23 08:11:07 -06:00
RigAccWellFlowCalculator wfPhaseAccumulator ( resultPointCalc - > pipeBranchCLCoords ( ) ,
resultPointCalc - > pipeBranchWellResultPoints ( ) ,
resultPointCalc - > pipeBranchMeasuredDepths ( ) ,
false ) ;
const std : : vector < double > & depthValues = wfPhaseAccumulator . pseudoLengthFromTop ( 0 ) ;
std : : vector < QString > tracerNames = wfPhaseAccumulator . tracerNames ( ) ;
for ( const QString & tracerName : tracerNames )
2017-11-08 04:22:16 -06:00
{
2017-11-23 08:11:07 -06:00
auto color = tracerName = = RIG_FLOW_OIL_NAME ? cvf : : Color3f : : DARK_GREEN :
tracerName = = RIG_FLOW_GAS_NAME ? cvf : : Color3f : : DARK_RED :
tracerName = = RIG_FLOW_WATER_NAME ? cvf : : Color3f : : BLUE :
cvf : : Color3f : : DARK_GRAY ;
if ( tracerName = = RIG_FLOW_OIL_NAME & & selectedPhases . count ( FLOW_PHASE_OIL )
| | tracerName = = RIG_FLOW_GAS_NAME & & selectedPhases . count ( FLOW_PHASE_GAS )
| | tracerName = = RIG_FLOW_WATER_NAME & & selectedPhases . count ( FLOW_PHASE_WATER ) )
{
2017-12-05 02:45:41 -06:00
FlowPhase flowPhase = FLOW_PHASE_NONE ;
if ( tracerName = = RIG_FLOW_OIL_NAME ) flowPhase = FLOW_PHASE_OIL ;
else if ( tracerName = = RIG_FLOW_GAS_NAME ) flowPhase = FLOW_PHASE_GAS ;
else if ( tracerName = = RIG_FLOW_WATER_NAME ) flowPhase = FLOW_PHASE_WATER ;
QString curveUnitText = RimWellPlotTools : : curveUnitText ( RimWellLogFile : : WELL_FLOW_COND_STANDARD , unitSet , flowPhase ) ;
2017-11-23 08:11:07 -06:00
const std : : vector < double > accFlow = wfPhaseAccumulator . accumulatedTracerFlowPrPseudoLength ( tracerName , 0 ) ;
2017-12-05 02:45:41 -06:00
addStackedCurve ( curveName + " , " + tracerName + " " + curveUnitText ,
2017-11-23 08:11:07 -06:00
depthValues ,
accFlow ,
plotTrack ,
color ,
curveGroupId ,
false ) ;
}
2017-11-08 04:22:16 -06:00
}
2017-11-06 15:23:54 -06:00
}
}
}
2017-11-13 04:10:27 -06:00
else if ( sourceDef . sourceType ( ) = = RifDataSourceForRftPlt : : OBSERVED )
2017-10-23 06:57:01 -05:00
{
2017-11-08 04:22:16 -06:00
RimWellLogFile * const wellLogFile = sourceDef . wellLogFile ( ) ;
2017-11-23 08:11:07 -06:00
if ( sourceDef . wellLogFile ( ) & & sourceDef . wellLogFile ( ) - > wellLogFileData ( ) )
2017-10-23 06:57:01 -05:00
{
2017-11-23 08:11:07 -06:00
RimWellLogFile : : WellFlowCondition flowCondition = sourceDef . wellLogFile ( ) - > wellFlowRateCondition ( ) ;
2017-10-25 07:43:17 -05:00
2017-11-23 08:11:07 -06:00
if ( ( m_useStandardConditionCurves ( ) & & flowCondition = = RimWellLogFile : : WELL_FLOW_COND_STANDARD )
| | ( m_useReservoirConditionCurves ( ) & & flowCondition = = RimWellLogFile : : WELL_FLOW_COND_RESERVOIR ) )
2017-10-25 07:43:17 -05:00
{
2017-11-23 08:11:07 -06:00
using ChannelValNameIdxTuple = std : : tuple < double , QString , int > ;
RigWellLogFile * wellLogFileData = sourceDef . wellLogFile ( ) - > wellLogFileData ( ) ;
QStringList channelNames = wellLogFileData - > wellLogChannelNames ( ) ;
std : : multiset < ChannelValNameIdxTuple > sortedChannels ;
2017-11-17 13:17:44 -06:00
std : : vector < std : : vector < double > > channelData ;
2017-11-23 08:11:07 -06:00
channelData . resize ( channelNames . size ( ) ) ;
for ( int chIdx = 0 ; chIdx < channelNames . size ( ) ; + + chIdx )
2017-10-25 07:43:17 -05:00
{
2017-11-23 08:11:07 -06:00
QString channelName = channelNames [ chIdx ] ;
2017-11-17 13:17:44 -06:00
channelData [ chIdx ] = wellLogFileData - > values ( channelName ) ;
2017-11-23 08:11:07 -06:00
if ( channelData [ chIdx ] . size ( ) )
2017-11-17 13:17:44 -06:00
{
2017-11-23 08:11:07 -06:00
sortedChannels . insert ( ChannelValNameIdxTuple ( - fabs ( channelData [ chIdx ] . front ( ) ) , channelName , chIdx ) ) ;
2017-11-17 13:17:44 -06:00
}
}
std : : vector < double > depthValues = wellLogFileData - > depthValues ( ) ;
2017-12-05 02:45:41 -06:00
RiaEclipseUnitTools : : UnitSystem unitSystem = RiaEclipseUnitTools : : UNITS_UNKNOWN ;
{
RiaDefines : : DepthUnitType depthUnit = wellLogFileData - > depthUnit ( ) ;
if ( depthUnit = = RiaDefines : : UNIT_FEET ) unitSystem = RiaEclipseUnitTools : : UNITS_FIELD ;
if ( depthUnit = = RiaDefines : : UNIT_METER ) unitSystem = RiaEclipseUnitTools : : UNITS_METRIC ;
}
2017-11-17 13:17:44 -06:00
2017-11-23 08:11:07 -06:00
for ( const ChannelValNameIdxTuple & channelInfo : sortedChannels )
2017-11-17 13:17:44 -06:00
{
const auto & channelName = std : : get < 1 > ( channelInfo ) ;
2017-11-23 08:11:07 -06:00
if ( selectedPhases . count ( RimWellPlotTools : : flowPhaseFromChannelName ( channelName ) ) > 0 )
2017-10-25 07:43:17 -05:00
{
2017-11-23 08:11:07 -06:00
auto color = RimWellPlotTools : : isOilFlowChannel ( channelName ) ? cvf : : Color3f : : DARK_GREEN :
RimWellPlotTools : : isGasFlowChannel ( channelName ) ? cvf : : Color3f : : DARK_RED :
2017-11-17 13:17:44 -06:00
RimWellPlotTools : : isWaterFlowChannel ( channelName ) ? cvf : : Color3f : : BLUE :
cvf : : Color3f : : DARK_GRAY ;
2017-11-08 04:22:16 -06:00
2017-12-05 02:45:41 -06:00
FlowPhase flowPhase = FLOW_PHASE_NONE ;
if ( RimWellPlotTools : : isOilFlowChannel ( channelName ) ) flowPhase = FLOW_PHASE_OIL ;
else if ( RimWellPlotTools : : isGasFlowChannel ( channelName ) ) flowPhase = FLOW_PHASE_GAS ;
else if ( RimWellPlotTools : : isWaterFlowChannel ( channelName ) ) flowPhase = FLOW_PHASE_WATER ;
2017-12-08 04:07:21 -06:00
QString curveUnitText = RimWellPlotTools : : curveUnitText ( flowCondition , unitSystem , flowPhase ) ;
2017-11-23 08:11:07 -06:00
2017-12-08 04:07:21 -06:00
addStackedCurve ( curveName + " , " + channelName + " " + curveUnitText ,
2017-11-23 08:11:07 -06:00
depthValues ,
2017-11-17 13:17:44 -06:00
channelData [ std : : get < 2 > ( channelInfo ) ] ,
2017-11-23 08:11:07 -06:00
plotTrack ,
2017-11-08 04:22:16 -06:00
color ,
2017-11-23 08:11:07 -06:00
curveGroupId ,
2017-11-06 15:23:54 -06:00
true ) ;
2017-11-23 08:11:07 -06:00
// Total flow channel will end up first, so just increment the group
// idx to make the rest of the phases group together
if ( RimWellPlotTools : : isTotalFlowChannel ( channelName ) ) curveGroupId + + ;
2017-10-25 07:43:17 -05:00
}
}
}
2017-10-23 06:57:01 -05:00
}
}
2017-10-27 08:17:24 -05:00
curveGroupId + + ;
2017-10-23 06:57:01 -05:00
}
2017-11-17 08:35:07 -06:00
2017-12-08 02:55:41 -06:00
updateWidgetTitleWindowTitle ( ) ;
2017-11-09 07:14:09 -06:00
m_wellLogPlot - > loadDataAndUpdate ( ) ;
2017-11-17 08:35:07 -06:00
m_wellLogPlot - > updateDepthZoom ( ) ;
plotTrack - > updateXZoom ( ) ;
2017-10-23 06:57:01 -05:00
}
2017-10-25 07:43:17 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-11-08 04:22:16 -06:00
void RimWellPltPlot : : addStackedCurve ( const QString & curveName ,
2017-10-25 07:43:17 -05:00
const std : : vector < double > & depthValues ,
const std : : vector < double > & accFlow ,
2017-10-27 08:17:24 -05:00
RimWellLogTrack * plotTrack ,
2017-11-08 04:22:16 -06:00
cvf : : Color3f color ,
2017-10-27 08:49:00 -05:00
int curveGroupId ,
bool doFillCurve )
2017-10-25 07:43:17 -05:00
{
RimWellFlowRateCurve * curve = new RimWellFlowRateCurve ;
2017-11-08 04:22:16 -06:00
curve - > setFlowValuesPrDepthValue ( curveName , depthValues , accFlow ) ;
2017-10-25 07:43:17 -05:00
2017-10-27 08:17:24 -05:00
curve - > setColor ( color ) ;
curve - > setGroupId ( curveGroupId ) ;
2017-11-08 04:58:14 -06:00
2017-11-17 06:52:29 -06:00
if ( curveGroupId = = 0 )
{
curve - > setDoFillCurve ( true ) ;
curve - > setSymbol ( RimPlotCurve : : SYMBOL_NONE ) ;
}
else
{
curve - > setDoFillCurve ( false ) ;
curve - > setSymbol ( RimSummaryCurveAppearanceCalculator : : cycledSymbol ( curveGroupId ) ) ;
}
2017-10-25 07:43:17 -05:00
2017-11-17 06:52:29 -06:00
curve - > setSymbolSkipDinstance ( 10 ) ;
plotTrack - > addCurve ( curve ) ;
2017-10-25 07:43:17 -05:00
}
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-11-15 09:17:55 -06:00
std : : vector < RifDataSourceForRftPlt > RimWellPltPlot : : selectedSourcesExpanded ( ) const
2017-10-23 06:57:01 -05:00
{
2017-11-13 04:10:27 -06:00
std : : vector < RifDataSourceForRftPlt > sources ;
for ( const RifDataSourceForRftPlt & addr : m_selectedSources ( ) )
2017-10-23 06:57:01 -05:00
{
2017-11-13 04:10:27 -06:00
if ( addr . sourceType ( ) = = RifDataSourceForRftPlt : : OBSERVED )
2017-10-23 06:57:01 -05:00
{
2017-11-09 03:03:32 -06:00
for ( RimWellLogFile * const wellLogFile : RimWellPlotTools : : wellLogFilesContainingFlow ( m_wellPathName ) )
2017-10-23 06:57:01 -05:00
{
2017-11-13 04:10:27 -06:00
sources . push_back ( RifDataSourceForRftPlt ( RifDataSourceForRftPlt : : OBSERVED , wellLogFile ) ) ;
2017-10-23 06:57:01 -05:00
}
}
else
sources . push_back ( addr ) ;
}
return sources ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget * RimWellPltPlot : : viewWidget ( )
{
return m_wellLogPlotWidget ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : zoomAll ( )
{
m_wellLogPlot ( ) - > zoomAll ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogPlot * RimWellPltPlot : : wellLogPlot ( ) const
{
return m_wellLogPlot ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : setCurrentWellName ( const QString & currWellName )
{
2017-11-08 09:35:58 -06:00
m_wellPathName = currWellName ;
2017-10-23 06:57:01 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPltPlot : : currentWellName ( ) const
{
2017-11-08 09:35:58 -06:00
return m_wellPathName ;
2017-10-23 06:57:01 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const char * RimWellPltPlot : : plotNameFormatString ( )
{
return PLOT_NAME_QFORMAT_STRING ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf : : PdmOptionItemInfo > RimWellPltPlot : : calculateValueOptions ( const caf : : PdmFieldHandle * fieldNeedingOptions , bool * useOptionsOnly )
{
QList < caf : : PdmOptionItemInfo > options ;
2017-11-09 03:03:32 -06:00
const QString simWellName = RimWellPlotTools : : simWellName ( m_wellPathName ) ;
2017-10-23 06:57:01 -05:00
2017-11-08 09:35:58 -06:00
if ( fieldNeedingOptions = = & m_wellPathName )
2017-10-23 06:57:01 -05:00
{
calculateValueOptionsForWells ( options ) ;
}
else if ( fieldNeedingOptions = = & m_selectedSources )
{
2017-11-13 04:10:27 -06:00
std : : set < RifDataSourceForRftPlt > optionAddresses ;
2017-10-31 09:41:28 -05:00
2017-11-09 03:03:32 -06:00
const std : : vector < RimEclipseResultCase * > rftCases = RimWellPlotTools : : rftCasesForWell ( simWellName ) ;
2017-11-15 09:17:55 -06:00
std : : set < RifDataSourceForRftPlt > availableRftSources ;
for ( const auto & rftCase : rftCases )
2017-11-07 07:40:36 -06:00
{
2017-11-15 09:17:55 -06:00
std : : set < QDateTime > rftTimes = rftCase - > rftReader ( ) - > availableTimeSteps ( simWellName , { RifEclipseRftAddress : : ORAT ,
RifEclipseRftAddress : : WRAT ,
RifEclipseRftAddress : : GRAT } ) ;
if ( rftTimes . size ( ) )
{
availableRftSources . insert ( RifDataSourceForRftPlt ( RifDataSourceForRftPlt : : RFT , rftCase ) ) ;
}
2017-11-07 07:40:36 -06:00
}
2017-11-15 09:17:55 -06:00
if ( availableRftSources . size ( ) )
2017-11-07 07:40:36 -06:00
{
2017-11-15 09:17:55 -06:00
options . push_back ( caf : : PdmOptionItemInfo : : createHeader ( RifDataSourceForRftPlt : : sourceTypeUiText ( RifDataSourceForRftPlt : : RFT ) , true ) ) ;
for ( const auto & addr : availableRftSources )
{
auto item = caf : : PdmOptionItemInfo ( addr . eclCase ( ) - > caseUserDescription ( ) , QVariant : : fromValue ( addr ) ) ;
item . setLevel ( 1 ) ;
options . push_back ( item ) ;
}
2017-11-07 07:40:36 -06:00
}
2017-11-09 03:03:32 -06:00
const std : : vector < RimEclipseResultCase * > gridCases = RimWellPlotTools : : gridCasesForWell ( simWellName ) ;
2017-11-07 07:40:36 -06:00
if ( gridCases . size ( ) > 0 )
{
2017-11-13 04:10:27 -06:00
options . push_back ( caf : : PdmOptionItemInfo : : createHeader ( RifDataSourceForRftPlt : : sourceTypeUiText ( RifDataSourceForRftPlt : : GRID ) , true ) ) ;
2017-11-07 07:40:36 -06:00
}
for ( const auto & gridCase : gridCases )
{
2017-11-13 04:10:27 -06:00
auto addr = RifDataSourceForRftPlt ( RifDataSourceForRftPlt : : GRID , gridCase ) ;
2017-11-07 07:40:36 -06:00
auto item = caf : : PdmOptionItemInfo ( gridCase - > caseUserDescription ( ) , QVariant : : fromValue ( addr ) ) ;
item . setLevel ( 1 ) ;
options . push_back ( item ) ;
}
2017-10-25 07:43:17 -05:00
2017-11-09 03:03:32 -06:00
if ( RimWellPlotTools : : wellLogFilesContainingFlow ( m_wellPathName ) . size ( ) > 0 )
2017-10-23 06:57:01 -05:00
{
2017-11-13 04:10:27 -06:00
options . push_back ( caf : : PdmOptionItemInfo : : createHeader ( RifDataSourceForRftPlt : : sourceTypeUiText ( RifDataSourceForRftPlt : : OBSERVED ) , true ) ) ;
2017-10-23 06:57:01 -05:00
2017-11-13 04:10:27 -06:00
auto addr = RifDataSourceForRftPlt ( RifDataSourceForRftPlt : : OBSERVED ) ;
2017-10-23 06:57:01 -05:00
auto item = caf : : PdmOptionItemInfo ( " Observed Data " , QVariant : : fromValue ( addr ) ) ;
item . setLevel ( 1 ) ;
options . push_back ( item ) ;
2017-10-31 09:41:28 -05:00
optionAddresses . insert ( addr ) ;
2017-10-23 06:57:01 -05:00
}
}
else if ( fieldNeedingOptions = = & m_selectedTimeSteps )
{
2017-11-16 09:35:55 -06:00
RimWellPlotTools : : calculateValueOptionsForTimeSteps ( RimWellPlotTools : : simWellName ( m_wellPathName ) ,
selectedSourcesExpanded ( ) ,
{ RifEclipseRftAddress : : ORAT ,
RifEclipseRftAddress : : WRAT ,
RifEclipseRftAddress : : GRAT } ,
options ) ;
2017-10-23 06:57:01 -05:00
}
2017-11-23 08:11:07 -06:00
if ( fieldNeedingOptions = = & m_phases )
2017-10-25 07:43:17 -05:00
{
2017-11-09 03:03:32 -06:00
options . push_back ( caf : : PdmOptionItemInfo ( " Oil " , FLOW_PHASE_OIL ) ) ;
options . push_back ( caf : : PdmOptionItemInfo ( " Gas " , FLOW_PHASE_GAS ) ) ;
options . push_back ( caf : : PdmOptionItemInfo ( " Water " , FLOW_PHASE_WATER ) ) ;
2017-11-23 08:11:07 -06:00
options . push_back ( caf : : PdmOptionItemInfo ( " Total " , FLOW_PHASE_TOTAL ) ) ;
2017-10-25 07:43:17 -05:00
}
2017-10-23 06:57:01 -05:00
return options ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : fieldChangedByUi ( const caf : : PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
RimViewWindow : : fieldChangedByUi ( changedField , oldValue , newValue ) ;
2017-11-08 09:35:58 -06:00
if ( changedField = = & m_wellPathName )
2017-10-23 06:57:01 -05:00
{
2017-11-08 09:35:58 -06:00
setDescription ( QString ( plotNameFormatString ( ) ) . arg ( m_wellPathName ) ) ;
2017-10-23 06:57:01 -05:00
}
2017-11-09 06:36:14 -06:00
if ( changedField = = & m_wellPathName )
2017-10-23 06:57:01 -05:00
{
RimWellLogTrack * const plotTrack = m_wellLogPlot - > trackByIndex ( 0 ) ;
2017-11-15 04:31:35 -06:00
plotTrack - > deleteAllCurves ( ) ;
m_selectedSources . v ( ) . clear ( ) ;
m_selectedTimeSteps . v ( ) . clear ( ) ;
2017-11-12 14:22:12 -06:00
updateFormationsOnPlot ( ) ;
2017-10-23 06:57:01 -05:00
}
else if ( changedField = = & m_selectedSources )
{
2017-12-14 05:53:50 -06:00
RimProject * project = RiaApplication : : instance ( ) - > project ( ) ;
RimWellPath * wellPath = project - > wellPathByName ( m_wellPathName ( ) ) ;
if ( wellPath & & ! wellPath - > wellPathGeometry ( ) )
{
for ( RifDataSourceForRftPlt address : m_selectedSources ( ) )
{
if ( address . sourceType ( ) = = RifDataSourceForRftPlt : : RFT | | address . sourceType ( ) = = RifDataSourceForRftPlt : : GRID )
{
if ( ! wellPath - > wellPathGeometry ( ) )
{
QString tmp = QString ( " Display of Measured Depth (MD) for Grid or RFT curves is not possible without a well log path, and the curve will be hidden in this mode. \n \n " ) ;
QMessageBox : : warning ( nullptr , " Grid/RFT curve without MD " , tmp ) ;
// Do not show multiple dialogs
break ;
}
}
}
}
2017-10-23 06:57:01 -05:00
}
if ( changedField = = & m_selectedSources | |
changedField = = & m_selectedTimeSteps )
{
2017-11-12 14:22:12 -06:00
updateFormationsOnPlot ( ) ;
2017-10-31 09:41:28 -05:00
syncSourcesIoFieldFromGuiField ( ) ;
2017-10-23 06:57:01 -05:00
syncCurvesFromUiSelection ( ) ;
}
2017-10-25 07:43:17 -05:00
2017-11-23 08:11:07 -06:00
if ( changedField = = & m_useStandardConditionCurves
| | changedField = = & m_useReservoirConditionCurves
| | changedField = = & m_phases )
2017-10-25 07:43:17 -05:00
{
syncCurvesFromUiSelection ( ) ;
}
2017-10-23 06:57:01 -05:00
}
2017-11-13 03:21:24 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : defineUiTreeOrdering ( caf : : PdmUiTreeOrdering & uiTreeOrdering , QString uiConfigName )
{
uiTreeOrdering . skipRemainingChildren ( true ) ;
}
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QImage RimWellPltPlot : : snapshotWindowContent ( )
{
QImage image ;
if ( m_wellLogPlotWidget )
{
QPixmap pix = QPixmap : : grabWidget ( m_wellLogPlotWidget ) ;
image = pix . toImage ( ) ;
}
return image ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : defineUiOrdering ( QString uiConfigName , caf : : PdmUiOrdering & uiOrdering )
{
2017-11-09 03:03:32 -06:00
const QString simWellName = RimWellPlotTools : : simWellName ( m_wellPathName ) ;
2017-10-23 06:57:01 -05:00
uiOrdering . add ( & m_userName ) ;
2017-11-08 09:35:58 -06:00
uiOrdering . add ( & m_wellPathName ) ;
2017-10-23 06:57:01 -05:00
caf : : PdmUiGroup * sourcesGroup = uiOrdering . addNewGroupWithKeyword ( " Sources " , " Sources " ) ;
sourcesGroup - > add ( & m_selectedSources ) ;
caf : : PdmUiGroup * timeStepsGroup = uiOrdering . addNewGroupWithKeyword ( " Time Steps " , " TimeSteps " ) ;
timeStepsGroup - > add ( & m_selectedTimeSteps ) ;
2017-11-23 08:11:07 -06:00
caf : : PdmUiGroup * flowGroup = uiOrdering . addNewGroupWithKeyword ( " Curve Selection " , " PhaseSelection " ) ;
flowGroup - > add ( & m_useStandardConditionCurves ) ;
flowGroup - > add ( & m_useReservoirConditionCurves ) ;
2017-10-25 07:43:17 -05:00
2017-11-23 08:11:07 -06:00
flowGroup - > add ( & m_phases ) ;
2017-10-23 06:57:01 -05:00
2017-11-06 09:07:29 -06:00
if ( m_wellLogPlot & & m_wellLogPlot - > trackCount ( ) > 0 )
{
RimWellLogTrack * track = m_wellLogPlot - > trackByIndex ( 0 ) ;
2017-12-11 05:59:03 -06:00
track - > uiOrderingForFormations ( uiOrdering ) ;
2017-11-06 09:07:29 -06:00
caf : : PdmUiGroup * legendAndAxisGroup = uiOrdering . addNewGroup ( " Legend and Axis " ) ;
legendAndAxisGroup - > setCollapsedByDefault ( true ) ;
m_wellLogPlot - > uiOrderingForPlot ( * legendAndAxisGroup ) ;
track - > uiOrderingForVisibleXRange ( * legendAndAxisGroup ) ;
m_wellLogPlot - > uiOrderingForVisibleDepthRange ( * legendAndAxisGroup ) ;
}
2017-10-23 06:57:01 -05:00
uiOrdering . skipRemainingFields ( true ) ;
}
2017-10-25 07:43:17 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : defineEditorAttribute ( const caf : : PdmFieldHandle * field , QString uiConfigName , caf : : PdmUiEditorAttribute * attribute )
{
if ( field = = & m_phases )
{
caf : : PdmUiTreeSelectionEditorAttribute * attrib = dynamic_cast < caf : : PdmUiTreeSelectionEditorAttribute * > ( attribute ) ;
attrib - > showTextFilter = false ;
attrib - > showToggleAllCheckbox = false ;
}
}
2017-10-27 02:38:24 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : initAfterRead ( )
{
RimViewWindow : : initAfterRead ( ) ;
// Postpone init until data has been loaded
m_doInitAfterLoad = true ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : setupBeforeSave ( )
{
2017-11-15 05:40:04 -06:00
syncSourcesIoFieldFromGuiField ( ) ;
2017-10-27 02:38:24 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : initAfterLoad ( )
{
2017-11-15 05:40:04 -06:00
std : : vector < RifDataSourceForRftPlt > selectedSources ;
2017-11-13 04:16:36 -06:00
for ( RimDataSourceForRftPlt * addr : m_selectedSourcesForIo )
2017-10-27 02:38:24 -05:00
{
2017-11-15 05:40:04 -06:00
selectedSources . push_back ( addr - > address ( ) ) ;
2017-10-27 02:38:24 -05:00
}
2017-11-15 05:40:04 -06:00
m_selectedSources = selectedSources ;
2017-10-27 02:38:24 -05:00
}
2017-10-31 09:41:28 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : syncSourcesIoFieldFromGuiField ( )
{
m_selectedSourcesForIo . clear ( ) ;
2017-11-15 05:40:04 -06:00
for ( const RifDataSourceForRftPlt & addr : m_selectedSources ( ) )
2017-10-31 09:41:28 -05:00
{
2017-11-13 04:16:36 -06:00
m_selectedSourcesForIo . push_back ( new RimDataSourceForRftPlt ( addr ) ) ;
2017-10-31 09:41:28 -05:00
}
}
2017-10-23 06:57:01 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : calculateValueOptionsForWells ( QList < caf : : PdmOptionItemInfo > & options )
{
RimProject * proj = RiaApplication : : instance ( ) - > project ( ) ;
if ( proj ! = nullptr )
{
// Observed wells
2017-11-08 09:35:58 -06:00
for ( const RimWellPath * const wellPath : proj - > allWellPaths ( ) )
2017-10-23 06:57:01 -05:00
{
2017-12-14 04:22:44 -06:00
const QString wellName = wellPath - > name ( ) ;
2017-10-23 06:57:01 -05:00
2017-12-14 04:22:44 -06:00
if ( wellPath - > wellPathGeometry ( ) | | RimWellPlotTools : : hasFlowData ( wellPath ) )
options . push_back ( caf : : PdmOptionItemInfo ( wellName , wellName ) ) ;
2017-10-23 06:57:01 -05:00
}
}
2017-11-06 07:20:43 -06:00
2017-11-15 09:17:55 -06:00
options . push_back ( caf : : PdmOptionItemInfo ( " None " , " " ) ) ;
2017-10-23 06:57:01 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPltPlot : : setDescription ( const QString & description )
{
m_userName = description ;
updateWidgetTitleWindowTitle ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPltPlot : : description ( ) const
{
return m_userName ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-31 06:49:14 -05:00
void RimWellPltPlot : : onLoadDataAndUpdate ( )
2017-10-23 06:57:01 -05:00
{
2017-10-27 02:38:24 -05:00
if ( m_doInitAfterLoad )
{
initAfterLoad ( ) ;
m_doInitAfterLoad = false ;
}
2017-11-13 01:56:22 -06:00
if ( m_isOnLoad )
{
if ( m_wellLogPlot - > trackCount ( ) > 0 )
{
m_wellLogPlot - > trackByIndex ( 0 ) - > setShowFormations ( true ) ;
}
m_isOnLoad = false ;
}
2017-10-23 06:57:01 -05:00
updateMdiWindowVisibility ( ) ;
2017-11-12 14:22:12 -06:00
updateFormationsOnPlot ( ) ;
2017-10-27 02:38:24 -05:00
syncCurvesFromUiSelection ( ) ;
2017-10-23 06:57:01 -05:00
m_wellLogPlot - > loadDataAndUpdate ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QWidget * RimWellPltPlot : : createViewWidget ( QWidget * mainWindowParent )
{
m_wellLogPlotWidget = new RiuWellPltPlot ( this , mainWindowParent ) ;
return m_wellLogPlotWidget ;
}