<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 The Well object
Some preliminaries...
Step1:  Load a well from LAS
In the Quick Start guide you saw how to quickly create a Project from a well with
Step2:  The Location is not stored correctly, with latitude stored in Section and Longitude stored in Township. Also the UWI is wrong (at the top). We can fix all this by 'remapping' some fields. This is done with a dictionary that maps a well's field to its location in the LAS file. For example, we can use the Well field ('Kennetcook #2') to as the UWI in our well with a mapping like
Step3:  Well header
Metadata about the well is stored in its header attribute
Step4:  Important note
At present, the well's header contains a DataFrame with the entire LAS file header.
In a future release, only the well information from the WELL part of the file will be stored in the well's header. (The Params data goes into the well.location attribute, and the Curve data goes into Welly's Curve objects.)
Well location
The well's location contains the location info from PARAMS, and will also store the well's 3D positional information, if available.
Step5:  The CRS for this well is missing; we can add one if we know it
Step6:  Right now there's no position log — we need to load a deviation survey.
Step7:  Add deviation data to a well
Let's load another well
Step8:  The columns are MD, inclination, azimuth, and TVD.
Step9:  add_deviation assumes those are the columns, and computes a position log.
Step10:  The columns in the position log are x offset, y offset, and TVD.
Step11:  For more about the location attribute, see the Well_location help.
Quick plot
welly produces matplotlib plots easily... but they aren't all that pretty. You can pass in an Axes object as ax, and you can embellish the plots by adding more matplotlib commands.
Step12:  Location and CRS
Step13:  Export curves to data matrix
Make a NumPy array
Step14:  Export curves to pandas
Pandas is an optional dependency. You'll need it to make this work.
Step15:  This also gives us another path to getting a matrix
Step16:  You'll have to get depth separately
Step17:  To get the UWI of the well as well, e.g. if you want to combine multiple wells (maybe using welly.Project.df())
Step18:  Pandas with an alias dictionary
Step19:  Make an 'empty' well
Step20:  We can set the UWI and name of a well directly on the well object, but these are the only attributes of the well we can set in this way.
<ASSISTANT_TASK:>
Python Code:
import numpy as np
import matplotlib.pyplot as plt
import welly
welly.__version__
Explanation: The Well object
Some preliminaries...
End of explanation
from welly import Well
well = Well.from_las('https://geocomp.s3.amazonaws.com/data/P-129.LAS')
well
Explanation: Load a well from LAS
In the Quick Start guide you saw how to quickly create a Project from a well with:
python
import welly
project = welly.from_las('path/to/well.las')
A welly.Project is a collection of welly.Well objects. But if you only have a single well, you may not need a Project; a Well object on its own will do. Then you could do this:
python
well, = welly.from_las('path/to/well.las')
The presence of the comma after well unpacks the single item into the welly variable. (This is a Python trick, it's not a Welly thing.)
Alternatively, you can use the Well.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.
End of explanation
remap = {
    'UWI': 'WELL',
    'KB': 'EKB',
    'LATI': 'SECT',
    'LONG': 'TOWN',
    'SECT': None,
    'TOWN': None,
    'LOC': None
}
well = Well.from_las('data/P-129_out.LAS', remap=remap)
well
Explanation: The Location is not stored correctly, with latitude stored in Section and Longitude stored in Township. Also the UWI is wrong (at the top). We can fix all this by 'remapping' some fields. This is done with a dictionary that maps a well's field to its location in the LAS file. For example, we can use the Well field ('Kennetcook #2') to as the UWI in our well with a mapping like: {'UWI': 'WELL'}. We can remove a bad item such as the Section name, by mapping to None:
End of explanation
well.header
Explanation: Well header
Metadata about the well is stored in its header attribute:
End of explanation
well.location
Explanation: Important note
At present, the well's header contains a DataFrame with the entire LAS file header.
In a future release, only the well information from the WELL part of the file will be stored in the well's header. (The Params data goes into the well.location attribute, and the Curve data goes into Welly's Curve objects.)
Well location
The well's location contains the location info from PARAMS, and will also store the well's 3D positional information, if available.
End of explanation
well.location.crs = welly.CRS.from_epsg(2038)
well.location
Explanation: The CRS for this well is missing; we can add one if we know it:
End of explanation
well.location.position
Explanation: Right now there's no position log — we need to load a deviation survey.
End of explanation
import numpy as np
from welly import Well
well = Well.from_las('data/P-130_out.LAS')
dev = np.loadtxt('data/P-130_deviation_survey.csv', delimiter=',', skiprows=1)
Explanation: Add deviation data to a well
Let's load another well:
End of explanation
dev[:5]
Explanation: The columns are MD, inclination, azimuth, and TVD.
End of explanation
p.location.add_deviation(dev[:, :3], td=2618.3)
Explanation: add_deviation assumes those are the columns, and computes a position log.
End of explanation
p.location.position[:5]
p.location.trajectory()
p.location.plot_plan()
p.location.plot_3d()
Explanation: The columns in the position log are x offset, y offset, and TVD.
End of explanation
tracks = ['MD', 'GR', 'RHOB', ['DT', 'DTS'], 'MD']
well.plot(tracks=tracks)
Explanation: For more about the location attribute, see the Well_location help.
Quick plot
welly produces matplotlib plots easily... but they aren't all that pretty. You can pass in an Axes object as ax, and you can embellish the plots by adding more matplotlib commands.
End of explanation
w.location
Explanation: Location and CRS
End of explanation
w.data_as_matrix()
Explanation: Export curves to data matrix
Make a NumPy array:
End of explanation
df = w.df()
df.head()
df.GR.plot()
Explanation: Export curves to pandas
Pandas is an optional dependency. You'll need it to make this work.
End of explanation
w.df().values
Explanation: This also gives us another path to getting a matrix:
End of explanation
w.df().index.values
Explanation: You'll have to get depth separately:
End of explanation
df = w.df(uwi=True)
df.head()
Explanation: To get the UWI of the well as well, e.g. if you want to combine multiple wells (maybe using welly.Project.df()):
End of explanation
alias
keys = ['CALI', 'Gamma', 'Density', 'Sonic', 'RLA1']
w.df(keys=keys, alias=alias, rename_aliased=True).head()
Explanation: Pandas with an alias dictionary
End of explanation
w = welly.Well()
w.header  # is empty
Explanation: Make an 'empty' well
End of explanation
w.uwi = 'foo'
w.uwi
w.header
Explanation: We can set the UWI and name of a well directly on the well object, but these are the only attributes of the well we can set in this way.
End of explanation
<END_TASK>