welly package#

Submodules#

welly.canstrat module#

Functions for importing Canstrat ASCII files.

copyright

2021 Agile Geoscience

license

Apache 2.0

welly.canstrat.cols(c)#
welly.canstrat.interval_to_card_7(iv, lith_field)#
welly.canstrat.well_to_card_1(well)#
welly.canstrat.well_to_card_2(well, key)#
Parameters
  • well (welly.Well) – Well object.

  • key (str) – The key of the predicted Striplog in well.data.

Returns

dict.

welly.canstrat.write_row(dictionary, card, log)#

Processes a single row from the file.

welly.canstrat_codes module#

Codes for Canstrat ASCII files; only used by canstrat.py.

copyright

2021 Agile Scientific

license

Apache 2.0

welly.crs module#

CRS functions. Modeled on fiona by Sean Gillies. https://github.com/Toblerity/Fiona

This version… :copyright: 2021 Agile Scientific :license: Apache 2.0

Original code… Copyright (c) 2007, Sean C. Gillies All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  • Neither the name of Sean C. Gillies nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

class welly.crs.CRS(*args, **kwargs)#

Bases: collections.abc.MutableMapping

property data#
classmethod from_epsg(code)#

Given an integer code, returns an EPSG-like mapping. Note: the input code is not validated against an EPSG database.

classmethod from_string(prjs)#

Turn a PROJ.4 string into a mapping of parameters. Bare parameters like “+no_defs” are given a value of True. All keys are checked against the all_proj_keys list.

Parameters

prjs (str) – A PROJ4 string.

to_string()#

Turn a CRS dict into a PROJ.4 string. Mapping keys are tested against all_proj_keys list. Values of True are omitted, leaving the key bare: {‘no_defs’: True} -> “+no_defs” and items where the value is otherwise not a str, int, or float are omitted.

Parameters

crs – A CRS dict as used in Location.

Returns

str. The string representation.

welly.curve module#

Defines log curves

copyright

2021 Agile Scientific

license

Apache 2.0

class welly.curve.Curve(data, *, index=None, basis=None, mnemonic=None, dtype=None, index_name=None, index_units=None, api=None, code=None, description=None, date=None, null=None, run=None, service_company=None, units=None, log_type=None)#

Bases: object

Curve object that can hold 1D and 2D categorical/numerical curve data.

Parameters
  • data (ndarray, Iterable, dict, or pd.DataFrame) – 1D/2D/3D curve numerical or categorical data. Dict can contain Series, arrays, constants, dataclass or list-like objects. If data is a dict, column order follows insertion-order. Input is passed as ‘data’ argument of pd.DataFrame constructor.

  • index (Index or array-like) – Optional. Index to use for resulting pd.DataFrame. Will default to RangeIndex if no indexing information part of input data and no index provided. Input is passed to ‘index’ parameter of the pd.DataFrame constructor.

  • mnemonic (list or str) – Optional. The mnemonic(s) of the curve if the data does not have them. It is passed as the ‘columns’ parameter of pd.DataFrame constructor. Single mnemonic for 1D data, multiple mnemnonics for 2D data.

  • dtype (str) – Optional. Data type to force. Only a single dtype is allowed. If None, infer. Passed to pd.DataFrame constructor.

  • index_name (str) – Optional. Name of the index that will be assigned to pd.DataFrame.index.name (e.g. ‘depth’, ‘time’).

  • index_units (str) – Optional. Unit of the index (e.g. ‘ft’, ‘m’, ‘ms’).

  • api (str) – Optional. Application program interface number.

  • code (int) – Optional. Log code

  • date (str) – Optional. Date of when the curve was recorded, interpreted or exported.

  • description (str) – Optional. Description of the curve.

  • null (float) – Optional. Numeric null value representation (e.g. -9999).

  • run (int) – Optional. The count of the run of the same measurement through the same well.

  • service_company (str) – Optional. Company that executed logging operations.

  • units (str) – Optional. Units of the curve measurements.

Returns

The curve object.

Return type

curve (welly.Curve)

apply(window_length, samples=True, func1d=None)#

Runs any kind of function over a window. Only works on a 1d Curve.

Parameters
  • window_length (int) – the window length. Required.

  • samples (bool) – window length is in samples. Use False for a window length given in metres.

  • func1d (function) – a function that takes a 1D array and returns a scalar. Default: np.mean().

Returns

Curve.

as_numpy()#

Return only the numeric columns as numpy array

astype(dtype, **kwargs)#

Assign dtype to the Curve df.

property basis#

The depth or time basis of the curve’s points.

Returns

ndarray. The array representation of the index.

property basis_units#
block(cutoffs=None, values=None, n_bins=0, right=False, function=None)#

Block a log based on number of bins, or on cutoffs.

Parameters
  • cutoffs (array) – the values at which to create the blocks. Pass a single number, or an array-like of multiple values. If you don’t pass cutoffs, you should pass n_bins (below).

  • values (array) – the values to map to. Defaults to [0, 1, 2,…]. There must be one more value than you have cutoffs (e.g. 2 cutoffs will create 3 zones, each of which needs a value).

  • n_bins (int) – The number of discrete values to use in the blocked log. Only used if you don’t pass cutoffs.

  • right (bool) – Indicating whether the intervals include the right or the left bin edge. Default behavior is right==False indicating that the interval does not include the right edge.

  • function (function) – transform the log with a reducing function, such as np.mean.

Returns

Curve.

describe()#

Returns statistics of the pd.DataFrame of the curve

despike(window_length=33, samples=True, z=2)#

Despiking filter.

Parameters
  • window_length (int) – window length in samples. Default 33 (or 5 m for most curves sampled at 0.1524 m intervals).

  • samples (bool) – window length is in samples. Use False for a window length given in metres.

  • z (float) – Z score

Returns

Curve.

property dtypes#

The data types is the pd.DataFrame data types (pd.Series)

get_alias(alias)#

Given a mnemonic, get the alias name(s) it falls under. If there aren’t any, you get an empty list.

Parameters

alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The alias list.

get_stats()#

Return basic statistics about the curve.

Parameters

arguents. (No) –

Retuns:

dict. The statistics.

property index#

The index is the pd.DataFrame index (pd.Index) of the Curve

property index_name#

The index name is the pd.DataFrame index name (str)

max(axis=0, **kwargs)#

Returns the maximum of the pd.DataFrame values of the columns in the curve in a pd.Series

mean(axis=0, **kwargs)#

Returns the mean of the pd.DataFrame values of the columns in the curve in a pd.Series

median(axis=0, **kwargs)#

Returns the median of the pd.DataFrame values of the columns in the curve in a pd.Series

min(axis=0, **kwargs)#

Returns the minimum of the pd.DataFrame values of the columns in the curve in a pd.Series

property mnemonic#

Return the mnemonic. For a 1d curve, the mnemonic is a string. For a multiple dimension curve, the mnemonic is a list.

plot(ax=None, legend=None, **kwargs)#

Plot a curve. Wrapping plot function from plot.py. By default only show the plot, not return the figure object.

Parameters
  • ax (ax) – A matplotlib axis.

  • legend (striplog.legend) – A legend. Optional. Should contain kwargs for ax.set().

  • kwargs – Arguments for ax.plot()

Returns

ax. If you passed in an ax, otherwise None.

plot_2d(ax=None, width=None, aspect=60, cmap=None, curve=False, ticks=(1, 10), **kwargs)#

Plot a 2D curve. Wrapping plot function from plot.py.

By default only show the plot, not return the figure object.

Parameters
  • ax (ax) – A matplotlib axis.

  • width (int) – The width of the image.

  • aspect (int) – The aspect ratio (not quantitative at all).

  • cmap (str) – The colourmap to use.

  • curve (bool) – Whether to plot the curve as well.

  • ticks (tuple) – The tick interval on the y-axis.

Returns

ax. If you passed in an ax, otherwise None.

plot_kde(ax=None, amax=None, amin=None, label=None)#

Plot a KDE for the curve. Very nice summary of KDEs: https://jakevdp.github.io/blog/2013/12/01/kernel-density-estimation/ Wrapping plot function from plot.py.

By default only show the plot, not return the figure object.

Parameters
  • ax (axis) – Optional matplotlib (MPL) axis to plot into. Returned.

  • amax (float) – Optional max value to permit.

  • amin (float) – Optional min value to permit.

  • label (string) – What to put on the y-axis. Defaults to curve name.

Returns

depending on what you ask for.

Return type

None, axis, figure

qflag(tests, alias=None)#

Run a test and return the corresponding results on a sample-by-sample basis. Wrapping function from quality.py.

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

qflags(tests, alias=None)#

Run a series of tests and return the corresponding results. Wrapping function from quality.py.

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

quality(tests, alias=None)#

Run a series of tests and return the corresponding results.

Wrapping function from quality.py

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

quality_score(tests, alias=None)#

Wrapping function from quality.py.

Run a series of tests and return the normalized score:

  • 1.0: Passed all tests.

  • (0-1): Passed a fraction of tests.

  • 0.0: Passed no tests.

  • -1.0: Took no tests.

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

float. The fraction of tests passed, or -1 for ‘took no tests’.

read_at(index_value, index_name=None, method='linear')#

Read the log at a specific depth/time or an array of depths/times. If the passed depth/time doesn’t exist in the index, interpolate or pick the nearest, depending on the passed method. Default is linear interpolation.

Parameters
  • index_value (float or list of floats) – value or values to read from Curve

  • index_name (str) – Name of the index (e.g. ‘DEPTH’, ‘MD’, ‘TWT’)

  • method (str) – Optional. Method of interpolation: {‘linear’, ‘pad’/’ffill’, ‘backfill’/’bfill’, ‘nearest’}

Returns

The curve value(s) that was read at

the provided index value(s).

Return type

read_value (float or ndarray)

property shape#

The number of dimensions is the pd.DataFrame shape (tuple) of the Curve

property size#

The size is the pd.DataFrame size (int) of the Curve

property start#

The value of the first index. Requires the df (pd.DataFrame) to exist. We keep track of this property because start (STRT) is a required field in a LAS file.

property step#

The increment of the index. Requires a numeric index. We keep track of this property because step (STEP) is a required field in a LAS file.

Returns

Float. If the index is numeric and equally sampled 0. If the index is numeric and not equally sampled None. If the index is not numeric

property stop#

The value of the last index. We keep track of this property because stop (STOP) is a required field in a LAS file.

to_basis(basis=None, start=None, stop=None, step=None, undefined=None, interp_kind='linear')#

Make a new curve in a new basis, given a basis, or a new start, step, and/or stop. You only need to set the parameters you want to change. If the new extents go beyond the current extents, the curve is padded with the undefined parameter.

Currently only works for 1D data (1-column df attribute)

Parameters
  • basis (ndarray) – The basis to compute values for. You can provide a basis, or start, stop, step, or a combination of the two.

  • start (float) – The start position to use. Overrides the start of the basis, if one is provided.

  • stop (float) – The end position to use. Overrides the end of the basis, if one is provided.

  • step (float) – The step to use. Overrides the step in the basis, if one is provided.

  • undefined (float) – The value to use outside the curve’s range. By default, np.nan is used.

  • interp_kind (str) – The kind of interpolation to use to compute the new positions, default is ‘linear’ for numerical data and ‘nearest’ for categorical data. Options are: {None, ‘linear’, backfill’/’bfill’, ‘pad’/’ffill’, ‘nearest’}

Returns

Curve. The current instance in the new basis.

to_basis_like(basis)#

Make a new curve in a new basis, given an existing one. Wraps to_basis().

Pass in a curve or the basis of a curve.

Parameters

basis (ndarray) – A basis, but can also be a Curve instance.

Returns

Curve. The current instance in the new basis.

property values#

The numpy.array representation of the pd.DataFrame of the Curve.

Returns a 1D array if the Curve is 1D, a 2D array if the Curve is 2D.

welly.defaults module#

Defines some default values.

copyright

2021 Agile Scientific

license

Apache 2.0

welly.fields module#

Field mapping from welly to LAS.

copyright

2021 Agile Geoscience

license

Apache 2.0

welly.header module#

Defines well headers.

copyright

2021 Agile Scientific

license

Apache 2.0

class welly.header.Header(params=None)#

Bases: dict

The well metadata or header information.

Not the same as an LAS header, but we might get info from there.

classmethod from_csv(csv_file)#

Not implemented. Will provide a route from CSV file.

classmethod from_lasio(header, remap=None, funcs=None)#

Assumes we’re starting with a lasio object, l.

Parameters
  • header (pd.DataFrame) – Header data from las file

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

welly.las module#

Module for reading and writing to and from LAS files

copyright

2021 Agile Scientific

license

Apache 2.0

welly.las.datasets_to_las(path, datasets, **kwargs)#

Write datasets to a LAS file on disk.

Parameters
  • path (Str) – Path to write LAS file to

  • (Dict['<name>' (datasets) – pd.DataFrame]): Dictionary maps a dataset name (e.g. ‘Curves’) or ‘Header’ to a pd.DataFrame.

Returns

Nothing, only writes in-memory object to disk as .las

welly.las.file_from_url(url)#

Retrieve a file from an HTTPS URL and return it as an in-memory stream for text.

Parameters

url (str) – URL to file.

Returns

an in-memory stream for text.

Return type

text_file (StringIO)

welly.las.from_las(file_ref, **kwargs)#

Read a LAS file with lasio and parse every LAS section to a dataset that consists of two pd.DataFrames:

  1. curve data

  2. header metadata

Only LAS 1.2 and 2.0 are currently supported. LAS 3.0 will be supported when lasio LAS 3.0 work in progress is completed:

The design of this reader already accommodates for LAS 3.0 functionality where one lasio.LASFile can contain multiple 1D, 2D or 3D dataset entries, instead of only 1D data and 1 dataset in LAS 1.2 and LAS 2.0.

Also see:

Parameters
  • file_ref (file-like object, str) – either a filename, an open file object, or a string containing the contents of a LAS file.

  • **kwargs

    The additional keyword arguments are propagated to the lasio reader so you can use when reading in a LAS file. Find the routines of the keyword possibilities here:

    • lasio.reader.open_with_codecs -

      manage issues relate to character encodings.

    • lasio.LASFile.read -

      control how NULL values and errors are handled during parsing.

Returns

pd.DataFrame]): Dictionary maps a

dataset name (e.g. ‘Curves’) or ‘Header’ to a pd.DataFrame.

Return type

datasets (Dict[‘<name>’

Description of datasets object:

datasets = {

‘Curves’: data, # for LAS 1.2 & LAS 2.0 ‘ASCII’: data, # for LAS 3.0 ‘Drilling’: data, # for LAS 3.0 ‘Core[1]’: data, # for LAS 3.0 - Run 1 ‘Core[2]’: data, # for LAS 3.0 - Run 2 ‘Header’: header, # for all (LAS 1.2, LAS 2.0, LAS 3.0)

}

Where…

data (pd.DataFrame): where:

  • every row represents a data index.

  • every column represents a data variable. Column name is the data variable mnemonic.

header (pd.DataFrame): where:

  • every row represents a line read from LAS file and columns.

  • column 1-5 - directly parsed from the

    HeaderItem.__dict__:

    ‘original_mnemonic’ - original mmnemonic ‘mnemonic’ - mnemonic ‘unit’ - unit ‘value’ - value ‘descr’ - description

  • column 6 - is added as a LAS section

    identifier:

    ‘section’ (str) - LAS Section name the line from the LAS file belongs to (e.g. ~Curves)

Example

>>> datasets = from_las(path)
>>> datasets['Curves']
     DEPT    CALI     FACIES
0    1.0     2.4438   0
1    1.5     2.4438   1
2    2.0     2.4438   2
>>> datasets['Header']
    original_mnemonic   mnemonic unit  value    descr         section
0   VERS                VERS           2.0                    Version
1   WRAP                WRAP           YES                    Version
0   STRT                STRT     M     1.0668   START DEPTH   Well
1   STOP                STOP     M     1.524    STOP DEPTH    Well
2   STEP                STEP     M     0.1524   STEP          Well
3   NULL                NULL           -999.25  NULL VALUE    Well
4   COMP                COMP           Energy.C COMPANY       Well
5   WELL                WELL                    WELL          Well
6   UWI                 UWI                     WELL          Well
7   FLD                 FLD                     FIELD         Well
0   DEPT                DEPT     m              DEPTH         Curves
1   CALI                CALI     in             Caliper       Curves
2   FACIES              FACIES                  Facies        Curves
2   EREF                EREF:1   M     100.0    Elevation     Parameter
0                       UNKNOWN                 Comment       Other
welly.las.from_las_2_or_older(las)#

Parse lasio.LASFile to two pd.DataFrames. The ‘Header’ and ‘Curves’ section translate both to a pd.DataFrame.

Requires: LASFile version 1.2 or 2.0.

Parameters

las (lasio.LASFile) – LASFile constructed through lasio.read()

Returns

pd.DataFrame]): Dictionary maps a

dataset name (e.g. ‘Curves’) or ‘Header’ to a pd.DataFrame.

Return type

datasets (Dict[‘<name>’

welly.las.from_lasio(las)#

Creates a datasets dictionary object from a lasio.LASFile.

Parameters

las (lasio.LASFile) – LASFile constructed through lasio.read()

Returns

(data, header)}

Return type

datasets = {‘Curves’

welly.las.get_las_version(las)#

Get the LAS file format version from an in-memory lasio.LAFile object.

There are 3 possible versions (https://www.cwls.org/products/):

  • LAS 1.2

  • LAS 2.0

  • LAS 3.0

Parameters

las (lasio.LASFile) – An in-memory lasio.LASFile object

Returns

LAS format version

Return type

version (float)

welly.las.to_lasio(well, keys=None, alias=None, basis=None, null_value=- 999.25, mnemonic_case='preserve')#

Constructor. If you have a well object, this will create a lasio.LASFile object from it.

Parameters
  • keys (list) – List of strings: the keys of the data items to include, if not all of them. You can have nested lists, such as you might use for tracks in well.plot().

  • alias (dict) – Optional. A dictionary alias for the curve mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • basis (numpy.ndarray) – Optional. The basis to export the curves in. If you don’t specify one, it will survey all the curves with survey_basis()`.

  • null_value (float) – Optional. The null value representation in the LAS file.

  • mnemonic_case (str) – Optional. Can be ‘upper’, ‘lower’, ‘title’, or ‘preserve’. Default: ‘preserve’.

Returns

las (lasio.LASFile). The lasio object representation of a LAS file.

welly.location module#

Defines well location.

copyright

2021 Agile Geoscience

license

Apache 2.0

class welly.location.Location(params=None)#

Bases: object

Contains all location and spatial information.

add_deviation(deviation, td=None, method='mc', update_deviation=True, azimuth_datum=0, course_length=30)#

Add a deviation survey to this instance, and try to compute a position log from it. Acts in place, modifying the Location instance directly.

Parameters
  • deviation (array) – The columns should be: MD, INCL, AZI.

  • td (Number) – The TD of the well, if not the end of the deviation survey you’re passing.

  • method (str) – ‘aa’: average angle ‘bt’: balanced tangential ‘mc’: minimum curvature

  • update_deviation – This function makes some adjustments to the dev- iation survey, to account for the surface and TD. If you do not want to change the stored deviation survey, set to False.

  • azimuth_datum (float) – The orientation of the azimuth datum, relative to the y-axis.

  • course_length (float) – The length over which to normalize the dogleg severity. Typical values are 30 m or 100 ft. Use 1 for no normal- ization.

Returns

None. Adds the position log to well.location in place.

crs_from_epsg(epsg)#

Sets the CRS using an EPSG code.

Parameters

epsg (int) – The EPSG code.

Returns

None.

crs_from_string(string)#

Sets the CRS using a PROJ4 string.

Parameters

string (int) – The PROJ4 string, eg ‘+init=epsg:4269 +no_defs’.

Returns

None.

classmethod from_lasio(header, remap=None, funcs=None)#

Make a Location object from a header object. See las.from_las() for header object description.

Parameters
  • header (pd.DataFrame) –

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

Returns

Location. An instance of this class.

classmethod from_petrel(fname, recalc=False, north='grid', columns=None, update=True, **kwargs)#

Add a location object from a Petrel dev file. Should contain the (x, y), the CRS, the KB, and the position log.

Parameters
  • fname (str) – The dev filename.

  • recalc (bool) – Whether to recalculate the position log from the deviation survey (if possible). Default: False.

  • north (str) – Can be ‘grid’ or ‘true’. This is only a preference; if only one AZIM column is present, you’re getting whatever it is.

  • columns (array) – The columns of the dev file holding the data. If recalc is False (default), then this will be the indices of (x, y, TVDSS), in that order and zero-indexed. Default in that case: [1, 2, 3]. However, if recalc is True then this will be the indices of the dev file columns giving (MD, INCL, AZIM), in that order. In this case the default is [0, 8, 10] for ‘grid’ north, or [0, 8, 7] for ‘true’ north.

  • update – This function makes some adjustments to the position or deviation data, to account for the surface and TD. If you don’t want to change the data from the file, set to False. (The Petrel file probably has absolute position, whereas welly computes relative position, so the first row is always (0, 0, 0). Also, welly always adds points for the 3D position of TD and KB.)

  • **kwargs – passed to welly.tools.compute_position_log.

Returns

Location. An instance of this class.

property md#

The measured depth of the deviation survey.

Returns

ndarray.

property md2tvd#

Provides an transformation and interpolation function that converts MD to TVD.

Parameters

kind (str) – The kind of interpolation to do, e.g. ‘linear’, ‘cubic’, ‘nearest’.

Returns

function.

plot_3d(ax=None, **kwargs)#

Make a 3D plot of the well trajectory.

plot_plan(ax=None, **kwargs)#

Make a map-like plot of the well trajectory.

TODO - Use cartopy or similar for this.

trajectory(datum=None, elev=True, points=1000, **kwargs)#

Get regularly sampled well trajectory. Assumes there is a position log already, e.g. resulting from calling add_deviation() on a deviation survey.

Parameters
  • datum (array-like) – A 3-element array with adjustments to (x, y, z). For example, the x-position, y-position, and KB of the tophole location.

  • elev (bool) – In general the (x, y, z) array of positions will have z as TVD, which is positive down. If elev is True, positive will be upwards.

  • points (int) – The number of points in the trajectory.

  • kwargs – Will be passed to scipy.interpolate.splprep().

Returns

ndarray. An array with shape (points x 3) representing the well

trajectory. Columns are (x, y, z).

property tvd#

The true vertical depth of the deviation survey.

Returns

ndarray.

property tvd2md#

Provides an transformation and interpolation function that converts MD to TVD.

Parameters

kind (str) – The kind of interpolation to do, e.g. ‘linear’, ‘cubic’, ‘nearest’.

Returns

function.

welly.plot module#

Module for plotting projects, wells and curves

copyright

2021 Agile Scientific

license

Apache 2.0

exception welly.plot.WellPlotError#

Bases: Exception

Generic error class.

welly.plot.plot_2d_curve(curve, ax=None, width=None, aspect=60, cmap=None, plot_curve=False, ticks=(1, 10), **kwargs)#

Plot a 2D curve.

Parameters
  • curve (welly.curve.Curve) – Curve object

  • ax (ax) – A matplotlib axis.

  • width (int) – The width of the image.

  • aspect (int) – The aspect ratio (not quantitative at all).

  • cmap (str) – The colourmap to use.

  • plot_curve (bool) – Whether to plot the curve as well.

  • ticks (tuple) – The tick interval on the y-axis.

Returns

ax. If you passed in an ax, otherwise None.

welly.plot.plot_curve(curve, ax=None, legend=None, **kwargs)#

Plot a curve.

Parameters
  • curve (welly.curve.Curve) – Curve object

  • ax (ax) – A matplotlib axis.

  • legend (striplog.legend) – A legend. Optional. Should contain kwargs for ax.set().

  • kwargs – Arguments for ax.plot()

Returns

ax. If you passed in an ax, otherwise the figure.

welly.plot.plot_depth_track_well(well, ax, md, kind='MD', tick_spacing=100)#

Depth track plotting for well.

Parameters
  • well (welly.well.Well) – Well object.

  • ax (ax) – A matplotlib axis.

  • md (ndarray) – The measured depths of the track.

  • kind (str) – The kind of track to plot.

Returns

ax.

welly.plot.plot_kde_curve(curve, ax=None, amax=None, amin=None, label=None)#

Plot a KDE for the curve. Very nice summary of KDEs: https://jakevdp.github.io/blog/2013/12/01/kernel-density-estimation/

Parameters
  • curve (welly.curve.Curve) – Curve object

  • ax (axis) – Optional matplotlib (MPL) axis to plot into. Returned.

  • amax (float) – Optional max value to permit.

  • amin (float) – Optional min value to permit.

  • label (string) – What to put on the y-axis. Defaults to curve name.

Returns

depending on what you ask for. The returned plot is a KDE plot for the curve.

Return type

None, axis, figure

welly.plot.plot_kdes_project(project, mnemonic, alias=None, uwi_regex=None)#

Plot KDEs for all curves with the given name.

Parameters
  • project (welly.project.Project) – Project object

  • menemonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • uwi_regex (str) – a regex pattern. Only this part of the UWI will be displayed on the plot of KDEs.

Returns

None or figure.

welly.plot.plot_map_project(project, fields=('x', 'y'), ax=None, label=None, width=6)#

Plot a map of the wells in the project.

Parameters
  • project (welly.project.Project) – Project object

  • fields (list) – The two fields of the location object to use as the x and y coordinates. Default: (‘x’, ‘y’)

  • ax (matplotlib.axes.Axes) – An axes object to plot into. Will be returned. If you don’t pass one, we’ll create one and give back the fig that it’s in.

  • label (str) – The field of the Well.header object to use as the label. Default: Well.header.name.

  • width (float) – The width, in inches, of the plot. Default: 6 in.

Returns

matplotlib.figure.Figure, or matplotlib.axes.Axes if you passed in

an axes object as ax.

welly.plot.plot_well(well, legend=None, tracks=None, track_titles=None, alias=None, basis=None, extents='td', **kwargs)#

Plot multiple tracks.

Parameters
  • well (welly.well.Well) – Well object.

  • legend (striplog.legend) – A legend instance.

  • tracks (list) – A list of strings and/or lists of strings. The tracks you want to plot from data. Optional, but you will usually want to give it.

  • track_titles (list) – Optional. A list of strings and/or lists of strings. The names to give the tracks, if you don’t want welly to guess.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • basis (ndarray) – Optional. The basis of the plot, if you don’t want welly to guess (probably the best idea).

  • extents (str) – What to use for the y limits: ‘td’ — plot 0 to TD. ‘curves’ — use a basis that accommodates all the curves. ‘all’ — use a basis that accommodates everything. (tuple) — give the upper and lower explictly.

Returns

None. The plot is a side-effect.

welly.project module#

Defines a multi-well ‘project’.

copyright

2021 Agile Scientific

license

Apache 2.0

class welly.project.Project(list_of_Wells, source='')#

Bases: object

Just a list of Well objects.

One day it might want its own CRS, but then we’d have to cast the CRSs of the contained data.

add_canstrat_striplogs(path, uwi_transform=None, name='canstrat')#

This may be too specific a method… just move it to the workflow.

Requires striplog.

property basis_range#

Returns a tuple of the min and max of all the curves in the wells in the project.

count_mnemonic(mnemonic, uwis=<property object>, alias=None)#

Counts the wells that have a given curve, given the mnemonic and an alias dict.

curve_table_html(uwis=None, keys=None, alias=None, tests=None, exclude=None, limit=0)#

Another version of the curve table.

Parameters
  • uwis (list) – Only these UWIs. List of str.

  • keys (list) – Only these names. List of str.

  • alias (dict) – Alias table, maps names to mnemomnics in order of preference.

  • tests (dict) – Test table, maps names to lists of functions.

  • exclude (list) – Except these names. List of str. Ignored if you pass keys.

  • limit (int) – Curve must be present in at least this many wells.

Returns

str. HTML representation of the table.

data_as_matrix(X_keys, y_key=None, alias=None, legend=None, match_only=None, field=None, field_function=None, table=None, legend_field=None, basis=None, step=None, window_length=None, window_step=1, test=None, remove_zeros=False, include_basis=False, include_index=False, include=None)#

Create train matrices of wells in project for mnemonic keys. Optionally add test matrices.

Parameters
  • X_keys (list) – list mnemonics to create X_train matrices from

  • y_key (str) – mnemonic to create y_train matrix

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • legend (Legend) – Passed to striplog.to_log(). If you want the codes to come from a legend, provide one. Otherwise the codes come from the log, using integers in the order of prevalence. If you use a legend, they are assigned in the order of the legend.

  • match_only (list) – Passed to striplog.to_log(). If you only want to match some attributes of the Components (e.g. lithology), provide a list of those you want to match.

  • field (str) – Passed to striplog.to_log(). If you want the data to come from one of the attributes of the components in the striplog, provide it.

  • field_function (function) – Passed to striplog.to_log(). Provide a function to apply to the field you are asking for. It’s up to you to make sure the function does what you want.

  • table (list) – Passed to striplog.to_log(). Provide a look-up table of values if you want. If you don’t, then it will be constructed from the data.

  • legend_field (str) – Passed to striplog.to_log(). If you want to get a log representing one of the fields in the legend, such as ‘width’ or ‘grainsize’.

  • basis (np.array or list) – basis to be used for returned sliced data

  • step (float or int) – step used for reindexing curve basis

  • window_length (int) – The number of samples to return around each sample. This will provide one or more shifted versions of the features.

  • window_step (int) – How much to step the offset versions.

  • test (list) – UWIs to create test matrices from.

  • remove_zeros (bool) – Whether to remove zeros from matrices

  • include_basis (bool) – Whether to include basis in matrices

  • include_index (bool) – Whether to include index in matrices

  • include (np.array) – An additional array to include in the matrices.

Returns

train and test matrices.

Return type

X_train, X_test, y_train, y_test (np.arrays)

df(keys=None, basis=None, alias=None, rename_aliased=True)#

Makes a pandas DataFrame containing Curve data for all the wells in the Project. The DataFrame has a dual index of well UWI and curve Depths. Requires pandas.

Parameters
  • keys (list) – List of strings: the keys of the data items to survey, if not all of them.

  • basis (array) – A basis, if you want to enforce one, otherwise you’ll get the result of survey_basis().

  • alias (dict) – Alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • rename_aliased (bool) – Whether to name the columns after the alias, i.e. the alias dictionary key, or after the curve mnemonic. Default is False, do not rename: use the mnemonic.

Returns

pandas.DataFrame.

filter_wells_by_data(keys, alias=None, func='all')#

Returns a new Project with only the wells which have the named data.

Parameters
  • keys (list) – the names of the data or curves to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • func (str or function) – a string from [‘any’, ‘all’, ‘nany’, ‘nall’] or a runnable function returning a boolean. Return True for wells you want to select. ‘any’ means you want wells which have any of the data keys specified in keys; ‘all’ means you need the well to have all of the keys. Conversely, ‘nany’ means you need the well to not have any of the named keys; ‘nall’ means you need the well to not have all of them (so a well with 4 of 5 named keys would be selected).

Returns

project.

find_wells_with_curve(mnemonic, alias=None)#

Returns a new Project with only the wells which have the named curve.

Parameters
  • mnemonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

project.

find_wells_without_curve(mnemonic, alias=None)#

Returns a new Project with only the wells which DO NOT have the named curve.

Parameters
  • menmonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

project.

classmethod from_las(path=None, remap=None, funcs=None, data=True, req=None, alias=None, max=None, encoding=None, printfname=None, index=None, **kwargs)#

Constructor. Essentially just wraps Well.from_las(), but is more convenient for most purposes.

Parameters
  • path (str or list) – The path of the LAS files, e.g. ./*.las (the default). It will attempt to load everything it finds, so make sure it only leads to LAS files.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Whether to load curves or not.

  • req (list) – A list of alias names, giving all required curves. If not all of the aliases are present, the well is not loaded.

  • alias (dict) – The alias dict, e.g. alias = {'gamma': ['GR', 'GR1'], 'density': ['RHOZ', 'RHOB'], 'pants': ['PANTS']}

  • max (int) – The max number of wells to load.

  • encoding (str) – File encoding; passed to lasio.

  • printfname (bool) – prints filename before trying to load it, for debugging

  • index (str) – Optional. Either “existing” (use the index as found in the LAS file) or “m”, “ft” to use lasio’s conversion of the relevant index unit.

Returns

project. The project object.

get_mnemonics(mnemonics, uwis=None, alias=None)#

Looks at all the wells in turn and returns the highest thing in the alias table.

Parameters
  • mnemonics (list) –

  • alias (dict) –

Returns

list. A list of lists.

get_well(uwi)#

Returns a Well object identified by UWI

Parameters

uwi (string) – the UWI string for the well.

Returns

well

get_wells(uwis=None)#

Returns a new Project with only the wells named by UWI.

Parameters

uwis (list) – list or tuple of UWI strings.

Returns

project.

merge_wells(right, keys=None)#

Returns a new Project object containing wells from self where curves from the wells on the right have been added. Matching between wells in self and right is based on uwi match and ony wells in self are considered.

Parameters
  • right (Project) – Project with well that needs to be merged.

  • keys (list) – list of mnemonics to merge.

Returns

Project

omit_wells(uwis=None)#

Returns a new project where wells with specified uwis have been omitted

Parameters

uwis (list) – list or tuple of UWI strings.

Returns

project

plot_kdes(mnemonic, alias=None, uwi_regex=None)#

Plot KDEs for all curves with the given name.

Parameters
  • mnemonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • uwi_regex (str) – a regex pattern. Only this part of the UWI will be displayed on the plot of KDEs.

Returns

None or figure.

plot_map(fields=('x', 'y'), ax=None, label=None, width=6)#

Plot a map of the wells in the project.

Parameters
  • fields (list) – The two fields of the location object to use as the x and y coordinates. Default: (‘x’, ‘y’)

  • ax (matplotlib.axes.Axes) – An axes object to plot into. Will be returned. If you don’t pass one, we’ll create one and give back the fig that it’s in.

  • label (str) – The field of the Well.header object to use as the label. Default: Well.header.name.

  • width (float) – The width, in inches, of the plot. Default: 6 in.

Returns

matplotlib.figure.Figure, or matplotlib.axes.Axes if you passed in

an axes object as ax.

pop(index)#
property uwis#

Returns the UWIs of the wells in the project.

welly.quality module#

Quality functions for welly.

copyright

2021 Agile Scientific

license

Apache 2.0

welly.quality.all_above(value)#
welly.quality.all_below(value)#
welly.quality.all_between(lower, upper)#
welly.quality.all_positive(curve)#

Define it this way to avoid NaN problem.

welly.quality.check_units(list_of_units)#
welly.quality.count_spikes(curve)#
welly.quality.fraction_not_nans(curve)#

Returns the fraction of the curve extents that are good (non-nan data).

welly.quality.fraction_not_zeros(curve)#

Returns the fraction of the curve extents that are not zeros.

welly.quality.fraction_within_range(xmin, xmax)#
welly.quality.mean_above(value)#
welly.quality.mean_below(value)#
welly.quality.mean_between(lower, upper)#
welly.quality.no_flat(curve)#
welly.quality.no_gaps(curve)#

Check for gaps, after ignoring any NaNs at the top and bottom.

welly.quality.no_monotonic(curve)#

no_flat on the differences of the curve

welly.quality.no_nans(curve)#

Check for NaNs anywhere at all in the curve, even the top or bottom.

welly.quality.no_similarities(well, keys, alias)#
welly.quality.no_spikes(tolerance)#

Arg tolerance is the number of spiky samples allowed.

welly.quality.not_empty(curve)#

If curve.df is not empty, return True.

welly.quality.qc_curve_group_well(well, tests, keys=None, alias=None)#

Run tests on a cohort of curves.

Parameters
  • well (welly.well.Well) – Well object.

  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another. See example in tests/test_quality.py

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict. Test results for all the curves.

{curve_name0: {test0: test_result0, …}, …}

welly.quality.qc_data_well(well, tests, keys=None, alias=None)#

Run a series of tests against the data and return the corresponding results.

Parameters
  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another. See example in tests/test_quality.py

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict. The results. Stick to booleans (True = pass) or ints.

({curve_name: {test_name: test_result}}

welly.quality.qc_table_html_well(well, tests, keys=None, alias=None)#

Makes a nice table out of qc_data().

Parameters
  • well (welly.well.Well) – Well object.

  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another. See example in tests/test_quality.py

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

str. An HTML string for visualization in Jupyter notebook.

Visualize through IPython.display.HTML(str)

welly.quality.qflag_curve(curve, tests, alias=None)#

Run a test and return the corresponding results on a sample-by-sample basis.

Parameters
  • curve (welly.curve.Curve) – Curve object.

  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict. The results. Stick to booleans (True = pass) or ints.

{test_name: test_result}

welly.quality.qflags_curve(curve, tests, alias=None)#

Run a series of tests and return the corresponding results.

Parameters
  • curve (welly.curve.Curve) – Curve object.

  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict. The results. Stick to booleans (True = pass) or ints.

{test_name: test_result}

welly.quality.quality_curve(curve, tests, alias=None)#

Run a series of tests and return the corresponding results.

Parameters
  • curve (welly.curve.Curve) – Curve object.

  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict. The results. Stick to booleans (True = pass) or ints.

{test_name: test_result}

welly.quality.quality_score_curve(curve, tests, alias=None)#

Run a series of tests and return the normalized score.

  • 1.0: Passed all tests.

  • (0-1): Passed a fraction of tests.

  • 0.0: Passed no tests.

  • -1.0: Took no tests.

Parameters
  • curve (welly.curve.Curve) – Curve object.

  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

float. The fraction of tests passed, or -1 for ‘took no tests’.

welly.quality.spike_locations(curve)#

Return the indicies of the spikes.

welly.scales module#

Custom scales for matplotlib.

copyright

2016 Joe Kington

Note: For the two scales, I’ve set the bounds such that you can never go beyond a set range. This gives “stretchy” panning when you reach the ends of a well. Sometimes you’ll want it, sometimes you won’t. In a lot of cases (e.g. multiple wells or flattening on a marker, etc) you’ll want to be able to go beyond the limits of the well. In that case, remove the “limit_range_for_scale” methods below (and BoundedScale entirely) and use an interpolation function that allows extrapolation beyond the limits of the input data.

class welly.scales.BoundedScale(axis, vmin=None, vmax=None)#

Bases: matplotlib.scale.LinearScale

Linear scale with set bounds that can’t be exceeded. Gives a “stretchy” panning effect.

limit_range_for_scale(vmin, vmax, minpos)#

Return the range vmin, vmax, restricted to the domain supported by this scale (if any).

minpos should be the minimum positive value in the data. This is used by log scales to determine a minimum value.

name = 'bounded'#
class welly.scales.PiecewiseLinearScale(axis, x=None, y=None)#

Bases: matplotlib.scale.ScaleBase

Scale based on a piecewise-linear transformation. For example, this might be used to show ticks in two-way time alongside a well log plotted in measured depth using a time-depth curve.

get_transform()#

Return the .Transform object associated with this scale.

limit_range_for_scale(vmin, vmax, minpos)#

Return the range vmin, vmax, restricted to the domain supported by this scale (if any).

minpos should be the minimum positive value in the data. This is used by log scales to determine a minimum value.

name = 'piecewise'#
set_default_locators_and_formatters(axis)#

Set the locators and formatters of axis to instances suitable for this scale.

class welly.scales.PiecewiseLinearTransform(x_from, y_to)#

Bases: matplotlib.transforms.Transform

Transform between two coordinate systems by interpolating between a pre-calculated set of points. For example, transform between time and depth using an average velocity curve.

has_inverse = True#

True if this transform has a corresponding inverse transform.

input_dims = 1#

The number of input dimensions of this transform. Must be overridden (with integers) in the subclass.

inverted()#

Return the corresponding inverse transformation.

It holds x == self.inverted().transform(self.transform(x)).

The return value of this method should be treated as temporary. An update to self does not cause a corresponding update to its inverted copy.

is_separable = True#

True if this transform is separable in the x- and y- dimensions.

output_dims = 1#

The number of output dimensions of this transform. Must be overridden (with integers) in the subclass.

transform_non_affine(x)#

Apply only the non-affine part of this transformation.

transform(values) is always equivalent to transform_affine(transform_non_affine(values)).

In non-affine transformations, this is generally equivalent to transform(values). In affine transformations, this is always a no-op.

Parameters

values (array) – The input values as NumPy array of length input_dims or shape (N x input_dims).

Returns

The output values as NumPy array of length input_dims or shape (N x output_dims), depending on the input.

Return type

array

welly.synthetic module#

Defines a synthetic seismogram.

copyright

2021 Agile Scientific

license

Apache 2.0

class welly.synthetic.Synthetic(data, basis=None, params=None)#

Bases: numpy.ndarray

Synthetic seismograms.

as_curve(data)#

Get the synthetic as a Curve, in depth. Facilitates plotting along- side other curve data.

property basis#

Compute basis rather than storing it.

plot(ax=None, **kwargs)#

Plot a synthetic.

Parameters
  • ax (ax) – A matplotlib axis.

  • legend (Legend) – For now, only here to match API for other plot methods.

Returns

ax. If you passed in an ax, otherwise None.

property stop#

Compute stop rather than storing it.

welly.tools module#

Some extra bits.

copyright

2021 Agile Scientific

license

Apache 2.0

welly.tools.compute_position_log(deviation, td=None, method='mc', azimuth_datum=0, course_length=1)#

Use wellpathpy to return the required welly objects

Parameters
  • deviation (ndarray) – A deviation survey with rows like MD, INC, AZI

  • td (float) – The TD of the well, if not the end of the deviation survey you’re passing.

  • method (str) – ‘mc’: minimum curvature ‘aa’: average angle ‘bt’: balanced tangential ‘hi’: high tangential ‘lo’: low tangential ‘rc’: radius of curvature

  • azimuth_datum (float) – The orientation of the azimuth datum, relative to the y-axis.

  • course_length (float) – Default: 1. The length over which to normalize the dogleg severity. Typical values are 30 m or 100 ft. Use 1 for no normalization. Note: from v0.5, default will be 30.

Returns

ndarray. A position log with rows like X-offset, Y-offset, Z-offset

welly.utils module#

Utility functions for welly.

Copyright: 2021 Agile Scientific Licence: Apache 2.0

class welly.utils.Linker(axes)#

Bases: object

Keeps y-limits of a sequence of axes in sync when panning/zooming.

By Joe Kington

rescale(axes)#
welly.utils.alias_map(alias)#

Reverse an alias dictionary, returning a new dict mapping mnemonics to alias names.

Parameters

alias (dict) – An alias dictionary.

Returns

A new dictionary mapping mnemonics to alias names.

Return type

dict

Example

>>> alias = {'Sonic': ['DT', 'DT4P'], 'Caliper': ['HCAL', 'CALI']}
>>> alias_map(alias)
{'DT': 'Sonic', 'DT4P': 'Sonic', 'HCAL': 'Caliper', 'CALI': 'Caliper'}
welly.utils.are_close(x, y)#
welly.utils.aspect(points)#

Aspect like 2:1 is twice as wide as high.

This function returns the WIDTH per unit height.

welly.utils.bbox(points)#
welly.utils.dd2dms(dd)#

Decimal degrees to DMS.

Parameters

dd (float) –

Returns

tuple. Degrees, minutes, and seconds.

welly.utils.deprecated(instructions)#

Flags a method as deprecated. This decorator can be used to mark functions as deprecated. It will result in a warning being emitted when the function is used.

Parameters

instructions (str) – A human-friendly string of instructions, such as: ‘Please migrate to add_proxy() ASAP.’

Returns

The decorated function.

welly.utils.dms2dd(dms)#

DMS to decimal degrees.

Parameters

dms (list) –

Returns

float.

welly.utils.extrapolate(a)#

From bruges

Extrapolate up and down an array from the first and last non-NaN samples.

E.g. Continue the first and last non-NaN values of a log up and down.

welly.utils.find_edges(a)#

Return two arrays: one of the changes, and one of the values.

Returns

Two ndarrays, tops and values.

Return type

tuple

welly.utils.find_file(pattern, path)#

A bit like grep. Finds a pattern, looking in path. Returns the filename.

welly.utils.find_nearest(a, value, index=False)#

Find the array value, or index of the array value, closest to some given value.

Parameters
  • a (ndarray) –

  • value (float) –

  • index (bool) – whether to return the index instead of the array value.

Returns

float. The array value (or index, as int) nearest the specified value.

welly.utils.find_previous(a, value, index=False, return_distance=False)#

Find the nearest array value, or index of the array value, before some given value. Optionally also return the fractional distance of the given value from that previous value.

Parameters
  • a (ndarray) –

  • value (float) –

  • index (bool) – whether to return the index instead of the array value. Default: False.

  • return_distance (bool) – whether to return the fractional distance from the nearest value to the specified value. Default: False.

Returns

float. The array value (or index, as int) before the specified value.

If return_distance==True then a tuple is returned, where the second value is the distance.

welly.utils.fix_ticks(ax)#

Center ticklabels and hide any outside axes limits.

By Joe Kington

welly.utils.flatten_list(L)#

Flattens a list. For example:

>> flatten_list([1, 2, [3, 4], [5, [6, 7]]]) [1, 2, 3, 4, 5, 6, 7]

welly.utils.get_columns_decimal_formatter(data, null_value=None)#

Get the column decimal point formatter from the two-dimensional numpy.ndarray. Get the number of decimal points from columns with numerical values (float or int). Take the highest number of decimal points of the column values. The dictionary maps the column order of occurrence to the numerical formatter function. If a column has no numerical values, don’t create a mapping for that column in the dictionary.

For example, an input np.ndarray might look like this.

  • 1st column values: most occurring 2 decimal points

  • 2nd column values: most occurring 5 decimal points

  • 3rd column values: most occurring 10 decimal points

This will return the following.

column_fmt = {0: ‘%.2f’, 1: ‘%.5f’, 2: ‘%.10f’}

Parameters
  • data (numpy.ndarray) – two-dimensional array with floats and/or ints (columns and rows).

  • null_value (float) – Optional. A float that represents null/NaN in the column values from which we do not take the number of decimals.

Returns

Mapping of order of column occurrence to most occurring decimal point formatting function

Return type

column_fmt (dict)

welly.utils.get_header_item(header, section, item, attrib='value', default=None, remap=None, funcs=None)#

Grabs a header item from a header pd.DataFrame and optionally renames and transforms it.

Parameters
  • header (pd.DataFrame) – Header from LAS file parsed to tabular form. See las.from_las() for more information.

  • section (str) – The LAS section to grab from, eg well

  • item (str) – The item in the LAS section to grab from, eg name

  • attrib (str) – The attribute of the item to grab, eg value

  • default (str) – What to return instead.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

Returns

The requested, optionally transformed, item.

welly.utils.get_lines(handle, line)#

Get zero-indexed line from an open file-like.

welly.utils.get_number_of_decimal_points(value)#

Get the number of decimal points from a numeric value (float or int).

Parameters

value (float or int) – Numeric value

Returns

Number of decimal points if value is of type float or int, otherwise return None.

Return type

n_decimals (int)

welly.utils.get_step_from_array(arr)#

Gets the ‘step’ or increment of the array. Requires numeric values in array

Parameters

arr (np.array) – The array

Returns

Float. If the index is numeric and equally sampled 0. If the index is numeric and not equally sampled None. If the index is not numeric

welly.utils.hex_is_dark(hexx, percent=50)#

Function to decide if a hex colour is dark.

Parameters

hexx (str) – A hexadecimal colour, starting with ‘#’.

Returns

The colour’s brightness is less than the given percent.

Return type

bool

welly.utils.hex_to_rgb(hexx)#

Utility function to convert hex to (r,g,b) triples. http://ageo.co/1CFxXpO

Parameters

hexx (str) – A hexadecimal colour, starting with ‘#’.

Returns

The equivalent RGB triple, in the range 0 to 255.

Return type

tuple

welly.utils.linear(u, v, d)#

Linear interpolation.

Parameters
  • u (float) –

  • v (float) –

  • d (float) – the relative distance between the two to return.

Returns

float. The interpolated value.

welly.utils.list_and_add(a, b)#

Concatenate anything into a list.

Parameters
  • a – the first thing

  • b – the second thing

Returns

list. All the things in a list.

welly.utils.moving_average(a, length, mode='valid')#

From bruges

Computes the mean in a moving window. Naive implementation.

Example

>>> test = np.array([1,9,9,9,9,9,9,2,3,9,2,2,3,1,1,1,1,3,4,9,9,9,8,3])
>>> moving_average(test, 7, mode='same')
[ 4.42857143,  5.57142857,  6.71428571,  7.85714286,  8.        ,
7.14285714,  7.14285714,  6.14285714,  5.14285714,  4.28571429,
3.14285714,  3.        ,  2.71428571,  1.57142857,  1.71428571,
2.        ,  2.85714286,  4.        ,  5.14285714,  6.14285714,
6.42857143,  6.42857143,  6.28571429,  5.42857143]
welly.utils.moving_avg_conv(a, length)#

From bruges

Moving average via convolution. Seems slower than naive.

welly.utils.nan_idx(y)#

Helper to handle indices and logical indices of NaNs.

Parameters

y (ndarray) – 1D array with possible NaNs

Returns

nans, logical indices of NaNs index, a function, with signature indices= index(logical_indices),

to convert logical indices of NaNs to ‘equivalent’ indices

Example

>> # linear interpolation of NaNs >> nans, x = nan_helper(y) >> y[nans] = np.interp(x(nans), x(~nans), y[~nans])

welly.utils.normalize(a, new_min=0.0, new_max=1.0)#

From bruges

Normalize an array to [0,1] or to arbitrary new min and max.

Parameters
  • a (ndarray) –

  • new_min (float) – the new min, default 0.

  • new_max (float) – the new max, default 1.

Returns

ndarray. The normalized array.

welly.utils.null(x)#

Null function. Used for default in functions that can apply a user- supplied function to data before returning.

welly.utils.null_default(x)#

Null function. Used for default in functions that can apply a user- supplied function to data before returning.

welly.utils.parabolic(f, x)#

Interpolation. From ageobot, from somewhere else.

welly.utils.ricker(f, length, dt)#

A Ricker wavelet.

Parameters
  • f (float) – frequency in Haz, e.g. 25 Hz.

  • length (float) – Length in s, e.g. 0.128.

  • dt (float) – sample interval in s, e.g. 0.001.

Returns

tuple. time basis, amplitude values.

welly.utils.rms(a)#

From bruges

Calculates the RMS of an array.

Parameters

a – An array.

Returns

The RMS of the array.

welly.utils.round_to_n(x, n)#

Round to sig figs

welly.utils.sharey(axes)#

Shared axes limits without shared locators, ticks, etc.

By Joe Kington

welly.utils.skip(x)#

Always returns None.

welly.utils.text_colour_for_hex(hexx, percent=50, dark='#000000', light='#ffffff')#

Function to decide what colour to use for a given hex colour.

Parameters

hexx (str) – A hexadecimal colour, starting with ‘#’.

Returns

The colour’s brightness is less than the given percent.

Return type

bool

welly.utils.to_filename(path)#

Convert string/pathlib.Path to string.

Parameters

path (str/pathlib.Path) – filename

Returns

filename

Return type

str

welly.utils.top_and_tail(a)#

Remove the NaNs from the top and tail (only) of a well log.

Parameters

a (ndarray) – An array.

Returns

The top and tailed array.

Return type

ndarray

welly.utils.unsharey(ax)#

Remove sharing from an axes.

By Joe Kington

welly.well module#

Defines wells.

copyright

2021 Agile Scientific

license

Apache 2.0

class welly.well.Well(params=None)#

Bases: object

Well contains everything about the well.

add_curves_from_las(fname, remap=None, funcs=None)#

Given a LAS file, add curves from it to the current well instance. Essentially just wraps add_curves_from_lasio().

Parameters
  • fname (str or list) – The path(s) of the LAS file to read curves from

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

Returns

None. Works in place.

add_curves_from_lasio(las)#

Given a LAS file, add curves from it to the current well instance. Essentially just wraps add_curves_from_lasio().

Parameters

las (lasio.LASFile object) – a lasio representation of a LAS file

Returns

None. Works in place.

add_header_item(item, value, unit=None, descr=None)#
Parameters
  • item (str) – The item name to add. Requires to be present in las_fields (e.g. well, uwi, null)

  • value (str/float/int) – The value of the item to add

  • unit (str) – Optional. The unit of the item to add

  • descr (str) – Optional. The description of the item to add

Returns

Nothing, works inplace.

alias_has_multiple(mnemonic, alias)#
assign_categorical(mnemonics)#

Assign the category dtype to the columns of the curve.df attribute.

Parameters

mnemonics (list) – Mnemonics of the curves to be assigned as categorical

Returns

Nothing, works inplace.

count_curves(keys=None, alias=None)#

Counts the number of curves in the well that will be selected with the given key list and the given alias dict. Used by Project’s curve table.

coverage(keys=None, alias=None)#

Plot the coverage of the curves in a well.

data_as_matrix(keys=None, return_meta=None, return_basis=False, basis=None, alias=None, start=None, stop=None, step=None, window_length=None, window_step=1, window_func=None)#

Provide a feature matrix, given a list of data items.

I think this will probably fail if there are striplogs in the data dictionary for this well.

Parameters
  • keys (list) – List of the logs to export from the data dictionary.

  • return_meta (bool) – Whether or not to return the basis and the keys (feature names). In a future release, this will be the default.

  • return_basis (bool) – Whether or not to return the basis that was used.

  • basis (ndarray) – The basis to use. Default is to survey all curves to find a common basis.

  • alias (dict) – A mapping of alias names to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • start (float) – Optionally override the start of whatever basis you find or (more likely) is surveyed.

  • stop (float) – Optionally override the stop of whatever basis you find or (more likely) is surveyed.

  • step (float) – Override the step in the basis from survey_basis.

  • window_length (int) – The number of samples to return around each sample. This will provide one or more shifted versions of the features.

  • window_step (int) – How much to step the offset versions.

  • window_func (function) – A function to apply to the window. The default is the identity function f(x) = x, which is the same as shifting the data. Passing np.mean would smooth the data.

Returns

ndarray. or ndarray, ndarray if return_basis=True

df(keys=None, basis=None, uwi=False, alias=None, rename_aliased=True)#

Return current curve data as a pandas.DataFrame object.

Requires pandas.

Everything has to have the same basis, because the depth is going to become the index of the DataFrame. If you don’t provide one, welly will make one using survey_basis().

Parameters
  • keys (list) – List of strings: the keys of the data items to survey, if not all of them.

  • basis (array) – A basis, if you want to enforce one, otherwise you’ll get the result of survey_basis().

  • uwi (bool) – Whether to add a ‘UWI’ column.

  • alias (dict) – Alias dictionary.

  • rename_aliased (bool) – Whether to name the columns after the alias, i.e. the alias dictionary key, or after the curve mnemonic. Default is True, use the alias names.

Returns

pandas.DataFrame.

classmethod from_datasets(datasets, remap=None, funcs=None, data=None, req=None, alias=None, fname=None, index_units=None)#

Constructor. If you have a datasets object, this will create a well object from it. See las.from_las() for a description of a datasets object.

Parameters
  • (Dict['<name>' (datasets) – pd.DataFrame]): Dictionary maps a dataset name (e.g. ‘Curves’ or ‘Header’) to a pd.DataFrame.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Whether to load curves or not.

  • req (list) – An alias list, giving all required curves.

  • alias (dict) – An alias dictionary.

  • fname (str) – The filename, if you want to keep it.

  • index_units (str) – Optional. The unit of the index upon construction of the Curves (e.g. ‘m’ or ‘ft’). Will perform unit conversion if specified index unit is different than the existing index unit.

Returns

well (welly.Well). The well object.

classmethod from_df(df, units=None, req=None, uwi=None, name=None)#

Constructor. If you have a pd.DataFrame with the time/depth index set as the pd.DataFrame index and the columns as the curve data, this makes a well object from it. The column name is taken as the respective curve mnemonic.

Use this if you don’t have a header dataframe with meta data. If you do, please use Well.from_datasets()

Parameters
  • df (pd.DataFrame) – Curve data.

  • units (dict) – Optional. Units of measurement of the curves in df.

  • req (list) – Optional. An alias list, giving all required curves.

  • uwi (str) – Unique Well Identifier (UWI)

  • name (str) – Name

Returns

well. The well object.

classmethod from_las(fname, remap=None, funcs=None, data=True, req=None, alias=None, encoding=None, printfname=False, index=None, **kwargs)#

Constructor. If you have a LAS file saved on disk, this creates a well object from it.

Parameters
  • fname (str or pathlib.Path) – The path of the LAS file, or a URL to one.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Optional. Whether to load the data or only the header.

  • req (list) – Optional. An alias list, giving all required curves.

  • alias (dict) – Optional. An alias dictionary.

  • encoding (str) – Optional. the character encoding used when reading the LAS file in from disk.

  • printfname (bool) – Optional. prints filename before trying to load it, for debugging.

  • index (str) – Optional. Either “existing” (use the index as found in the LAS file) or “m”, “ft” to use lasio’s conversion of the relevant index unit.

  • kwargs – More keyword arguments are passed to lasio.

Returns

well. The well object.

classmethod from_lasio(las, remap=None, funcs=None, data=True, req=None, alias=None, fname=None, index=None)#

Constructor. If you already have the lasio object, then this makes a well object from it.

Parameters
  • las (lasio.LASFile object) – a lasio representation of a LAS file.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Whether to load curves or not.

  • req (list) – An alias list, giving all required curves.

  • alias (dict) – An alias dictionary.

  • fname (str) – The filename, if you want to keep it.

  • index (str) – Optional. Either “existing” (use the index as found in the LAS file) or “m”, “ft” to use lasio’s conversion of the relevant index unit.

Returns

well (welly.Well). The well object.

get_alias(mnemonic, alias=None)#

Get the alias key that this mnemonic belongs to.

Returns: str.

get_curve(mnemonic, alias=None)#

Wraps get_mnemonic.

Instead of picking curves by name directly from the data dict, you can pick them up with this method, which takes account of the alias dict you pass it. If you do not pass an alias dict, then you get the curve you asked for, if it exists, or None. NB Wells do not have alias dicts, but Projects do.

Parameters
  • mnemonic (str) – the name of the curve you want.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

Curve.

get_mnemonic(mnemonic, alias=None)#

Instead of picking curves by name directly from the data dict, you can pick them up with this method, which takes account of the alias dict you pass it. If you do not pass an alias dict, then you get the curve you asked for, if it exists, or None. NB Wells do not have alias dicts, but Projects do.

Parameters
  • mnemonic (str) – the name of the curve you want.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

str.

get_mnemonics_from_regex(pattern)#

Should probably integrate getting curves with regex, vs getting with aliases, even though mixing them is probably confusing. For now I can’t think of another use case for these wildcards, so I’ll just implement for the curve table and we can worry about a nice solution later if we ever come back to it.

is_complete(keys=None, alias=None)#

Returns False if the well does not have one or more of the keys in its data dictionary. Used by project.data_to_matrix().

make_synthetic(srd=0, v_repl_seismic=2000, v_repl_log=2000, f=50, dt=0.001)#

Early hack. Use with extreme caution.

Hands-free. There’ll be a more granualr version in synthetic.py.

Assumes DT is in µs/m and RHOB is kg/m3.

There is no handling yet for TVD.

The datum handling is probably sketchy.

property name#

Property. Simply a shortcut to the well name from the header, or the empty string if there isn’t one.

plot(legend=None, tracks=None, track_titles=None, alias=None, basis=None, extents='td', **kwargs)#

Plot multiple tracks. Wrapping plot function from plot.py. By default only show the plot, not return the figure object.

Parameters
  • legend (striplog.legend) – A legend instance.

  • tracks (list) – A list of strings and/or lists of strings. The tracks you want to plot from data. Optional, but you will usually want to give it.

  • track_titles (list) – Optional. A list of strings and/or lists of strings. The names to give the tracks, if you don’t want welly to guess.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics.

  • basis (ndarray) – Optional. The basis of the plot, if you don’t want welly to guess (probably the best idea).

  • extents (str) – What to use for the y limits: ‘td’: plot 0 to TD. ‘curves’: use a basis that accommodates all the curves. ‘all’: use a basis that accommodates everything. (tuple): give the upper and lower explictly.

Returns

None. The plot is a side-effect.

qc_curve_group(tests, keys=None, alias=None)#

Run tests on a cohort of curves. Wrapping functions from quality.py

Parameters
  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another.

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict.

qc_data(tests, keys=None, alias=None)#

Run a series of tests against the data and return the corresponding results. Wrapping frunction from quality.py.

Parameters
  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another.

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

qc_table_html(tests, keys=None, alias=None)#

Makes a nice table out of qc_data() Wrapping function from quality.py.

Returns

str. An HTML string for visualization in Jupyter notebook. Visualize through IPython.display.HTML(str)

survey_basis(keys=None, alias=None, step=None)#

Look at the basis of all the curves in well.data and return a basis with the minimum start, maximum depth, and minimum step.

Parameters
  • keys (list) – List of strings: the keys of the data items to survey, if not all of them.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics.

  • step (float) – a new step, if you want to change it.

Returns

ndarray. The most complete common basis.

to_canstrat(key, log, lith_field, filename=None, as_text=False)#

Make a Canstrat DAT (aka ASCII) file.

Parameters
  • filename (str) –

  • key (str) –

  • log (str) – the log name, should be 6 characters.

  • lith_field (str) – Primary component. Must match the Canstrat definitions.

  • filename

  • as_text (bool) – if you don’t want to write a file.

to_datasets(keys=None, alias=None, basis=None, null_value=- 999.25)#

Unpack a well to datasets (a dict with pd.DataFrames)

to_las(fname, keys=None, basis=None, null_value=- 999.25, mnemonic_case='preserve', **kwargs)#

Writes the current well instance as a LAS file. Essentially just wraps to_lasio(), but is more convenient for most purposes.

Parameters
  • fname (str) – The path of the LAS file to create.

  • basis (ndarray) – Optional. The basis to export the curves in. If you don’t specify one, it will survey all the curves with survey_basis().

  • null_value (float) – Optional. numeric null value representation

  • keys (list) – List of strings: the keys of the data items to include, if not all of them. You can have nested lists, such as you might use for tracks in well.plot().

Other keyword Args are passed to lasio.LASFile.write().

Returns

None. Writes the file as a side-effect.

to_lasio(keys=None, alias=None, basis=None, null_value=- 999.25, mnemonic_case=None)#

Makes a lasio object from the current well.

Parameters
  • keys (list) – List of strings: the keys of the data items to include, if not all of them. You can have nested lists, such as you might use for tracks in well.plot().

  • alias (dict) – Optional. A dictionary alias for the curve mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • basis (numpy.ndarray) – Optional. The basis to export the curves in. If you don’t specify one, it will survey all the curves with survey_basis()`.

  • null_value (float) – Optional. The null value representation in the LAS file.

Returns

las (lasio.LASFile). The lasio object representation of a LAS file.

unify_basis(keys=None, alias=None, basis=None, start=None, stop=None, step=None)#

Give every Curve in the well, or everything in the list of keys, the same basis. If you don’t provide a basis, welly will try to get one using survey_basis().

Parameters
  • keys (list) – List of strings: the keys of the data items to unify, if not all of them.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • basis (ndarray) – A basis: the regularly sampled depths at which you want the samples.

  • start (float) – Optionally override the start of whatever basis you provide or is surveyed.

  • stop (float) – Optionally override the stop of whatever basis you provide or is surveyed.

  • step (float) – Optionally override the step in the basis.

Returns

None. Works in place.

property uwi#

Property. Simply a shortcut to the UWI from the header, or the empty string if there isn’t one.

exception welly.well.WellError#

Bases: Exception

Generic error class.

Module contents#

welly#

class welly.CRS(*args, **kwargs)#

Bases: collections.abc.MutableMapping

property data#
classmethod from_epsg(code)#

Given an integer code, returns an EPSG-like mapping. Note: the input code is not validated against an EPSG database.

classmethod from_string(prjs)#

Turn a PROJ.4 string into a mapping of parameters. Bare parameters like “+no_defs” are given a value of True. All keys are checked against the all_proj_keys list.

Parameters

prjs (str) – A PROJ4 string.

to_string()#

Turn a CRS dict into a PROJ.4 string. Mapping keys are tested against all_proj_keys list. Values of True are omitted, leaving the key bare: {‘no_defs’: True} -> “+no_defs” and items where the value is otherwise not a str, int, or float are omitted.

Parameters

crs – A CRS dict as used in Location.

Returns

str. The string representation.

class welly.Curve(data, *, index=None, basis=None, mnemonic=None, dtype=None, index_name=None, index_units=None, api=None, code=None, description=None, date=None, null=None, run=None, service_company=None, units=None, log_type=None)#

Bases: object

Curve object that can hold 1D and 2D categorical/numerical curve data.

Parameters
  • data (ndarray, Iterable, dict, or pd.DataFrame) – 1D/2D/3D curve numerical or categorical data. Dict can contain Series, arrays, constants, dataclass or list-like objects. If data is a dict, column order follows insertion-order. Input is passed as ‘data’ argument of pd.DataFrame constructor.

  • index (Index or array-like) – Optional. Index to use for resulting pd.DataFrame. Will default to RangeIndex if no indexing information part of input data and no index provided. Input is passed to ‘index’ parameter of the pd.DataFrame constructor.

  • mnemonic (list or str) – Optional. The mnemonic(s) of the curve if the data does not have them. It is passed as the ‘columns’ parameter of pd.DataFrame constructor. Single mnemonic for 1D data, multiple mnemnonics for 2D data.

  • dtype (str) – Optional. Data type to force. Only a single dtype is allowed. If None, infer. Passed to pd.DataFrame constructor.

  • index_name (str) – Optional. Name of the index that will be assigned to pd.DataFrame.index.name (e.g. ‘depth’, ‘time’).

  • index_units (str) – Optional. Unit of the index (e.g. ‘ft’, ‘m’, ‘ms’).

  • api (str) – Optional. Application program interface number.

  • code (int) – Optional. Log code

  • date (str) – Optional. Date of when the curve was recorded, interpreted or exported.

  • description (str) – Optional. Description of the curve.

  • null (float) – Optional. Numeric null value representation (e.g. -9999).

  • run (int) – Optional. The count of the run of the same measurement through the same well.

  • service_company (str) – Optional. Company that executed logging operations.

  • units (str) – Optional. Units of the curve measurements.

Returns

The curve object.

Return type

curve (welly.Curve)

apply(window_length, samples=True, func1d=None)#

Runs any kind of function over a window. Only works on a 1d Curve.

Parameters
  • window_length (int) – the window length. Required.

  • samples (bool) – window length is in samples. Use False for a window length given in metres.

  • func1d (function) – a function that takes a 1D array and returns a scalar. Default: np.mean().

Returns

Curve.

as_numpy()#

Return only the numeric columns as numpy array

astype(dtype, **kwargs)#

Assign dtype to the Curve df.

property basis#

The depth or time basis of the curve’s points.

Returns

ndarray. The array representation of the index.

property basis_units#
block(cutoffs=None, values=None, n_bins=0, right=False, function=None)#

Block a log based on number of bins, or on cutoffs.

Parameters
  • cutoffs (array) – the values at which to create the blocks. Pass a single number, or an array-like of multiple values. If you don’t pass cutoffs, you should pass n_bins (below).

  • values (array) – the values to map to. Defaults to [0, 1, 2,…]. There must be one more value than you have cutoffs (e.g. 2 cutoffs will create 3 zones, each of which needs a value).

  • n_bins (int) – The number of discrete values to use in the blocked log. Only used if you don’t pass cutoffs.

  • right (bool) – Indicating whether the intervals include the right or the left bin edge. Default behavior is right==False indicating that the interval does not include the right edge.

  • function (function) – transform the log with a reducing function, such as np.mean.

Returns

Curve.

describe()#

Returns statistics of the pd.DataFrame of the curve

despike(window_length=33, samples=True, z=2)#

Despiking filter.

Parameters
  • window_length (int) – window length in samples. Default 33 (or 5 m for most curves sampled at 0.1524 m intervals).

  • samples (bool) – window length is in samples. Use False for a window length given in metres.

  • z (float) – Z score

Returns

Curve.

property dtypes#

The data types is the pd.DataFrame data types (pd.Series)

get_alias(alias)#

Given a mnemonic, get the alias name(s) it falls under. If there aren’t any, you get an empty list.

Parameters

alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The alias list.

get_stats()#

Return basic statistics about the curve.

Parameters

arguents. (No) –

Retuns:

dict. The statistics.

property index#

The index is the pd.DataFrame index (pd.Index) of the Curve

property index_name#

The index name is the pd.DataFrame index name (str)

max(axis=0, **kwargs)#

Returns the maximum of the pd.DataFrame values of the columns in the curve in a pd.Series

mean(axis=0, **kwargs)#

Returns the mean of the pd.DataFrame values of the columns in the curve in a pd.Series

median(axis=0, **kwargs)#

Returns the median of the pd.DataFrame values of the columns in the curve in a pd.Series

min(axis=0, **kwargs)#

Returns the minimum of the pd.DataFrame values of the columns in the curve in a pd.Series

property mnemonic#

Return the mnemonic. For a 1d curve, the mnemonic is a string. For a multiple dimension curve, the mnemonic is a list.

plot(ax=None, legend=None, **kwargs)#

Plot a curve. Wrapping plot function from plot.py. By default only show the plot, not return the figure object.

Parameters
  • ax (ax) – A matplotlib axis.

  • legend (striplog.legend) – A legend. Optional. Should contain kwargs for ax.set().

  • kwargs – Arguments for ax.plot()

Returns

ax. If you passed in an ax, otherwise None.

plot_2d(ax=None, width=None, aspect=60, cmap=None, curve=False, ticks=(1, 10), **kwargs)#

Plot a 2D curve. Wrapping plot function from plot.py.

By default only show the plot, not return the figure object.

Parameters
  • ax (ax) – A matplotlib axis.

  • width (int) – The width of the image.

  • aspect (int) – The aspect ratio (not quantitative at all).

  • cmap (str) – The colourmap to use.

  • curve (bool) – Whether to plot the curve as well.

  • ticks (tuple) – The tick interval on the y-axis.

Returns

ax. If you passed in an ax, otherwise None.

plot_kde(ax=None, amax=None, amin=None, label=None)#

Plot a KDE for the curve. Very nice summary of KDEs: https://jakevdp.github.io/blog/2013/12/01/kernel-density-estimation/ Wrapping plot function from plot.py.

By default only show the plot, not return the figure object.

Parameters
  • ax (axis) – Optional matplotlib (MPL) axis to plot into. Returned.

  • amax (float) – Optional max value to permit.

  • amin (float) – Optional min value to permit.

  • label (string) – What to put on the y-axis. Defaults to curve name.

Returns

depending on what you ask for.

Return type

None, axis, figure

qflag(tests, alias=None)#

Run a test and return the corresponding results on a sample-by-sample basis. Wrapping function from quality.py.

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

qflags(tests, alias=None)#

Run a series of tests and return the corresponding results. Wrapping function from quality.py.

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

quality(tests, alias=None)#

Run a series of tests and return the corresponding results.

Wrapping function from quality.py

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

quality_score(tests, alias=None)#

Wrapping function from quality.py.

Run a series of tests and return the normalized score:

  • 1.0: Passed all tests.

  • (0-1): Passed a fraction of tests.

  • 0.0: Passed no tests.

  • -1.0: Took no tests.

Parameters
  • tests (list) – a list of functions.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

float. The fraction of tests passed, or -1 for ‘took no tests’.

read_at(index_value, index_name=None, method='linear')#

Read the log at a specific depth/time or an array of depths/times. If the passed depth/time doesn’t exist in the index, interpolate or pick the nearest, depending on the passed method. Default is linear interpolation.

Parameters
  • index_value (float or list of floats) – value or values to read from Curve

  • index_name (str) – Name of the index (e.g. ‘DEPTH’, ‘MD’, ‘TWT’)

  • method (str) – Optional. Method of interpolation: {‘linear’, ‘pad’/’ffill’, ‘backfill’/’bfill’, ‘nearest’}

Returns

The curve value(s) that was read at

the provided index value(s).

Return type

read_value (float or ndarray)

property shape#

The number of dimensions is the pd.DataFrame shape (tuple) of the Curve

property size#

The size is the pd.DataFrame size (int) of the Curve

property start#

The value of the first index. Requires the df (pd.DataFrame) to exist. We keep track of this property because start (STRT) is a required field in a LAS file.

property step#

The increment of the index. Requires a numeric index. We keep track of this property because step (STEP) is a required field in a LAS file.

Returns

Float. If the index is numeric and equally sampled 0. If the index is numeric and not equally sampled None. If the index is not numeric

property stop#

The value of the last index. We keep track of this property because stop (STOP) is a required field in a LAS file.

to_basis(basis=None, start=None, stop=None, step=None, undefined=None, interp_kind='linear')#

Make a new curve in a new basis, given a basis, or a new start, step, and/or stop. You only need to set the parameters you want to change. If the new extents go beyond the current extents, the curve is padded with the undefined parameter.

Currently only works for 1D data (1-column df attribute)

Parameters
  • basis (ndarray) – The basis to compute values for. You can provide a basis, or start, stop, step, or a combination of the two.

  • start (float) – The start position to use. Overrides the start of the basis, if one is provided.

  • stop (float) – The end position to use. Overrides the end of the basis, if one is provided.

  • step (float) – The step to use. Overrides the step in the basis, if one is provided.

  • undefined (float) – The value to use outside the curve’s range. By default, np.nan is used.

  • interp_kind (str) – The kind of interpolation to use to compute the new positions, default is ‘linear’ for numerical data and ‘nearest’ for categorical data. Options are: {None, ‘linear’, backfill’/’bfill’, ‘pad’/’ffill’, ‘nearest’}

Returns

Curve. The current instance in the new basis.

to_basis_like(basis)#

Make a new curve in a new basis, given an existing one. Wraps to_basis().

Pass in a curve or the basis of a curve.

Parameters

basis (ndarray) – A basis, but can also be a Curve instance.

Returns

Curve. The current instance in the new basis.

property values#

The numpy.array representation of the pd.DataFrame of the Curve.

Returns a 1D array if the Curve is 1D, a 2D array if the Curve is 2D.

class welly.Header(params=None)#

Bases: dict

The well metadata or header information.

Not the same as an LAS header, but we might get info from there.

classmethod from_csv(csv_file)#

Not implemented. Will provide a route from CSV file.

classmethod from_lasio(header, remap=None, funcs=None)#

Assumes we’re starting with a lasio object, l.

Parameters
  • header (pd.DataFrame) – Header data from las file

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

class welly.Location(params=None)#

Bases: object

Contains all location and spatial information.

add_deviation(deviation, td=None, method='mc', update_deviation=True, azimuth_datum=0, course_length=30)#

Add a deviation survey to this instance, and try to compute a position log from it. Acts in place, modifying the Location instance directly.

Parameters
  • deviation (array) – The columns should be: MD, INCL, AZI.

  • td (Number) – The TD of the well, if not the end of the deviation survey you’re passing.

  • method (str) – ‘aa’: average angle ‘bt’: balanced tangential ‘mc’: minimum curvature

  • update_deviation – This function makes some adjustments to the dev- iation survey, to account for the surface and TD. If you do not want to change the stored deviation survey, set to False.

  • azimuth_datum (float) – The orientation of the azimuth datum, relative to the y-axis.

  • course_length (float) – The length over which to normalize the dogleg severity. Typical values are 30 m or 100 ft. Use 1 for no normal- ization.

Returns

None. Adds the position log to well.location in place.

crs_from_epsg(epsg)#

Sets the CRS using an EPSG code.

Parameters

epsg (int) – The EPSG code.

Returns

None.

crs_from_string(string)#

Sets the CRS using a PROJ4 string.

Parameters

string (int) – The PROJ4 string, eg ‘+init=epsg:4269 +no_defs’.

Returns

None.

classmethod from_lasio(header, remap=None, funcs=None)#

Make a Location object from a header object. See las.from_las() for header object description.

Parameters
  • header (pd.DataFrame) –

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

Returns

Location. An instance of this class.

classmethod from_petrel(fname, recalc=False, north='grid', columns=None, update=True, **kwargs)#

Add a location object from a Petrel dev file. Should contain the (x, y), the CRS, the KB, and the position log.

Parameters
  • fname (str) – The dev filename.

  • recalc (bool) – Whether to recalculate the position log from the deviation survey (if possible). Default: False.

  • north (str) – Can be ‘grid’ or ‘true’. This is only a preference; if only one AZIM column is present, you’re getting whatever it is.

  • columns (array) – The columns of the dev file holding the data. If recalc is False (default), then this will be the indices of (x, y, TVDSS), in that order and zero-indexed. Default in that case: [1, 2, 3]. However, if recalc is True then this will be the indices of the dev file columns giving (MD, INCL, AZIM), in that order. In this case the default is [0, 8, 10] for ‘grid’ north, or [0, 8, 7] for ‘true’ north.

  • update – This function makes some adjustments to the position or deviation data, to account for the surface and TD. If you don’t want to change the data from the file, set to False. (The Petrel file probably has absolute position, whereas welly computes relative position, so the first row is always (0, 0, 0). Also, welly always adds points for the 3D position of TD and KB.)

  • **kwargs – passed to welly.tools.compute_position_log.

Returns

Location. An instance of this class.

property md#

The measured depth of the deviation survey.

Returns

ndarray.

property md2tvd#

Provides an transformation and interpolation function that converts MD to TVD.

Parameters

kind (str) – The kind of interpolation to do, e.g. ‘linear’, ‘cubic’, ‘nearest’.

Returns

function.

plot_3d(ax=None, **kwargs)#

Make a 3D plot of the well trajectory.

plot_plan(ax=None, **kwargs)#

Make a map-like plot of the well trajectory.

TODO - Use cartopy or similar for this.

trajectory(datum=None, elev=True, points=1000, **kwargs)#

Get regularly sampled well trajectory. Assumes there is a position log already, e.g. resulting from calling add_deviation() on a deviation survey.

Parameters
  • datum (array-like) – A 3-element array with adjustments to (x, y, z). For example, the x-position, y-position, and KB of the tophole location.

  • elev (bool) – In general the (x, y, z) array of positions will have z as TVD, which is positive down. If elev is True, positive will be upwards.

  • points (int) – The number of points in the trajectory.

  • kwargs – Will be passed to scipy.interpolate.splprep().

Returns

ndarray. An array with shape (points x 3) representing the well

trajectory. Columns are (x, y, z).

property tvd#

The true vertical depth of the deviation survey.

Returns

ndarray.

property tvd2md#

Provides an transformation and interpolation function that converts MD to TVD.

Parameters

kind (str) – The kind of interpolation to do, e.g. ‘linear’, ‘cubic’, ‘nearest’.

Returns

function.

class welly.Project(list_of_Wells, source='')#

Bases: object

Just a list of Well objects.

One day it might want its own CRS, but then we’d have to cast the CRSs of the contained data.

add_canstrat_striplogs(path, uwi_transform=None, name='canstrat')#

This may be too specific a method… just move it to the workflow.

Requires striplog.

property basis_range#

Returns a tuple of the min and max of all the curves in the wells in the project.

count_mnemonic(mnemonic, uwis=<property object>, alias=None)#

Counts the wells that have a given curve, given the mnemonic and an alias dict.

curve_table_html(uwis=None, keys=None, alias=None, tests=None, exclude=None, limit=0)#

Another version of the curve table.

Parameters
  • uwis (list) – Only these UWIs. List of str.

  • keys (list) – Only these names. List of str.

  • alias (dict) – Alias table, maps names to mnemomnics in order of preference.

  • tests (dict) – Test table, maps names to lists of functions.

  • exclude (list) – Except these names. List of str. Ignored if you pass keys.

  • limit (int) – Curve must be present in at least this many wells.

Returns

str. HTML representation of the table.

data_as_matrix(X_keys, y_key=None, alias=None, legend=None, match_only=None, field=None, field_function=None, table=None, legend_field=None, basis=None, step=None, window_length=None, window_step=1, test=None, remove_zeros=False, include_basis=False, include_index=False, include=None)#

Create train matrices of wells in project for mnemonic keys. Optionally add test matrices.

Parameters
  • X_keys (list) – list mnemonics to create X_train matrices from

  • y_key (str) – mnemonic to create y_train matrix

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • legend (Legend) – Passed to striplog.to_log(). If you want the codes to come from a legend, provide one. Otherwise the codes come from the log, using integers in the order of prevalence. If you use a legend, they are assigned in the order of the legend.

  • match_only (list) – Passed to striplog.to_log(). If you only want to match some attributes of the Components (e.g. lithology), provide a list of those you want to match.

  • field (str) – Passed to striplog.to_log(). If you want the data to come from one of the attributes of the components in the striplog, provide it.

  • field_function (function) – Passed to striplog.to_log(). Provide a function to apply to the field you are asking for. It’s up to you to make sure the function does what you want.

  • table (list) – Passed to striplog.to_log(). Provide a look-up table of values if you want. If you don’t, then it will be constructed from the data.

  • legend_field (str) – Passed to striplog.to_log(). If you want to get a log representing one of the fields in the legend, such as ‘width’ or ‘grainsize’.

  • basis (np.array or list) – basis to be used for returned sliced data

  • step (float or int) – step used for reindexing curve basis

  • window_length (int) – The number of samples to return around each sample. This will provide one or more shifted versions of the features.

  • window_step (int) – How much to step the offset versions.

  • test (list) – UWIs to create test matrices from.

  • remove_zeros (bool) – Whether to remove zeros from matrices

  • include_basis (bool) – Whether to include basis in matrices

  • include_index (bool) – Whether to include index in matrices

  • include (np.array) – An additional array to include in the matrices.

Returns

train and test matrices.

Return type

X_train, X_test, y_train, y_test (np.arrays)

df(keys=None, basis=None, alias=None, rename_aliased=True)#

Makes a pandas DataFrame containing Curve data for all the wells in the Project. The DataFrame has a dual index of well UWI and curve Depths. Requires pandas.

Parameters
  • keys (list) – List of strings: the keys of the data items to survey, if not all of them.

  • basis (array) – A basis, if you want to enforce one, otherwise you’ll get the result of survey_basis().

  • alias (dict) – Alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • rename_aliased (bool) – Whether to name the columns after the alias, i.e. the alias dictionary key, or after the curve mnemonic. Default is False, do not rename: use the mnemonic.

Returns

pandas.DataFrame.

filter_wells_by_data(keys, alias=None, func='all')#

Returns a new Project with only the wells which have the named data.

Parameters
  • keys (list) – the names of the data or curves to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • func (str or function) – a string from [‘any’, ‘all’, ‘nany’, ‘nall’] or a runnable function returning a boolean. Return True for wells you want to select. ‘any’ means you want wells which have any of the data keys specified in keys; ‘all’ means you need the well to have all of the keys. Conversely, ‘nany’ means you need the well to not have any of the named keys; ‘nall’ means you need the well to not have all of them (so a well with 4 of 5 named keys would be selected).

Returns

project.

find_wells_with_curve(mnemonic, alias=None)#

Returns a new Project with only the wells which have the named curve.

Parameters
  • mnemonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

project.

find_wells_without_curve(mnemonic, alias=None)#

Returns a new Project with only the wells which DO NOT have the named curve.

Parameters
  • menmonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

project.

classmethod from_las(path=None, remap=None, funcs=None, data=True, req=None, alias=None, max=None, encoding=None, printfname=None, index=None, **kwargs)#

Constructor. Essentially just wraps Well.from_las(), but is more convenient for most purposes.

Parameters
  • path (str or list) – The path of the LAS files, e.g. ./*.las (the default). It will attempt to load everything it finds, so make sure it only leads to LAS files.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Whether to load curves or not.

  • req (list) – A list of alias names, giving all required curves. If not all of the aliases are present, the well is not loaded.

  • alias (dict) – The alias dict, e.g. alias = {'gamma': ['GR', 'GR1'], 'density': ['RHOZ', 'RHOB'], 'pants': ['PANTS']}

  • max (int) – The max number of wells to load.

  • encoding (str) – File encoding; passed to lasio.

  • printfname (bool) – prints filename before trying to load it, for debugging

  • index (str) – Optional. Either “existing” (use the index as found in the LAS file) or “m”, “ft” to use lasio’s conversion of the relevant index unit.

Returns

project. The project object.

get_mnemonics(mnemonics, uwis=None, alias=None)#

Looks at all the wells in turn and returns the highest thing in the alias table.

Parameters
  • mnemonics (list) –

  • alias (dict) –

Returns

list. A list of lists.

get_well(uwi)#

Returns a Well object identified by UWI

Parameters

uwi (string) – the UWI string for the well.

Returns

well

get_wells(uwis=None)#

Returns a new Project with only the wells named by UWI.

Parameters

uwis (list) – list or tuple of UWI strings.

Returns

project.

merge_wells(right, keys=None)#

Returns a new Project object containing wells from self where curves from the wells on the right have been added. Matching between wells in self and right is based on uwi match and ony wells in self are considered.

Parameters
  • right (Project) – Project with well that needs to be merged.

  • keys (list) – list of mnemonics to merge.

Returns

Project

omit_wells(uwis=None)#

Returns a new project where wells with specified uwis have been omitted

Parameters

uwis (list) – list or tuple of UWI strings.

Returns

project

plot_kdes(mnemonic, alias=None, uwi_regex=None)#

Plot KDEs for all curves with the given name.

Parameters
  • mnemonic (str) – the name of the curve to look for.

  • alias (dict) – a welly alias dictionary. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • uwi_regex (str) – a regex pattern. Only this part of the UWI will be displayed on the plot of KDEs.

Returns

None or figure.

plot_map(fields=('x', 'y'), ax=None, label=None, width=6)#

Plot a map of the wells in the project.

Parameters
  • fields (list) – The two fields of the location object to use as the x and y coordinates. Default: (‘x’, ‘y’)

  • ax (matplotlib.axes.Axes) – An axes object to plot into. Will be returned. If you don’t pass one, we’ll create one and give back the fig that it’s in.

  • label (str) – The field of the Well.header object to use as the label. Default: Well.header.name.

  • width (float) – The width, in inches, of the plot. Default: 6 in.

Returns

matplotlib.figure.Figure, or matplotlib.axes.Axes if you passed in

an axes object as ax.

pop(index)#
property uwis#

Returns the UWIs of the wells in the project.

class welly.Synthetic(data, basis=None, params=None)#

Bases: numpy.ndarray

Synthetic seismograms.

as_curve(data)#

Get the synthetic as a Curve, in depth. Facilitates plotting along- side other curve data.

property basis#

Compute basis rather than storing it.

plot(ax=None, **kwargs)#

Plot a synthetic.

Parameters
  • ax (ax) – A matplotlib axis.

  • legend (Legend) – For now, only here to match API for other plot methods.

Returns

ax. If you passed in an ax, otherwise None.

property stop#

Compute stop rather than storing it.

class welly.Well(params=None)#

Bases: object

Well contains everything about the well.

add_curves_from_las(fname, remap=None, funcs=None)#

Given a LAS file, add curves from it to the current well instance. Essentially just wraps add_curves_from_lasio().

Parameters
  • fname (str or list) – The path(s) of the LAS file to read curves from

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

Returns

None. Works in place.

add_curves_from_lasio(las)#

Given a LAS file, add curves from it to the current well instance. Essentially just wraps add_curves_from_lasio().

Parameters

las (lasio.LASFile object) – a lasio representation of a LAS file

Returns

None. Works in place.

add_header_item(item, value, unit=None, descr=None)#
Parameters
  • item (str) – The item name to add. Requires to be present in las_fields (e.g. well, uwi, null)

  • value (str/float/int) – The value of the item to add

  • unit (str) – Optional. The unit of the item to add

  • descr (str) – Optional. The description of the item to add

Returns

Nothing, works inplace.

alias_has_multiple(mnemonic, alias)#
assign_categorical(mnemonics)#

Assign the category dtype to the columns of the curve.df attribute.

Parameters

mnemonics (list) – Mnemonics of the curves to be assigned as categorical

Returns

Nothing, works inplace.

count_curves(keys=None, alias=None)#

Counts the number of curves in the well that will be selected with the given key list and the given alias dict. Used by Project’s curve table.

coverage(keys=None, alias=None)#

Plot the coverage of the curves in a well.

data_as_matrix(keys=None, return_meta=None, return_basis=False, basis=None, alias=None, start=None, stop=None, step=None, window_length=None, window_step=1, window_func=None)#

Provide a feature matrix, given a list of data items.

I think this will probably fail if there are striplogs in the data dictionary for this well.

Parameters
  • keys (list) – List of the logs to export from the data dictionary.

  • return_meta (bool) – Whether or not to return the basis and the keys (feature names). In a future release, this will be the default.

  • return_basis (bool) – Whether or not to return the basis that was used.

  • basis (ndarray) – The basis to use. Default is to survey all curves to find a common basis.

  • alias (dict) – A mapping of alias names to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • start (float) – Optionally override the start of whatever basis you find or (more likely) is surveyed.

  • stop (float) – Optionally override the stop of whatever basis you find or (more likely) is surveyed.

  • step (float) – Override the step in the basis from survey_basis.

  • window_length (int) – The number of samples to return around each sample. This will provide one or more shifted versions of the features.

  • window_step (int) – How much to step the offset versions.

  • window_func (function) – A function to apply to the window. The default is the identity function f(x) = x, which is the same as shifting the data. Passing np.mean would smooth the data.

Returns

ndarray. or ndarray, ndarray if return_basis=True

df(keys=None, basis=None, uwi=False, alias=None, rename_aliased=True)#

Return current curve data as a pandas.DataFrame object.

Requires pandas.

Everything has to have the same basis, because the depth is going to become the index of the DataFrame. If you don’t provide one, welly will make one using survey_basis().

Parameters
  • keys (list) – List of strings: the keys of the data items to survey, if not all of them.

  • basis (array) – A basis, if you want to enforce one, otherwise you’ll get the result of survey_basis().

  • uwi (bool) – Whether to add a ‘UWI’ column.

  • alias (dict) – Alias dictionary.

  • rename_aliased (bool) – Whether to name the columns after the alias, i.e. the alias dictionary key, or after the curve mnemonic. Default is True, use the alias names.

Returns

pandas.DataFrame.

classmethod from_datasets(datasets, remap=None, funcs=None, data=None, req=None, alias=None, fname=None, index_units=None)#

Constructor. If you have a datasets object, this will create a well object from it. See las.from_las() for a description of a datasets object.

Parameters
  • (Dict['<name>' (datasets) – pd.DataFrame]): Dictionary maps a dataset name (e.g. ‘Curves’ or ‘Header’) to a pd.DataFrame.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Whether to load curves or not.

  • req (list) – An alias list, giving all required curves.

  • alias (dict) – An alias dictionary.

  • fname (str) – The filename, if you want to keep it.

  • index_units (str) – Optional. The unit of the index upon construction of the Curves (e.g. ‘m’ or ‘ft’). Will perform unit conversion if specified index unit is different than the existing index unit.

Returns

well (welly.Well). The well object.

classmethod from_df(df, units=None, req=None, uwi=None, name=None)#

Constructor. If you have a pd.DataFrame with the time/depth index set as the pd.DataFrame index and the columns as the curve data, this makes a well object from it. The column name is taken as the respective curve mnemonic.

Use this if you don’t have a header dataframe with meta data. If you do, please use Well.from_datasets()

Parameters
  • df (pd.DataFrame) – Curve data.

  • units (dict) – Optional. Units of measurement of the curves in df.

  • req (list) – Optional. An alias list, giving all required curves.

  • uwi (str) – Unique Well Identifier (UWI)

  • name (str) – Name

Returns

well. The well object.

classmethod from_las(fname, remap=None, funcs=None, data=True, req=None, alias=None, encoding=None, printfname=False, index=None, **kwargs)#

Constructor. If you have a LAS file saved on disk, this creates a well object from it.

Parameters
  • fname (str or pathlib.Path) – The path of the LAS file, or a URL to one.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Optional. Whether to load the data or only the header.

  • req (list) – Optional. An alias list, giving all required curves.

  • alias (dict) – Optional. An alias dictionary.

  • encoding (str) – Optional. the character encoding used when reading the LAS file in from disk.

  • printfname (bool) – Optional. prints filename before trying to load it, for debugging.

  • index (str) – Optional. Either “existing” (use the index as found in the LAS file) or “m”, “ft” to use lasio’s conversion of the relevant index unit.

  • kwargs – More keyword arguments are passed to lasio.

Returns

well. The well object.

classmethod from_lasio(las, remap=None, funcs=None, data=True, req=None, alias=None, fname=None, index=None)#

Constructor. If you already have the lasio object, then this makes a well object from it.

Parameters
  • las (lasio.LASFile object) – a lasio representation of a LAS file.

  • remap (dict) – Optional. A dict of ‘old’: ‘new’ LAS field names.

  • funcs (dict) – Optional. A dict of ‘las field’: function() for implementing a transform before loading. Can be a lambda.

  • data (bool) – Whether to load curves or not.

  • req (list) – An alias list, giving all required curves.

  • alias (dict) – An alias dictionary.

  • fname (str) – The filename, if you want to keep it.

  • index (str) – Optional. Either “existing” (use the index as found in the LAS file) or “m”, “ft” to use lasio’s conversion of the relevant index unit.

Returns

well (welly.Well). The well object.

get_alias(mnemonic, alias=None)#

Get the alias key that this mnemonic belongs to.

Returns: str.

get_curve(mnemonic, alias=None)#

Wraps get_mnemonic.

Instead of picking curves by name directly from the data dict, you can pick them up with this method, which takes account of the alias dict you pass it. If you do not pass an alias dict, then you get the curve you asked for, if it exists, or None. NB Wells do not have alias dicts, but Projects do.

Parameters
  • mnemonic (str) – the name of the curve you want.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

Curve.

get_mnemonic(mnemonic, alias=None)#

Instead of picking curves by name directly from the data dict, you can pick them up with this method, which takes account of the alias dict you pass it. If you do not pass an alias dict, then you get the curve you asked for, if it exists, or None. NB Wells do not have alias dicts, but Projects do.

Parameters
  • mnemonic (str) – the name of the curve you want.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

str.

get_mnemonics_from_regex(pattern)#

Should probably integrate getting curves with regex, vs getting with aliases, even though mixing them is probably confusing. For now I can’t think of another use case for these wildcards, so I’ll just implement for the curve table and we can worry about a nice solution later if we ever come back to it.

is_complete(keys=None, alias=None)#

Returns False if the well does not have one or more of the keys in its data dictionary. Used by project.data_to_matrix().

make_synthetic(srd=0, v_repl_seismic=2000, v_repl_log=2000, f=50, dt=0.001)#

Early hack. Use with extreme caution.

Hands-free. There’ll be a more granualr version in synthetic.py.

Assumes DT is in µs/m and RHOB is kg/m3.

There is no handling yet for TVD.

The datum handling is probably sketchy.

property name#

Property. Simply a shortcut to the well name from the header, or the empty string if there isn’t one.

plot(legend=None, tracks=None, track_titles=None, alias=None, basis=None, extents='td', **kwargs)#

Plot multiple tracks. Wrapping plot function from plot.py. By default only show the plot, not return the figure object.

Parameters
  • legend (striplog.legend) – A legend instance.

  • tracks (list) – A list of strings and/or lists of strings. The tracks you want to plot from data. Optional, but you will usually want to give it.

  • track_titles (list) – Optional. A list of strings and/or lists of strings. The names to give the tracks, if you don’t want welly to guess.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics.

  • basis (ndarray) – Optional. The basis of the plot, if you don’t want welly to guess (probably the best idea).

  • extents (str) – What to use for the y limits: ‘td’: plot 0 to TD. ‘curves’: use a basis that accommodates all the curves. ‘all’: use a basis that accommodates everything. (tuple): give the upper and lower explictly.

Returns

None. The plot is a side-effect.

qc_curve_group(tests, keys=None, alias=None)#

Run tests on a cohort of curves. Wrapping functions from quality.py

Parameters
  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another.

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

dict.

qc_data(tests, keys=None, alias=None)#

Run a series of tests against the data and return the corresponding results. Wrapping frunction from quality.py.

Parameters
  • tests (dict) – a dictionary of tests, mapping mnemonics to lists of tests. Two special keys, all and each map tests to the set of all curves, and to each curve in the well, respectively. You only need all if the test involves multiple inputs, e.g. comparing one curve to another.

  • keys (list) – a list of the mnemonics to run the tests against.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

Returns

list. The results. Stick to booleans (True = pass) or ints.

qc_table_html(tests, keys=None, alias=None)#

Makes a nice table out of qc_data() Wrapping function from quality.py.

Returns

str. An HTML string for visualization in Jupyter notebook. Visualize through IPython.display.HTML(str)

survey_basis(keys=None, alias=None, step=None)#

Look at the basis of all the curves in well.data and return a basis with the minimum start, maximum depth, and minimum step.

Parameters
  • keys (list) – List of strings: the keys of the data items to survey, if not all of them.

  • alias (dict) – a dictionary mapping mnemonics to lists of mnemonics.

  • step (float) – a new step, if you want to change it.

Returns

ndarray. The most complete common basis.

to_canstrat(key, log, lith_field, filename=None, as_text=False)#

Make a Canstrat DAT (aka ASCII) file.

Parameters
  • filename (str) –

  • key (str) –

  • log (str) – the log name, should be 6 characters.

  • lith_field (str) – Primary component. Must match the Canstrat definitions.

  • filename

  • as_text (bool) – if you don’t want to write a file.

to_datasets(keys=None, alias=None, basis=None, null_value=- 999.25)#

Unpack a well to datasets (a dict with pd.DataFrames)

to_las(fname, keys=None, basis=None, null_value=- 999.25, mnemonic_case='preserve', **kwargs)#

Writes the current well instance as a LAS file. Essentially just wraps to_lasio(), but is more convenient for most purposes.

Parameters
  • fname (str) – The path of the LAS file to create.

  • basis (ndarray) – Optional. The basis to export the curves in. If you don’t specify one, it will survey all the curves with survey_basis().

  • null_value (float) – Optional. numeric null value representation

  • keys (list) – List of strings: the keys of the data items to include, if not all of them. You can have nested lists, such as you might use for tracks in well.plot().

Other keyword Args are passed to lasio.LASFile.write().

Returns

None. Writes the file as a side-effect.

to_lasio(keys=None, alias=None, basis=None, null_value=- 999.25, mnemonic_case=None)#

Makes a lasio object from the current well.

Parameters
  • keys (list) – List of strings: the keys of the data items to include, if not all of them. You can have nested lists, such as you might use for tracks in well.plot().

  • alias (dict) – Optional. A dictionary alias for the curve mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • basis (numpy.ndarray) – Optional. The basis to export the curves in. If you don’t specify one, it will survey all the curves with survey_basis()`.

  • null_value (float) – Optional. The null value representation in the LAS file.

Returns

las (lasio.LASFile). The lasio object representation of a LAS file.

unify_basis(keys=None, alias=None, basis=None, start=None, stop=None, step=None)#

Give every Curve in the well, or everything in the list of keys, the same basis. If you don’t provide a basis, welly will try to get one using survey_basis().

Parameters
  • keys (list) – List of strings: the keys of the data items to unify, if not all of them.

  • alias (dict) – an alias dictionary, mapping mnemonics to lists of mnemonics. e.g. {‘density’: [‘DEN’, ‘DENS’]}

  • basis (ndarray) – A basis: the regularly sampled depths at which you want the samples.

  • start (float) – Optionally override the start of whatever basis you provide or is surveyed.

  • stop (float) – Optionally override the stop of whatever basis you provide or is surveyed.

  • step (float) – Optionally override the step in the basis.

Returns

None. Works in place.

property uwi#

Property. Simply a shortcut to the UWI from the header, or the empty string if there isn’t one.

welly.read_las(path, **kwargs)#

A package namespace method to be called as welly.read_las.

Just wraps Project.from_las(). Creates a Project from a .LAS file.

Parameters
  • path (str) – path or URL where LAS is located. *.las to load all files in dir

  • () (**kwargs) – See Project.from_las()` for addictional arguments

Returns

welly.Project. The Project object.