A striplog depends on a hierarchy of objects. This notebook shows the objects and their basic functionality.
Striplogs (a set of Intervals) are described in a separate notebook.
Decors and Legends are also described in another notebook.
In [10]:
import striplog
striplog.__version__
Out[10]:
In [11]:
from striplog import Lexicon
print(Lexicon.__doc__)
In [12]:
lexicon = Lexicon.default()
lexicon
Out[12]:
In [13]:
lexicon.synonyms
Out[13]:
Most of the lexicon works 'behind the scenes' when processing descriptions into Rock components.
In [14]:
lexicon.find_synonym('Halite')
Out[14]:
In [15]:
s = "grysh gn ss w/ sp gy sh"
lexicon.expand_abbreviations(s)
Out[15]:
A set of attributes. All are optional.
In [16]:
from striplog import Component
In [17]:
print(Component.__doc__)
We define a new rock with a Python dict object:
In [18]:
r = {'colour': 'grey',
'grainsize': 'vf-f',
'lithology': 'sand'}
rock = Component(r)
rock
Out[18]:
The Rock has a colour:
In [19]:
rock.colour
Out[19]:
And it has a summary, which is generated from its attributes.
In [20]:
rock.summary()
Out[20]:
We can format the summary if we wish:
In [21]:
rock.summary(fmt="My rock: {lithology} ({colour}, {GRAINSIZE})")
Out[21]:
We can compare rocks with the usual == operator:
In [22]:
rock2 = Component({'grainsize': 'VF-F',
'colour': 'Grey',
'lithology': 'Sand'})
rock == rock2
Out[22]:
In order to create a Component object from text, we need a lexicon to compare the text against. The lexicon describes the language we want to extract, and what it means.
In [23]:
rock3 = Component.from_text('Grey fine sandstone.', lexicon)
rock3
Out[23]:
In [24]:
rock4 = Component.from_text('Grey, sandstone, vf-f ', lexicon)
rock4
Out[24]:
In [25]:
from striplog import Interval
print(Interval.__doc__)
I might make an Interval explicitly from a Component...
In [26]:
Interval(10, 20, components=[rock])
Out[26]:
... or I might pass a description and a lexicon and Striplog will parse the description and attempt to extract structured Component objects from it.
In [27]:
Interval(20, 40, "Grey sandstone with shale flakes.", lexicon=lexicon)
Out[27]:
Notice I only got one Component, even though the description contains a subordinate lithology. This is the default behaviour, we have to ask for more components:
In [28]:
interval = Interval(20, 40, "Grey sandstone with black shale flakes.", lexicon=lexicon, max_component=2)
interval
Out[28]:
Intervals have a primary attribute, which holds the first component, no matter how many components there are.
In [29]:
interval.primary
Out[29]:
Ask for the summary to see the thickness and a Rock summary of the primary component. Note that the format code only applies to the Rock part of the summary.
In [30]:
interval.summary(fmt="{colour} {lithology} {amount}")
Out[30]:
We can compare intervals, based on their thickness. Let's make one which is 5 m thicker than the prvious one.
In [31]:
interval_2 = Interval(40, 65, "Red sandstone.", lexicon=lexicon)
Technical aside: The Interval class is a functools.total_ordering, so providing __eq__ and one other comparison (such as __lt__) in the class definition means that instances of the class have implicit order. So you can use sorted on a Striplog, for example.
It wasn't clear to me whether this should compare tops (say), so that '>' might mean 'deeper', or if it should be keyed on thickness. I chose the latter, and implemented other comparisons instead.
In [32]:
print(interval_2 == interval)
print(interval_2 > interval)
print(max(interval, interval_2).summary())
We can combine intervals with the + operator. (However, you cannot subtract intervals.)
In [33]:
interval_2 + interval
Out[33]:
If we add a number to an interval, it adds thickness to the base.
In [34]:
interval + 5
Out[34]:
Adding a rock adds a (minor) component and adds to the description.
In [35]:
interval + rock3
Out[35]:
©2015 Agile Geoscience. Licensed CC-BY. striplog.py