Petrolib: Official Documentations

Overview
This is a python software package designed to help geoscientists perform quick formation evaluation workflow by estimating reservoir petrophysical parameters such as:
Volume of Shale using various methods like Clavier, Stieber and Larionov methods
Porosity - Effective and Total porosities using the Density and Wyllie’s sonic methods.
Water Saturation - using both archie and simmandoux methods
Permeability
In addition to estimating these parameters, log plots are automatically displayed for proper interpretation. Also a pay summary result is generated in XLSX to help quantify the over-all quality of reservoirs.
Installation
You can install the package into your local machine using the pip command:
pip install petrolib
To import the package, use:
import petrolib
print(petrolib.__version__)
>>> '1.2.5'
Contents
Overview
This is a python software package designed to help geoscientists perform quick formation evaluation workflow by estimating reservoir petrophysical parameters such as:
Volume of Shale using various methods like Clavier, Stieber and Larionov methods
Porosity - Effective and Total porosities using the Density and Wyllie’s sonic methods.
Water Saturation - using both archie and simmandoux methods
Permeability
In addition to estimating these parameters, log plots are automatically displayed for proper interpretation. Also a pay summary result/dataframe is produced to help quantify the over-all quality of the reservoirs. Cutoff such as the porosity, shale volume and water saturation are applied to flag pay regions. The pay summary include:
net, gross and not net thicknesses
% net-to-gross
average volume of shale
average porosity
bulk volume of water
water saturation.
Interestingly, the parameters are computed and displayed only for the zones of interest picked. Plots such as neutron-density and pickett are available for reservoir assessment. Geolocations of the wells can also be visualised.
Installation
You can install the package into your local machine using the pip command:
pip install petrolib
Functionalities
The package is designed to handle:
Loading of well data
Processing of well log data
Statistical analysis such as log frequencies and correlation
Well log visualization
Plot well locations on an actual map
Facilitates the loading of well tops.
Plot log curves along with zonation tracks
Neutron-density cross plot
Pickett Plot
Quickstart
import necessaries
from pathlib import Path
from petrolib import procs
from petrolib import file_reader as fr
from petrolib.workflow import Quanti
from petrolib.plots import tripleCombo, Zonation, plotLog
Load data
well_path = Path(r"./15_9-19.las")
tops_path = Path(r'./well tops.csv')
df, las = fr.load_las(well_path, return_csv=True, curves=['GR', 'RT', 'NPHI', RHOB'])
Process data
df = procs.process_data(df, 'GR', 'RT', 'NPHI', 'RHOB')
Triple combo
%matplotlib inline
tripleCombo(df, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB', ztop=3300,
zbot=3450, res_thres=10, fill='right', palette_op='rainbow', limit='left')
Zone plot
zones = Zonation(df, path=tops_path)
zones.plotZone('DEPTH', ['GR', 'RT', 'RHOB', 'NPHI', 'CALI'], 3300, 3600, '15_9-19')
plotLog('DEPTH', ['GR', 'RT', 'RHOB', 'NPHI', 'CALI'], 3300, 3600, '15_9-19')
Calling the zonation object to extra info
ztop, zbot, zn, fm = zones()
Formation evaluation
pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB', use_mean=True)
vsh = pp.vshale(method='clavier', show_plot=True, palette_op='cubehelix', figsize=(9,12))
por = pp.porosity(method='density', show_plot=True, figsize=(10, 12))
sw = pp.water_saturation(method='archie', show_plot=True, figsize=(10, 12))
perm = pp.permeability(show_plot=True, figsize=(9, 10))
flags = pp.flags(por_cutoff=.12, vsh_cutoff=.5, sw_cutoff=0.8, show_plot=True, palette_op='cubehelix', figsize=(20, 15))
ps = pp.paySummary(name='15-9_F1A')
Save results to excel
pp.save(file_name='Pay Summary')
Modules
file_reader
A Python module for loading data into code environment.
Handle files with extension such LAS, TSV, CSV or TXT
- petrolib.file_reader.load_las(file: Path | str, return_csv: bool = False, curves: list | tuple = None) lasio.las.LASFile | pd.DataFrame [source]
Function to read LAS file
- Parameters:
file (pathlib.Path or str) – Filename or filepath specifying the LAS file
return_csv (bool default False) – If True, both dataframe and LAS object are returned. If False, returns only LAS object
curves (list or tuple, optional) – If specified, returns only dataframe containing the log curves specified. If not, all available logs are imported
- Return type:
Returns either LAS and/or dataframe object of the well data
Example
>>> #return both dataframe containing only ['GR','RT', 'RHOB'] curves and the lasio object >>> df, las = load_las(well_path, return_csv=True, curves=['GR', 'RT', 'RHOB'])
>>> #return only LAS object >>> las = load_las(well_path)
- petrolib.file_reader.load_table(file: Path | str, curves: list[str] = None, delimiter: str = None, header: int | list[int] | str = 'infer', skiprows: list | int = None, sheet_name: int | str | list = None) pd.DataFrame [source]
Function to load a table data, either csv, tsv, or excel file
- Parameters:
file (pathlib.Path or str) – Filename or filepath specifying the file
curves (list or tuple, optional) – If specified, returns only dataframe containing the log curves specified If not, all available logs are imported
delimiter (str, default ',') – Delimiter to use
header (int, list of int, default 'infer') – Row number(s) to use as the column names, and the start of the data. Default behavior is to infer the column names. See official pandas doc for more..
skiprows (list, int , optional) – Line numbers to skip (0-indexed) or number of lines to skip (int) at the start of the file
sheet_name (str, int, list, default None) –
Strings are used for sheet names. Integers are used in zero-indexed sheet positions.
Available cases:
0 : 1st sheet as a DataFrame
1: 2nd sheet as a DataFrame
”Sheet1” : Load sheet with name “Sheet1”
[0, 1, “Sheet5”]: Load first, second and sheet named “Sheet5” as a dict of DataFrame
defaults to None: All sheets.
See help(pd.read_excel) for more
Example
>>> well_path = Path(r"C:\Users\USER\Documents\petrolib\test\petrolib\petrolib\15_9-19.csv")
>>> #loads all logs >>> df = load_table(well_path)
>>> #loads specific >>> df = load_table(well_path, ['GR', 'RT'], skiprows=[1]) >>> df
interp
Python module for reservoir interpretation from plots
- petrolib.interp.crossPlot(df: DataFrame, column_x: str, column_y: str, hue: str | None = None, color_code: str | None = None, figsize: tuple = (20, 7), rhob_fluid: float = 1.0, res_name: str | None = None, cmap='viridis')[source]
Plots the cross plot relationship of density against porosity on compatible scales to facilitate in identification of reservoir type and its fluid type.
This code was initially written by Yohanes Nuwara but was modified to give the resulting plot a more classic and pretty view.
- Parameters:
df (pd.DataFrame) – Dataframe of well
column_x (str) – Porosity column
column_y (str) – Density column
hue (str) – Column to color code the scatter plot by
color_code (str default None) – Color code typing. If ‘num’, arg hue must be a continuous column. If ‘cat’, argument hue must be a categorical column
figsize (tuple) – Size of plot
rhob_fluid (float, default 1.0) – Fluid density
res_name (str) – Reservoir name
cmap (str) – color map
- Return type:
A plot showing the neutron-density cross plot
Example
>>> from petrolib.interp import crossPlot >>> crossPlot(df=df, column_x='NPHI', column_y='RHOB', res_name='RES_A', color_code='num', hue='GR')
- petrolib.interp.picketPlot(df: DataFrame, rt: str = 'RT', por: str = 'NPHI', rwa: float = 0.018, a: float = 1.0, m: float = 1.8, n: float = 2.0, res_name: str | None = None, figsize: tuple = (20, 8), hue: str | None = None, color_code: str | None = None, cmap=None)[source]
Plot Pickett plot based on a pattern recognition approach to solving Archie’s equation. The resistivity and porosity logs are plotted on a logarithmic scales to evaluate formation characteristics of conventional, granular reservoirs. Read more here: https://wiki.seg.org/wiki/Pickett_plot
- Parameters:
df (pd.DataFrame) – Dataframe
rt (str) – Resistivity column
rwa (float default 0.03) – Formation water resisitivity
a (float default, 1.) – Turtuosity factor
m (float default 2.) – Cementation factor
n (float default 2.) – Saturation exponent
res_name (str) – Reservoir/Zone name
figsize (tuple) – Size of plot
hue (str) – Column to color code the scatter plot by.
color_code (str default None) – Color code typing. If ‘num’, arg hue must be a continuous column If ‘cat’, argument hue must be a categorical column if None, there is no color coding
cmap (str) – Color map option
Example
>>> import petrolib.interp.picketPlot >>> picketPlot(df, color_code='num', hue='GR', cmap='rainbow')
>>> from petrolib.interp import picketPlot >>> picketPlot(df, rt='RT', por='NPHI')
plots
A Python module for displaying log, lithofacies and zonation plots
- class petrolib.plots.Zonation(df: DataFrame, zones: List[Dict[str, List[float]]] | None = None, path: Path | None = None)[source]
Bases:
object
This is a zonation class that extract zone/reservoir information from the file. This information may include top, bottom and zone/reservoir name. This information can be accessed when an instance of Zonation object is called.
- df
Dataframe of well data
- Type:
pd.DataFrame
- zones
A optional attribute containing list of dictionaries that holds zone information If None, path must be supplied
- Type:
list of dictionaries, default None
- path
A csv file containing reservoir info. To be able to use this, the information in the file should be entered in the following format
top, bottom, zonename 100, 200, RES_A 210, 220, RES_B
If None, zone must be passed
- Type:
Path or str, default None
Example
>>> from petrolib.plots import Zonation >>> zones = Zonation(df, path='./well tops.csv') >>> zones = Zonation(df, zones = [{'RES_A':[3000, 3100]}, {'RES_B':[3300, 3400]}])
>>> #get reservoir information by calling the Zonation object >>> #ztop = top ; zbot = base; zn = zonename ; fm = formation mids to place zone name in plot >>> ztop, zbot, zn, fm = zones()
- plotZone(depth: str, logs: List[str], top: float, bottom: float, title: str = 'Log Plot', figsize: tuple = (8, 12))[source]
Plots log curves with zonation track.
- Parameters:
depth (str) – Depth column
logs (list of str) – A list of logs curves to include in plot
top (float) – Minimum depth to zoom on
bottom (float) – Maximum depth to zoom on
title (str) – Plot title
figsize (tuple) – Size of plot
Example
>>> Zonation.plotZone('DEPTH', ['GR', 'RT', 'RHOB', 'NPHI', 'CALI'], 3300, 3600, 'Volve')
- petrolib.plots.plotLoc(data: list[lasio.las.LASFile], shape_file: Path = None, area: str = None, figsize: tuple = (7, 7), label: list = None, withmap: bool = False, return_table: bool = False) pd.DataFrame | None [source]
Plots location of wells The longitude and latitude must be available in the LAS files
- Parameters:
data (list) – List of lasio.las.LASFile objects
shape_file (str, default None) – A .shp, .shx or .dbf file containing the shape file of the area where the well is located If not supplied, area must be passed
area (str default, None) – Well location. Must inlcude area from gpd.datasets.get_path(‘naturalearth_lowres’)
figsize (tuple) – Size of plot
label (list of str) – Well name(s). Must be a list of equal length with data
withmap (bool default False) – Plots location of wells on a map if True Plots the location on a scatter plot if False
return_table (bool default False) – Return well information such as the long, lat and name
Example
>>> plotLoc(data=[las], area='Norway', label=['15_9-F-1A'], withmap=True, figsize=(30, 10))
- petrolib.plots.plotLog(df: DataFrame, depth: str, logs: List[str], top: float, bottom: float, title: str = 'Log Plot', figsize: tuple = (8, 12))[source]
Plots log curves singly. To plot overlay plots use plots.plotLogs or plots.plotLogFacies
- Parameters:
df (pd.DataFrame) – Dataframe
depth (str) – Depth column
logs (list of str) – A list of logs curves to include in plot
top (float) – Minimum depth to zoom on
bottom (float) – Maximum depth to zoom on
title (str) – Plot title
figsize (tuple) – Size of plot
Example
>>> from petrolib.plots import plotLog >>> plotLog('DEPTH', ['GR', 'RT', 'RHOB', 'NPHI', 'CALI'], 3300, 3600, 'Volve') >>> plotLog(df,'DEPTH', ['NPHI'], 2751, 2834.58, 'Fre-1')
- petrolib.plots.plotLogFacies(df: DataFrame, depth: str, logs: List[list], top: float, bottom: float, facies: str | None = None, title: str = 'Log Plot', figsize: tuple = (8, 12))[source]
Plots overlayed/super-imposed log curves along with the facies.
- Parameters:
df (pd.DataFrame) – Dataframe
depth (str) – Depth column
logs (list of lists/str) – A list of logs curves to include in plot
top (float) – Minimum depth to zoom on
bottom (float) – Maximum depth to zoom on
facies (str) –
- Facies columns. Supported facies include :
[‘Sandstone’, ‘Sandstone/Shale’, ‘Shale’, ‘Marl’, ‘Dolomite’, ‘Limestone’, ‘Chalk’, ‘Halite’, ‘Anhydrite’, ‘Tuff’, ‘Coal’, ‘Basement’]
title (str) – Plot title
figsize (tuple) – Size of plot
Example
>>> from petrolib.plots import * >>> plotLogFacies(well11, 'DEPTH', ['GR', 'RT', ['RHOB', 'NPHI']], facies='litho', top=well11.DEPTH.min(), bottom=well11.DEPTH.max(), figsize=(9, 12), title='15-9-F1A')
- petrolib.plots.plotLogs(df: DataFrame, depth: str, logs: List[List[str]], top: float, bottom: float, title: str = 'Log Plot', figsize: tuple = (8, 12))[source]
Plots overlayed/super-imposed log curves.
- Parameters:
df (pd.DataFrame) – Dataframe
depth (str) – Depth column
logs (list of lists/str) – A list of logs curves to include in plot
top (float) – Minimum depth to zoom on
bottom (float) – Maximum depth to zoom on
title (str) – Plot title
figsize (tuple) – Size of plot
Example
>>> plotLogs(well11, 'DEPTH', ['GR', 'RT', ['RHOB', 'NPHI']], top=well11.DEPTH.min(), >>> bottom=well11.DEPTH.max(), figsize=(9, 12), title='15-9-F1A')
- petrolib.plots.plotZoneCombo(data: DataFrame, depth: str, gr: str, res: str, nphi: str, rhob: str, ztop: float, zbot: float, ztops: List[float], zbots: List[float], zonename: List[str], limit: str, res_thres: float = 10.0, palette_op: str | None = None, fill: str | None = None, title: str = 'Log plot', figsize: tuple = (10, 20)) None [source]
Function for plotting three combo logs alongside the zonation/reservoir track
- Parameters:
df (pd.DataFrame) – Dataframe of data
depth (str) – Depth column
gr (str) – Gamma ray column
res (str) – Resistivity column
nphi (str) – Neutron porosity column
rhob (str) – Bulk density column
ztop (float) – Top or minimum depth value
zbot (float) – Bottom or maximum depth value
ztops (list of float) – Tops (depth) of each reservoir/zones
zbots (list of float) – Bottom (depth) of each reservoir/zones
zonename (list of str) – Name of each zones
limit (str default None) – Tells which side to fill the gamma ray track, [‘left’, ‘right’]. lf None, it’s filled in both sides delineating shale-sand region
res_thres (float) – Resistivity threshold to use in the identification on hydrocarbon bearing zone
palette_op (str optional) – Palette option to fill gamma ray log. If None, `fill must be provided
fill (str default None) –
To show either of the porous and/or non porous zones in the neutron-density crossover. Can either be [‘left’, ‘right’, ‘both’]
default None - show neither of the porous nor non-porous zones
’left’ - shows only porous zones
’right’ - shows only non-porous zones
’both’ - shows both porous and non-porous zones
figsize (tuple) – Size of plot
Example
>>> from petrolib.plots import plotZoneCombo >>> plotZoneCombo(well11, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB', min(ztop), max(zbot), >>> ztop, zbot, zn, fill='both', limit=None, figsize=(13, 30), title='ATAGA-11')
- petrolib.plots.tripleCombo(data: DataFrame, depth: str, gr: str, res: str, nphi: str, rhob: str, ztop: float, zbot: float, res_thres: float = 10.0, fill: str | None = None, palette_op: str | None = None, limit: str | None = None, figsize: tuple = (9, 10), title: str = 'Three Combo Log Plot') None [source]
Plots a three combo log of well data
- Parameters:
data (pd.DataFrame) – Dataframe of data
depth (str) – Depth column
gr (str) – Gamma ray column
res (str) – Resistivity column
nphi (str) – Neutron porosity column
rhob (str) – Bulk density column
ztop (list) – Top or minimum depth to zoom on.
zbot (list) – Bottom or maximum depth to zoom on.
res_thres (float) – Resistivity threshold to use in the identification on hydrocarbon bearing zone
fill (str default None) –
To show either of the porous and/or non porous zones in the neutron-density crossover. Can either be [‘left’, ‘right’, ‘both’]
default None - show neither of the porous nor non-porous zones
’left’ - shows only porous zones
’right’ - shows only non-porous zones
’both’ - shows both porous and non-porous zones
palette_op (str optional) – Palette option to fill gamma ray log
limit (str default None) – Tells which side to fill the gamma ray track, [‘left’, ‘right’] lf None, it’s filled in both sides delineating shale-sand region
figsize (tuple) – Size of plot
title (str) – Title of plot
Example
>>> import matplotlib inline >>> from petrolib.plots import tripleCombo >>> # %matplotlib inline >>> tripleCombo(df, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB', ztop=3300, >>> zbot=3450, res_thres=10, fill='right', palette_op='rainbow', limit='left')
procs
Python module for data processing and lithofacies modelling
- petrolib.procs.model_facies(df: DataFrame, gr: str, env: str = 'SS') DataFrame [source]
Models lithofacies from Gamma ray log specific to a particular environment
- Parameters:
df (pd.DataFrame) – dataframe
gr (str) – Gamma ray log column
env (str) – Environment type. Either siliciclastic or carbonate * ‘SS’ for Siliclastic (Shale and Sandstone) environment * ‘CO’ for carbonate (Anhydrite, Limestone, Dolomite, Sandstone, Shale) environment
Example
>>> from petrolib.interp import model_facies >>> model_facies(df, gr='GR', env='SS')
- petrolib.procs.process_data(df: DataFrame, gr: str, rt: str, nphi: str, rhob: str, dt: str | None = None, trim: str = 'both') DataFrame [source]
Function to preprocess data before beginning petrophysics workflow. This processing workflow uses conventional values for the log curves. To use user-defined preprocessing method , refer to the petrolib.data.procs.trim()
- Parameters:
df (pd.DataFrame) – dataframe object
gr (str) – Gamma ray column
rt (str) – Resistivity column
nphi (str) – Neutron porosity column
rhob (str) – Bulk density column
sonic (str, default None) – Sonic column (optional)
trim (str default 'both') – Conditions for trim arbitrary values * ‘max’ : to trim values higher than conventional maximum values * ‘min’ : to trim values lower than conventional lower values * default ‘both’ : to trim both lower and higher values to conventional high and lower values
- Return type:
A new copy of dataframe containing processed data
Example
>>> df = process_data(df, 'GR', 'RT', 'NPHI', 'RHOB') >>> df.describe() |DEPTH | GR | RT | NPHI | RHOB| +-------+-------+-------+--------+------+ count | 35361 | 34671 | 34211 | 10524 |10551 | -------+-------+-------+-------+--------+------+ mean | 1913.9| 56.97 | 1.95 | 0.17 | 2.48 | -------+-------+-------+-------+--------+------+ min | 145.9| 0.15 | 0.2 | 0.03 | 1.98 | ------+-------+-------+-------+--------+------+ max | 3681.9| 200 | 2000 | 0.45 | 2.93| ----------------------------------------------
- petrolib.procs.set_alias(df: DataFrame, DEPTH: str, GR: str, RT: str, NPHI: str, RHOB: str, DT: str | None = None) DataFrame [source]
Function to rename the log curves in order to maintain petrophysics conventions
- Parameters:
df (pd.DataFrame) – dataframe object
DEPTH (str) – Depth column
GR (str) – Gamma ray column
RT (str) – Resistivity column
NPHI (str) – Neutron porosity column
RHOB (str) – Bulk density column
DT (str, default None) – Sonic column (optional)
- Return type:
Returns data of renamed log curves
Example
>>> df = set_alias(df, 'DEPT', 'GR','RES', 'NPHI', 'RHOB') >>> print(df.columns) >>> ['DEPTH', 'GR', 'RT', 'NPHI', 'RHOB']
- petrolib.procs.trim(df: pd.DataFrame, col: str, lower: int | float, upper: int | float)[source]
Function to preprocess data by trimming arbitrary values
- Parameters:
df (pd.DataFrame) – Dataframe
col (str) – Log curve to trim its values
lower (int or float) – Lower limit or minimum value
upper (int or float) – Upper limit or maximum value
- Return type:
Dataframe with user defined log limits
Example
>>> trim(df, 'GR', lower=0, upper=200)
stats
Python module for handling data statistics
- class petrolib.stats.Correlation(dataframe: DataFrame)[source]
Bases:
object
A correlation class for pearson and chatterjee method of statistical significance.
- Parameters:
df (pd.DataFrame) – Takes in only the dataframe
- corr(method: str = 'chatterjee')[source]
Function to calculate the linear (Pearson’s) and non-linear (Chatterjee’s) relationships between log curves. Relationship between well logs are usually non-linear.
- Parameters:
method (str, default 'chatterjee') –
Method of correlation. {‘chatterjee’, ‘pearsonr’, ‘linear’, ‘nonlinear’}
’linear’ is the same as ‘pearsonr’
’nonlinear’ is the same as ‘chatterjee’
- Return type:
Correlation matrix of all possible log curves combination
Example
>>> corr = Correlation(df) >>> v = corr.corr(method='chatterjee)
- plot_heatmap(title: str = 'Correlation Heatmap', figsize: slice = (12, 7), annot: bool = True, cmap=None)[source]
Plots the heat map of Correlation Matrix
- Parameters:
title (str) – Title of plot
figsize (slice) – Size of plot
annot (bool, default True) – To annotate the coefficient in the plot
cmap (matplotlib colormap name or object, or list of colors, optional) – The mapping from data values to color space
Example
>>> corr = Correlation(df) >>> v = corr.corr(method='chatterjee) >>> corr.plot_heatmap(cmap='Reds')
- petrolib.stats.displayFreq(df: pd.DataFrame, *cols: tuple[str], bins: int = 12, figsize: slice = (8, 8))[source]
Function to plot the frequency distribution of well log curves
- Parameters:
df (pd.DataFrame) – Dataframe of data
cols (tuple[str]) – log curves to show its distribution
bins (int) – Number of bins to group the data
figsize (slice) – Size of plot
- Return type:
Shows a plot of the frequency distribution of well log curves
Example
>>> from petrolib.stats import displayFreq >>> displayFreq(df, 'GR','CALI', 'COAL', 'DT', 'DT_LOG', bins=15, figsize=(20,10))
utils
workflow
Python module for petrophysics
- class petrolib.workflow.Quanti(df: DataFrame, zonename: list, ztop: list, zbot: list, f_mids: list, depth: str, gr: str, rt: str, nphi: str, rhob: str, sonic: str | None = None, use_mean: bool | None = None, use_median: bool | None = None)[source]
Bases:
object
Class to petrophysics workflow to evaluate any number of reservoirs of interest. Computes IGR/VSH, Total and Effective Porosities, Water and Hydrocarbon Saturation, Permeability
- df
Dataframe of data
- Type:
pd.DataFrame
- zonename
List of zonenames. Will be accessed from the zonation file passed into Zonation class
- Type:
list
- ztop
Tops of the reservoirs. Will be accessed from the zonation file passed into Zonation class
- Type:
list
- zbot
Bottoms of the reservoirs. Will be accessed from the zonation file passed into Zonation class
- Type:
list
- f_mids
Formation mids to help place the zonename in the plots. Will be accessed from the zonation file passed into Zonation class
- Type:
list
- depth
Depth column
- Type:
str
- gr
Gamma ray column
- Type:
str
- rt
Resistivity column
- Type:
str
- nphi
Neutron porosity column
- Type:
str
- rhob
Bulk density column
- Type:
str
- sonic
Sonic column (optional)
- Type:
str default None
- use_mean
For cutoff. Whether to use mean of GR in IGR/VSH computation or not. If None, uses either median or average value
- Type:
bool default None
- use_median; bool default None
For cutoff. Whether to use median of GR in IGR/VSH computation or not. If None, uses either mean or average value
Example
>>> #loading libraries/packages >>> from petrolib.workflow import Quanti >>> from petrolib.plot import Zonation >>> from petrolib.file_reader import load_las >>> from pathlib import Path
>>> #loading well file and zonation/tops file >>> well_path = Path(r"./15_9-F-1A.LAS") >>> contact_path = Path(r"./well tops.csv")
>>> las, df= load_las(well_path, curves=['GR', 'RT', 'NPHI', 'RHOB'], return_las=True)
>>> #creating zonation class to extra info >>> zones = Zonation(df, path=contact_path) >>> ztop, zbot, zn, fm = zones()
>>> #creating quanti class >>> pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB', use_mean=True)
- flags(vsh_cutoff: float, por_cutoff: float, sw_cutoff: float, ref_unit: str = 'm', show_plot: bool = False, palette_op: str | None = None, figsize: tuple | None = None)[source]
Create the {ROCK, RES, PAY} flags
To use, must have called vshale, porosity, water_saturation and permeability methods
- Parameters:
vsh_method (float) – Volume of Shale cutoff. Applied only to [‘ROCK’] flag
por_cutoff (float) – Porosity cutoff. Applied only to the [‘ROCK’, ‘RES’] flags
sw_cutoff (float) – Water Saturation cutoff. Applied only to the [‘ROCK’, ‘RES’, ‘PAY] flags
ref_unit (str default 'm') – Reference unit for measured depth. Defaults to metres
show_plot (bool default False) – Display plot if True.. Plots GR, RT, VSH, SW, Perm, NPHI/RHOB, PHIE/PHIT, [‘ROCK’, ‘RES’, ‘PAY] flags and Zonation track
palette_op (str default None) – palette option for VSH coloring. Check https://matplotlib.org/stable/tutorials/colors/colormaps.html for availabel palette options
figsize (tuple default None) – Size of plot
- Return type:
Either/Both Dataframe containing the flags and the plot if show_plot=True
Example
>>> # Create Quanti class >>> pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB')
>>> # Display plot only >>> pp.flags(por_cutoff=.12, vsh_cutoff=.5, sw_cutoff=0.8, show_plot=True, palette_op='cubehelix', figsize=(20, 15))
>>> # Display data only >>> y = pp.flags(por_cutoff=.12, vsh_cutoff=.5, sw_cutoff=0.8) >>> result = pd.concat(y) >>> print(result)
- paySummary(name: str)[source]
- Computes the
net, grossand not net thicknesses
net-to-gross
average volume of shale
average porosity value
bulk volume of water
water saturation
for each of the three flags {ROCK, RES, PAY}
- Parameters:
name (str) – Name of the well
- Return type:
Displays the Pay Summary Report table
Example
>>> pp.paySummary(name='15-9_F1A')
- permeability(show_plot: bool = False, figsize: tuple | None = None)[source]
Computes the permeability. To use, must have called vshale and porosity and water_saturation methods
- Parameters:
show_plot (bool default False) – Display plot if True.. Plots PHIE, Permeability and Zone track
figsize (tuple default None) – Size of plot
- Return type:
Either/Both Dataframe containing the Perm and the plot if show_plot=True
Example
>>> # create Quanti class >>> pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB')
>>> # display plot only >>> pp.vshale(method='clavier') >>> pp.porosity(method='density') >>> pp.water_saturation(method='archie') >>> pp.permeability(show_plot=True, figsize=(9, 10))
>>> # display data only >>> x = pp.vshale(method='clavier') >>> y = pp.porosity(method='density') >>> z = pp.water_saturation(method='archie') >>> a = pp.permeability() >>> result = pd.concat(a) >>> print(result)
- porosity(method: str = 'density', rhob_shale: float = 2.4, rhob_fluid: float = 1.0, rhob_matrix: float = 2.65, fzs: float | None = None, show_plot: bool = False, figsize: tuple | None = None)[source]
Computes the effective and total porosities using the ‘density’ and Wyllie’s ‘sonic’ method. To use, must have called the vshale method
- Parameters:
method (str default 'density') – Porosity method. {‘density’, ‘sonic’}
rhob_shale (float default 2.4) – Shale matrix
rhob_fluid (float default 1.0) – Fluid density
rhob_matrix (float default 2.65) – Matrix density
fzs (float default None) – Flushed zone saturation for PHIE. If None, it is calculated from rhob_fluid, rhob_shale and rhob_matrix
show_plot (bool default False) – Display plot if True.. Plots RHOB, VSH, PHIE/PHIT and Zone track
figsize (tuple default None) – Size of plot
- Return type:
Either/Both Dataframe containing the PHIE/PHIT and the plot if show_plot=True
Example
>>> # create Quanti class >>> pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB')
>>> # display plot only >>> pp.porosity(method='density', show_plot=True, figsize=(10, 12))
>>> # display data only >>> y = pp.porosity(method='density') >>> result = pd.concat(y) >>> print(result)
- report()[source]
Displays the methods used in each parameter estimations and cutoff used for flagging
- save(file_name: str)[source]
A method to save the pay summary results into a excel file
- Parameters:
file_name (str) – name of to save the pay summary report as
- vshale(method: str = 'linear', show_plot: bool = False, palette_op: str | None = None, figsize: tuple | None = None)[source]
Computes the Volume of Shale
- Parameters:
method (str default 'linear') – Volume of Shale method. {‘linear’, ‘clavier’, ‘larionov_ter’, ‘larionov_older’, ‘stieber_1’, ‘stieber_2, ‘stieber_m_pliocene’} * Linear = Gamma Ray Index (IGR) * Larionov Tertiary * Larionov Older Rocks * Stieber (Miocene/Pliocene)
show_plot (bool default False) – Display plot if True.. Plots GR, VSH and Zone track
palette_op (str default None) – Palette option for to color code vshale plot. Check https://matplotlib.org/stable/tutorials/colors/colormaps.html
figsize (tuple default None) – Size of plot
- Return type:
Either/Both Dataframe containing the VSH and the plot if show_plot=True
Example
>>> # create Quanti class >>> pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB')
>>> # display plot only >>> pp.vshale(method='clavier', show_plot=True, palette_op='cubehelix', figsize=(9,12))
>>> # display data only >>> x = pp.vshale(method='clavier') >>> x = pd.concat(x) >>> print(x)
- water_saturation(method: str = 'archie', rw: float = 0.03, a: float = 1.0, m: float = 2.0, n: float = 2.0, show_plot: bool = False, figsize: tuple | None = None)[source]
Computes water and hydrocarbon saturation To use, must have called both vshale and porosity methods
- Parameters:
method (str default 'archie') – Water Saturation method. {‘archie’, ‘simmandoux’}
rw (float default 0.03) – Formation water resisitivity
a (float default, 1.) – Turtuosity factor
m (float default 2.) – Cementation factor
n (float default 2.) – Saturation exponent
show_plot (bool default False) – Display plot if True.. Plots RT, SW, PHIE/PHIT and Zone track
figsize (tuple default None) – Size of plot
- Return type:
Either/Both Dataframe containing the SW, SH and the plot if show_plot=True
Example
>>> # create Quanti class >>> pp = Quanti(df, zn, ztop, zbot, fm, 'DEPTH', 'GR', 'RT', 'NPHI', 'RHOB')
>>> # display plot only >>> pp.water_saturation(method='archie', show_plot=True, figsize=(10, 12))
>>> # display data only >>> z = pp.water_saturation(method='archie') >>> result = pd.concat(z) >>> print(result)
Tutorial
A notebook has been prepared to walk user through on how to use the package for petrophysical workflow. Find the link here: