Reading well logs


In [2]:
from las import LASReader
import numpy as np

In [69]:
fname = "L-30.las"
d = LASReader(fname, null_subs=np.nan)

In [70]:
d.curves.names


Out[70]:
['DEPTH',
 'CALD',
 'CALS',
 'DEPT',
 'DRHO',
 'DT',
 'GRD',
 'GRS',
 'ILD',
 'ILM',
 'LL8',
 'NPHILS',
 'NPHISS',
 'RHOB',
 'SP']

In [71]:
z = d.data['DEPTH']
gr = d.data['GRD']

In [72]:
import matplotlib.pyplot as plt
%matplotlib inline

In [73]:
z.size


Out[73]:
25621

In [81]:
fig = plt.figure(figsize=(15,2))
ax = fig.add_subplot(111)
ax.plot(z[22000:24000], gr[22000:24000])
plt.savefig('test.svg')


Reading string into las.py


In [42]:
t = """~Version Information Section
 VERS.      2.0         :CWLS LOG ASCII STANDARD - VERSION 2.0
 WRAP.      NO          :SINGLE LINE PER DEPTH STEP
 CREA.      8/24/2011 12:51:22
~Well Information Section
#MNEM.UNIT                      VALUE/NAME                 DESCRIPTION
#----.----     ----------------------------------   --------------------
 STRT .FT           1140.0000                         :START DEPTH
 STOP .FT          13950.0000                         :STOP DEPTH
 STEP .FT              0.5000                         :STEP VALUE
 NULL .             -999.0000                         :NULL VALUE
 SRVC .          SCH                                  :Service Company/Logging company
 DATE .          08/24/2011                           :LAS file Creation Date
 WELL .          PENOBSCOT L-30                       :Well Name
 COMP .          SHELL CANADA RESOURCES LIMITED       :Company
 FLD  .          Wildcat                              :Field
 STATE.          Nova Scotia Shelf                    :State
 COUNT.          Canada                               :Country
 LOC  .          44� 09' 43.558"N LAT|60� 04' 0   :Location
 LATI .          0                                    :Latitude/Northing
 LONG .          0                                    :Longitude/Easting
 PDAT .          RT                                   :Permanent Datum
 EPDAT.          0.0000                               :Elevation of Permanent Datum
 LGMEA.          RT                                   :Log Measured from
 APDAT.          98.0000                              :Elevation Above Permanent Datum
 KB   .          99.0000                              :KB Elevation
 GL   .          -451.0000                            :GL Elevation
 RWS  .          0                                    :Def_Rw
 WST  .          0                                    :Def_Rwt
 ERT  .          0.0000                               :RT Elevation
 CNTY .          NOVA SCOTIA SHELF                    :County
~Curve Information Section
#MNEM  .UNIT         CURVE DESCRIPTION
#----  .----         -------------------------
 DEPTH .FT           :1 Depth
 CALD  .IN           :2 Caliper    Caliper - Density
 CALS  .IN           :3 Caliper    Caliper - Sonic
 DEPT  .FT           :4 Depth
 DRHO  .G/CC         :5 Drho       Delta Rho
 DT    .US/F         :6 Sonic      Delta-T
 GRD   .GAPI         :7 GammaRay   Gamma Ray - Density
 GRS   .GAPI         :8 GammaRay   Gamma Ray - Sonic
 ILD   .OHMM         :9 DeepRes    Deep Induction Standard Processed Resistivity
 ILM   .OHMM         :10 MedRes     Medium Induction Standard Processed Resistivity
 LL8   .OHMM         :11 ShalRes    Latero-Log 8
 NPHILS.V/V          :12 Neutron    Neutron Porosity - Ls Mtx
 NPHISS.V/V          :13 Neutron    Neutron Porosity - Ss Mtx
 RHOB  .G/CC         :14 Density    Bulk Density
 SP    .MV           :15 SP         Spontaneous Potential
~Parameter Information Section
#MNEM.UNIT                      VALUE                       DESCRIPTION
#----.----     ----------------------------------   --------------------
~A  DEPTH     CALD      CALS      DEPT      DRHO       DT        GRD       GRS       ILD       ILM       LL8     NPHILS    NPHISS     RHOB       SP    
  1140.0000 -999.0000 -999.0000  1140.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1140.5000 -999.0000 -999.0000  1140.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1141.0000 -999.0000 -999.0000  1141.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1141.5000 -999.0000 -999.0000  1141.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1142.0000 -999.0000 -999.0000  1142.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1142.5000 -999.0000 -999.0000  1142.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1143.0000 -999.0000 -999.0000  1143.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1143.5000 -999.0000 -999.0000  1143.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1144.0000 -999.0000 -999.0000  1144.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1144.5000 -999.0000 -999.0000  1144.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1145.0000 -999.0000 -999.0000  1145.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1145.5000 -999.0000 -999.0000  1145.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1146.0000 -999.0000 -999.0000  1146.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1146.5000 -999.0000 -999.0000  1146.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1147.0000 -999.0000 -999.0000  1147.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1147.5000 -999.0000 -999.0000  1147.5000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1148.0000 -999.0000 -999.0000  1148.0000 -999.0000 -999.0000 -999.0000   34.0030 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1148.5000 -999.0000   12.6410  1148.5000 -999.0000 -999.0000 -999.0000   33.4520 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1149.0000 -999.0000   12.8850  1149.0000 -999.0000 -999.0000 -999.0000   34.2220 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000
  1149.5000 -999.0000   13.1580  1149.5000 -999.0000 -999.0000 -999.0000   36.1130 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000 -999.0000  -48.1260
  1150.0000 -999.0000   13.2850  1150.0000 -999.0000 -999.0000 -999.0000   39.8810 2022.9510    0.6080    0.6750 -999.0000 -999.0000 -999.0000  -53.8200
  1150.5000 -999.0000   13.3860  1150.5000 -999.0000  154.5910 -999.0000   42.4540 2022.9510    0.6080    0.8400 -999.0000 -999.0000 -999.0000  -60.3410
  1151.0000 -999.0000   13.0860  1151.0000 -999.0000  150.0320 -999.0000   41.5810 2022.9510    0.6080    1.4500 -999.0000 -999.0000 -999.0000  -63.8710
  1151.5000 -999.0000   12.7960  1151.5000 -999.0000  172.7620 -999.0000   40.8280   12.7410    1.6040    1.9370 -999.0000 -999.0000 -999.0000  -67.2120"""

