Data Analysis - Curve Types

version - 1.0 (IN PROGRESS)

The purpose of this notebook is to do some basic datanalysis and exploration - it needs the field data - quicklook forecast (or final forecast) in order to analyse the full history of the well

It allows to do: - Computation of curve types - Plots of curve types - Fitting for curve types - Test forecasting based on curve types hypothesis

Library loading:

[1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import logging
from frflib.forecast_methods import forecast_wf

from frflib.utils.curve_types import curve_type, plot_curve_type, plot_single_curvetype,merge_category
from frflib.config.config_func import get_var_type
from frflib.config.config_func import get_var_fromvar
from frflib.forecast_tools.datamanip_tools import reindex_df
from frflib.utils.dataframe_func import df_fast_loc

from frflib.plots.utils import get_group_colors
from frflib.utils.curve_types import plot_curve_type

from frflib.forecast_methods.forecast_wf import ForecastWF
from frflib.data_class import input_data
from importlib import reload
import inspect
import frflib
InputData= input_data.InputData
[2]:
PATH_FRFLIB= os.path.dirname(inspect.getsourcefile(frflib))
PATH_TO_DATA= os.path.join(PATH_FRFLIB,"sample_data")

Data Import

[3]:
project_id="01"
wf_name="dataset_01_simple_wf"

WF_PATH=os.path.join(PATH_TO_DATA,f"{wf_name}.hdf")
DATA_PATH=os.path.join(PATH_TO_DATA,f"dataset_{project_id}.hdf")
[4]:
field_data = InputData.load_hdf(DATA_PATH)
wf = ForecastWF.load_from_hdf( WF_PATH, field_data)
field_data._compute_indicators()
wf.enrich_data()
field_data_enriched = wf.enriched_data
[5]:
df_full = wf.get_result_summary(include_stat=True)

If the worklow is going to be applied on a subset of data. It can be extracted using the function subset or a well lsit

## curve type

Parameters

[6]:
groupby_val = ['reservoir']
min_elements = 10
percentile=[0.2,0.5,0.8]
min_active_months=200
[7]:
df_dynamic = wf.enriched_data.df_dynamic

Compute curve type

[8]:
serie_groupby = merge_category(field_data.df_static, groupby_val, min_elements=min_elements)
df_type_curve,df_dyn_resample = curve_type(df_dynamic, serie_groupby, percentile=percentile,min_active_months=min_active_months )

plot result

[9]:

map_colors = get_group_colors(df_type_curve.reset_index(), 'groupby', min_elements=0, select_top=None, color_scale='tab10')
[10]:
plot_curve_type(df_type_curve,var_plots=['oil_rate_stbd', 'oil_cum_mmbbl', 'bsw_vv', 'liq_rate_stbd'],
                range_x=[0,20],
                   color_discrete_map=map_colors)
[11]:
plot_single_curvetype(df_type_curve, df_dyn_resample, group = 'Deltaic',
                     var_plots = ['oil_rate_stbd', 'bsw_vv', 'gor_vv', 'liq_rate_stbd'],
                     color_list = ['green', 'blue', 'pink'], percentile = [0.2,0.5,0.8],
                    range_x = [0,25])

Scatter plot of wells

[12]:
df_plot = df_full.join(serie_groupby).dropna()
[13]:
from frflib.plots.plotly_ import plot_histogram,plot_time_serie, plot_stacked_series, plot_scatter

scatter_param ={
    'title': 'Well map - AMAL',
'x_axis': 'x_bh_m' ,
'y_axis': 'y_bh_m',
'x_range': [0.27e+6,0.3e+6],
'y_range': [0.915e+6,0.935e+6], # [2,4.5],
# 'xaxis_type' : None,
# 'yaxis_type' : None, #log
'color' : 'groupby', # 'field'#'sub_group_res' #
'size' : 'max_oil_rate_stbd', #'max_oil_rate_stbd'
'symbol' :'groupby' ,#'reservoir', #"reservoir",# None,
'hover_data':['wellname'],
'same_scale': True,
'height' : 600,
'width' : 900,
'color_discrete_map':map_colors
# 'trendline' : 'ols' #'ols' #None, #'ols'
}

# correct the axis names
plot_scatter(df_plot.reset_index(),**scatter_param)

Export csv

[14]:
filename_export = 'curve_type.csv'
df_type_curve.to_csv(filename_export)

Fit Curve Types

The objective of this section is to fit all the curve types by parameters

[15]:
df_type_curve['P50_oil_cum_mmbbl'] = df_type_curve['P50_oil_rate_stbd'].groupby('groupby').cumsum()*30.5*1e-6
df_type_curve['active_days'] = 25
[16]:
from frflib.forecast_tools.fitters.fitter_catalog import FitDCAHyperPlateau, FitSigmoid
from frflib.forecast_tools.fitters.abs_fitter_class import fit_group, plot_group_fit

FitterClass = FitDCAHyperPlateau
fitter_param = {'min_fit_points':3}
data = df_type_curve #.loc[df_type_curve.count_oil_rate_stbd>2]
x_var = 'P50_oil_cum_mmbbl'
y_var = 'P50_oil_rate_stbd'

df ,fit_dict = fit_group(data, x_var, y_var,FitterClass,**fitter_param)
[17]:
from frflib.plots.matplotlib_ import plot_group_fit
plot_group_fit(df, fit_dict, y_var,x_axis=x_var, well_list='all')
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
../_images/notebooks_02_data_analysis_curve_types_29_1.png
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
../_images/notebooks_02_data_analysis_curve_types_29_3.png
No artists with labels found to put in legend.  Note that artists whose label start with an underscore are ignored when legend() is called with no argument.
../_images/notebooks_02_data_analysis_curve_types_29_5.png

Blind Test Based curve types forecast:

[18]:
wl_list = df_full.loc[df_full.reservoir.isin(['Deltaic'])].index
field_data_nw = field_data.subset(wl = wl_list)
[19]:
# field_data_nw.df_static.loc[field_data_nw.df_static['polygone']=='0']
[20]:
from frflib.forecast_methods import forecast_wf,forecast_new_wf
forecast_new_wf = reload(forecast_new_wf)
ForecastNewWF = forecast_new_wf.ForecastNewWF
[21]:
general_forecast_params = {
    'forecast_name': 'wf_ctype',
    'forecast_end_date': "01/01/2040",
    'forecast_fluids': ['oil','water'],
    'forecast_mode': 'blind_test',  # 'forecast_mode': 'forecast',blind_test
    'abandonned_wells': 5,
    'uptime_selection': 'constant_value',
    'constant_value': 1.0,
    'period_for_avg_months': 12,
    'short_term_forecast_adjustment': 0,
    'blind_test_duration': 60,
}
para_ctype_nodatefilter = [{
    'forecaster_name': 'curve_type_oil',
    "learn_x": 'cum_active_days',
    'groupby_category': 'reservoir'
},
    {
    'forecaster_name': 'curve_type_bsw',
    "learn_x": 'cum_active_days',
    'groupby_category': 'reservoir'
}
]

para_ctype_datefilter = [{
    'forecaster_name': 'curve_type_oil',
    'early_date_filter': '1/1/2006',
    "learn_x": 'cum_active_days',
    'groupby_category': 'reservoir'
}
]

Blind test setup:

The idea is to test what would be the forecast for a given number of wells when selecting a curve type based on average behavior. All the wells that started after a certain date will be removed and then forecast based on the group to which they belong It is possible also to filter some wells based on start-up date to take into account only the more recent wells

Blindtest parameters:

[22]:
# wf_ctype_bt_nofilter = ForecastNewWF.execute(field_data_enriched, general_forecast_params, para_ctype_nodatefilter, nproc=1)
# general_forecast_params['forecast_name']= 'wf_ctype_date_filter'
# wf_ctype_bt = ForecastNewWF.execute(field_data_enriched, general_forecast_params, para_ctype_datefilter, nproc=1)

Restults

[23]:
# from frflib.plots.forecast_plots import plot_group_forecast
# y_axis = 'oil_rate_stbd'
# fig_field = plot_group_forecast([wf_ctype_bt, wf_ctype_bt_nofilter], color_list = ['red', 'yellow', 'orange', 'grey'], x_axis='date', y_axis =y_axis)
# fig_field.show()
[24]:
#y_axis = 'water_rate_stbd'
#fig_field = plot_group_forecast([wf_ctype_bt, wf_ctype_bt_nofilter], color_list = ['red', 'yellow', 'orange', 'grey'], x_axis='date', y_axis =y_axis)
#fig_field.show()
Well by well:
[25]:
from frflib.plots.forecast_plots import *
#plot_wells([wf_ctype_bt, wf_ctype_bt_nofilter],x_axis='date', y_axis_list = ['oil_rate_stbd', 'oil_cum_mmbbl'],well_list ='all')
[26]:
#wf_ctype_bt.plot_blind_test()
[27]:
#wf_ctype_bt_nofilter.plot_blind_test()
[ ]: