Wells

Well (single)

Functions

xtgeo.well_from_file(wfile, fformat=None, mdlogname=None, zonelogname=None, lognames='all', lognames_strict=False, strict=False)[source]

Make an instance of a Well directly from file import.

Parameters:
  • wfile (str | Path) – File path for well, either a string or a pathlib.Path instance

  • fformat (str | None) – “rms_ascii”, “csv”, or “hdf5”. If None (default), auto-detect from file extension or file signature.

  • mdlogname (str | None) – Name of Measured Depth log, if any

  • zonelogname (str | None) – Name of Zonelog, if any

  • lognames (str | list[str] | None) – Name or list of lognames to import, default is “all”

  • lognames_strict (bool | None) – If True, all lognames must be present.

  • strict (bool | None) – If True, then import will fail if zonelogname or mdlogname are asked for but those names are not present in wells.

Return type:

Well

Example:

>>> import xtgeo
>>> import pathlib
>>> welldir = pathlib.Path("../foo")
>>> mywell = xtgeo.well_from_file(welldir / "OP_1.w")

Changed in version 2.1: Added lognames and lognames_strict

Changed in version 2.1: strict now defaults to False

xtgeo.well_from_roxar(project, name, trajectory='Drilled trajectory', logrun='log', lognames='all', lognames_strict=False, inclmd=False, inclsurvey=False)[source]

This makes an instance of a Well directly from Roxar RMS.

Note this method works only when inside RMS, or when RMS license is activated (through the roxar environment).

Parameters:
  • project (str | object) – Path to project or magic the project variable in RMS.

  • name (str) – Name of Well, as shown in RMS.

  • trajectory (str | None) – Name of trajectory in RMS.

  • logrun (str | None) – Name of logrun in RMS.

  • lognames (str | list[str] | None) – List of lognames to import, or use ‘all’ for all present logs

  • lognames_strict (bool | None) – If True and log is not in lognames is a list, an Exception will be raised.

  • inclmd (bool | None) – If True, a Measured Depth log will be included.

  • inclsurvey (bool | None) – If True, logs for azimuth and deviation will be included.

Return type:

Well

Returns:

Well instance.

Example:

# inside RMS:
import xtgeo
mylogs = ['ZONELOG', 'GR', 'Facies']
mywell = xtgeo.well_from_roxar(
    project, "31_3-1", trajectory="Drilled", logrun="log", lognames=mylogs
)

Changed in version 2.1: lognames defaults to “all”, not None

Classes

class xtgeo.Well(rkb=0.0, xpos=0.0, ypos=0.0, wname='', df=None, mdlogname=None, zonelogname=None, wlogtypes=None, wlogrecords=None, filesrc=None)[source]

Bases: object

Class for a single well in the XTGeo framework.

The well logs are stored in a Pandas dataframe, which make manipulation easy and fast.

The well trajectory are here represented as first 3 columns in the dataframe, and XYZ have pre-defined names: X_UTME, Y_UTMN, Z_TVDSS.

Other geometry logs may has also ‘semi-defined’ names, but this is not a strict rule:

M_MDEPTH or Q_MDEPTH: Measured depth, either real/true (M_xx) or quasi computed/estimated (Q_xx). The Quasi may be incorrect for all uses, but sufficient for some computations.

Similar for M_INCL, Q_INCL, M_AZI, Q_ASI.

All Pandas values (yes, discrete also!) are currently stored as float64 format, and undefined values are Nan. Integers are stored as Float due to the (historic) lacking support for ‘Integer Nan’.

Note there is a method that can return a dataframe (copy) with Integer and Float columns, see get_filled_dataframe().

The instance can be made either from file or by specification:

>>> well1 = xtgeo.well_from_file(well_dir + '/OP_1.w')
>>> well2 = xtgeo.Well(rkb=32.0, xpos=1234.0, ypos=4567.0, wname="Foo",
            df: mydataframe, ...)
Parameters:
  • rkb (float) – Well RKB height

  • xpos (float) – Well head X pos

  • ypos (float) – Well head Y pos

  • wname (str) – well name

  • df (DataFrame | None) – A pandas dataframe with log values, expects columns to include ‘X_UTME’, ‘Y_UTMN’, ‘Z_TVDSS’ for x, y and z coordinates. Other columns should be log values.

  • filesrc (str | Path | None) – source file if any

  • mdlogname (str | None) – Name of Measured Depth log, if any.

  • zonelogname (str | None) – Name of Zonelog, if any

  • wlogtypes (dict[str, str] | None) – dictionary of log types, ‘DISC’ (discrete) or ‘CONT’ (continuous), defaults to to ‘CONT’.

  • wlogrecords (dict[str, str] | None) – dictionary of codes for ‘DISC’ logs, None for no codes given, defaults to None.

Public Data Attributes:

xname

Return or set name of X coordinate column.

yname

Return or set name of Y coordinate column.

zname

Return or set name of Z coordinate column.

metadata

Return metadata object instance of type MetaDataRegularSurface.

rkb

Returns RKB height for the well (read only).

xpos

Returns well header X position (read only).

ypos

Returns well header Y position (read only).

wellname

Returns well name, read only.

name

Returns or set (rename) a well name.

wname

Returns or set (rename) a well name.

safewellname

Get well name on syntax safe form; '/' and spaces replaced with '_'.

xwellname

See safewellname.

shortwellname

Well name on a short form where blockname/spaces removed (read only).

truewellname

Returns well name on the assummed form aka '31/2-E-4 AH2'.

mdlogname

Returns name of MD log, if any (None if missing).

zonelogname

Returns or sets name of zone log, return None if missing.

dataframe

Returns or set the Pandas dataframe object for all logs.

nrow

Returns the Pandas dataframe object number of rows.

ncol

Returns the Pandas dataframe object number of columns.

nlogs

Returns the Pandas dataframe object number of columns.

lognames_all

Returns dataframe column names as list, including mandatory coords.

lognames

Returns the Pandas dataframe column as list excluding coords.

wlogtypes

Returns wlogtypes

wlogrecords

Returns wlogrecords

Public Methods:

ensure_consistency()

Ensure consistency for the instance.

get_short_wellname(wellname)

Well name on a short name form where blockname and spaces are removed.

describe([flush])

Describe an instance by printing to stdout.

to_file(wfile[, fformat, compression])

Export well to file or memory stream.

to_hdf(wfile[, compression])

Export well to HDF based file.

to_roxar(project, wname[, lognames, ...])

Export (save/store) a well to a roxar project.

get_lognames()

Get the lognames for all logs.

get_wlogs()

Get a compound dictionary with well log metadata.

set_wlogs(wlogs)

Set a compound dictionary with well log metadata.

isdiscrete(logname)

Return True of log is discrete, otherwise False.

copy()

Copy a Well instance to a new unique Well instance.

rename_log(lname, newname)

Rename a log, e.g. Poro to PORO.

create_log(lname[, logtype, logrecord, ...])

Create a new log with initial values.

copy_log(lname, newname[, force])

Copy a log from an existing to a name

delete_log(lname)

Delete/remove an existing log, or list of logs.

delete_logs(lname)

Delete/remove an existing log, or list of logs.

get_logtype(lname)

Returns the type of a given log (e.g. DISC or CONT), None if not present.

set_logtype(lname, ltype)

Sets the type of a give log (e.g. DISC or CONT).

get_logrecord(lname)

Returns the record (dict) of a given log name, None if not exists.

set_logrecord(lname, newdict)

Sets the record (dict) of a given discrete log.

get_logrecord_codename(lname, key)

Returns the name entry of a log record, for a given key.

get_dataframe([copy])

Get a copy (default) or a view of the dataframe.

get_filled_dataframe([fill_value, ...])

Fill the Nan's in the dataframe with real UNDEF values.

set_dataframe(dfr)

Set the dataframe.

create_relative_hlen()

Make a relative length of a well, as a log.

geometrics()

Compute some well geometrical arrays MD, INCL, AZI, as logs.

truncate_parallel_path(other[, xtol, ytol, ...])

Truncate the part of the well trajectory that is ~parallel with other.

may_overlap(other)

Consider if well overlap in X Y coordinates with other well, True/False.

limit_tvd(tvdmin, tvdmax)

Truncate the part of the well that is outside tvdmin, tvdmax.

downsample([interval, keeplast])

Downsample by sampling every N'th element (coarsen only).

rescale([delta, tvdrange])

Rescale (refine or coarse) by sampling a delta along the trajectory, in MD.

get_polygons([skipname])

Return a Polygons object from the well trajectory.

get_fence_polyline([sampling, nextend, ...])

Return a fence polyline as a numpy array, a Polygons object or a bool.

create_surf_distance_log(surf[, name])

Make a log that is vertical distance to a regular surface.

report_zonation_holes([threshold])

Reports if well has holes in zonation, less or equal to N samples.

get_zonation_points([tops, incl_limit, ...])

Extract zonation points from Zonelog and make a marker list.

get_zone_interval(zonevalue[, resample, ...])

Extract the X Y Z ID line (polyline) segment for a given zonevalue.

get_fraction_per_zone(dlogname, dcodes[, ...])

Get fraction of a discrete parameter, e.g. a facies, per zone.

mask_shoulderbeds(inputlogs, targetlogs[, ...])

Mask data around zone boundaries or other discrete log boundaries.

get_surface_picks(surf)

Return Points obj where well crosses the surface (horizon picks).

make_ijk_from_grid(grid[, grid_id, activeonly])

Look through a Grid and add grid I J K as discrete logs.

get_cell_intersections(grid[, ...])

Compute where this well's trajectory enters and exits each grid cell.

make_zone_qual_log(zqname)

Create a zone quality/indicator (flag) log.

get_gridproperties(gridprops[, grid, prop_id])

Look through a Grid and add a set of grid properties as logs.


__init__(rkb=0.0, xpos=0.0, ypos=0.0, wname='', df=None, mdlogname=None, zonelogname=None, wlogtypes=None, wlogrecords=None, filesrc=None)[source]
copy()[source]

Copy a Well instance to a new unique Well instance.

copy_log(lname, newname, force=True)[source]

Copy a log from an existing to a name

If the new log already exists, it will be silently overwritten, unless the option force=False.

Parameters:
  • lname (str) – name of existing log

  • newname (str) – name of new log

Return type:

bool

Returns:

True if a new log is made (either new or force overwrite an existing) or False if the new log already exists, and force=False.

Note:

A copy can also be done directly in the dataframe, but with less
consistency checks; hence this method is recommended
create_log(lname, logtype='CONT', logrecord=None, value=0.0, force=True)[source]

Create a new log with initial values.

If the logname already exists, it will be silently overwritten, unless the option force=False.

Parameters:
  • lname (str) – name of new log

  • logtype (str) – Must be ‘CONT’ (default) or ‘DISC’ (discrete)

  • logrecord (dict | None) – A dictionary of key: values for ‘DISC’ logs

  • value (float) – initial value to set

  • force (bool) – If True, and lname exists, it will be overwritten, if False, no new log will be made. Will return False.

Return type:

bool

Returns:

True ff a new log is made (either new or force overwrite an existing) or False if the new log already exists, and force=False.

Note:

A new log can also be created by adding it to the dataframe directly, but
with less control over e.g. logrecord
create_relative_hlen()[source]

Make a relative length of a well, as a log.

The first well og entry defines zero, then the horizontal length is computed relative to that by simple geometric methods.

create_surf_distance_log(surf, name='DIST_SURF')[source]

Make a log that is vertical distance to a regular surface.

If the trajectory is above the surface (i.e. more shallow), then the distance sign is positive.

Parameters:
  • surf (object) – The RegularSurface instance.

  • name (str | None) – The name of the new log. If it exists it will be overwritten.

Example:

mywell.rescale()  # optional
thesurf = xtgeo.surface_from_file("some.gri")
mywell.create_surf_distance_log(thesurf, name="sdiff")
property dataframe

Returns or set the Pandas dataframe object for all logs.

delete_log(lname)[source]

Delete/remove an existing log, or list of logs.

Will continue silently if a log does not exist.

Parameters:

lname (str | list[str]) – A logname or a list of lognames

Return type:

int

Returns:

Number of logs deleted

Note:

A log can also be deleted by simply removing it from the dataframe.
delete_logs(lname)

Delete/remove an existing log, or list of logs.

Will continue silently if a log does not exist.

Parameters:

lname (str | list[str]) – A logname or a list of lognames

Return type:

int

Returns:

Number of logs deleted

Note:

A log can also be deleted by simply removing it from the dataframe.
describe(flush=True)[source]

Describe an instance by printing to stdout.

downsample(interval=4, keeplast=True)[source]

Downsample by sampling every N’th element (coarsen only).

Parameters:
  • interval (int) – Sampling interval.

  • keeplast (bool) – If True, the last element from the original dataframe is kept, to avoid that the well is shortened.

ensure_consistency()[source]

Ensure consistency for the instance.

Added in version 3.5.

geometrics()[source]

Compute some well geometrical arrays MD, INCL, AZI, as logs.

These are kind of quasi measurements hence the logs will named with a Q in front as Q_MDEPTH, Q_INCL, and Q_AZI.

These logs will be added to the dataframe. If the mdlogname attribute does not exist in advance, it will be set to ‘Q_MDEPTH’.

Returns:

False if geometrics cannot be computed

get_cell_intersections(grid, sampling_step=1.0, refine_iters=20, active_only=False, zerobased=False)[source]

Compute where this well’s trajectory enters and exits each grid cell.

Walks the well polyline through the 3D corner-point grid and returns, for every cell the trajectory passes through, the (X, Y, Z) coordinates and Measured Depth (MD) at which the well enters and exits that cell.

The implementation is a hybrid algorithm: an analytic ray-tracing fast path is used for convex (planar-faced) cells, with automatic fallback to a sample-and-bisect scheme on distorted/non-convex cells.

Parameters:
  • grid (Grid) – A XTGeo Grid instance.

  • sampling_step (float) – Sampling step length used by the bisection fallback, in the same units as the well coordinates. Smaller values give higher accuracy on distorted cells at the cost of speed. The ray-tracing fast path is unaffected by this. Must be > 0.

  • refine_iters (int) – Maximum number of bisection iterations used by the fallback to localize a cell-boundary crossing.

  • active_only (bool) – If True, cells with ACTNUM=0 are skipped from the output (the trajectory still travels through them, but they are not reported).

  • zerobased (bool) – If True, I/J/K indices start from 0. If False (default), they start from 1, consistent with other XTGeo grid methods such as Grid.get_ijk().

Return type:

DataFrame

Returns:

A pandas.DataFrame with one row per (cell, traversal), sorted in trajectory order. Columns:

  • I, J, K: cell indices (int). 1-based by default, 0-based if zerobased=True.

  • ENTRY_EASTING, ENTRY_NORTHING, ENTRY_TVD, ENTRY_MD: where the trajectory enters the cell.

  • EXIT_EASTING, EXIT_NORTHING, EXIT_TVD, EXIT_MD: where it exits.

  • LENGTH_MD: EXIT_MD - ENTRY_MD (in-cell traversal length).

Note

Rows where any of X, Y, Z, or MD is NaN (common for undefined samples in well data) are automatically removed before processing.

Raises:

ValueError – If the well has no MD log, if sampling_step is not positive, or if refine_iters is negative. A trajectory with fewer than 2 finite samples returns an empty DataFrame (not an error).

Example:

grid = xtgeo.grid_from_file("mygrid.roff")
well = xtgeo.well_from_file("mywell.rmswell", mdlogname="MD")
df = well.get_cell_intersections(grid, active_only=True)
print(df.head())
get_dataframe(copy=True)[source]

Get a copy (default) or a view of the dataframe.

Parameters:

copy (bool) – If True, return a deep copy. A view (copy=False) will be faster and more memory efficient, but less “safe” for some cases when manipulating dataframes.

Changed in version 3.7: Added copy keyword

get_fence_polyline(sampling=20.0, nextend=2, tvdmin=None, asnumpy=True)[source]

Return a fence polyline as a numpy array, a Polygons object or a bool.

The result will aim for a regular sampling interval, useful for extracting fence plots (cross-sections).

Parameters:
  • sampling (float) – Sampling interval i.e. horizonal distance (input)

  • nextend (int) – Number if sampling to extend; e.g. 2 * 20

  • tvdmin (float) – Minimum TVD starting point.

  • as_numpy (bool) – If True, a numpy array, otherwise a Polygons object with 5 columns where the 2 last are HLEN and POLY_ID and the POLY_ID will be set to 0.

Return type:

ndarray | Polygons | bool

Returns:

A numpy array of shape (NLEN, 5) in F order, Or a Polygons object with 5 columns If not possible, return False

Changed in version 2.1: improved algorithm

get_filled_dataframe(fill_value=1e+33, fill_value_int=2000000000)[source]

Fill the Nan’s in the dataframe with real UNDEF values.

This module returns a copy of the dataframe in the object; it does not change the instance.

Note that DISC logs will be casted to columns with integer as datatype.

Returns:

A pandas dataframe where Nan er replaces with preset

high XTGeo UNDEF values, or user defined values.

get_fraction_per_zone(dlogname, dcodes, zonelist=None, incl_limit=80, count_limit=3, zonelogname=None)[source]

Get fraction of a discrete parameter, e.g. a facies, per zone.

It can be constrained by an inclination.

Also, it needs to be evaluated only of ZONE is complete; either INCREASE or DECREASE ; hence a quality flag is made and applied.

Parameters:
  • dlogname (str) – Name of discrete log, e.g. ‘FACIES’

  • dnames (list of int) – Codes of facies (or similar) to report for

  • zonelist (list of int) – Zones to use

  • incl_limit (float) – Inclination limit for well path.

  • count_limit (int) – Minimum number of counts required per segment for valid calculations

  • zonelogname (str). If None, the Well() – applied

Returns:

A pandas dataframe (ready for the xyz/Points class), None if a zonelog is missing or or dlogname is missing, list is zero length for any reason.

get_gridproperties(gridprops, grid=('ICELL', 'JCELL', 'KCELL'), prop_id='_model')[source]

Look through a Grid and add a set of grid properties as logs.

The name of the logs will …

This can be done to sample model properties along a well.

Parameters:
  • gridprops (Grid) – A XTGeo GridProperties instance (a collection of properties) or a single GridProperty instance

  • grid (Grid or tuple) – A XTGeo Grid instance or a reference via tuple. If this is tuple with log names, it states that these logs already contains the gridcell IJK numbering.

  • prop_id (str) – Add a tag (optional) to the current log name, e.g as PORO_model, where _model is the tag.

Raises:

None

Added in version 2.1.

get_lognames()[source]

Get the lognames for all logs.

get_logrecord(lname)[source]

Returns the record (dict) of a given log name, None if not exists.

Return type:

dict[int, str] | Sequence[str] | None

get_logrecord_codename(lname, key)[source]

Returns the name entry of a log record, for a given key.

Example:

# get the name for zonelog entry no 4:
zname = well.get_logrecord_codename('ZONELOG', 4)
Return type:

str | None

get_logtype(lname)[source]

Returns the type of a given log (e.g. DISC or CONT), None if not present.

Return type:

str | None

get_polygons(skipname=False)[source]

Return a Polygons object from the well trajectory.

Parameters:

skipname (bool) – If True then name column is omitted

Added in version 2.1.

Changed in version 2.13: Added skipname key

static get_short_wellname(wellname)[source]

Well name on a short name form where blockname and spaces are removed.

This should cope with both North Sea style and Haltenbanken style. E.g.: ‘31/2-G-5 AH’ -> ‘G-5AH’, ‘6472_11-F-23_AH_T2’ -> ‘F-23AHT2’

get_surface_picks(surf)[source]

Return Points obj where well crosses the surface (horizon picks).

There may be several points in the Points() dataframe attribute. Also a DIRECTION column will show 1 if surface is penetrated from above, and -1 if penetrated from below.

Parameters:

surf (RegularSurface) – The surface instance

Returns:

A Points instance, or None if no crossing points

Added in version 2.8.

get_wlogs()[source]

Get a compound dictionary with well log metadata.

The result will be an dict on the form:

{"X_UTME": ["CONT", None], ... "Facies": ["DISC", {1: "BG", 2: "SAND"}]}

Return type:

dict

get_zonation_points(tops=True, incl_limit=80, top_prefix='Top', zonelist=None, use_undef=False)[source]

Extract zonation points from Zonelog and make a marker list.

Currently it is either ‘Tops’ or ‘Zone’ (thicknesses); default is tops (i.e. tops=True).

The zonelist can be a list of zones, or a tuple with two members specifying first and last member. Note however that the zonation shall be without jumps and increasing. E.g.:

zonelist=(1, 5)  # meaning [1, 2, 3, 4, 5]
# or
zonelist=[1, 2, 3, 4]
# while _not_ legal:
zonelist=[1, 4, 8]

Zone numbers less than 0 are not accepted

Parameters:
  • tops (bool) – If True then compute tops, else (thickness) points.

  • incl_limit (float) – If given, and usezone is True, the max angle of inclination to be used as input to zonation points.

  • top_prefix (str) – As well logs usually have isochore (zone) name, this prefix could be Top, e.g. ‘SO43’ –> ‘TopSO43’

  • zonelist (list of int or tuple) – Zones to use

  • use_undef (bool) – If True, then transition from UNDEF is also used.

Returns:

A pandas dataframe (ready for the xyz/Points class), None if a zonelog is missing

get_zone_interval(zonevalue, resample=1, extralogs=None)[source]

Extract the X Y Z ID line (polyline) segment for a given zonevalue.

Parameters:
  • zonevalue (int) – The zone value to extract

  • resample (int) – If given, downsample every N’th sample to make polylines smaller in terms of bit and bytes. 1 = No downsampling.

  • extralogs (list of str) – List of extra log names to include

Returns:

A pandas dataframe X Y Z ID (ready for the xyz/Polygon class), None if a zonelog is missing or actual zone does dot exist in the well.

isdiscrete(logname)[source]

Return True of log is discrete, otherwise False.

Parameters:

logname (str) – Name of log to check if discrete or not

Added in version 2.2.0.

limit_tvd(tvdmin, tvdmax)[source]

Truncate the part of the well that is outside tvdmin, tvdmax.

Range will be in tvdmin <= tvd <= tvdmax.

Parameters:
  • tvdmin (float) – Minimum TVD

  • tvdmax (float) – Maximum TVD

property lognames

Returns the Pandas dataframe column as list excluding coords.

Type:

list

property lognames_all

Returns dataframe column names as list, including mandatory coords.

Type:

list

make_ijk_from_grid(grid, grid_id='', activeonly=True, **kwargs)[source]

Look through a Grid and add grid I J K as discrete logs.

Note that the the grid counting has base 1 (first row is 1 etc).

By default, log (i.e. column names in the dataframe) will be ICELL, JCELL, KCELL, but you can add a tag (ID) to that name.

Parameters:
  • grid (Grid) – A XTGeo Grid instance

  • grid_id (str) – Add a tag (optional) to the current log name

  • activeonly (bool) – If True, only active cells are applied (algorithm 2 only)

Raises:

RuntimeError – ‘Error from C routine, code is …’

Changed in version 2.9: Added keys for and activeonly

make_zone_qual_log(zqname)[source]

Create a zone quality/indicator (flag) log.

This routine looks through to zone log and flag intervals according to neighbouring zones:

  • 0: Undetermined flag

  • 1: Zonelog interval numbering increases,

    e.g. for zone 2: 1 1 1 1 2 2 2 2 2 5 5 5 5 5

  • 2: Zonelog interval numbering decreases,

    e.g. for zone 2: 6 6 6 2 2 2 2 1 1 1

  • 3: Interval is a U turning point, e.g. 0 0 0 2 2 2 1 1 1

  • 4: Interval is a inverse U turning point, 3 3 3 2 2 2 5 5

  • 9: Interval is bounded by one or more missing sections,

    e.g. 1 1 1 2 2 2 -999 -999

If a log with the name exists, it will be silently replaced

Parameters:

zqname (str) – Name of quality log

mask_shoulderbeds(inputlogs, targetlogs, nsamples=2, strict=False)[source]

Mask data around zone boundaries or other discrete log boundaries.

This operates on number of samples, hence the actual distance which is masked depends on the sampling interval (ie. count) or on distance measures. Distance measures are TVD (true vertical depth) or MD (measured depth).

_images/wells-mask-shoulderbeds.png
Parameters:
  • inputlogs (list[str]) – List of input logs, must be of discrete type.

  • targetlogs (list[str]) – List of logs where mask is applied.

  • nsamples (int | dict[str, float] | None) – Number of samples around boundaries to filter, per side, i.e. value 2 means 2 above and 2 below, in total 4 samples. As alternative specify nsamples indirectly with a relative distance, as a dictionary with one record, as {“tvd”: 0.5} or {“md”: 0.7}.

  • strict (bool | None) – If True, will raise Exception of any of the input or target log names are missing.

Return type:

bool

Returns:

True if any operation has been done. False in case nothing has been done,

e.g. no targetlogs for this particular well and strict is False.

Raises:

ValueError – Various messages when wrong or inconsistent input.

Example

>>> mywell1 = Well(well_dir + '/OP_1.w')
>>> mywell2 = Well(well_dir + '/OP_2.w')
>>> did_succeed = mywell1.mask_shoulderbeds(["Zonelog", "Facies"], ["Perm"])
>>> did_succeed = mywell2.mask_shoulderbeds(
...     ["Zonelog"],
...     ["Perm"],
...     nsamples={"tvd": 0.8}
... )
may_overlap(other)[source]

Consider if well overlap in X Y coordinates with other well, True/False.

property mdlogname

Returns name of MD log, if any (None if missing).

Type:

str

property metadata

Return metadata object instance of type MetaDataRegularSurface.

property name

Returns or set (rename) a well name.

property ncol

Returns the Pandas dataframe object number of columns.

Type:

int

property nlogs

Returns the Pandas dataframe object number of columns.

Type:

int

property nrow

Returns the Pandas dataframe object number of rows.

Type:

int

rename_log(lname, newname)[source]

Rename a log, e.g. Poro to PORO.

report_zonation_holes(threshold=5)[source]

Reports if well has holes in zonation, less or equal to N samples.

Zonation may have holes due to various reasons, and usually a few undef samples indicates that something is wrong. This method reports well and start interval of the “holes”

The well shall have zonelog from import (via zonelogname attribute) and preferly a MD log (via mdlogname attribute); however if the latter is not present, a report withou MD values will be present.

Parameters:

threshold (int) – Number of samples (max.) that defines a hole, e.g. 5 means that undef samples in the range [1, 5] (including 5) is applied

Returns:

A Pandas dataframe as a report. None if no list is made.

Raises:

RuntimeError if zonelog is not present

rescale(delta=0.15, tvdrange=None)[source]

Rescale (refine or coarse) by sampling a delta along the trajectory, in MD.

Parameters:
  • delta (float) – Step length

  • tvdrange (tuple of floats) – Resampling can be limited to TVD interval

Changed in version 2.2: Added tvdrange

property rkb

Returns RKB height for the well (read only).

property safewellname

Get well name on syntax safe form; ‘/’ and spaces replaced with ‘_’.

set_dataframe(dfr)[source]

Set the dataframe.

set_logrecord(lname, newdict)[source]

Sets the record (dict) of a given discrete log.

Return type:

None

set_logtype(lname, ltype)[source]

Sets the type of a give log (e.g. DISC or CONT).

Return type:

None

set_wlogs(wlogs)[source]

Set a compound dictionary with well log metadata.

This operation is somewhat risky as it may lead to inconsistency, so use with care! Typically, one will use get_wlogs() first and then modify some attributes.

Parameters:

wlogs (dict) – Input data dictionary

Raises:
  • ValueError – Invalid log type found in input:

  • ValueError – Invalid log record found in input:

  • ValueError – Invalid input key found:

  • ValueError – Invalid log record found in input:

property shortwellname

Well name on a short form where blockname/spaces removed (read only).

This should cope with both North Sea style and Haltenbanken style.

E.g.: ‘31/2-G-5 AH’ -> ‘G-5AH’, ‘6472_11-F-23_AH_T2’ -> ‘F-23AHT2’

Type:

str

to_file(wfile, fformat='rms_ascii', compression='lzf')[source]

Export well to file or memory stream.

Parameters:
  • wfile (str | Path | BytesIO) – File name or stream.

  • fformat (str | None) – File format (‘rms_ascii’/’rmswell’, ‘csv’, ‘hdf/hdf5/h5’).

  • compression (str | None) – Compression for HDF5 format only. Default is ‘lzf’.

Example:

>>> xwell = Well(well_dir + '/OP_1.w')
>>> dfr = xwell.get_dataframe()
>>> dfr['Poro'] += 0.1
>>> xwell.set_dataframe(dfr)
>>> filename = xwell.to_file(outdir + "/somefile_copy.rmswell")
to_hdf(wfile, compression='lzf')[source]

Export well to HDF based file.

Deprecated since version 4.19: (approx) Use to_file() with fformat='hdf5' instead. This method is redundant and will be removed in version 5.0.

Warning

This implementation is currently experimental and only recommended for testing.

Parameters:
  • wfile (str | Path) – HDF File name to write to export to.

  • compression (str | None) – Compression type (default ‘lzf’).

Return type:

Path

Returns:

A Path instance to actual file applied.

Added in version 2.14.

to_roxar(project, wname, lognames='all', realisation=0, trajectory='Drilled trajectory', logrun='log', update_option=None)[source]

Export (save/store) a well to a roxar project.

Note this method works only when inside RMS, or when RMS license is activated in terminal.

The current implementation will either update the existing well (then well log array size must not change), or it will make a new well in RMS.

Parameters:
  • project (Any) – Magic string ‘project’ or file path to project

  • wname (str) – Name of well, as shown in RMS.

  • lognames (str | list[str]) – List of lognames to save, or use simply ‘all’ for current logs for this well. Default is ‘all’

  • realisation (int) – Currently inactive

  • trajectory (str) – Name of trajectory in RMS, default is “Drilled trajectory”

  • logrun (str) – Name of logrun in RMS, default is “log”

  • update_option (str) – None | “overwrite” | “append”. This only applies when the well (wname) exists in RMS, and rules are based on name matching. Default is None which means that all well logs in RMS are emptied and then replaced with the content from xtgeo. The “overwrite” option will replace logs in RMS with logs from xtgeo, and append new if they do not exist in RMS. The “append” option will only append logs if name does not exist in RMS already. Reading only a subset of logs and then use “overwrite” or “append” may speed up execution significantly.

Note

When project is file path (direct access, outside RMS) then to_roxar() will implicitly do a project save. Otherwise, the project will not be saved until the user do an explicit project save action.

Example:

# assume that existing logs in RMS are ["PORO", "PERMH", "GR", "DT", "FAC"]
# read only one existing log (faster)

wll = xtgeo.well_from_roxar(project, "WELL1", lognames=["PORO"])
dfr = wll.get_dataframe()
dfr["PORO"] += 0.2  # add 0.2 to PORO log
wll.set_dataframe(dfr)
wll.create_log("NEW", value=0.333)  # create a new log with constant value

# the "option" is a variable... for output, ``lognames="all"`` is default
if option is None:
    # remove all current logs in RMS; only logs will be PORO and NEW
    wll.to_roxar(project, "WELL1", update_option=option)
elif option == "overwrite":
    # keep all original logs but update PORO and add NEW
    wll.to_roxar(project, "WELL1", update_option=option)
elif option == "append":
    # keep all original logs as they were (incl. PORO) and add NEW
    wll.to_roxar(project, "WELL1", update_option=option)

Note

The keywords lognames and update_option will interact

Added in version 2.12.

Changed in version 2.15: Saving to new wells enabled (earlier only modifying existing)

Changed in version 3.5: Add key update_option

property truewellname

Returns well name on the assummed form aka ‘31/2-E-4 AH2’.

truncate_parallel_path(other, xtol=None, ytol=None, ztol=None, itol=None, atol=None)[source]

Truncate the part of the well trajectory that is ~parallel with other.

Parameters:
  • other (Well) – Other well to compare with

  • xtol (float) – Tolerance in X (East) coord for measuring unit

  • ytol (float) – Tolerance in Y (North) coord for measuring unit

  • ztol (float) – Tolerance in Z (TVD) coord for measuring unit

  • itol (float) – Tolerance in inclination (degrees)

  • atol (float) – Tolerance in azimuth (degrees)

property wellname

Returns well name, read only.

Type:

str

property wlogrecords

Returns wlogrecords

property wlogtypes

Returns wlogtypes

property wname

Returns or set (rename) a well name.

property xname

Return or set name of X coordinate column.

property xpos

Returns well header X position (read only).

property xwellname

See safewellname.

property yname

Return or set name of Y coordinate column.

property ypos

Returns well header Y position (read only).

property zname

Return or set name of Z coordinate column.

property zonelogname

Returns or sets name of zone log, return None if missing.

Type:

str

Wells (multiple)

Functions

xtgeo.wells_from_files(filelist, *args, **kwargs)[source]

Import wells from a list of files (filelist).

Creates a Wells object from a list of filenames. Remaining arguments are

the same as xtgeo.well_from_file().

Parameters:

filelist (list of filenames) – List with file names

Example

Here the from_file method is used to initiate the object directly:

>>> mywells = Wells(
...     [well_dir + '/OP_1.w', well_dir + '/OP_2.w']
... )
xtgeo.wells_from_stacked_file(wfile, fformat=None)[source]

Import multiple wells from a single concatenated (stacked) file.

This function reads files that contain multiple wells in a single file, as created by Wells.to_stacked_file().

For CSV format, expects a WELLNAME column to identify each well. For RMS ASCII format, reads multiple well entries, each with its own header.

Parameters:
  • wfile (Union[str, Path, StringIO, BytesIO]) – File name or stream.

  • fformat (str | None) – File format (‘rmswell’ or ‘csv’). If None, auto-detect from file extension or signature.

Return type:

Wells

Returns:

Wells instance containing all wells from the file.

Example:

>>> wells = xtgeo.wells_from_stacked_file("all_wells.csv", fformat="csv")
>>> wells = xtgeo.wells_from_stacked_file("all_wells.rmswell")

Added in version 4.19: (approximate)

Classes

class xtgeo.Wells(wells=None)[source]

Bases: object

Class for a collection of Well objects, for operations that involves a number of wells.

See also the xtgeo.well.Well class.

Parameters:

wells (list[Well]) – The list of Well objects.

Public Data Attributes:

names

Returns a list of well names (read only).

wells

Returns or sets a list of XTGeo Well objects, None if empty.

Public Methods:

describe([flush])

Describe an instance by printing to stdout

copy()

Copy a Wells instance to a new unique instance (a deep copy).

get_well(name)

Get a Well() instance by name, or None

get_dataframe([filled, fill_value1, fill_value2])

Get a big dataframe for all wells or blocked wells in instance, with well name as first column

to_stacked_file(wfile[, fformat])

Export multiple wells to a single concatenated (stacked) file.

quickplot([filename, title])

Fast plot of wells using matplotlib.

limit_tvd(tvdmin, tvdmax)

Limit TVD to be in range tvdmin, tvdmax for all wells

downsample([interval, keeplast])

Downsample by sampling every N'th element (coarsen only), all wells.

wellintersections([wfilter, showprogress])

Get intersections between wells, return as dataframe table.


__init__(wells=None)[source]
copy()[source]

Copy a Wells instance to a new unique instance (a deep copy).

describe(flush=True)[source]

Describe an instance by printing to stdout

downsample(interval=4, keeplast=True)[source]

Downsample by sampling every N’th element (coarsen only), all wells.

get_dataframe(filled=False, fill_value1=-999, fill_value2=-9999)[source]

Get a big dataframe for all wells or blocked wells in instance, with well name as first column

Parameters:
  • filled (bool) – If True, then NaN’s are replaces with values

  • fill_value1 (int) – Only applied if filled=True, for logs that have missing values

  • fill_value2 (int) – Only applied if filled=True, when logs are missing completely for that well.

get_well(name)[source]

Get a Well() instance by name, or None

limit_tvd(tvdmin, tvdmax)[source]

Limit TVD to be in range tvdmin, tvdmax for all wells

property names

Returns a list of well names (read only).

Example:

namelist = wells.names
for prop in namelist:
    print ('Well name is {}'.format(name))
quickplot(filename=None, title='QuickPlot')[source]

Fast plot of wells using matplotlib.

Parameters:
  • filename (str) – Name of plot file; None will plot to screen.

  • title (str) – Title of plot

to_stacked_file(wfile, fformat='rms_ascii')[source]

Export multiple wells to a single concatenated (stacked) file.

For CSV format, all wells are combined into a single table with a WELLNAME column to identify each well.

For RMS ASCII format, each well is written sequentially in the standard RMS well format (with its own header and data section).

Parameters:
  • wfile (Union[str, Path, StringIO, BytesIO]) – File name or stream.

  • fformat (str | None) – File format (‘rms_ascii’/’rmswell’ or ‘csv’). HDF5 format is not supported for multiple wells.

Return type:

Path | BytesIO | StringIO

Returns:

Path to the file that was written.

Example:

>>> wells = Wells([well1, well2, well3])
>>> wells.to_stacked_file("all_wells.csv", fformat="csv")
>>> wells.to_stacked_file("all_wells.rmswell", fformat="rms_ascii")

Added in version 4.19: (approximate)

wellintersections(wfilter=None, showprogress=False)[source]

Get intersections between wells, return as dataframe table.

Notes on wfilter: A wfilter is settings to improve result. In particular to remove parts of trajectories that are parallel.

wfilter = {‘parallel’: {‘xtol’: 4.0, ‘ytol’: 4.0, ‘ztol’:2.0,

‘itol’:10, ‘atol’:2}}

Here xtol is tolerance in X coordinate; further Y tolerance, Z tolerance, (I)nclination tolerance, and (A)zimuth tolerance.

Parameters:
  • tvdrange (tuple of floats) – Search interval. One is often just interested in the reservoir section.

  • wfilter (dict) – A dictionrary for filter options, in order to improve result. See example above.

  • showprogress (bool) – Will show progress to screen if enabled.

Returns:

A Pandas dataframe object, with columns WELL, CWELL and UTMX UTMY

TVD coordinates for CWELL where CWELL crosses WELL, and also MDEPTH for the WELL.

property wells

Returns or sets a list of XTGeo Well objects, None if empty.

Blocked well (single)

Functions

xtgeo.blockedwell_from_file(bwfile, fformat=None, mdlogname=None, zonelogname=None, strict=False, lognames='all', lognames_strict=False)[source]

Make an instance of a BlockedWell directly from file import.

Parameters:
  • bwfile (str) – Name of file

  • fformat (str) – File format: rms_ascii, csv, hdf5. If None (default), auto-detect from file extension or file signature.

  • mdlogname (str) – See Well.from_file()

  • zonelogname (str) – See Well.from_file()

  • strict (bool) – See Well.from_file()

  • lognames – Name or list of lognames to import, default is “all”

  • lognames_strict – If True, require all logs in lognames to be present

Example:

>>> import xtgeo
>>> well3 = xtgeo.blockedwell_from_file(well_dir + '/OP_1.bw')
xtgeo.blockedwell_from_roxar(project, gname, bwname, wname, lognames=None, ijk=True, realisation=0)[source]

This makes an instance of a BlockedWell directly from Roxar RMS.

For arguments, see BlockedWell.from_roxar().

Example:

# inside RMS:
import xtgeo
mylogs = ['ZONELOG', 'GR', 'Facies']
mybw = xtgeo.blockedwell_from_roxar(project, 'Simgrid', 'BW', '31_3-1',
                                    lognames=mylogs)

Classes

class xtgeo.BlockedWell(*args, **kwargs)[source]

Bases: Well

Class for a blocked well in the XTGeo framework, subclassed from the Well class.

Similar to Wells, the blocked well logs are stored as Pandas dataframe, which make manipulation easy and fast.

For blocked well logs, the numbers of rows cannot be changed if you want to save the result in RMS, as this is derived from the grid. Also the blocked well icon must exist before save.

The well trajectory are here represented as logs, and XYZ have magic names as default: X_UTME, Y_UTMN, Z_TVDSS, which are the three first Pandas columns.

Other geometry logs has also ‘semi-magic’ names:

M_MDEPTH or Q_MDEPTH: Measured depth, either real/true (M…) or quasi computed/estimated (Q…). The Quasi computations may be incorrect for all uses, but sufficient for some computations.

Similar for M_INCL, Q_INCL, M_AZI, Q_AZI.

I_INDEX, J_INDEX, K_INDEX: They are grid indices. For practical reasons they are treated as a CONT logs, since the min/max grid indices usually are unknown, and hence making a code index is not trivial.

All Pandas values (yes, discrete also!) are stored as float32 or float64 format, and undefined values are Nan. Integers are stored as Float due to the lacking support for ‘Integer Nan’ (currently lacking in Pandas, but may come in later Pandas versions).

Note there is a method that can return a dataframe (copy) with Integer and Float columns, see get_filled_dataframe().

The instance can be made either from file or:

>>> well1 = xtgeo.blockedwell_from_file(well_dir + '/OP_1.bw')  # RMS ascii well

If in RMS, instance can be made also from RMS icon:

well4 = xtgeo.blockedwell_from_roxar(
    project,
    'gridname',
    'bwname',
    'wellname',
)

Public Data Attributes:

gridname

Returns or set (rename) the grid name that the blocked wells belongs to.

Inherited from Well

xname

Return or set name of X coordinate column.

yname

Return or set name of Y coordinate column.

zname

Return or set name of Z coordinate column.

metadata

Return metadata object instance of type MetaDataRegularSurface.

rkb

Returns RKB height for the well (read only).

xpos

Returns well header X position (read only).

ypos

Returns well header Y position (read only).

wellname

Returns well name, read only.

name

Returns or set (rename) a well name.

wname

Returns or set (rename) a well name.

safewellname

Get well name on syntax safe form; '/' and spaces replaced with '_'.

xwellname

See safewellname.

shortwellname

Well name on a short form where blockname/spaces removed (read only).

truewellname

Returns well name on the assummed form aka '31/2-E-4 AH2'.

mdlogname

Returns name of MD log, if any (None if missing).

zonelogname

Returns or sets name of zone log, return None if missing.

dataframe

Returns or set the Pandas dataframe object for all logs.

nrow

Returns the Pandas dataframe object number of rows.

ncol

Returns the Pandas dataframe object number of columns.

nlogs

Returns the Pandas dataframe object number of columns.

lognames_all

Returns dataframe column names as list, including mandatory coords.

lognames

Returns the Pandas dataframe column as list excluding coords.

wlogtypes

Returns wlogtypes

wlogrecords

Returns wlogrecords

Public Methods:

to_file(bwfile[, fformat, compression])

Export BlockedWell to file.

copy()

Copy a Well instance to a new unique Well instance.

to_roxar(project, gridname, bwname, wname[, ...])

Set (export) a single blocked well item inside roxar project.

Inherited from Well

ensure_consistency()

Ensure consistency for the instance.

get_short_wellname(wellname)

Well name on a short name form where blockname and spaces are removed.

describe([flush])

Describe an instance by printing to stdout.

to_file(wfile[, fformat, compression])

Export well to file or memory stream.

to_hdf(wfile[, compression])

Export well to HDF based file.

to_roxar(project, wname[, lognames, ...])

Export (save/store) a well to a roxar project.

get_lognames()

Get the lognames for all logs.

get_wlogs()

Get a compound dictionary with well log metadata.

set_wlogs(wlogs)

Set a compound dictionary with well log metadata.

isdiscrete(logname)

Return True of log is discrete, otherwise False.

copy()

Copy a Well instance to a new unique Well instance.

rename_log(lname, newname)

Rename a log, e.g. Poro to PORO.

create_log(lname[, logtype, logrecord, ...])

Create a new log with initial values.

copy_log(lname, newname[, force])

Copy a log from an existing to a name

delete_log(lname)

Delete/remove an existing log, or list of logs.

delete_logs(lname)

Delete/remove an existing log, or list of logs.

get_logtype(lname)

Returns the type of a given log (e.g. DISC or CONT), None if not present.

set_logtype(lname, ltype)

Sets the type of a give log (e.g. DISC or CONT).

get_logrecord(lname)

Returns the record (dict) of a given log name, None if not exists.

set_logrecord(lname, newdict)

Sets the record (dict) of a given discrete log.

get_logrecord_codename(lname, key)

Returns the name entry of a log record, for a given key.

get_dataframe([copy])

Get a copy (default) or a view of the dataframe.

get_filled_dataframe([fill_value, ...])

Fill the Nan's in the dataframe with real UNDEF values.

set_dataframe(dfr)

Set the dataframe.

create_relative_hlen()

Make a relative length of a well, as a log.

geometrics()

Compute some well geometrical arrays MD, INCL, AZI, as logs.

truncate_parallel_path(other[, xtol, ytol, ...])

Truncate the part of the well trajectory that is ~parallel with other.

may_overlap(other)

Consider if well overlap in X Y coordinates with other well, True/False.

limit_tvd(tvdmin, tvdmax)

Truncate the part of the well that is outside tvdmin, tvdmax.

downsample([interval, keeplast])

Downsample by sampling every N'th element (coarsen only).

rescale([delta, tvdrange])

Rescale (refine or coarse) by sampling a delta along the trajectory, in MD.

get_polygons([skipname])

Return a Polygons object from the well trajectory.

get_fence_polyline([sampling, nextend, ...])

Return a fence polyline as a numpy array, a Polygons object or a bool.

create_surf_distance_log(surf[, name])

Make a log that is vertical distance to a regular surface.

report_zonation_holes([threshold])

Reports if well has holes in zonation, less or equal to N samples.

get_zonation_points([tops, incl_limit, ...])

Extract zonation points from Zonelog and make a marker list.

get_zone_interval(zonevalue[, resample, ...])

Extract the X Y Z ID line (polyline) segment for a given zonevalue.

get_fraction_per_zone(dlogname, dcodes[, ...])

Get fraction of a discrete parameter, e.g. a facies, per zone.

mask_shoulderbeds(inputlogs, targetlogs[, ...])

Mask data around zone boundaries or other discrete log boundaries.

get_surface_picks(surf)

Return Points obj where well crosses the surface (horizon picks).

make_ijk_from_grid(grid[, grid_id, activeonly])

Look through a Grid and add grid I J K as discrete logs.

get_cell_intersections(grid[, ...])

Compute where this well's trajectory enters and exits each grid cell.

make_zone_qual_log(zqname)

Create a zone quality/indicator (flag) log.

get_gridproperties(gridprops[, grid, prop_id])

Look through a Grid and add a set of grid properties as logs.


__init__(*args, **kwargs)[source]
copy()[source]

Copy a Well instance to a new unique Well instance.

copy_log(lname, newname, force=True)

Copy a log from an existing to a name

If the new log already exists, it will be silently overwritten, unless the option force=False.

Parameters:
  • lname (str) – name of existing log

  • newname (str) – name of new log

Return type:

bool

Returns:

True if a new log is made (either new or force overwrite an existing) or False if the new log already exists, and force=False.

Note:

A copy can also be done directly in the dataframe, but with less
consistency checks; hence this method is recommended
create_log(lname, logtype='CONT', logrecord=None, value=0.0, force=True)

Create a new log with initial values.

If the logname already exists, it will be silently overwritten, unless the option force=False.

Parameters:
  • lname (str) – name of new log

  • logtype (str) – Must be ‘CONT’ (default) or ‘DISC’ (discrete)

  • logrecord (dict | None) – A dictionary of key: values for ‘DISC’ logs

  • value (float) – initial value to set

  • force (bool) – If True, and lname exists, it will be overwritten, if False, no new log will be made. Will return False.

Return type:

bool

Returns:

True ff a new log is made (either new or force overwrite an existing) or False if the new log already exists, and force=False.

Note:

A new log can also be created by adding it to the dataframe directly, but
with less control over e.g. logrecord
create_relative_hlen()

Make a relative length of a well, as a log.

The first well og entry defines zero, then the horizontal length is computed relative to that by simple geometric methods.

create_surf_distance_log(surf, name='DIST_SURF')

Make a log that is vertical distance to a regular surface.

If the trajectory is above the surface (i.e. more shallow), then the distance sign is positive.

Parameters:
  • surf (object) – The RegularSurface instance.

  • name (str | None) – The name of the new log. If it exists it will be overwritten.

Example:

mywell.rescale()  # optional
thesurf = xtgeo.surface_from_file("some.gri")
mywell.create_surf_distance_log(thesurf, name="sdiff")
property dataframe

Returns or set the Pandas dataframe object for all logs.

delete_log(lname)

Delete/remove an existing log, or list of logs.

Will continue silently if a log does not exist.

Parameters:

lname (str | list[str]) – A logname or a list of lognames

Return type:

int

Returns:

Number of logs deleted

Note:

A log can also be deleted by simply removing it from the dataframe.
delete_logs(lname)

Delete/remove an existing log, or list of logs.

Will continue silently if a log does not exist.

Parameters:

lname (str | list[str]) – A logname or a list of lognames

Return type:

int

Returns:

Number of logs deleted

Note:

A log can also be deleted by simply removing it from the dataframe.
describe(flush=True)

Describe an instance by printing to stdout.

downsample(interval=4, keeplast=True)

Downsample by sampling every N’th element (coarsen only).

Parameters:
  • interval (int) – Sampling interval.

  • keeplast (bool) – If True, the last element from the original dataframe is kept, to avoid that the well is shortened.

ensure_consistency()

Ensure consistency for the instance.

Added in version 3.5.

geometrics()

Compute some well geometrical arrays MD, INCL, AZI, as logs.

These are kind of quasi measurements hence the logs will named with a Q in front as Q_MDEPTH, Q_INCL, and Q_AZI.

These logs will be added to the dataframe. If the mdlogname attribute does not exist in advance, it will be set to ‘Q_MDEPTH’.

Returns:

False if geometrics cannot be computed

get_cell_intersections(grid, sampling_step=1.0, refine_iters=20, active_only=False, zerobased=False)

Compute where this well’s trajectory enters and exits each grid cell.

Walks the well polyline through the 3D corner-point grid and returns, for every cell the trajectory passes through, the (X, Y, Z) coordinates and Measured Depth (MD) at which the well enters and exits that cell.

The implementation is a hybrid algorithm: an analytic ray-tracing fast path is used for convex (planar-faced) cells, with automatic fallback to a sample-and-bisect scheme on distorted/non-convex cells.

Parameters:
  • grid (Grid) – A XTGeo Grid instance.

  • sampling_step (float) – Sampling step length used by the bisection fallback, in the same units as the well coordinates. Smaller values give higher accuracy on distorted cells at the cost of speed. The ray-tracing fast path is unaffected by this. Must be > 0.

  • refine_iters (int) – Maximum number of bisection iterations used by the fallback to localize a cell-boundary crossing.

  • active_only (bool) – If True, cells with ACTNUM=0 are skipped from the output (the trajectory still travels through them, but they are not reported).

  • zerobased (bool) – If True, I/J/K indices start from 0. If False (default), they start from 1, consistent with other XTGeo grid methods such as Grid.get_ijk().

Return type:

DataFrame

Returns:

A pandas.DataFrame with one row per (cell, traversal), sorted in trajectory order. Columns:

  • I, J, K: cell indices (int). 1-based by default, 0-based if zerobased=True.

  • ENTRY_EASTING, ENTRY_NORTHING, ENTRY_TVD, ENTRY_MD: where the trajectory enters the cell.

  • EXIT_EASTING, EXIT_NORTHING, EXIT_TVD, EXIT_MD: where it exits.

  • LENGTH_MD: EXIT_MD - ENTRY_MD (in-cell traversal length).

Note

Rows where any of X, Y, Z, or MD is NaN (common for undefined samples in well data) are automatically removed before processing.

Raises:

ValueError – If the well has no MD log, if sampling_step is not positive, or if refine_iters is negative. A trajectory with fewer than 2 finite samples returns an empty DataFrame (not an error).

Example:

grid = xtgeo.grid_from_file("mygrid.roff")
well = xtgeo.well_from_file("mywell.rmswell", mdlogname="MD")
df = well.get_cell_intersections(grid, active_only=True)
print(df.head())
get_dataframe(copy=True)

Get a copy (default) or a view of the dataframe.

Parameters:

copy (bool) – If True, return a deep copy. A view (copy=False) will be faster and more memory efficient, but less “safe” for some cases when manipulating dataframes.

Changed in version 3.7: Added copy keyword

get_fence_polyline(sampling=20.0, nextend=2, tvdmin=None, asnumpy=True)

Return a fence polyline as a numpy array, a Polygons object or a bool.

The result will aim for a regular sampling interval, useful for extracting fence plots (cross-sections).

Parameters:
  • sampling (float) – Sampling interval i.e. horizonal distance (input)

  • nextend (int) – Number if sampling to extend; e.g. 2 * 20

  • tvdmin (float) – Minimum TVD starting point.

  • as_numpy (bool) – If True, a numpy array, otherwise a Polygons object with 5 columns where the 2 last are HLEN and POLY_ID and the POLY_ID will be set to 0.

Return type:

ndarray | Polygons | bool

Returns:

A numpy array of shape (NLEN, 5) in F order, Or a Polygons object with 5 columns If not possible, return False

Changed in version 2.1: improved algorithm

get_filled_dataframe(fill_value=1e+33, fill_value_int=2000000000)

Fill the Nan’s in the dataframe with real UNDEF values.

This module returns a copy of the dataframe in the object; it does not change the instance.

Note that DISC logs will be casted to columns with integer as datatype.

Returns:

A pandas dataframe where Nan er replaces with preset

high XTGeo UNDEF values, or user defined values.

get_fraction_per_zone(dlogname, dcodes, zonelist=None, incl_limit=80, count_limit=3, zonelogname=None)

Get fraction of a discrete parameter, e.g. a facies, per zone.

It can be constrained by an inclination.

Also, it needs to be evaluated only of ZONE is complete; either INCREASE or DECREASE ; hence a quality flag is made and applied.

Parameters:
  • dlogname (str) – Name of discrete log, e.g. ‘FACIES’

  • dnames (list of int) – Codes of facies (or similar) to report for

  • zonelist (list of int) – Zones to use

  • incl_limit (float) – Inclination limit for well path.

  • count_limit (int) – Minimum number of counts required per segment for valid calculations

  • zonelogname (str). If None, the Well() – applied

Returns:

A pandas dataframe (ready for the xyz/Points class), None if a zonelog is missing or or dlogname is missing, list is zero length for any reason.

get_gridproperties(gridprops, grid=('ICELL', 'JCELL', 'KCELL'), prop_id='_model')

Look through a Grid and add a set of grid properties as logs.

The name of the logs will …

This can be done to sample model properties along a well.

Parameters:
  • gridprops (Grid) – A XTGeo GridProperties instance (a collection of properties) or a single GridProperty instance

  • grid (Grid or tuple) – A XTGeo Grid instance or a reference via tuple. If this is tuple with log names, it states that these logs already contains the gridcell IJK numbering.

  • prop_id (str) – Add a tag (optional) to the current log name, e.g as PORO_model, where _model is the tag.

Raises:

None

Added in version 2.1.

get_lognames()

Get the lognames for all logs.

get_logrecord(lname)

Returns the record (dict) of a given log name, None if not exists.

Return type:

dict[int, str] | Sequence[str] | None

get_logrecord_codename(lname, key)

Returns the name entry of a log record, for a given key.

Example:

# get the name for zonelog entry no 4:
zname = well.get_logrecord_codename('ZONELOG', 4)
Return type:

str | None

get_logtype(lname)

Returns the type of a given log (e.g. DISC or CONT), None if not present.

Return type:

str | None

get_polygons(skipname=False)

Return a Polygons object from the well trajectory.

Parameters:

skipname (bool) – If True then name column is omitted

Added in version 2.1.

Changed in version 2.13: Added skipname key

static get_short_wellname(wellname)

Well name on a short name form where blockname and spaces are removed.

This should cope with both North Sea style and Haltenbanken style. E.g.: ‘31/2-G-5 AH’ -> ‘G-5AH’, ‘6472_11-F-23_AH_T2’ -> ‘F-23AHT2’

get_surface_picks(surf)

Return Points obj where well crosses the surface (horizon picks).

There may be several points in the Points() dataframe attribute. Also a DIRECTION column will show 1 if surface is penetrated from above, and -1 if penetrated from below.

Parameters:

surf (RegularSurface) – The surface instance

Returns:

A Points instance, or None if no crossing points

Added in version 2.8.

get_wlogs()

Get a compound dictionary with well log metadata.

The result will be an dict on the form:

{"X_UTME": ["CONT", None], ... "Facies": ["DISC", {1: "BG", 2: "SAND"}]}

Return type:

dict

get_zonation_points(tops=True, incl_limit=80, top_prefix='Top', zonelist=None, use_undef=False)

Extract zonation points from Zonelog and make a marker list.

Currently it is either ‘Tops’ or ‘Zone’ (thicknesses); default is tops (i.e. tops=True).

The zonelist can be a list of zones, or a tuple with two members specifying first and last member. Note however that the zonation shall be without jumps and increasing. E.g.:

zonelist=(1, 5)  # meaning [1, 2, 3, 4, 5]
# or
zonelist=[1, 2, 3, 4]
# while _not_ legal:
zonelist=[1, 4, 8]

Zone numbers less than 0 are not accepted

Parameters:
  • tops (bool) – If True then compute tops, else (thickness) points.

  • incl_limit (float) – If given, and usezone is True, the max angle of inclination to be used as input to zonation points.

  • top_prefix (str) – As well logs usually have isochore (zone) name, this prefix could be Top, e.g. ‘SO43’ –> ‘TopSO43’

  • zonelist (list of int or tuple) – Zones to use

  • use_undef (bool) – If True, then transition from UNDEF is also used.

Returns:

A pandas dataframe (ready for the xyz/Points class), None if a zonelog is missing

get_zone_interval(zonevalue, resample=1, extralogs=None)

Extract the X Y Z ID line (polyline) segment for a given zonevalue.

Parameters:
  • zonevalue (int) – The zone value to extract

  • resample (int) – If given, downsample every N’th sample to make polylines smaller in terms of bit and bytes. 1 = No downsampling.

  • extralogs (list of str) – List of extra log names to include

Returns:

A pandas dataframe X Y Z ID (ready for the xyz/Polygon class), None if a zonelog is missing or actual zone does dot exist in the well.

property gridname

Returns or set (rename) the grid name that the blocked wells belongs to.

isdiscrete(logname)

Return True of log is discrete, otherwise False.

Parameters:

logname (str) – Name of log to check if discrete or not

Added in version 2.2.0.

limit_tvd(tvdmin, tvdmax)

Truncate the part of the well that is outside tvdmin, tvdmax.

Range will be in tvdmin <= tvd <= tvdmax.

Parameters:
  • tvdmin (float) – Minimum TVD

  • tvdmax (float) – Maximum TVD

property lognames

Returns the Pandas dataframe column as list excluding coords.

Type:

list

property lognames_all

Returns dataframe column names as list, including mandatory coords.

Type:

list

make_ijk_from_grid(grid, grid_id='', activeonly=True, **kwargs)

Look through a Grid and add grid I J K as discrete logs.

Note that the the grid counting has base 1 (first row is 1 etc).

By default, log (i.e. column names in the dataframe) will be ICELL, JCELL, KCELL, but you can add a tag (ID) to that name.

Parameters:
  • grid (Grid) – A XTGeo Grid instance

  • grid_id (str) – Add a tag (optional) to the current log name

  • activeonly (bool) – If True, only active cells are applied (algorithm 2 only)

Raises:

RuntimeError – ‘Error from C routine, code is …’

Changed in version 2.9: Added keys for and activeonly

make_zone_qual_log(zqname)

Create a zone quality/indicator (flag) log.

This routine looks through to zone log and flag intervals according to neighbouring zones:

  • 0: Undetermined flag

  • 1: Zonelog interval numbering increases,

    e.g. for zone 2: 1 1 1 1 2 2 2 2 2 5 5 5 5 5

  • 2: Zonelog interval numbering decreases,

    e.g. for zone 2: 6 6 6 2 2 2 2 1 1 1

  • 3: Interval is a U turning point, e.g. 0 0 0 2 2 2 1 1 1

  • 4: Interval is a inverse U turning point, 3 3 3 2 2 2 5 5

  • 9: Interval is bounded by one or more missing sections,

    e.g. 1 1 1 2 2 2 -999 -999

If a log with the name exists, it will be silently replaced

Parameters:

zqname (str) – Name of quality log

mask_shoulderbeds(inputlogs, targetlogs, nsamples=2, strict=False)

Mask data around zone boundaries or other discrete log boundaries.

This operates on number of samples, hence the actual distance which is masked depends on the sampling interval (ie. count) or on distance measures. Distance measures are TVD (true vertical depth) or MD (measured depth).

_images/wells-mask-shoulderbeds.png
Parameters:
  • inputlogs (list[str]) – List of input logs, must be of discrete type.

  • targetlogs (list[str]) – List of logs where mask is applied.

  • nsamples (int | dict[str, float] | None) – Number of samples around boundaries to filter, per side, i.e. value 2 means 2 above and 2 below, in total 4 samples. As alternative specify nsamples indirectly with a relative distance, as a dictionary with one record, as {“tvd”: 0.5} or {“md”: 0.7}.

  • strict (bool | None) – If True, will raise Exception of any of the input or target log names are missing.

Return type:

bool

Returns:

True if any operation has been done. False in case nothing has been done,

e.g. no targetlogs for this particular well and strict is False.

Raises:

ValueError – Various messages when wrong or inconsistent input.

Example

>>> mywell1 = Well(well_dir + '/OP_1.w')
>>> mywell2 = Well(well_dir + '/OP_2.w')
>>> did_succeed = mywell1.mask_shoulderbeds(["Zonelog", "Facies"], ["Perm"])
>>> did_succeed = mywell2.mask_shoulderbeds(
...     ["Zonelog"],
...     ["Perm"],
...     nsamples={"tvd": 0.8}
... )
may_overlap(other)

Consider if well overlap in X Y coordinates with other well, True/False.

property mdlogname

Returns name of MD log, if any (None if missing).

Type:

str

property metadata

Return metadata object instance of type MetaDataRegularSurface.

property name

Returns or set (rename) a well name.

property ncol

Returns the Pandas dataframe object number of columns.

Type:

int

property nlogs

Returns the Pandas dataframe object number of columns.

Type:

int

property nrow

Returns the Pandas dataframe object number of rows.

Type:

int

rename_log(lname, newname)

Rename a log, e.g. Poro to PORO.

report_zonation_holes(threshold=5)

Reports if well has holes in zonation, less or equal to N samples.

Zonation may have holes due to various reasons, and usually a few undef samples indicates that something is wrong. This method reports well and start interval of the “holes”

The well shall have zonelog from import (via zonelogname attribute) and preferly a MD log (via mdlogname attribute); however if the latter is not present, a report withou MD values will be present.

Parameters:

threshold (int) – Number of samples (max.) that defines a hole, e.g. 5 means that undef samples in the range [1, 5] (including 5) is applied

Returns:

A Pandas dataframe as a report. None if no list is made.

Raises:

RuntimeError if zonelog is not present

rescale(delta=0.15, tvdrange=None)

Rescale (refine or coarse) by sampling a delta along the trajectory, in MD.

Parameters:
  • delta (float) – Step length

  • tvdrange (tuple of floats) – Resampling can be limited to TVD interval

Changed in version 2.2: Added tvdrange

property rkb

Returns RKB height for the well (read only).

property safewellname

Get well name on syntax safe form; ‘/’ and spaces replaced with ‘_’.

set_dataframe(dfr)

Set the dataframe.

set_logrecord(lname, newdict)

Sets the record (dict) of a given discrete log.

Return type:

None

set_logtype(lname, ltype)

Sets the type of a give log (e.g. DISC or CONT).

Return type:

None

set_wlogs(wlogs)

Set a compound dictionary with well log metadata.

This operation is somewhat risky as it may lead to inconsistency, so use with care! Typically, one will use get_wlogs() first and then modify some attributes.

Parameters:

wlogs (dict) – Input data dictionary

Raises:
  • ValueError – Invalid log type found in input:

  • ValueError – Invalid log record found in input:

  • ValueError – Invalid input key found:

  • ValueError – Invalid log record found in input:

property shortwellname

Well name on a short form where blockname/spaces removed (read only).

This should cope with both North Sea style and Haltenbanken style.

E.g.: ‘31/2-G-5 AH’ -> ‘G-5AH’, ‘6472_11-F-23_AH_T2’ -> ‘F-23AHT2’

Type:

str

to_file(bwfile, fformat=None, compression='lzf')[source]

Export BlockedWell to file.

Parameters:
  • bwfile – File name or pathlib.Path or stream

  • fformat – File format (‘rms_ascii’/’rmswell’, ‘csv’, ‘hdf’/’hdf5’/’h5’). If None (default), uses ‘rms_ascii’.

  • compression (str | None) – Compression for HDF5 format only. Default is ‘lzf’.

Returns:

Path to file (or file object if stream was provided)

Example:

>>> mybw = xtgeo.blockedwell_from_file(well_dir + '/OP_1.bw')
>>> mybw.to_file(outdir + '/OP_1_copy.bw')

Changed in version 4.0: Added explicit to_file method for BlockedWell

to_hdf(wfile, compression='lzf')

Export well to HDF based file.

Deprecated since version 4.19: (approx) Use to_file() with fformat='hdf5' instead. This method is redundant and will be removed in version 5.0.

Warning

This implementation is currently experimental and only recommended for testing.

Parameters:
  • wfile (str | Path) – HDF File name to write to export to.

  • compression (str | None) – Compression type (default ‘lzf’).

Return type:

Path

Returns:

A Path instance to actual file applied.

Added in version 2.14.

to_roxar(project, gridname, bwname, wname, lognames='all', realisation=0, ijk=False)[source]

Set (export) a single blocked well item inside roxar project.

Note this method works only when inside RMS, or when RMS license is activated. RMS will store blocked wells as a Gridmodel feature, not as a well.

Note

When project is file path (direct access, outside RMS) then to_roxar() will implicitly do a project save. Otherwise, the project will not be saved until the user do an explicit project save action.

Parameters:
  • project (Any) – Magic object ‘project’ or file path to project

  • gridname (str) – Name of GridModel icon in RMS

  • bwname (str) – Name of Blocked Well icon in RMS, usually ‘BW’

  • wname (str) – Name of well, as shown in RMS.

  • lognames (str | list[str]) – List of lognames to include, or use ‘all’ for all current blocked logs for this well (except index logs). Default is “all”.

  • realisation (int) – Realisation index (0 is default)

  • ijk (bool) – If True, then also write special index logs if they exist, such as I_INDEX, J_INDEX, K_INDEX, etc. Default is False

Return type:

None

property truewellname

Returns well name on the assummed form aka ‘31/2-E-4 AH2’.

truncate_parallel_path(other, xtol=None, ytol=None, ztol=None, itol=None, atol=None)

Truncate the part of the well trajectory that is ~parallel with other.

Parameters:
  • other (Well) – Other well to compare with

  • xtol (float) – Tolerance in X (East) coord for measuring unit

  • ytol (float) – Tolerance in Y (North) coord for measuring unit

  • ztol (float) – Tolerance in Z (TVD) coord for measuring unit

  • itol (float) – Tolerance in inclination (degrees)

  • atol (float) – Tolerance in azimuth (degrees)

property wellname

Returns well name, read only.

Type:

str

property wlogrecords

Returns wlogrecords

property wlogtypes

Returns wlogtypes

property wname

Returns or set (rename) a well name.

property xname

Return or set name of X coordinate column.

property xpos

Returns well header X position (read only).

property xwellname

See safewellname.

property yname

Return or set name of Y coordinate column.

property ypos

Returns well header Y position (read only).

property zname

Return or set name of Z coordinate column.

property zonelogname

Returns or sets name of zone log, return None if missing.

Type:

str

Blocked wells (multiple)

Functions

xtgeo.blockedwells_from_files(filelist, fformat='rms_ascii', mdlogname=None, zonelogname=None, strict=True)[source]

Import blocked wells from a list of files (filelist).

Parameters:
  • filelist (list of str) – List with file names

  • fformat (str) – File format, rms_ascii (rms well) is currently supported and default format.

  • mdlogname (str) – Name of measured depth log, if any

  • zonelogname (str) – Name of zonation log, if any

  • strict (bool) – If True, then import will fail if zonelogname or mdlogname are asked for but not present in wells.

Example

Here the from_file method is used to initiate the object directly:

mywells = BlockedWells(['31_2-6.w', '31_2-7.w', '31_2-8.w'])
xtgeo.blockedwells_from_stacked_file(bwfile, fformat=None, mdlogname=None, zonelogname=None, strict=False)[source]

Import multiple blocked wells from a single concatenated (stacked) file.

This function reads files that contain multiple blocked wells in a single file, as created by BlockedWells.to_stacked_file().

For CSV format, expects a WELLNAME column to identify each blocked well. For RMS ASCII format, reads multiple blocked well entries, each with its own header.

Parameters:
  • bwfile (Union[str, Path, StringIO, BytesIO]) – File name or stream.

  • fformat (str | None) – File format (‘rms_ascii’/’rmswell’ or ‘csv’). If None, auto-detect from file extension or signature.

  • mdlogname (str | None) – Name of measured depth log to use

  • zonelogname (str | None) – Name of zone log to use

  • strict (bool) – If True, raise error if mdlogname/zonelogname not found

Return type:

BlockedWells

Returns:

BlockedWells instance containing all blocked wells from the file.

Example:

>>> bwells = xtgeo.blockedwells_from_stacked_file(
...     "all_bwells.csv", fformat="csv"
... )
>>> bwells = xtgeo.blockedwells_from_stacked_file("all_bwells.rmswell")

Added in version 4.19: (approximate)

xtgeo.blockedwells_from_roxar(project, gname, bwname, lognames=None, ijk=True)[source]

This makes an instance of a BlockedWells directly from Roxar RMS.

For arguments, see BlockedWells.from_roxar().

Note the difference between classes BlockedWell and BlockedWells.

Example:

# inside RMS:
import xtgeo
mylogs = ['ZONELOG', 'GR', 'Facies']
mybws = xtgeo.blockedwells_from_roxar(project, 'Simgrid', 'BW',
                                    lognames=mylogs)

Classes

class xtgeo.BlockedWells(wells=None)[source]

Bases: Wells

Class for a collection of BlockedWell objects, for operations that involves a number of wells.

See also the xtgeo.well.BlockedWell class.

Public Data Attributes:

Inherited from Wells

names

Returns a list of well names (read only).

wells

Returns or sets a list of XTGeo Well objects, None if empty.

Public Methods:

copy()

Copy a BlockedWells instance to a new unique instance.

get_blocked_well(name)

Get a BlockedWell() instance by name, or None

to_stacked_file(bwfile[, fformat, compression])

Export multiple blocked wells to a single concatenated (stacked) file.

Inherited from Wells

describe([flush])

Describe an instance by printing to stdout

copy()

Copy a Wells instance to a new unique instance (a deep copy).

get_well(name)

Get a Well() instance by name, or None

get_dataframe([filled, fill_value1, fill_value2])

Get a big dataframe for all wells or blocked wells in instance, with well name as first column

to_stacked_file(wfile[, fformat])

Export multiple wells to a single concatenated (stacked) file.

quickplot([filename, title])

Fast plot of wells using matplotlib.

limit_tvd(tvdmin, tvdmax)

Limit TVD to be in range tvdmin, tvdmax for all wells

downsample([interval, keeplast])

Downsample by sampling every N'th element (coarsen only), all wells.

wellintersections([wfilter, showprogress])

Get intersections between wells, return as dataframe table.


__init__(wells=None)
copy()[source]

Copy a BlockedWells instance to a new unique instance.

describe(flush=True)

Describe an instance by printing to stdout

downsample(interval=4, keeplast=True)

Downsample by sampling every N’th element (coarsen only), all wells.

get_blocked_well(name)[source]

Get a BlockedWell() instance by name, or None

get_dataframe(filled=False, fill_value1=-999, fill_value2=-9999)

Get a big dataframe for all wells or blocked wells in instance, with well name as first column

Parameters:
  • filled (bool) – If True, then NaN’s are replaces with values

  • fill_value1 (int) – Only applied if filled=True, for logs that have missing values

  • fill_value2 (int) – Only applied if filled=True, when logs are missing completely for that well.

get_well(name)

Get a Well() instance by name, or None

limit_tvd(tvdmin, tvdmax)

Limit TVD to be in range tvdmin, tvdmax for all wells

property names

Returns a list of well names (read only).

Example:

namelist = wells.names
for prop in namelist:
    print ('Well name is {}'.format(name))
quickplot(filename=None, title='QuickPlot')

Fast plot of wells using matplotlib.

Parameters:
  • filename (str) – Name of plot file; None will plot to screen.

  • title (str) – Title of plot

to_stacked_file(bwfile, fformat='rms_ascii', compression='lzf')[source]

Export multiple blocked wells to a single concatenated (stacked) file.

For CSV format, all blocked wells are combined into a single table with a WELLNAME column to identify each blocked well.

For RMS ASCII format, each blocked well is written sequentially in the standard RMS well format (with its own header and data section).

Parameters:
  • bwfile (Union[str, Path, StringIO, BytesIO]) – File name or stream.

  • fformat (str | None) – File format (‘rms_ascii’/’rmswell’ or ‘csv’). Default is ‘rms_ascii’. HDF5 is not supported.

  • compression (str | None) – Not used, kept for API compatibility.

Return type:

Path | BytesIO | StringIO

Returns:

Path to the file that was written.

Example:

>>> bwells = BlockedWells([bwell1, bwell2, bwell3])
>>> bwells.to_stacked_file("all_bwells.csv", fformat="csv")
>>> bwells.to_stacked_file("all_bwells.rmswell", fformat="rms_ascii")

Added in version 4.19: (approximate)

wellintersections(wfilter=None, showprogress=False)

Get intersections between wells, return as dataframe table.

Notes on wfilter: A wfilter is settings to improve result. In particular to remove parts of trajectories that are parallel.

wfilter = {‘parallel’: {‘xtol’: 4.0, ‘ytol’: 4.0, ‘ztol’:2.0,

‘itol’:10, ‘atol’:2}}

Here xtol is tolerance in X coordinate; further Y tolerance, Z tolerance, (I)nclination tolerance, and (A)zimuth tolerance.

Parameters:
  • tvdrange (tuple of floats) – Search interval. One is often just interested in the reservoir section.

  • wfilter (dict) – A dictionrary for filter options, in order to improve result. See example above.

  • showprogress (bool) – Will show progress to screen if enabled.

Returns:

A Pandas dataframe object, with columns WELL, CWELL and UTMX UTMY

TVD coordinates for CWELL where CWELL crosses WELL, and also MDEPTH for the WELL.

property wells

Returns or sets a list of XTGeo Well objects, None if empty.