In [43]:
import StringIO

In [44]:
from las import LASReader

In [45]:
f = StringIO.StringIO()

In [46]:
f.write(t)
f.seek(0)

Now we have a file object.


In [47]:
d = LASReader(f)

In [48]:
d.well.WELL.data


Out[48]:
'PENOBSCOT L-30'

In [49]:
d.well.KB.data


Out[49]:
'99.0000'

In [50]:
d.curves.names


Out[50]:
['DEPTH',
 'CALD',
 'CALS',
 'DEPT',
 'DRHO',
 'DT',
 'GRD',
 'GRS',
 'ILD',
 'ILM',
 'LL8',
 'NPHILS',
 'NPHISS',
 'RHOB',
 'SP']

In [58]:
d.data[d.curves.names[0]]


Out[58]:
array([ 1140. ,  1140.5,  1141. ,  1141.5,  1142. ,  1142.5,  1143. ,
        1143.5,  1144. ,  1144.5,  1145. ,  1145.5,  1146. ,  1146.5,
        1147. ,  1147.5,  1148. ,  1148.5,  1149. ,  1149.5,  1150. ,
        1150.5,  1151. ,  1151.5])

In [57]:
d.data


Out[57]:
(24,)

Using fuzzyLAS


In [82]:
import requests
import urllib2
import json

In [19]:
mnemonic = 'DTS'
url = "http://fuzzylas.org/lookup?mnemonic={0}&method=simple&guesses=1&format=json".format(mnemonic)

In [90]:
r = urllib2.urlopen(url)

In [91]:
text = r.readlines()[0]

In [92]:
j = json.loads(text)
j


Out[92]:
[{u'DTS': [{u'company': u'Baker Hughes',
    u'description': u'Shear wave slowness',
    u'method': u'Wireline',
    u'mnemonic': u'DTS',
    u'model': u'XMACF1',
    u'type': u'Curve',
    u'units': u's/m',
    u'unittype': u'Acoustic transit time (usec/ft)'},
   {u'company': u'Baker Hughes',
    u'description': u'Shear Slowness',
    u'method': u'LWD',
    u'mnemonic': u'DTS',
    u'model': u'SoundTrak - Acoustic',
    u'type': u'Curve',
    u'units': u'',
    u'unittype': u's'}]},
 {u'DTS': 0}]

In [23]:
# These are regexs
aliases = {
    'GR': ['gamma', 'gapi'],
    'DT': ['slowness', 'acoustic.+?travel', 'usec\/ft'],
    'RT': ['resistivity',],
}

In [24]:
def fuzzy_lookup(mnemonic):
    """
    Gets a result from fuzzyLAS.
    """
    url = "http://fuzzylas.org/lookup?mnemonic={0}&method=simple&guesses=1&format=json".format(mnemonic)
    r = requests.get(url)
    if r.ok:
        return json.loads(r.text)
    else:
        print "ERROR: Lookup failed."
        return None

In [25]:
import re

def get_alias(fuzzylas_json=None):
    """
    Takes a result from fuzzyLAS and finds an alias.
    """
    if not fuzzylas_json:
        print "ERROR: No JSON"
        return None
        
    for k, v in fuzzylas_json[0].items():
        for result in v:
            for a, l in aliases.items():
                # a is the key to alias to
                # l is the list of words to recognize
                f = re.IGNORECASE
                regex = re.compile(r'(\b' + r'\b|\b'.join(l) + r'\b)', flags=f)
                if regex.search(result['description']) or regex.search(result['unittype']):
                    return a

In [26]:
get_alias(fuzzy_lookup('DTS'))


Out[26]:
'DT'

In [35]:
def get_aliases(curves):
    result = {}
    for nasty in curves:
        nice = get_alias(fuzzy_lookup(nasty))
        if nice:
            result[nice] = nasty
    return result

In [37]:
c = get_aliases(['DTS', 'GRD', 'GAMMA', 'arse'])

In [38]:
c.keys()


Out[38]:
['RT', 'DT', 'GR']

In [39]:
c.values()


Out[39]:
['GRD', 'DTS', 'GAMMA']

In [40]:
for k, v in c.items():
    print "{} will be aliased to {}".format(v, k)


GRD will be aliased to RT
DTS will be aliased to DT
GAMMA will be aliased to GR

In [59]:
ind = [d.curves.names[0]] + c.values()

In [60]:
ind


Out[60]:
['DEPTH', 'GRD', 'DTS', 'GAMMA']

In [78]:
d.data[ind]


Out[78]:
array([(1140.0, nan), (1140.5, nan), (1141.0, nan), ..., (13949.0, nan),
       (13949.5, nan), (13950.0, nan)], 
      dtype=[('DEPTH', '<f8'), ('GRD', '<f8')])

In [79]:
mydata = {'DEPTH': list(d.data['DEPTH'])}

In [ ]: