2017-10-05 09:29:19 +02: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 "RimWellLogRftCurve.h"
2017-10-12 13:37:03 +02:00
#include "RiaApplication.h"
2017-10-05 10:49:26 +02:00
#include "RiaEclipseUnitTools.h"
2017-10-05 09:29:19 +02:00
#include "RimEclipseResultCase.h"
2017-10-12 13:37:03 +02:00
#include "RimMainPlotCollection.h"
#include "RimProject.h"
2017-10-05 09:29:19 +02:00
#include "RimTools.h"
2017-10-05 10:49:26 +02:00
#include "RimWellLogPlot.h"
2017-10-12 13:37:03 +02:00
#include "RimWellLogPlotCollection.h"
2017-11-02 12:30:17 +01:00
#include "RimWellLogTrack.h"
2017-10-12 13:37:03 +02:00
#include "RimWellPath.h"
2017-10-05 10:49:26 +02:00
#include "RigEclipseCaseData.h"
2017-10-12 13:37:03 +02:00
#include "RigEclipseWellLogExtractor.h"
#include "RigMainGrid.h"
2017-10-05 10:49:26 +02:00
#include "RigWellLogCurveData.h"
2017-10-12 13:37:03 +02:00
#include "RigWellPath.h"
#include "RigWellPathIntersectionTools.h"
2017-10-05 10:49:26 +02:00
#include "RiuLineSegmentQwtPlotCurve.h"
2017-11-02 12:30:17 +01:00
#include "RiuWellLogTrack.h"
2017-10-05 09:29:19 +02:00
2017-10-06 13:35:49 +02:00
#include "RifEclipseRftAddress.h"
2017-10-12 13:37:03 +02:00
#include "RifReaderEclipseRft.h"
2017-10-05 09:29:19 +02:00
#include "cafPdmObject.h"
2017-10-12 13:37:03 +02:00
#include "cafVecIjk.h"
2017-10-05 09:29:19 +02:00
#include "cvfAssert.h"
2017-10-06 09:32:27 +02:00
#include <qwt_plot.h>
2017-10-05 13:49:49 +02:00
#include <QString>
2017-10-12 13:37:03 +02:00
#include <numeric>
#include <vector>
2017-10-06 13:35:49 +02:00
namespace caf
{
template <>
2017-11-13 15:17:49 +01:00
void caf :: AppEnum < RifEclipseRftAddress :: RftWellLogChannelType >:: setUp ()
2017-10-06 13:35:49 +02:00
{
addItem ( RifEclipseRftAddress :: NONE , "NONE" , "None" );
addItem ( RifEclipseRftAddress :: DEPTH , "DEPTH" , "Depth" );
addItem ( RifEclipseRftAddress :: PRESSURE , "PRESSURE" , "Pressure" );
addItem ( RifEclipseRftAddress :: SWAT , "SWAT" , "Water Saturation" );
addItem ( RifEclipseRftAddress :: SOIL , "SOIL" , "Oil Saturation" );
addItem ( RifEclipseRftAddress :: SGAS , "SGAS" , "Gas Saturation" );
addItem ( RifEclipseRftAddress :: WRAT , "WRAT" , "Water Flow" );
addItem ( RifEclipseRftAddress :: ORAT , "ORAT" , "Oil Flow" );
addItem ( RifEclipseRftAddress :: GRAT , "GRAT" , "Gas flow" );
setDefault ( RifEclipseRftAddress :: NONE );
}
}
2017-10-05 09:29:19 +02:00
CAF_PDM_SOURCE_INIT ( RimWellLogRftCurve , "WellLogRftCurve" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogRftCurve :: RimWellLogRftCurve ()
{
CAF_PDM_InitObject ( "Well Log RFT Curve" , "" , "" , "" );
CAF_PDM_InitFieldNoDefault ( & m_eclipseResultCase , "CurveEclipseResultCase" , "Eclipse Result Case" , "" , "" , "" );
m_eclipseResultCase . uiCapability () -> setUiTreeChildrenHidden ( true );
CAF_PDM_InitFieldNoDefault ( & m_timeStep , "TimeStep" , "Time Step" , "" , "" , "" );
CAF_PDM_InitFieldNoDefault ( & m_wellName , "WellName" , "Well Name" , "" , "" , "" );
2017-10-06 13:35:49 +02:00
2017-10-05 09:29:19 +02:00
CAF_PDM_InitFieldNoDefault ( & m_wellLogChannelName , "WellLogChannelName" , "Well Property" , "" , "" , "" );
2017-11-02 12:30:17 +01:00
m_isUsingPseudoLength = false ;
2017-10-05 09:29:19 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogRftCurve ::~ RimWellLogRftCurve ()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellLogRftCurve :: wellName () const
{
return m_wellName ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellLogRftCurve :: wellLogChannelName () const
{
2017-10-06 13:35:49 +02:00
return m_wellLogChannelName (). text ();
2017-10-05 09:29:19 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-05 13:49:49 +02:00
void RimWellLogRftCurve :: setEclipseResultCase ( RimEclipseResultCase * eclipseResultCase )
2017-10-05 09:29:19 +02:00
{
2017-10-05 13:49:49 +02:00
m_eclipseResultCase = eclipseResultCase ;
2017-10-05 09:29:19 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-05 13:49:49 +02:00
RimEclipseResultCase * RimWellLogRftCurve :: eclipseResultCase () const
2017-10-05 09:29:19 +02:00
{
2017-10-05 13:49:49 +02:00
return m_eclipseResultCase ;
2017-10-05 09:29:19 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-05 13:49:49 +02:00
void RimWellLogRftCurve :: setRftAddress ( RifEclipseRftAddress address )
2017-10-05 09:29:19 +02:00
{
2017-10-05 13:49:49 +02:00
m_timeStep = address . timeStep ();
m_wellName = address . wellName ();
2017-11-13 15:17:49 +01:00
m_wellLogChannelName = address . wellLogChannel ();
2017-10-05 09:29:19 +02:00
}
//--------------------------------------------------------------------------------------------------
2017-10-06 14:20:01 +02:00
///
//--------------------------------------------------------------------------------------------------
RifEclipseRftAddress RimWellLogRftCurve :: rftAddress () const
{
return RifEclipseRftAddress ( m_wellName , m_timeStep , m_wellLogChannelName ());
}
2017-10-09 12:03:18 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogRftCurve :: setDefaultAddress ( QString wellName )
{
RifReaderEclipseRft * reader = rftReader ();
if ( ! reader ) return ;
bool wellNameHasRftData = false ;
std :: set < QString > wellNames = reader -> wellNames ();
for ( const QString & wellNameWithRft : wellNames )
{
if ( wellName == wellNameWithRft )
{
wellNameHasRftData = true ;
m_wellName = wellName ;
break ;
}
}
2017-11-01 11:47:47 +01:00
if ( ! wellNameHasRftData )
{
m_wellLogChannelName = RifEclipseRftAddress :: NONE ;
m_timeStep = QDateTime ();
return ;
}
2017-10-09 12:03:18 +02:00
m_wellLogChannelName = RifEclipseRftAddress :: PRESSURE ;
std :: vector < QDateTime > timeSteps = reader -> availableTimeSteps ( m_wellName , m_wellLogChannelName ());
if ( timeSteps . size () > 0 )
{
m_timeStep = timeSteps [ 0 ];
}
2017-10-27 12:15:48 +02:00
else
{
m_timeStep = QDateTime ();
}
2017-10-09 12:03:18 +02:00
}
2017-10-10 08:46:12 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogRftCurve :: updateWellChannelNameAndTimeStep ()
{
if ( ! m_timeStep (). isValid () || m_wellLogChannelName () == RifEclipseRftAddress :: NONE )
{
setDefaultAddress ( m_wellName );
return ;
}
RifReaderEclipseRft * reader = rftReader ();
if ( ! reader ) return ;
2017-11-13 15:17:49 +01:00
std :: vector < RifEclipseRftAddress :: RftWellLogChannelType > channelNames = reader -> availableWellLogChannels ( m_wellName );
2017-10-10 08:46:12 +02:00
2017-10-31 15:06:17 +01:00
if ( channelNames . empty ())
2017-10-10 08:46:12 +02:00
{
2017-10-31 15:06:17 +01:00
m_wellLogChannelName = RifEclipseRftAddress :: NONE ;
2017-10-10 08:46:12 +02:00
}
2017-10-31 15:06:17 +01:00
else if ( std :: find ( channelNames . begin (), channelNames . end (), m_wellLogChannelName ()) == channelNames . end ())
2017-10-10 08:46:12 +02:00
{
2017-10-31 15:06:17 +01:00
m_wellLogChannelName = RifEclipseRftAddress :: PRESSURE ;
2017-10-10 08:46:12 +02:00
}
2017-10-31 15:06:17 +01:00
std :: vector < QDateTime > timeSteps = reader -> availableTimeSteps ( m_wellName , m_wellLogChannelName ());
2017-10-10 08:46:12 +02:00
2017-10-31 15:06:17 +01:00
if ( timeSteps . empty ())
2017-10-10 08:46:12 +02:00
{
2017-10-31 15:06:17 +01:00
m_timeStep = QDateTime ();
2017-10-10 08:46:12 +02:00
}
2017-10-31 15:06:17 +01:00
else if ( std :: find ( timeSteps . begin (), timeSteps . end (), m_timeStep ()) == timeSteps . end ())
2017-10-10 08:46:12 +02:00
{
2017-10-31 15:06:17 +01:00
m_timeStep = timeSteps [ 0 ];
2017-10-10 08:46:12 +02:00
}
}
2017-10-06 14:20:01 +02:00
//--------------------------------------------------------------------------------------------------
2017-10-05 09:29:19 +02:00
///
//--------------------------------------------------------------------------------------------------
QString RimWellLogRftCurve :: createCurveAutoName ()
{
2017-11-01 14:34:47 +01:00
QStringList name ;
2017-11-01 16:19:18 +01:00
if ( ! wellName (). isEmpty ())
2017-10-06 14:38:20 +02:00
{
2017-11-01 14:34:47 +01:00
name . push_back ( wellName ());
2017-10-06 14:38:20 +02:00
}
2017-11-01 16:19:18 +01:00
name . push_back ( "RFT" );
2017-11-01 14:34:47 +01:00
if ( m_eclipseResultCase )
2017-10-06 14:38:20 +02:00
{
2017-11-01 14:34:47 +01:00
name . push_back ( m_eclipseResultCase -> caseName ());
2017-10-06 14:38:20 +02:00
}
2017-11-13 15:17:49 +01:00
if ( wellLogChannelName () != caf :: AppEnum < RifEclipseRftAddress :: RftWellLogChannelType >:: text ( RifEclipseRftAddress :: NONE ))
2017-10-06 14:38:20 +02:00
{
2017-11-13 15:17:49 +01:00
RifEclipseRftAddress :: RftWellLogChannelType channelNameEnum = caf :: AppEnum < RifEclipseRftAddress :: RftWellLogChannelType >:: fromText ( wellLogChannelName ());
name . push_back ( caf :: AppEnum < RifEclipseRftAddress :: RftWellLogChannelType >:: uiText ( channelNameEnum ));
2017-10-06 14:38:20 +02:00
}
if ( ! m_timeStep (). isNull ())
{
2017-11-01 14:34:47 +01:00
name . push_back ( m_timeStep (). toString ( RimTools :: dateFormatString ()));
2017-10-06 14:38:20 +02:00
}
2017-11-01 14:34:47 +01:00
return name . join ( ", " );
2017-10-05 09:29:19 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogRftCurve :: onLoadDataAndUpdate ( bool updateParentPlot )
{
2017-11-11 23:15:13 +01:00
this -> RimPlotCurve :: updateCurvePresentation ( updateParentPlot );
2017-10-05 10:49:26 +02:00
2017-11-02 12:30:17 +01:00
m_isUsingPseudoLength = false ;
2017-10-05 10:49:26 +02:00
if ( isCurveVisible ())
{
m_curveData = new RigWellLogCurveData ;
RimWellLogPlot * wellLogPlot ;
firstAncestorOrThisOfType ( wellLogPlot );
CVF_ASSERT ( wellLogPlot );
2017-10-12 13:37:03 +02:00
std :: vector < double > measuredDepthVector = measuredDepthValues ();
2017-10-31 15:06:17 +01:00
std :: vector < double > tvDepthVector = tvDepthValues ();
std :: vector < double > values = xValues ();
2017-10-05 21:25:45 +02:00
2017-11-01 13:58:46 +01:00
if ( values . empty () ||
values . size () != tvDepthVector . size () ||
values . size () != measuredDepthVector . size ())
{
this -> detachQwtCurve ();
return ;
}
2017-10-12 13:37:03 +02:00
m_curveData -> setValuesWithTVD ( values , measuredDepthVector , tvDepthVector , RiaEclipseUnitTools :: depthUnit ( m_eclipseResultCase -> eclipseCaseData () -> unitsType ()), false );
2017-10-05 10:49:26 +02:00
RiaDefines :: DepthUnitType displayUnit = RiaDefines :: UNIT_METER ;
if ( wellLogPlot )
{
displayUnit = wellLogPlot -> depthUnit ();
}
2017-10-12 13:37:03 +02:00
if ( wellLogPlot -> depthType () == RimWellLogPlot :: MEASURED_DEPTH )
{
m_qwtPlotCurve -> setSamples ( m_curveData -> xPlotValues (). data (), m_curveData -> measuredDepthPlotValues ( displayUnit ). data (), static_cast < int > ( m_curveData -> xPlotValues (). size ()));
}
else
{
m_qwtPlotCurve -> setSamples ( m_curveData -> xPlotValues (). data (), m_curveData -> trueDepthPlotValues ( displayUnit ). data (), static_cast < int > ( m_curveData -> xPlotValues (). size ()));
2017-11-02 12:30:17 +01:00
m_isUsingPseudoLength = false ;
}
if ( m_isUsingPseudoLength )
{
RimWellLogTrack * wellLogTrack ;
firstAncestorOrThisOfType ( wellLogTrack );
CVF_ASSERT ( wellLogTrack );
RiuWellLogTrack * viewer = wellLogTrack -> viewer ();
if ( viewer )
{
viewer -> setDepthTitle ( "PL/" + wellLogPlot -> depthPlotTitle ());
}
2017-10-12 13:37:03 +02:00
}
2017-10-05 10:49:26 +02:00
m_qwtPlotCurve -> setLineSegmentStartStopIndices ( m_curveData -> polylineStartStopIndices ());
2017-10-05 09:29:19 +02:00
2017-11-11 23:15:13 +01:00
if ( updateParentPlot && m_parentQwtPlot )
{
updateZoomInParentPlot ();
m_parentQwtPlot -> replot ();
}
2017-10-05 10:49:26 +02:00
}
2017-10-05 09:29:19 +02:00
}
2017-10-05 13:49:49 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogRftCurve :: defineUiOrdering ( QString uiConfigName , caf :: PdmUiOrdering & uiOrdering )
{
RimPlotCurve :: updateOptionSensitivity ();
caf :: PdmUiGroup * curveDataGroup = uiOrdering . addNewGroup ( "Curve Data" );
2017-10-05 21:25:45 +02:00
curveDataGroup -> add ( & m_eclipseResultCase );
2017-10-05 13:49:49 +02:00
curveDataGroup -> add ( & m_wellName );
curveDataGroup -> add ( & m_wellLogChannelName );
curveDataGroup -> add ( & m_timeStep );
caf :: PdmUiGroup * appearanceGroup = uiOrdering . addNewGroup ( "Appearance" );
RimPlotCurve :: appearanceUiOrdering ( * appearanceGroup );
caf :: PdmUiGroup * nameGroup = uiOrdering . addNewGroup ( "Curve Name" );
nameGroup -> add ( & m_showLegend );
RimPlotCurve :: curveNameUiOrdering ( * nameGroup );
}
2017-10-05 09:29:19 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList < caf :: PdmOptionItemInfo > RimWellLogRftCurve :: calculateValueOptions ( const caf :: PdmFieldHandle * fieldNeedingOptions , bool * useOptionsOnly )
{
QList < caf :: PdmOptionItemInfo > options ;
options = RimWellLogCurve :: calculateValueOptions ( fieldNeedingOptions , useOptionsOnly );
if ( options . size () > 0 ) return options ;
if ( fieldNeedingOptions == & m_eclipseResultCase )
{
RimTools :: caseOptionItems ( & options );
options . push_front ( caf :: PdmOptionItemInfo ( "None" , nullptr ));
}
2017-10-05 21:25:45 +02:00
else if ( fieldNeedingOptions == & m_wellName )
2017-10-05 13:49:49 +02:00
{
2017-10-06 09:32:27 +02:00
options . push_back ( caf :: PdmOptionItemInfo ( "None" , "" ));
2017-10-05 21:25:45 +02:00
RifReaderEclipseRft * reader = rftReader ();
if ( reader )
{
std :: set < QString > wellNames = reader -> wellNames ();
for ( const QString & name : wellNames )
{
options . push_back ( caf :: PdmOptionItemInfo ( name , name , false , QIcon ( ":/Well.png" )));
}
}
}
else if ( fieldNeedingOptions == & m_wellLogChannelName )
{
2017-10-06 13:35:49 +02:00
RifReaderEclipseRft * reader = rftReader ();
if ( reader )
2017-10-05 21:25:45 +02:00
{
2017-11-13 15:17:49 +01:00
for ( const RifEclipseRftAddress :: RftWellLogChannelType & channelName : reader -> availableWellLogChannels ( m_wellName ))
2017-10-06 13:35:49 +02:00
{
2017-11-13 15:17:49 +01:00
options . push_back ( caf :: PdmOptionItemInfo ( caf :: AppEnum < RifEclipseRftAddress :: RftWellLogChannelType >:: uiText ( channelName ), channelName ));
2017-10-06 13:35:49 +02:00
}
2017-10-05 21:25:45 +02:00
}
2017-10-27 16:00:47 +02:00
if ( options . empty ())
{
2017-11-13 15:17:49 +01:00
options . push_back ( caf :: PdmOptionItemInfo ( caf :: AppEnum < RifEclipseRftAddress :: RftWellLogChannelType >:: uiText ( RifEclipseRftAddress :: NONE ), RifEclipseRftAddress :: NONE ));
2017-10-27 16:00:47 +02:00
}
2017-10-05 13:49:49 +02:00
}
2017-10-05 21:25:45 +02:00
else if ( fieldNeedingOptions == & m_timeStep )
2017-10-05 13:49:49 +02:00
{
2017-10-05 21:25:45 +02:00
RifReaderEclipseRft * reader = rftReader ();
if ( reader )
{
2017-10-06 14:38:20 +02:00
QString dateFormat = "dd MMM yyyy" ;
2017-10-06 13:35:49 +02:00
std :: vector < QDateTime > timeStamps = reader -> availableTimeSteps ( m_wellName , m_wellLogChannelName ());
2017-10-05 21:25:45 +02:00
for ( const QDateTime & dt : timeStamps )
{
2017-10-06 14:38:20 +02:00
options . push_back ( caf :: PdmOptionItemInfo ( dt . toString ( dateFormat ), dt ));
2017-10-05 21:25:45 +02:00
}
}
2017-10-05 13:49:49 +02:00
2017-10-06 09:32:27 +02:00
options . push_back ( caf :: PdmOptionItemInfo ( "None" , QDateTime ()));
2017-10-05 13:49:49 +02:00
}
2017-10-05 09:29:19 +02:00
return options ;
}
2017-10-05 11:08:30 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellLogRftCurve :: fieldChangedByUi ( const caf :: PdmFieldHandle * changedField , const QVariant & oldValue , const QVariant & newValue )
{
2017-10-31 15:06:17 +01:00
m_idxInWellPathToIdxInRftFile . clear ();
2017-10-05 11:08:30 +02:00
RimWellLogCurve :: fieldChangedByUi ( changedField , oldValue , newValue );
2017-10-05 21:25:45 +02:00
if ( changedField == & m_eclipseResultCase )
{
2017-10-10 08:46:12 +02:00
m_timeStep = QDateTime ();
m_wellName = "" ;
m_wellLogChannelName = RifEclipseRftAddress :: NONE ;
2017-10-05 21:25:45 +02:00
this -> loadDataAndUpdate ( true );
}
else if ( changedField == & m_wellName )
2017-10-05 11:08:30 +02:00
{
2017-10-10 08:46:12 +02:00
updateWellChannelNameAndTimeStep ();
2017-10-05 11:08:30 +02:00
this -> loadDataAndUpdate ( true );
}
else if ( changedField == & m_wellLogChannelName )
{
2017-10-27 12:15:48 +02:00
if ( m_wellLogChannelName == RifEclipseRftAddress :: NONE )
{
m_timeStep = QDateTime ();
}
2017-10-05 11:08:30 +02:00
this -> loadDataAndUpdate ( true );
}
else if ( changedField == & m_timeStep )
{
this -> loadDataAndUpdate ( true );
}
}
2017-10-05 09:29:19 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderEclipseRft * RimWellLogRftCurve :: rftReader () const
{
if ( ! m_eclipseResultCase ()) return nullptr ;
return m_eclipseResultCase () -> rftReader ();
2017-10-05 11:08:30 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-31 15:06:17 +01:00
RigEclipseWellLogExtractor * RimWellLogRftCurve :: extractor ()
2017-10-05 11:08:30 +02:00
{
RifReaderEclipseRft * reader = rftReader ();
2017-10-31 15:06:17 +01:00
if ( ! reader ) return nullptr ;
2017-10-05 11:08:30 +02:00
2017-10-31 15:06:17 +01:00
RimMainPlotCollection * mainPlotCollection ;
this -> firstAncestorOrThisOfTypeAsserted ( mainPlotCollection );
2017-10-05 11:08:30 +02:00
2017-10-31 15:06:17 +01:00
RimWellLogPlotCollection * wellLogCollection = mainPlotCollection -> wellLogPlotCollection ();
if ( ! wellLogCollection ) return nullptr ;
2017-10-05 11:08:30 +02:00
2017-10-31 15:06:17 +01:00
RigEclipseWellLogExtractor * eclExtractor = nullptr ;
2017-10-05 11:08:30 +02:00
2017-10-31 15:06:17 +01:00
RimProject * proj = RiaApplication :: instance () -> project ();
2017-11-17 15:35:07 +01:00
RimWellPath * wellPath = proj -> wellPathFromSimWellName ( m_wellName ());
2017-10-31 15:06:17 +01:00
eclExtractor = wellLogCollection -> findOrCreateExtractor ( wellPath , m_eclipseResultCase );
if ( ! eclExtractor )
{
std :: vector < const RigWellPath *> wellPaths = proj -> simulationWellBranches ( m_wellName ());
if ( wellPaths . size () == 0 ) return nullptr ;
eclExtractor = wellLogCollection -> findOrCreateSimWellExtractor ( m_wellName (), QString ( "Find or create sim well extractor" ), wellPaths [ 0 ], m_eclipseResultCase -> eclipseCaseData ());
2017-11-02 12:30:17 +01:00
m_isUsingPseudoLength = true ;
2017-10-31 15:06:17 +01:00
}
return eclExtractor ;
2017-10-05 11:08:30 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-31 15:06:17 +01:00
bool RimWellLogRftCurve :: createWellPathIdxToRftFileIdxMapping ()
2017-10-05 11:08:30 +02:00
{
2017-10-31 15:06:17 +01:00
if ( ! m_idxInWellPathToIdxInRftFile . empty ())
{
return true ;
}
RigEclipseWellLogExtractor * eclExtractor = extractor ();
if ( ! eclExtractor ) return false ;
2017-10-05 11:08:30 +02:00
2017-10-31 15:06:17 +01:00
std :: vector < CellIntersectionInfo > intersections = eclExtractor -> intersectionInfo ();
2017-11-01 11:47:47 +01:00
if ( intersections . empty ()) return false ;
2017-10-31 15:06:17 +01:00
std :: map < size_t , size_t > globCellIndicesToIndexInWell ;
2017-11-01 11:47:47 +01:00
for ( size_t idx = 0 ; idx < intersections . size (); idx ++ )
2017-10-31 15:06:17 +01:00
{
2017-11-01 11:47:47 +01:00
globCellIndicesToIndexInWell [ intersections [ idx ]. globCellIndex ] = idx ;
2017-10-31 15:06:17 +01:00
}
2017-10-05 11:08:30 +02:00
2017-10-12 13:37:03 +02:00
RifEclipseRftAddress depthAddress ( m_wellName (), m_timeStep , RifEclipseRftAddress :: DEPTH );
2017-10-31 15:06:17 +01:00
std :: vector < caf :: VecIjk > rftIndices ;
rftReader () -> cellIndices ( depthAddress , & rftIndices );
const RigMainGrid * mainGrid = eclExtractor -> caseData () -> mainGrid ();
2017-11-01 11:47:47 +01:00
for ( size_t idx = 0 ; idx < rftIndices . size (); idx ++ )
2017-10-31 15:06:17 +01:00
{
2017-11-01 11:47:47 +01:00
caf :: VecIjk ijkIndex = rftIndices [ idx ];
2017-10-31 15:06:17 +01:00
size_t globalCellIndex = mainGrid -> cellIndexFromIJK ( ijkIndex . i (), ijkIndex . j (), ijkIndex . k ());
2017-10-05 11:08:30 +02:00
2017-11-01 11:47:47 +01:00
if ( globCellIndicesToIndexInWell . find ( globalCellIndex ) != globCellIndicesToIndexInWell . end ())
{
m_idxInWellPathToIdxInRftFile [ globCellIndicesToIndexInWell [ globalCellIndex ]] = idx ;
}
2017-10-31 15:06:17 +01:00
}
return true ;
2017-10-12 13:37:03 +02:00
}
2017-10-31 15:06:17 +01:00
2017-10-12 13:37:03 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2017-10-31 15:06:17 +01:00
size_t RimWellLogRftCurve :: rftFileIndex ( size_t wellPathIndex )
2017-10-12 13:37:03 +02:00
{
2017-10-31 15:06:17 +01:00
if ( m_idxInWellPathToIdxInRftFile . empty ())
{
createWellPathIdxToRftFileIdxMapping ();
}
2017-10-05 11:08:30 +02:00
2017-10-31 15:06:17 +01:00
if ( m_idxInWellPathToIdxInRftFile . find ( wellPathIndex ) == m_idxInWellPathToIdxInRftFile . end ())
{
return cvf :: UNDEFINED_SIZE_T ;
}
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
return m_idxInWellPathToIdxInRftFile [ wellPathIndex ];
}
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < size_t > RimWellLogRftCurve :: sortedIndicesInRftFile ()
{
if ( m_idxInWellPathToIdxInRftFile . empty ())
{
createWellPathIdxToRftFileIdxMapping ();
}
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
std :: vector < size_t > indices ;
for ( auto it = m_idxInWellPathToIdxInRftFile . begin (); it != m_idxInWellPathToIdxInRftFile . end (); it ++ )
{
indices . push_back ( it -> second );
}
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
return indices ;
}
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < double > RimWellLogRftCurve :: xValues ()
{
RifReaderEclipseRft * reader = rftReader ();
std :: vector < double > values ;
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
if ( ! reader ) return values ;
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
RifEclipseRftAddress address ( m_wellName (), m_timeStep , m_wellLogChannelName ());
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
reader -> values ( address , & values );
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
bool wellPathExists = createWellPathIdxToRftFileIdxMapping ();
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
if ( wellPathExists )
{
std :: vector < double > valuesSorted ;
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
for ( size_t idx : sortedIndicesInRftFile ())
{
if ( idx < values . size ())
{
valuesSorted . push_back (( values . at ( idx )));
}
}
return valuesSorted ;
}
else
2017-10-12 13:37:03 +02:00
{
2017-10-31 15:06:17 +01:00
return values ;
2017-10-12 13:37:03 +02:00
}
2017-10-31 15:06:17 +01:00
}
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < double > RimWellLogRftCurve :: tvDepthValues ()
{
RifReaderEclipseRft * reader = rftReader ();
std :: vector < double > values ;
if ( ! reader ) return values ;
2017-10-12 13:37:03 +02:00
RifEclipseRftAddress depthAddress ( m_wellName (), m_timeStep , RifEclipseRftAddress :: DEPTH );
2017-10-31 15:06:17 +01:00
reader -> values ( depthAddress , & values );
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
bool wellPathExists = createWellPathIdxToRftFileIdxMapping ();
if ( wellPathExists )
2017-10-12 13:37:03 +02:00
{
2017-10-31 15:06:17 +01:00
std :: vector < double > valuesSorted ;
for ( size_t idx : sortedIndicesInRftFile ())
{
if ( idx < values . size ())
{
valuesSorted . push_back (( values . at ( idx )));
}
}
return valuesSorted ;
}
else
{
return values ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std :: vector < double > RimWellLogRftCurve :: measuredDepthValues ()
{
std :: vector < double > measuredDepthForCells ;
RigEclipseWellLogExtractor * eclExtractor = extractor ();
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
if ( ! eclExtractor ) return measuredDepthForCells ;
2017-10-12 13:37:03 +02:00
2017-10-31 15:06:17 +01:00
std :: vector < double > measuredDepthForIntersections = eclExtractor -> measuredDepth ();
2017-11-01 11:47:47 +01:00
if ( measuredDepthForIntersections . empty ())
{
return measuredDepthForCells ;
}
2017-10-31 15:06:17 +01:00
std :: vector < size_t > globCellIndices = eclExtractor -> intersectedCellsGlobIdx ();
2017-11-01 11:47:47 +01:00
2017-10-31 15:06:17 +01:00
for ( size_t i = 0 ; i < globCellIndices . size () - 1 ; i = i + 2 )
{
double sum = measuredDepthForIntersections [ i ] + measuredDepthForIntersections [ i + 1 ];
measuredDepthForCells . push_back ( sum / 2.0 );
}
std :: vector < double > measuredDepthForCellsWhichHasRftData ;
for ( size_t i = 0 ; i < measuredDepthForCells . size (); i ++ )
{
if ( rftFileIndex ( i ) != cvf :: UNDEFINED_SIZE_T )
{
measuredDepthForCellsWhichHasRftData . push_back ( measuredDepthForCells [ i ]);
}
2017-10-12 13:37:03 +02:00
}
2017-10-31 15:06:17 +01:00
return measuredDepthForCellsWhichHasRftData ;
2017-10-12 13:37:03 +02:00
}