Welly and LAS files

Some preliminaries...


In [9]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import welly
welly.__version__


Out[9]:
'0.3.3'

In [10]:
import matplotlib
matplotlib.__version__


Out[10]:
'2.0.0'

In [11]:
import lasio
lasio.__version__


Out[11]:
'0.15.1'

Load a well from LAS

Use the from_las() method to load a well by passing a filename as a str.

This is really just a wrapper for lasio but instantiates a Header, Curves, etc.


In [12]:
from welly import Well

In [14]:
w = Well.from_las('P-129_out.LAS')

In [15]:
from striplog import Legend, Striplog
legend = Legend.builtin('NSDOE')
strip = Striplog.from_image('P-129_280_1935.png', 280, 1935, legend=legend)

In [16]:
w.data['strip'] = strip

Save LAS file

We can write out to LAS with a simple command, passing the file name you want:


In [17]:
w.to_las('out.las')

Let's just check we get the same thing out of that file as we put in:


In [18]:
w.plot()



In [19]:
z = Well.from_las('out.las')
z.plot()



In [20]:
z.data['CALI'].plot()


We don't get the striplog back (right hand side), but everything else looks good.

Maybe should be called 'meta' as it's not really a header...


In [21]:
w.header


Out[21]:
{'name': 'Kennetcook #2', 'field': 'Windsor Block', 'license': 'P-129', 'uwi': "Long = 63* 45'24.460  W", 'company': 'Elmworth Energy Corporation'}

In [22]:
w.header.name


Out[22]:
'Kennetcook #2'

In [23]:
w.uwi


Out[23]:
"Long = 63* 45'24.460  W"

What?? OK, we need to load this file more carefully...

Coping with messy LAS

Some file headers are a disgrace:

# LAS format log file from PETREL
# Project units are specified as depth units
#==================================================================
~Version information
VERS.   2.0:
WRAP.   YES:
#==================================================================
~WELL INFORMATION
#MNEM.UNIT      DATA             DESCRIPTION
#---- ------ --------------   -----------------------------
STRT .M      1.0668          :START DEPTH     
STOP .M      1939.13760      :STOP DEPTH     
STEP .M       0.15240        :STEP        
NULL .          -999.25      :NULL VALUE
COMP .        Elmworth Energy Corporation              :COMPANY
WELL .        Kennetcook #2                            :WELL
FLD  .        Windsor Block                            :FIELD
LOC  .        Lat = 45* 12' 34.237" N                  :LOCATION
PROV .        Nova Scotia                              :PROVINCE
  UWI.        Long = 63* 45'24.460  W                  :UNIQUE WELL ID
LIC  .        P-129                                    :LICENSE NUMBER
CTRY .        CA                                       :COUNTRY (WWW code)
 DATE.        10-Oct-2007                              :LOG DATE {DD-MMM-YYYY}
SRVC .        Schlumberger                             :SERVICE COMPANY
LATI .DEG                                              :LATITUDE
LONG .DEG                                              :LONGITUDE
GDAT .                                                 :GeoDetic Datum
SECT .        45.20 Deg N                              :Section
RANG .        PD 176                                   :Range
TOWN .        63.75 Deg W                              :Township

In [24]:
import welly
import re

def transform_ll(text):
    def callback(match):
        d = match.group(1).strip()
        m = match.group(2).strip()
        s = match.group(3).strip()
        c = match.group(4).strip()
        if c.lower() in ('w', 's') and d[0] != '-':
            d = '-' + d
        return ' '.join([d, m, s])
    pattern = re.compile(r""".+?([-0-9]+?).? ?([0-9]+?).? ?([\.0-9]+?).? +?([NESW])""", re.I)
    text = pattern.sub(callback, text)
    return welly.utils.dms2dd([float(i) for i in text.split()])

In [25]:
print(transform_ll("""Lat = 45* 12' 34.237" N"""))
print(transform_ll("""Long = 63* 45'24.460  W"""))


45.20951027777778
-62.243205555555555

In [26]:
remap = {
    'LATI': 'LOC',  # Use LOC for the parameter LATI.
    'LONG': 'UWI',  # Use UWI for the parameter LONG.
    'SECT': None,   # Use nothing for the parameter SECT.
    'RANG': None,   # Use nothing for the parameter RANG.
    'TOWN': None,   # Use nothing for the parameter TOWN.
}

funcs = {
    'LATI': transform_ll,  # Pass LATI through this function before loading.
    'LONG': transform_ll,  # Pass LONG through it too.
    'UWI': lambda x: "No name, oh no!"
}

In [27]:
w = Well.from_las('P-129_out.LAS', remap=remap, funcs=funcs)

In [28]:
w.location


Out[28]:
Location({'td': 1935.0, 'crs': CRS({}), 'location': 'Lat = 45* 12\' 34.237" N', 'country': 'CA', 'province': 'Nova Scotia', 'latitude': 45.20951027777778, 'longitude': -62.243205555555555, 'kb': 94.8, 'gl': 90.3, 'tdd': 1935.0, 'tdl': 1935.0, 'deviation': None, 'position': None})

In [29]:
w.location.crs  # Should not contain SECT, RANG or TOWN


Out[29]:
CRS({})

In [30]:
w.uwi


Out[30]:
'No name, oh no!'

In [ ]: