In [1]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import welly
welly.__version__
Out[1]:
In [2]:
import os
env = %env
In [3]:
w = welly.Well()
In [4]:
w.header.uwi = 'foo'
In [5]:
w.header
Out[5]:
In [6]:
w.uwi
Out[6]:
Or, instantiate with some basic data:
In [7]:
w = welly.Well(params={'header': {'name': 'foo', 'uwi':'05045123450000'}})
In [8]:
w.header
Out[8]:
In [9]:
w.header['uwi']
Out[9]:
The well name and UWI are also provided at the well level for convenience:
In [10]:
w.name, w.uwi
Out[10]:
In [4]:
from welly import Well
In [5]:
w = Well.from_las('P-129_out.LAS')
In [40]:
w.data['GR'].null = -111.11
In [41]:
w.las.well["NULL"].value = -111.11
In [49]:
w.header
Out[49]:
In [47]:
l = w.to_lasio()
In [48]:
l.well['NULL']
Out[48]:
In [9]:
w.to_las('x.las', null_value=-111.111)
In [10]:
!ls -l x.las
In [11]:
!head -100 x.las
In [13]:
w.las.params['UWID'].value
Out[13]:
In [14]:
tracks = ['MD', 'GR', 'RHOB', ['DT', 'DTS'], 'MD']
w.plot(tracks=tracks)
In [18]:
alias = {
"Gamma": ["GR", "GAM", "GRC", "SGR", "NGT"],
"Density": ["RHOZ", "RHOB", "DEN", "RHOZ"],
"Sonic": ["DT", "AC", "DTP", "DT4P"],
"Caliper": ["CAL", "CALI", "CALS", "C1"],
'Porosity SS': ['NPSS', 'DPSS'],
}
In [8]:
import welly.quality as q
tests = {
'Each': [
q.no_flat,
q.no_monotonic,
q.no_gaps,
],
'Gamma': [
q.all_positive,
q.all_below(450),
q.check_units(['API', 'GAPI']),
],
'DT': [
q.all_positive,
],
'Sonic': [
q.all_between(1, 10000), # 1333 to 5000 m/s
q.no_spikes(10), # 10 spikes allowed
],
}
In [9]:
w = Well.from_las('P-129_out.LAS')
r = w.qc_data(tests, alias=alias)
This returns a dictionary of curves in which the values are dictionaries of test name: test result pairs.
In [10]:
r
Out[10]:
There's also an HTML table for rendering in Notebooks:
In [11]:
from IPython.display import HTML
html = w.qc_table_html(tests, alias=alias)
HTML(html)
Out[11]:
In [12]:
from striplog import Legend, Striplog
legend = Legend.builtin('NSDOE')
strip = Striplog.from_image('P-129_280_1935.png', 280, 1935, legend=legend)
strip.plot()
In [13]:
w.data['strip'] = strip
In [14]:
tracks = ['MD', 'strip', 'GR', 'RHOB', ['DT', 'DTS'], 'MD']
w.plot(tracks=tracks)
plt.ylim(1000, 1200)
Out[14]:
In [15]:
w.header
Out[15]:
In [16]:
w.header.name
Out[16]:
In [17]:
w.uwi # Fails because not present in this file. See one way to add it in a minute.
Out[17]:
In [18]:
w.location
Out[18]:
In [19]:
from welly import CRS
w.location.crs = CRS.from_epsg(2038)
In [20]:
w.location.crs
Out[20]:
Right now there's no position log — we need to load a deviation survey.
In [21]:
w.location.position
In [3]:
import numpy as np
from welly import Well
p = Well.from_las('P-130_out.LAS')
In [4]:
dev = np.loadtxt('P-130_deviation_survey.csv', delimiter=',', skiprows=1)
The columns are MD, inclination, azimuth, and TVD.
In [5]:
dev[:5]
Out[5]:
add_deviation assumes those are the columns, and computes a position log.
In [6]:
p.location.add_deviation(dev[:, :3], td=2618.3)
The columns in the position log are x offset, y offset, and TVD.
In [7]:
p.location.position[:5]
Out[7]:
In [8]:
p.location.trajectory()
Out[8]:
In [9]:
p.location.plot_plan()
In [10]:
p.location.plot_3d()
In [27]:
w.data_as_matrix()
Out[27]:
In [4]:
df = w.df()
In [5]:
df.head()
Out[5]:
In [7]:
df.GR.plot()
Out[7]:
This also gives us another path to getting a matrix:
In [31]:
w.df().values
Out[31]:
You'll have to get depth separately:
In [32]:
w.df().index.values
Out[32]:
To get the UWI of the well as well, e.g. if you want to combine multiple wells (maybe using welly.Project.df()):
In [33]:
df = w.df(uwi=True)
In [34]:
df.head()
Out[34]:
In [6]:
alias
Out[6]:
In [10]:
keys = ['CALI', 'Gamma', 'Density', 'Sonic', 'RLA1']
w.df(keys=keys, alias=alias, rename_aliased=True).head()
Out[10]:
In [ ]: