Skip to content

Instantly share code, notes, and snippets.

@kwinkunks
Last active June 15, 2021 19:41
Show Gist options
  • Save kwinkunks/170247aa1f852946f63378cfa304d980 to your computer and use it in GitHub Desktop.
Save kwinkunks/170247aa1f852946f63378cfa304d980 to your computer and use it in GitHub Desktop.
Reads special core analysis and core description from SPWLA formatted files.
#!/usr/bin/env python
"""
Reads special core analysis and core description from SPWLA formatted files.
Usage:
./spwla.py infile.spwla outfile.csv
Author:
Matt Hall, ca. 2021
© agilescientific.com
Licence:
Apache 2.0
"""
import pandas as pd
from parsimonious import Grammar
from parsimonious import NodeVisitor
GRAMMAR = Grammar(
r"""
file = file_block field_block core_groups*
file_block = "10" ws number ws file_data ws
file_data = well_name ws country ws date ws company ws
field_block = "15" ws number ws number ws field_row+
field_row = number ws number ws number ws "0" company ws field_name ws
core_groups = range_block data_blocks*
range_block = "20" ws number ws range_data ws
range_data = number ws number ws start_depth ws stop_depth ws number ws number ws
data_blocks = depth_block descr_block? data_block?
depth_block = "30" ws "1" ws depth ws number ws number ws
descr_block = "36" ws "1" ws "1" ws description ws
data_block = "40" ws "1" ws record_count ws data ws
start_depth = number+
stop_depth = number+
record_count = number+
depth = number+
description = sentence+
field_name = sentence+
well_name = sentence+
ws = ~r"\s*"
number = ~r"[-.0-9]+"
data = ~r"[- .0-9]+"
country = ~r"[A-Z]+"i
company = ~r"[-_A-Z]+"i
date = ~r"[A-Z0-9]+"i
sentence = ~r"[-., /A-Z0-9]"i
"""
)
class FileVisitor(NodeVisitor):
"""
Crawl the tree collecting the data.
"""
def __init__(self, date_fmt="%y%b%d"):
self.date_fmt = date_fmt
# -------------- File --------------
def visit_file(self, node, visited_children):
file, fields, cores = visited_children
info = {}
info['file'] = file
info['fields'] = fields
info['cores'] = cores
return info
# -------------- Meta --------------
def visit_file_block(self, node, visited_children):
*_, file_data, _ = visited_children
return file_data
def visit_file_data(self, node, visited_children):
well, _, country, _, date, _, company, _ = node.children
meta = {'well name': well.text}
meta['country'] = country.text
meta['company'] = company.text
try:
meta['date'] = pd.to_datetime(date.text, format=self.date_fmt).isoformat()
except (TypeError, ValueError) as e:
meta['date'] = date.text
return meta
# -------------- Fields --------------
def visit_field_block(self, node, visited_children):
*_, fields = visited_children
return fields
def visit_field_row(self, node, visited_children):
*_, field, _ = node.children
return field.text.strip()
# -------------- Groups --------------
def visit_core_groups(self, node, visited_children):
core_info, core_data, *_ = visited_children
if not isinstance(core_data, list):
core_data = []
return {'meta': core_info, 'samples': core_data}
# -------------- Range --------------
def visit_range_block(self, node, visited_children):
*_, rnge, _ = visited_children
return rnge
def visit_range_data(self, node, visited_children):
*_, start, _, stop, _, _, _, seq, _ = node.children
meta = {'seq': int(seq.text), 'start': float(start.text), 'stop': float(stop.text)}
return meta
# -------------- ALL DATA --------------
def visit_data_blocks(self, node, visited_children):
depth, descr, data = visited_children
if not isinstance(descr, list):
descr = ['']
if not isinstance(data, list):
data = [[]]
return {'depth': depth, 'descr': descr[0], 'data': data[0]}
# -------------- Depth --------------
def visit_depth_block(self, node, visited_children):
_, _, _, _, depth, *_ = node.children
return float(depth.text)
# -------------- Descr --------------
def visit_descr_block(self, node, visited_children):
*_, descr, _ = visited_children
return descr.strip()
def visit_description(self, node, visited_children):
return node.text
# -------------- Data --------------
def visit_data_block(self, node, visited_children):
*_, data, _ = visited_children
return data
def visit_data(self, node, visited_children):
return [float(x) for x in node.text.split()]
# -------------- Generic --------------
def generic_visit(self, node, visited_children):
return visited_children or node
def parse(fname, grammar=None, date_fmt="%y%b%d"):
"""
Given an SPWLA file and a parsimonious PEG grammar, return an abstract
syntax tree as a dictionary.
"""
with open(fname) as f:
text = f.read()
if grammar is None:
grammar = GRAMMAR
tree = grammar.parse(text)
fv = FileVisitor(date_fmt=date_fmt)
return fv.visit(tree)
def serialize(f):
"""
Turn the abstract syntax tree into tidy data (i.e. one row per record).
"""
records = []
for core in f['cores']:
for sample in core['samples']:
record = {}
record['well name'] = f['file']['well name']
record['country'] = f['file']['country']
record['company'] = f['file']['company']
record['date'] = f['file']['date']
record['core'] = core['meta']['seq']
for i, field in enumerate(f['fields']):
record['depth'] = sample['depth']
record['descr'] = sample['descr']
record[field] = sample['data'][i]
records.append(record)
return records
def to_csv(seq, fname):
"""
Take the big list of records and save a CSV. Trivial.
"""
df = pd.DataFrame(seq)
df.to_csv(fname)
return
if __name__ == "__main__":
import sys
if len(sys.argv) != 3:
print("Use like: python spwla.py infile outfile")
_, infile, outfile = sys.argv
to_csv(serialize(parse(infile)))
print("Success.")
10 2
9999/9-9 Norway 9Sep99
Weatherford-Labs
15 10 10
1507 1602 2031 0Weatherford-Labs Nitrogen Permeability, Hor.
1512 1602 2031 0Weatherford-Labs Klinkenberg corrected gas perm, Hor.
1510 1602 2031 0Weatherford-Labs Nitrogen Permeability, Vert.
1515 1602 2031 0Weatherford-Labs Klinkenberg corrected gas perm, Vert.
1402 1211 3084 0Weatherford-Labs Porosity, Horizontal PLUG
1403 1211 3084 0Weatherford-Labs Porosity, Vertical PLUG
1401 1212 3084 0Weatherford-Labs Porosity, Summation
1302 1103 3085 0Weatherford-Labs CORE Oil Saturation
1301 1103 3085 0Weatherford-Labs CORE Water Saturation
2451 1201 1086 0Weatherford-Labs Grain Density, Hor.
20 1
0.00 0.00 1918.00 1983.72 0.0 1
30 1
1918.95 0.00 1.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.44722 -1002.00000 14.78718 -1002.00000 -1002.00000
30 1
1919.95 0.00 2.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 17.06246 -1002.00000 18.06427 -1002.00000 -1002.00000
30 1
1920.95 0.00 3.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 19.58139 -1002.00000 19.01052 -1002.00000 -1002.00000
30 1
1921.95 0.00 4.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.32791 -1002.00000 17.92610 -1002.00000 -1002.00000
30 1
1922.95 0.00 5.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.67100 -1002.00000 20.77644 -1002.00000 -1002.00000
30 1
1923.95 0.00 6.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 15.49629 -1002.00000 24.60543 -1002.00000 -1002.00000
30 1
1924.95 0.00 7.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.28268 -1002.00000 12.88050 -1002.00000 -1002.00000
30 1
1925.95 0.00 8.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.43782 -1002.00000 13.75609 -1002.00000 -1002.00000
30 1
1926.95 0.00 9.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 17.31157 -1002.00000 14.66162 -1002.00000 -1002.00000
30 1
1927.95 0.00 10.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 19.34322 -1002.00000 13.08335 -1002.00000 -1002.00000
30 1
1928.95 0.00 11.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.61451 -1002.00000 18.12203 -1002.00000 -1002.00000
30 1
1929.95 0.00 12.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.17023 -1002.00000 14.21380 -1002.00000 -1002.00000
30 1
1930.95 0.00 13.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.13845 -1002.00000 11.11148 -1002.00000 -1002.00000
30 1
1931.95 0.00 14.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 13.27176 -1002.00000 12.31301 -1002.00000 -1002.00000
30 1
1932.95 0.00 15.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 10.50659 -1002.00000 19.31734 -1002.00000 -1002.00000
30 1
1933.95 0.00 16.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.97168 -1002.00000 21.41411 -1002.00000 -1002.00000
30 1
1934.95 0.00 17.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.40207 -1002.00000 43.12578 -1002.00000 -1002.00000
30 1
1935.95 0.00 18.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 22.72481 -1002.00000 55.43833 -1002.00000 -1002.00000
30 1
1936.95 0.00 19.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.41375 -1002.00000 59.59112 -1002.00000 -1002.00000
30 1
1937.95 0.00 20.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.85675 -1002.00000 50.40101 -1002.00000 -1002.00000
30 1
1938.95 0.00 21.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 17.93774 -1002.00000 44.58358 -1002.00000 -1002.00000
30 1
1940.95 0.00 22.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 18.46985 -1002.00000 49.18243 -1002.00000 -1002.00000
30 1
1941.95 0.00 23.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 14.96825 -1002.00000 47.84605 -1002.00000 -1002.00000
30 1
1942.95 0.00 24.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 19.11698 -1002.00000 47.18030 -1002.00000 -1002.00000
30 1
1943.95 0.00 25.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 17.74624 -1002.00000 47.80520 -1002.00000 -1002.00000
30 1
1944.95 0.00 26.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 11.29837 -1002.00000 46.18566 -1002.00000 -1002.00000
30 1
1945.95 0.00 27.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 19.35403 -1002.00000 45.72604 -1002.00000 -1002.00000
30 1
1946.95 0.00 28.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 15.65132 -1002.00000 47.17111 -1002.00000 -1002.00000
30 1
1947.95 0.00 29.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 13.45465 -1002.00000 40.23944 -1002.00000 -1002.00000
30 1
1948.95 0.00 30.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.54562 -1002.00000 34.87458 -1002.00000 -1002.00000
30 1
1949.95 0.00 31.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 11.08179 -1002.00000 64.16965 -1002.00000 -1002.00000
30 1
1950.95 0.00 32.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 3.50706 -1002.00000 76.56872 -1002.00000 -1002.00000
30 1
1951.95 0.00 33.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 23.04111 -1002.00000 31.48476 -1002.00000 -1002.00000
30 1
1952.95 0.00 34.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 7.55727 -1002.00000 47.81084 -1002.00000 -1002.00000
30 1
1953.95 0.00 35.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.55133 -1002.00000 75.47066 -1002.00000 -1002.00000
30 1
1954.95 0.00 36.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.19806 -1002.00000 50.59302 -1002.00000 -1002.00000
30 1
1955.95 0.00 37.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 15.14130 -1002.00000 35.65407 -1002.00000 -1002.00000
30 1
1956.95 0.00 38.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 9.91299 -1002.00000 47.36896 -1002.00000 -1002.00000
30 1
1957.95 0.00 39.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 13.16705 -1002.00000 55.15691 -1002.00000 -1002.00000
30 1
1958.95 0.00 40.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 15.19265 -1002.00000 53.82990 -1002.00000 -1002.00000
30 1
1959.95 0.00 41.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.62524 -1002.00000 95.89247 -1002.00000 -1002.00000
30 1
1960.95 0.00 42.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 15.74543 -1002.00000 46.03859 -1002.00000 -1002.00000
30 1
1961.95 0.00 43.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 8.15361 -1002.00000 79.35339 -1002.00000 -1002.00000
30 1
1962.95 0.00 44.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 9.97245 -1002.00000 56.16000 -1002.00000 -1002.00000
30 1
1963.95 0.00 45.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 8.24661 -1002.00000 98.42603 -1002.00000 -1002.00000
30 1
1964.95 0.00 46.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 23.81549 -1002.00000 56.95147 -1002.00000 -1002.00000
30 1
1965.95 0.00 47.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 3.19908 -1002.00000 86.53224 -1002.00000 -1002.00000
30 1
1966.95 0.00 48.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 11.62171 -1002.00000 39.52339 -1002.00000 -1002.00000
30 1
1967.95 0.00 49.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 7.92546 -1002.00000 57.87248 -1002.00000 -1002.00000
30 1
1968.95 0.00 50.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 7.92801 -1002.00000 57.82173 -1002.00000 -1002.00000
30 1
1969.95 0.00 51.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 14.87131 -1002.00000 38.74371 -1002.00000 -1002.00000
30 1
1970.95 0.00 52.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 13.93970 -1002.00000 48.10920 -1002.00000 -1002.00000
30 1
1971.95 0.00 53.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 21.59065 -1002.00000 62.04790 -1002.00000 -1002.00000
30 1
1972.95 0.00 54.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 15.92102 -1002.00000 33.92419 -1002.00000 -1002.00000
30 1
1973.95 0.00 55.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 13.01351 -1002.00000 45.90810 -1002.00000 -1002.00000
30 1
1974.95 0.00 56.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.65552 -1002.00000 99.24864 -1002.00000 -1002.00000
30 1
1975.40 0.00 57.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 10.63793 -1002.00000 51.12690 -1002.00000 -1002.00000
30 1
1976.95 0.00 58.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 13.12366 -1002.00000 41.39759 -1002.00000 -1002.00000
30 1
1977.95 0.00 59.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 8.31683 -1002.00000 56.20088 -1002.00000 -1002.00000
30 1
1978.95 0.00 60.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 11.32338 -1002.00000 35.14869 -1002.00000 -1002.00000
30 1
1979.95 0.00 61.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 19.25363 -1002.00000 42.43396 -1002.00000 -1002.00000
30 1
1980.95 0.00 62.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 16.71245 -1002.00000 66.71907 -1002.00000 -1002.00000
30 1
1981.95 0.00 63.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 17.71018 -1002.00000 40.64401 -1002.00000 -1002.00000
30 1
1982.95 0.00 64.11
40 1 10
-1002.00000 -1002.00000 -1002.00000 -1002.00000 -1002.00000 24.12447 -1002.00000 43.71244 -1002.00000 -1002.00000
30 1
1918.05 0.00 1
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,Pyr.
40 1 10
139.86600 125.90000 17.99700 14.71500 20.50453 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.70829
30 1
1918.25 0.00 2
36 1 1
Sst.Lt-gry.VF-gr.Sbang.W-cmt.VW-srt.Irr Lam.w-tr C,Cl,Mic,Pyr.
40 1 10
59.95900 52.31800 8.64900 6.70600 19.31275 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.67364
30 1
1918.50 0.00 3
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,poss Fe-min.
40 1 10
114.34100 102.19600 38.99200 33.07200 20.09979 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.66061
30 1
1918.75 0.00 4
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,poss Fe-min.
40 1 10
85.74300 75.83300 37.67300 31.89500 19.27230 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.67859
30 1
1919.33 0.00 5
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,tr Pyr.
40 1 10
69.43300 60.92200 36.57900 30.77100 19.42854 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.66734
30 1
1919.53 0.00 6
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,tr Pyr.
40 1 10
79.05700 69.70600 46.11600 39.48700 19.00624 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.67377
30 1
1919.73 0.00 7
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,tr Pyr.
40 1 10
78.72200 69.40000 23.46900 19.32600 18.22899 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.66057
30 1
1919.89 0.00 8
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Irr Lam.w-tr C,Cl,Mic,tr Pyr.
40 1 10
79.59100 70.19600 72.44000 63.74100 20.12889 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.69615
30 1
1920.10 0.00 9
36 1 1
Sst.Lt-gry.VF/F-gr.Sbang.W-cmt.W-srt.Lam.w-Cl,Mic,tr Pyr.
40 1 10
18.72400 15.45700 143.77300 129.17200 15.74091 -1002.00000 -1002.00000 -1002.00000 -1002.00000 2.68513
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment