Docstrings for quick_pp package

Porosity module

quick_pp.porosity.normalize_volumetric(phit, **volumetrics)[source]

Normalize lithology given total porosity.

Parameters:
  • phit (np.ndarray or float) – Total porosity in fraction (v/v).

  • **volumetrics – Keyword arguments representing volumetric fractions (v/v) relative to matrix.

Returns:

Normalized volumetric fractions relative to bulk volume.

Return type:

dict

quick_pp.porosity.unnormalize_volumetric(phit, **normalized_volumetrics)[source]

Unnormalize lithology given total porosity.

This is the reverse of normalize_volumetric. It calculates the matrix-relative volumetrics from bulk-relative (normalized) volumetrics.

Parameters:
  • phit (np.ndarray or float) – Total porosity in fraction (v/v).

  • **normalized_volumetrics – Keyword arguments representing bulk-relative (normalized) volumetric fractions of the bulk volume (v/v).

Returns:

Unnormalized volumetric fractions relative to the matrix volume.

Return type:

dict

quick_pp.porosity.get_volumetric_dict(df)[source]

Given dataframe, return a dictionary of the key and values of lithology metrics in the data.

Parameters:

df (pd.DataFrame) – Dataframe with well log data.

Returns:

Dictionary of the key and values of lithology metrics in the data.

Return type:

dict

quick_pp.porosity.effective_porosity(phit, phi_shale, vshale)[source]

Computes effective porosity from total porosity, total porosity of shale and shale volume.

Parameters:
  • phit (np.ndarray or float) – Total porosity [fraction].

  • phi_shale (np.ndarray or float) – Total porosity of shale [fraction].

  • vshale (np.ndarray or float) – Shale volume [fraction].

Returns:

porosity – Effective porosity [fraction].

Return type:

float

quick_pp.porosity.estimate_shale_porosity_trend(rho_clw: ndarray, rho_dry_clay: float = 2.72, rho_fluid: float = 1.0)[source]

Calculate clay porosity given bulk density of wet clay line.

Parameters:
  • rho_clw (np.ndarray or float) – Bulk density of wet clay line.

  • rho_dry_clay (float, optional) – Bulk density of dry clay. Defaults to 2.72.

  • rho_fluid (float, optional) – Bulk density of fluid. Defaults to 1.0.

Returns:

Clay porosity.

Return type:

np.ndarray or float

quick_pp.porosity.estimate_shale_porosity(nphi, phit)[source]

Computes shale porosity from neutron porosity and total porosity.

Parameters:
  • nphi (np.ndarray or float) – Neutron porosity (hydrocarbon corrected) [fraction].

  • phit (np.ndarray or float) – Total porosity [fraction].

Returns:

Shale porosity [fraction].

Return type:

np.ndarray or float

quick_pp.porosity.rho_matrix(**volumetrics)[source]

Estimate average matrix density based on mineral volumes and their densities from Config.

Parameters:

**volumetrics – Keyword arguments where keys are mineral volume names (e.g., vsand, vclay) and values are their volume fractions.

Returns:

Matrix density in g/cc.

Return type:

np.ndarray or float

quick_pp.porosity.density_porosity(rhob, rho_matrix, rho_fluid: float = 1.0)[source]

Computes density porosity from bulk, matrix and fluid densities

Parameters:
  • rhob (np.ndarray or float) – Bulk density log in g/cc.

  • rho_matrix (np.ndarray or float) – Matrix density in g/cc.

  • rho_fluid (float, optional) – Density of fluid in g/cc. Defaults to 1.0 g/cc.

Returns:

Density porosity [fraction]

Return type:

np.ndarray or float

quick_pp.porosity.dt_matrix(vsand=0, vclay=0, vcalc=0, vdolo=0, vheavy=0, dt_sand: float = 0, dt_silt: float = 0, dt_clay: float = 0, dt_calc: float = 0, dt_dolo: float = 0, dt_heavy: float = 0)[source]

Estimate average matrix sonic transit time based on dry sand, dry silt dry calcite and dry dolomite volume and transit time of each.

Parameters:
  • vsand (np.ndarray or float, optional) – Volume of sand. Defaults to 0.

  • vclay (np.ndarray or float, optional) – Volume of clay. Defaults to 0.

  • vcalc (np.ndarray or float, optional) – Volume of calcite. Defaults to 0.

  • vdolo (np.ndarray or float, optional) – Volume of dolomite. Defaults to 0.

  • vheavy (np.ndarray or float, optional) – Volume of heavy minerals. Defaults to 0.

  • dt_sand (float, optional) – Sonic transit time of sand in us/ft. Defaults to None.

  • dt_silt (float, optional) – Sonic transit time of silt in us/ft. Defaults to None.

  • dt_clay (float, optional) – Sonic transit time of clay in us/ft. Defaults to None.

  • dt_calc (float, optional) – Sonic transit time of calcite in us/ft. Defaults to None.

  • dt_dolo (float, optional) – Sonic transit time of dolomite in us/ft. Defaults to None.

  • dt_heavy (float, optional) – Sonic transit time of heavy minerals in us/ft. Defaults to 0.0.

Returns:

Matrix sonic transit time in us/ft.

Return type:

np.ndarray or float

quick_pp.porosity.sonic_porosity_wyllie(dt, dt_matrix, dt_fluid)[source]

Computes sonic porosity based on Wyllie’s equation from interval, matrix, and fluid transit time.

Parameters:
  • dt (np.ndarray or float) – Interval transit time [us/ft].

  • dt_matrix (np.ndarray or float) – Matrix transit time [us/ft]. Sandstone: 51-55, Limestone: 43-48, Dolomite: 43-39, Shale: 60-170.

  • dt_fluid (np.ndarray or float) – Fluid transit time [us/ft]. Water: 190, Oil: 240, Gas: 630.

Returns:

porosity – Sonic porosity [fraction].

Return type:

np.ndarray or float

quick_pp.porosity.sonic_porosity_hunt_raymer(dt, dt_matrix, dt_fluid)[source]

Computes sonic porosity based on Hunt-Raymer’s equation from interval, matrix and transit time.

Parameters:
  • dt (np.ndarray or float) – Interval transit time [us/ft].

  • dt_matrix (np.ndarray or float) – Matrix transit time [us/ft]. Sandstone: 51-55, Limestone: 43-48, Dolomite: 43-39, Shale: 60-170.

  • dt_fluid (np.ndarray or float) – Fluid transit time [us/ft]. Water: 190, Oil: 240, Gas: 630.

Returns:

porosity – Sonic porosity [fraction].

Return type:

np.ndarray or float

quick_pp.porosity.neu_den_xplot_poro_pt(nphi: float, rhob: float, model: str = 'ssc', dry_min1_point: tuple = (), dry_silt_point: tuple = (), dry_clay_point: tuple = (), fluid_point: tuple = (1.0, 1.0))[source]

Calculate porosity given a pair of neutron porosity and bulk density data point. This function is designed to process a single data point.

Parameters:
  • nphi (float) – Neutron porosity log value.

  • rhob (float) – Bulk density log value.

  • model (str, optional) – Lithology model, either ‘ssc’ (Sand Silt Clay) or ‘ss’ (Sand Shale). Defaults to ‘ssc’.

  • dry_min1_point (tuple, optional) – Neutron porosity and bulk density of mineral 1 point. Defaults to ().

  • dry_silt_point (tuple, optional) – Neutron porosity and bulk density of dry silt point. Defaults to ().

  • dry_clay_point (tuple, optional) – Neutron porosity and bulk density of dry clay point. Defaults to ().

  • fluid_point (tuple, optional) – Neutron porosity and bulk density of fluid point. Defaults to (1.0, 1.0).

Returns:

Total porosity for the given data point.

Return type:

float

quick_pp.porosity.neu_den_xplot_poro(nphi, rhob, model: str = 'ssc', dry_min1_point: tuple = (), dry_silt_point: tuple = (), dry_clay_point: tuple = (), fluid_point: tuple = (1.0, 1.0))[source]

Calculate porosity given neutron porosity and bulk density logs.

This function processes arrays of log data.

Parameters:
  • nphi (np.ndarray or float) – Neutron porosity log.

  • rhob (np.ndarray or float) – Bulk density log.

  • model (str, optional) – Lithology model, either ‘ssc’ (Sand Silt Clay), ‘ss’ (Sand Shale) or ‘carb’ (Carbonate). Defaults to ‘ssc’.

  • dry_min1_point (tuple, optional) – Neutron porosity and bulk density of dry min1 point. Defaults to ().

  • dry_silt_point (tuple, optional) – Neutron porosity and bulk density of dry silt point. Defaults to ().

  • dry_clay_point (tuple, optional) – Neutron porosity and bulk density of dry clay point. Defaults to ().

  • fluid_point (tuple, optional) – Neutron porosity and bulk density of fluid point. Defaults to (1.0, 1.0).

Returns:

Total porosity log.

Return type:

np.ndarray or float

quick_pp.porosity.porosity_correction_averaging(nphi, rhob, rho_ma=2.65, method='weighted')[source]

Correct porosity using averaging method. Weighted average: (2 * dphi + nphi) / 3 Arithmetic average: (dphi + nphi) / 2 Gaymard average: sqrt((dphi**2 + nphi**2) / 2) Gas average: sqrt((dphi**2 + nphi**2) / 2)

Parameters:
  • nphi (np.ndarray or float) – Neutron porosity.

  • rhob (np.ndarray or float) – Bulk density log.

  • rho_ma (float, optional) – Matrix density. Defaults to 2.65.

  • method (str, optional) – Averaging method selection from ‘weighted’, ‘arithmetic’ or ‘gaymard’. Defaults to ‘weighted’.

Returns:

Corrected porosity.

Return type:

np.ndarray or float

quick_pp.porosity.porosity_trend(tvdss, unit='ft')[source]

Calculate porosity trend based on TVDSS (Schmoker, 1982)

Parameters:
  • tvdss (np.ndarray or float) – True Vertical Depth Subsea.

  • unit (str, optional) – Unit of depth, either ‘ft’ or ‘m’. Defaults to ‘ft’.

Returns:

Porosity trend.

Return type:

np.ndarray or float

quick_pp.porosity.nmr_porosity(t2_dist, t2_bins, t2_cutoff=33)[source]

Calculate NMR porosity from T2 distribution.

Total porosity is the sum of all T2 distribution amplitudes. Effective porosity is the sum of T2 distribution amplitudes above the T2 cutoff.

Parameters:
  • t2_dist (array-like) – T2 distribution amplitudes

  • t2_bins (array-like) – T2 time bins corresponding to distribution

  • t2_cutoff (float, optional) – T2 cutoff time in ms. Defaults to 33ms.

Returns:

Total porosity and effective porosity (phit, phie)

Return type:

tuple

Lithology module

Saturation module

quick_pp.saturation.archie_saturation(rt, rw, phit, a=1, m=2, n=2)[source]

Estimate water saturation based on Archie’s model for clean sand.

Parameters:
  • rt (np.ndarray or float) – True resistivity or deep resistivity log [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • a (float, optional) – Tortuosity factor. Defaults to 1.0.

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

  • n (float, optional) – Saturation exponent. Defaults to 2.0.

Returns:

Water saturation (fraction).

Return type:

np.ndarray or float

References

Archie, G.E. (1942). The Electrical Resistivity Log as an Aid in Determining Some Reservoir Characteristics. Transactions of the AIME, 146(1), 54-62.

quick_pp.saturation.waxman_smits_saturation(rt, rw, phit, Qv=None, B=None, m=2, n=2)[source]

Estimate water saturation using the Waxman-Smits model for shaly sands.

This function iteratively solves the Waxman-Smits equation, which accounts for the conductivity of clay minerals in the formation.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • Qv (np.ndarray or float, optional) – Cation exchange capacity per unit pore volume [meq/cm³]. Defaults to 0.3 if not provided.

  • B (np.ndarray or float, optional) – Equivalent conductance of clay exchange cations [S·m²/meq]. If not provided, it is estimated based on Rw at 25°C.

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

  • n (float, optional) – Saturation exponent. Defaults to 2.0.

Returns:

Water saturation (fraction).

Return type:

np.ndarray or float

References

Waxman, M.H. and Smits, L.J.M. (1968). Electrical Conductivities in Oil-Bearing Shaly Sands. Society of Petroleum Engineers Journal, 8(2), 107-122.

Ausburn, B.E. and Freedman, R. (1985). The Waxman-Smits Equation For Shaly Sands: I. Simple Methods Of Solution, II. Error Analysis. The Log Analyst, 26.

quick_pp.saturation.normalized_waxman_smits_saturation(rt, rw, phit, vshale, phit_shale, rt_shale, m=2, n=2)[source]

Estimate water saturation using the normalized Waxman-Smits model (Juhasz, 1981).

This is a variation of the Waxman-Smits model that uses normalized Qv (Qvn) and derives the B parameter from shale properties.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • vshale (np.ndarray or float) – Volume of shale [fraction].

  • phit_shale (np.ndarray or float) – Porosity of the shale [fraction].

  • rt_shale (np.ndarray or float) – Resistivity of the shale [ohm.m].

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

  • n (float, optional) – Saturation exponent. Defaults to 2.0.

Returns:

Water saturation (fraction).

Return type:

np.ndarray or float

References

Juhasz, I. (1981). Normalized Qv—The Key to Shaly Sand Evaluation Using the Waxman-Smits Equation in the Absence of Core Data. SPWLA 22nd Annual Logging Symposium.

quick_pp.saturation.dual_water_saturation(rt, rw, phit, a, m, n, swb, rwb)[source]

Estimate water saturation using the Dual Water model.

The Dual Water model is an extension of the Waxman-Smits model that considers two types of water in the pore space: bound water and free water.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • rw (np.ndarray or float) – Formation (free) water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • a (float) – Tortuosity factor.

  • m (float) – Cementation exponent.

  • n (float) – Saturation exponent.

  • swb (np.ndarray or float) – Bound water saturation [fraction of total porosity].

  • rwb (np.ndarray or float) – Bound water resistivity [ohm.m].

Returns:

Total water saturation (fraction).

Return type:

np.ndarray or float

References

Clavier, C., Coates, G., and Dumanoir, J. (1984). The Theoretical and Experimental Bases for the “Dual Water” Model for the Interpretation of Shaly Sands. Society of Petroleum Engineers Journal, 24(2), 153-168.

quick_pp.saturation.indonesian_saturation(rt, rw, phie, vsh, rsh, a, m, n)[source]

Estimate water saturation using the Indonesian model (Poupon-Leveaux, 1971).

This model is often used for shaly sands, particularly in formations with fresh water.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phie (np.ndarray or float) – Effective porosity [fraction].

  • vsh (np.ndarray or float) – Volume of shale [fraction].

  • rsh (np.ndarray or float) – Resistivity of shale [ohm.m].

  • a (float) – Tortuosity factor.

  • m (float) – Cementation exponent. Defaults to 2.0.

  • n (float) – Saturation exponent.

Returns:

Water saturation (fraction).

Return type:

np.ndarray or float

References

Poupon, A., and Leveaux, J. (1971). Evaluation of Water Saturation in Shaly Formations. The Log Analyst, 12(4).

quick_pp.saturation.simandoux_saturation(rt, rw, phit, vsh, rsh, a, m)[source]

Estimate water saturation using the Simandoux model (1963).

This is a classic shaly sand model that adds a shale conductivity term to the clean sand Archie equation.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • vsh (np.ndarray or float) – Volume of shale [fraction].

  • rsh (np.ndarray or float) – Resistivity of shale [ohm.m].

  • a (float) – Tortuosity factor.

  • m (float) – Cementation exponent.

Returns:

Water saturation (fraction).

Return type:

np.ndarray or float

quick_pp.saturation.connectivity_saturation(rt, rw, phit, mu=2, chi_w=0)[source]

Estimate water saturation using the Connectivity Equation (Montaron, 2009).

This model relates water saturation to porosity and a water connectivity index, offering an alternative to traditional shaly sand models.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • mu (float, optional) – Conductivity exponent, typically 1.6-2.0. Defaults to 2.0.

  • chi_w (float, optional) – Water connectivity correction index, typically -0.02 to 0.02. Defaults to 0.

Returns:

Water saturation (fraction).

Return type:

np.ndarray or float

References

Montaron, B. (2009). The Connectivity Equation: A New Formation Evaluation Concept. SPWLA 50th Annual Logging Symposium.

quick_pp.saturation.estimate_swb(phit, vsh, nphi_sh)[source]

Estimate bound water saturation based on dual water model. :param phit: Total porosity in fraction. :type phit: np.ndarray or float :param vsh: Volume of shale in fraction. :type vsh: np.ndarray or float :param nphi_sh: Neutron porosity reading in a nearby 100% shale interval in fraction. :type nphi_sh: np.ndarray or float

Returns:

Bound water saturation.

Return type:

np.ndarray or float

quick_pp.saturation.estimate_chi_w(s_cw, phit, sigma_cw, sigma_w, mu=2)[source]

Estimate water connectivity correction index based on connectivity model Montaron 2009 :param s_cw: Water saturation, ranges from 0 to 1. :type s_cw: np.ndarray or float :param phit: Total porosity. :type phit: np.ndarray or float :param sigma_cw: Conductivity of clay water, ranges from 0 to 1. :type sigma_cw: np.ndarray or float :param sigma_w: Water conductivity, ranges from 0 to 1. :type sigma_w: np.ndarray or float :param mu: Conductivity exponent, ranges from 1.6 to 2.0. Defaults to 2.0. :type mu: float, optional

Returns:

Water connectivity correction index.

Return type:

np.ndarray or float

quick_pp.saturation.estimate_temperature_gradient(tvd, unit='metric')[source]

Estimate formation temperature based on gradient of 25 degC/km or 15 degF/1000ft.

Parameters:
  • tvd (np.ndarray or float) – True vertical depth in m.

  • unit (str, optional) – The unit system for depth and gradient, either ‘metric’ or ‘imperial’. Defaults to ‘metric’.

Returns:

Formation temperature in degrees Celsius.

Return type:

np.ndarray or float

quick_pp.saturation.estimate_b_waxman_smits(T, rw)[source]

Estimate the B parameter (equivalent conductance) for the Waxman-Smits model.

This function uses the empirical relationship proposed by Juhasz (1981) which relates B to formation temperature and water resistivity.

Parameters:
  • T (np.ndarray or float) – Formation temperature in degrees Celsius.

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

Returns:

The B parameter for the Waxman-Smits equation.

Return type:

np.ndarray or float

References

Juhasz, I. (1981). Normalized Qv—The Key to Shaly Sand Evaluation Using the Waxman-Smits Equation in the Absence of Core Data. SPWLA 22nd Annual Logging Symposium.

quick_pp.saturation.estimate_rw_temperature_salinity(temp_formation, water_salinity)[source]

Estimate formation water resistivity (Rw) from temperature and salinity. Based on Crain’s Petrophysical Handbook, which attributes the algorithm to the Bateman and Konen (1977) method.

This function uses a common empirical formula to approximate Rw.

Parameters:
  • temp_formation (np.ndarray or float) – Formation temperature [degrees Celsius].

  • water_salinity (np.ndarray or float) – Water salinity [parts per million (ppm)].

Returns:

Estimated formation water resistivity [ohm.m].

Return type:

np.ndarray or float

quick_pp.saturation.estimate_rw_surface(temp_formation, rw_surface, temp_surface=20)[source]

Estimate downhole formation water resistivity (Rw) from surface measurements.

This uses Arps’ formula to adjust resistivity for temperature.

Parameters:
  • temp_formation (np.ndarray or float) – Formation temperature [degrees Celsius].

  • rw_surface (float) – Water resistivity measured at surface temperature [ohm.m].

  • temp_surface (float, optional) – Surface temperature [degrees Celsius]. Defaults to 20.

Returns:

Estimated formation water resistivity at formation temperature [ohm.m].

Return type:

np.ndarray or float

quick_pp.saturation.estimate_rw_archie(phit, rt, a=1, m=2)[source]

Estimate formation water resistivity (Rw) from a water-bearing interval using Archie’s equation.

This method assumes the interval is 100% water-saturated (Sw=1) and calculates Rw. It then fits a minimum trend line to the calculated values to find a representative Rw.

Parameters:
  • phit (np.ndarray or float) – Total porosity [fraction].

  • rt (np.ndarray or float) – True resistivity [ohm.m].

  • a (float, optional) – Tortuosity factor. Defaults to 1.0.

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

Returns:

Estimated formation water resistivity [ohm.m].

Return type:

np.ndarray or float

quick_pp.saturation.estimate_rw_waxman_smits(phit, rt, a=1, m=2, B=None, Qv=None)[source]

Estimate Rw from a water-bearing interval using the Waxman-Smits equation.

This method assumes the interval is 100% water-saturated (Sw=1) and calculates Rw. It then fits a minimum trend line to the calculated values.

Parameters:
  • phit (np.ndarray or float) – Total porosity [fraction].

  • rt (np.ndarray or float) – True resistivity [ohm.m].

  • a (float, optional) – Tortuosity factor. Defaults to 1.0.

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

  • B (float, optional) – Equivalent conductance of clay exchange cations. Defaults to 2.0.

  • Qv (float, optional) – Cation exchange capacity. Defaults to 0.3.

Returns:

Estimated formation water resistivity [ohm.m].

Return type:

np.ndarray or float

quick_pp.saturation.estimate_rw_from_shale_trend(rt, phit, vshale, depth, m=1.3)[source]

Estimate Rw by extrapolating the resistivity trend from shales into sands.

This method identifies a resistivity trend with depth in nearby shales and assumes this trend represents the Ro (resistivity of 100% water-saturated rock) baseline. Rw is then calculated from this Ro trend and formation porosity.

Parameters:
  • rt (np.ndarray or float) – True resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • vshale (np.ndarray or float) – Volume of shale [fraction].

  • depth (np.ndarray or float) – Depth log.

  • m (float, optional) – Shale cementation or shape factor. Defaults to 1.3.

Returns:

Estimated formation water resistivity [ohm.m].

Return type:

np.ndarray or float

quick_pp.saturation.estimate_rt_shale(rt, vshale)[source]

Estimate shale resistivity (Rsh) from log data.

This function identifies shale intervals based on a Vshale cutoff (50th percentile), applies a rolling average to the resistivity in those intervals, and then propagates this value across the entire log interval.

Parameters:
  • rt (pd.Series or np.ndarray) – True resistivity log [ohm.m].

  • vshale (pd.Series or np.ndarray) – Volume of shale log [fraction].

Returns:

Estimated shale resistivity log [ohm.m].

Return type:

pd.Series

quick_pp.saturation.estimate_qv(vcld, phit, rho_clay=2.65, cec_clay=0.062)[source]

Estimate Qv (cation exchange capacity per unit pore volume) from clay properties.

Parameters:
  • vcld (np.ndarray or float) – Volume of dry clay [fraction of bulk volume].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • rho_clay (float, optional) – Bulk density of dry clay [g/cm³]. Defaults to 2.65.

  • cec_clay (float, optional) – Cation exchange capacity of clay [meq/g]. Defaults to 0.062.

Returns:

Qv in meq/cm³.

Return type:

np.ndarray or float

quick_pp.saturation.estimate_qvn(vclay, phit, phit_clay)[source]

Estimate normalized Qv (Qvn) for the Juhasz (1981) model.

Parameters:
  • vclay (np.ndarray or float) – Volume of clay [fraction].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • phit_clay (np.ndarray or float) – Total porosity of the clay [fraction].

Returns:

Normalized Qv (Qvn).

Return type:

np.ndarray or float

quick_pp.saturation.estimate_qv_ward(rt, phit, B, rw, m)[source]

Estimate Qv from water-bearing zone logs using the Ward (1973) method.

This method inverts the Waxman-Smits equation, assuming Sw=1, to solve for Qv.

Parameters:
  • rt (np.ndarray or float) – True resistivity in a water-bearing zone [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • B (float) – Equivalent conductance of clay exchange cations [S·m²/meq].

  • rw (float) – Formation water resistivity [ohm.m].

  • m (float) – Cementation exponent.

Returns:

Qv in meq/cm³.

Return type:

np.ndarray or float

References

Ward, B. (1973). Internal SIPM Report.

quick_pp.saturation.estimate_qv_hill(vclb, phit, water_salinity=10000)[source]

Estimate Qv using the empirical relationship from Hill, Shirley, and Klein (1979).

This method relates Qv to the bulk volume of clay-bound water and water salinity.

Parameters:
  • vclb (np.ndarray or float) – Volume of clay bound water [fraction of bulk volume].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • water_salinity (float, optional) – Water salinity in ppm. Defaults to 10000.

Returns:

Qv in meq/cm³.

Return type:

np.ndarray or float

References

Hill, H.J., Shirley, O.J., and Klein, G.E. (1979). Bound Water in Shaly Sands—Its Relation to Qv and Other Formation Properties. The Log Analyst, 20(3).

quick_pp.saturation.estimate_qv_lavers(phit, a=0.000305, b=3.49)[source]

Estimate Qv from porosity using the Lavers (1975) empirical equation.

This method provides a quick estimate of Qv based on a power-law relationship with total porosity.

Parameters:
  • phit (np.ndarray or float) – Total porosity [fraction].

  • a (float, optional) – Empirical constant. Defaults to 3.05e-4.

  • b (float, optional) – Empirical exponent. Defaults to 3.49.

Returns:

Qv in meq/cm³.

Return type:

np.ndarray or float

References

Lavers, B.A., Smits, L.J.M., and van Baaren, C. (1975). Some fundamental problems of formation evaluation in the North Sea. The Log Analyst, 16(3).

quick_pp.saturation.estimate_bqv(phit, max_phit_clean_sand, C)[source]

Estimate BQv (Bulk Volume of clay-bound water) using the Juhasz/Rackley method.

This method relates the reduction in porosity from a clean sand trend to the amount of clay-bound water.

Parameters:
  • phit (np.ndarray or float) – Total porosity [fraction].

  • max_phit_clean_sand (float) – Maximum porosity of the clean sand trend.

  • C (float) – A constant that depends on the clay type.

Returns:

Bulk volume of clay-bound water [fraction of bulk volume].

Return type:

np.ndarray or float

quick_pp.saturation.estimate_m_archie(rt, rw, phit)[source]

Estimate the apparent cementation exponent (m) using Archie’s equation.

This function inverts Archie’s equation in a water-bearing zone (assuming Sw=1) to solve for ‘m’.

Parameters:
  • rt (np.ndarray or float) – True resistivity in a water-bearing zone [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

Returns:

Apparent cementation exponent (m).

Return type:

np.ndarray or float

quick_pp.saturation.estimate_m_indonesian(rt, rw, phie, vsh, rsh)[source]

Estimate the apparent cementation exponent (m) using the Indonesian model.

This function inverts the Indonesian saturation equation in a water-bearing zone (assuming Sw=1) to solve for ‘m’. It is typically used in shaly intervals.

Parameters:
  • rt (np.ndarray or float) – True resistivity in a water-bearing zone [ohm.m].

  • rw (np.ndarray or float) – Formation water resistivity [ohm.m].

  • phie (np.ndarray or float) – Effective porosity [fraction].

  • vsh (np.ndarray or float) – Volume of shale [fraction].

  • rsh (np.ndarray or float) – Resistivity of shale [ohm.m].

Returns:

Apparent cementation exponent (m).

Return type:

np.ndarray or float

quick_pp.saturation.estimate_m_star(m_apparent, b_parameter, qv, rw, phi)[source]

Estimates m* from an apparent Archie m in a shaly sand. Note: This is a simplified approximation.

quick_pp.saturation.qv_phit_xplot(phit, qv)[source]

Generate a Qv vs 1/PHIT crossplot.

This plot is used to analyze the relationship between cation exchange capacity (Qv) and porosity, which can help in understanding clay distribution. A best-fit straight line is overlaid on the data.

Parameters:
  • phit (np.ndarray or float) – Total porosity [fraction].

  • qv (np.ndarray or float) – Cation exchange capacity per unit pore volume [meq/cm³].

quick_pp.saturation.cwa_qvn_xplot(rt, phit, qvn, m=2.0, rw=0.2, slope=250)[source]

Generate a Cwa vs Qvn plot for shaly sand analysis.

This plot is used to graphically solve for water saturation in the normalized Waxman-Smits (Juhasz) model.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • qvn (np.ndarray or float) – Normalized Qv.

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

  • rw (float, optional) – Formation water resistivity [ohm.m]. Used for the trend line. Defaults to 0.2.

  • slope (float, optional) – Slope of the interpretation line. Defaults to 250.0.

quick_pp.saturation.cwa_vclay_phit_xplot(rt, phit, vclay, m=2.0, rw=0.2, slope=250)[source]

Generate a Cwa vs Vclay/PHIT ratio plot for shaly sand analysis.

This plot is used to graphically solve for water saturation in shaly sand models where the clay volume to porosity ratio is a key parameter.

Parameters:
  • rt (np.ndarray or float) – True resistivity of the formation [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • vclay (np.ndarray or float) – Volume of clay [fraction].

  • m (float, optional) – Cementation exponent. Defaults to 2.0.

  • rw (float, optional) – Formation water resistivity [ohm.m]. Used for the trend line. Defaults to 0.2.

  • slope (float, optional) – Slope of the interpretation line. Defaults to 250.0.

quick_pp.saturation.swirr_xplot(swt, phit, c=0.0125, label='', log_log=False, title='')[source]

Generate a Buckles plot (SWT vs. PHIT) to estimate irreducible water saturation.

This crossplot helps identify the hyperbolic trend of irreducible water saturation, where PHIT * Swirr = constant (C).

Parameters:
  • swt (np.ndarray or float) – Water saturation [fraction].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • c (float, optional) – The Buckles constant (PHIT * Swirr) for the iso-line. Defaults to 0.0125.

  • label (str, optional) – Label for the scattered data points. Defaults to ‘’.

  • log_log (bool, optional) – If True, both axes will be on a logarithmic scale. Defaults to False.

  • title (str, optional) – Title for the plot. Defaults to ‘’.

quick_pp.saturation.rt_phit_xplot(rt, phit, m=2, rw=0.01)[source]

Generate an Rt vs. PHIT (Hingle) plot.

This plot is useful for visualizing the relationship between true resistivity and total porosity, often used for identifying water-bearing zones and estimating formation water resistivity (Rw) and cementation exponent (m).

Parameters:
  • rt (np.ndarray or float) – True resistivity or deep resistivity log [ohm.m].

  • phit (np.ndarray or float) – Total porosity [fraction].

  • m (float, optional) – Cementation exponent for the iso-line. Defaults to 2.0.

  • rw (float, optional) – Formation water resistivity for the iso-line [ohm.m]. Defaults to 0.01.

Returns:

The generated RT vs PHIT plot.

Return type:

matplotlib.figure.Figure

quick_pp.saturation.pickett_plot(rt, phit, m=-2, min_rw=0.1, shift=0.2, title='Pickett Plot')[source]

Generate a Pickett plot (log-log of Rt vs. PHIT).

This plot is a graphical tool to determine the cementation exponent (m), formation water resistivity (Rw), and water saturation (Sw) from log data.

Parameters:
  • rt (np.ndarray or float) – True resistivity log [ohm.m].

  • phit (np.ndarray or float) – Total porosity log [fraction].

  • m (float, optional) – The slope of the water-bearing line (should be negative). Defaults to -2.

  • min_rw (float, optional) – The Rw value for the 100% water saturation line. Defaults to 0.1.

  • shift (float, optional) – Increment to generate other iso-Sw lines. Defaults to 0.2.

  • title (str, optional) – Title for the plot. Defaults to ‘Pickett Plot’.

Returns:

The function generates a plot but does not return any object.

Return type:

None

quick_pp.saturation.RI_plot(sw, rt, ro)[source]

Generate a Resistivity Index (RI) vs. Sw plot from lab data.

This log-log plot is used to determine the saturation exponent (n). The slope of the best-fit line through the data is -n. The trend line should pass through the (1, 1) point.

Parameters:
  • sw (np.ndarray or float) – Water saturation from core analysis [fraction].

  • rt (np.ndarray or float) – True resistivity of the core sample at a given Sw [ohm.m].

  • ro (np.ndarray or float) – Resistivity of the same core sample when 100% water-saturated [ohm.m].

Returns:

The function generates a plot but does not return any object.

Return type:

None

quick_pp.saturation.FF_plot(phit, ro, rw)[source]

Generate a Formation Factor (FF) vs. Porosity plot from lab data.

This log-log plot is used to determine the tortuosity factor (a) and the cementation exponent (m). The slope of the best-fit line is -m, and the intercept at PHIT=1 is ‘a’.

Parameters:
  • phit (np.ndarray or float) – Porosity from core analysis [fraction].

  • ro (np.ndarray or float) – Resistivity of the 100% water-saturated core sample [ohm.m].

  • rw (np.ndarray or float) – Resistivity of the saturating water [ohm.m].

Returns:

The function generates a plot but does not return any object.

Return type:

None

Permeability module

quick_pp.permeability.choo_permeability(vclay, vsilt, phit, B=None, A=None, C=None, m=2)[source]

Estimate permeability using Choo’s equation. Suitable for shaly sand formations.

Parameters:
  • vclay (np.ndarray or float) – Volume of clay in fraction.

  • vsilt (np.ndarray or float) – Volume of silt in fraction.

  • phit (np.ndarray or float) – Total porosity in fraction.

  • B (float, optional) – Constant derived from cementation and compaction factor. If None, it is calculated as m * ((2 / C) + 1) + 2. Defaults to None.

  • A (float, optional) – Constant based on 0.125 * rg**2 / 10. Defaults to 1.65e7.

  • C (float, optional) – Constant. Defaults to 1.78.

  • m (int, optional) – Cementation exponent. Defaults to 2.

Returns:

Choo’s permeability in mD.

Return type:

float

quick_pp.permeability.kozeny_carman_permeability(phit, S=0.01)[source]

Estimate permeability using Kozeny-Carman’s equation. Generally suitable for clean and unconsolidated sands.

Parameters:
  • phit (np.ndarray or float) – Total porosity in fraction.

  • S (float, optional) – Specific surface area of the grains. Defaults to 0.01.

Returns:

Permeability in mD.

Return type:

float

quick_pp.permeability.timur_permeability(phit, Swirr)[source]

Estimate permeability based on Timur (1968) empirical equation established on 155 sandstone samples from 3 different oil fields in North America. Best suited for sandstones.

Parameters:
  • phit (np.ndarray or float) – Porosity in fraction.

  • Swirr (np.ndarray or float) – Irreducible water saturation in fraction.

Returns:

Permeability in mD.

Return type:

float

quick_pp.permeability.coates_permeability(phie, Swirr, a=1)[source]

Estimate permeability based on Coates (1974). Suitable for sandstones, including shaly formations.

Parameters:
  • phie (np.ndarray or float) – Effective porosity in fraction.

  • Swirr (np.ndarray or float) – Irreducible water saturation in fraction.

  • a (int, optional) – Constant. Defaults to 1.

Returns:

Coates permeability in mD.

Return type:

float

quick_pp.permeability.tixier_permeability(phit, Swirr)[source]

Estimate permeability based on Tixier (1949). Suitable for clean formations at irreducible water saturation.

Parameters:
  • phit (np.ndarray or float) – Porosity in fraction.

  • Swirr (np.ndarray or float) – Irreducible water saturation in fraction.

Returns:

Permeability in mD

Return type:

float

quick_pp.permeability.morris_biggs_permeability(phit, C, Swirr)[source]

Estimate permeability based on Morris and Biggs (1967). Suitable for sandstone reservoirs.

Parameters:
  • phit (np.ndarray or float) – Total porosity in fraction.

  • C (float) – A constant which depends on the density of hydrocarbon in the formation. 250 for medium oil. 79 for gas.

  • Swirr (np.ndarray or float) – Irreducible water saturation in fraction.

Returns:

Permeability in mD.

Return type:

float

quick_pp.permeability.morris_biggs_modified_permeability(phit, phie, Vbwi)[source]

Estimate permeability based on Morris and Biggs (1967). Suitable for sandstone reservoirs.

Parameters:
  • phit (np.ndarray or float) – Total porosity in fraction.

  • phie (np.ndarray or float) – Effective porosity in fraction.

  • Vbwi (np.ndarray or float) – Volume of bound water in fraction.

Returns:

Permeability in mD.

Return type:

float

quick_pp.permeability.estimate_krw(swt, swirr)[source]

Estimate permeability based on Park Jones (1945)

Parameters:
  • swt (np.ndarray or float) – Total water saturation.

  • swirr (np.ndarray or float) – Irreducible water saturation.

Returns:

Water relative permeability.

Return type:

float

quick_pp.permeability.estimate_kro(swt, swirr)[source]

Estimate permeability based on Park Jones (1945)

Parameters:
  • swt (np.ndarray or float) – Total water saturation.

  • swirr (np.ndarray or float) – Irreducible water saturation.

Returns:

Oil relative permeability.

Return type:

float

quick_pp.permeability.estimate_wor(krw, kro, A=2)[source]

Estimating Water Oil Ratio of surface production. Based on Pirson (1950).

Parameters:
  • krw (np.ndarray or float) – Water relative permeability.

  • kro (np.ndarray or float) – Oil relative permeability.

  • A (float) – Constant. Defaults to 2. Light oil: 1 - 5 Medium oil: 10 - 50 Heavy oil: > 50

Returns:

Water Oil Ratio.

Return type:

float

quick_pp.permeability.estimate_wc(wor)[source]

Estimating Water Cut of surface production.

Parameters:

wor (np.ndarray or float) – Water Oil Ratio.

Returns:

Water Cut.

Return type:

float

Reservoir Summary module

quick_pp.ressum.calc_reservoir_summary(depth, vshale, phit, swt, perm, zones, cutoffs=None)[source]

Calculate reservoir summary based on cutoffs on vshale, phit, and swt.

This function aggregates petrophysical properties over specified zones and flags (all, rock, reservoir, pay) to provide a comprehensive reservoir summary.

Parameters:
  • depth (np.ndarray or float) – Depth, either MD or TVD.

  • vshale (np.ndarray or float) – Volume of shale in fraction.

  • phit (np.ndarray or float) – Total porosity in fraction.

  • swt (np.ndarray or float) – Total water saturation in fraction.

  • perm (np.ndarray or float) – Permeability.

  • zones (np.ndarray or str) – Zone names.

  • cutoffs (dict, optional) – A dictionary with ‘VSHALE’, ‘PHIT’, and ‘SWT’ cutoffs. Defaults to dict(VSHALE=0.4, PHIT=0.01, SWT=0.9).

Returns:

A DataFrame containing the reservoir summary in tabular format.

Return type:

pd.DataFrame

quick_pp.ressum.flag_interval(vshale, phit, swt, cutoffs: dict)[source]

Flag interval based on cutoffs.

Parameters:
  • vshale (np.ndarray or float) – Vshale values.

  • phit (np.ndarray or float) – Total porosity values.

  • swt (np.ndarray or float) – Water saturation values.

  • cutoffs (dict) – A dictionary with ‘VSHALE’, ‘PHIT’, and ‘SWT’ cutoffs.

Returns:

A tuple containing the rock, reservoir, and pay flags.

Return type:

tuple[np.ndarray, np.ndarray, np.ndarray]

quick_pp.ressum.volumetric_method(area_bound: tuple, thickness_bound: tuple, porosity_bound: tuple, water_saturation_bound: tuple, volume_factor_bound: tuple, recovery_factor_bound: tuple = None, random_state=None)[source]

Generate random samples for volumetric parameters based on specified distributions.

This function uses truncated normal distributions for area, thickness, porosity, water saturation, and recovery factor, and a uniform distribution for the volume factor.

Parameters:
  • area_bound (tuple) – (min, max, mean, std) for area in acres.

  • thickness_bound (tuple) – (min, max, mean, std) for thickness in feet.

  • porosity_bound (tuple) – (min, max, mean, std) for porosity in fraction.

  • water_saturation_bound (tuple) – (min, max, mean, std) for water saturation in fraction.

  • volume_factor_bound (tuple) – (min, max) for the volume factor (unitless).

  • recovery_factor_bound (tuple, optional) – (min, max, mean, std) for the recovery factor. Defaults to None.

  • random_state (int, optional) – A seed for the random number generator. Defaults to None.

Returns:

A tuple of the generated random samples for (area, thickness, porosity, sw, bo, rf).

Return type:

tuple

quick_pp.ressum.mc_volumetric_method(area_bound: tuple, thickness_bound: tuple, porosity_bound: tuple, water_saturation_bound: tuple, volume_factor_bound: tuple, n_try=10000, percentile=None)[source]

Monte Carlo simulation for volumetric method. This function performs a Monte Carlo simulation to estimate the distribution of in-place hydrocarbon volumes and generates diagnostic plots.

Parameters:
  • area_bound (tuple) – (min, max, mean, std) for area in acres.

  • thickness_bound (tuple) – (min, max, mean, std) for thickness in feet.

  • porosity_bound (tuple) – (min, max, mean, std) for porosity in fraction.

  • water_saturation_bound (tuple) – (min, max, mean, std) for water saturation in fraction.

  • volume_factor_bound (tuple) – (min, max) for the volume factor (unitless).

  • n_try (int, optional) – Number of trials. Defaults to 10000.

  • percentile (list, optional) – Percentiles to calculate and display. Defaults to [10, 50, 90].

Returns:

A tuple containing arrays of the generated volumes and input parameters.

Return type:

tuple

quick_pp.ressum.calculate_volume(x, area, thickness, porosity, water_saturation, volume_factor, recovery_factor=1)[source]

Calculate volume using the volumetric method.

This function is a helper for sensitivity analysis, applying a perturbation x to the calculation.

Parameters:
  • x (float) – A perturbation factor.

  • area (float) – Area in acres.

  • thickness (float) – Thickness in feet.

  • porosity (float) – Porosity in fraction.

  • water_saturation (float) – Water saturation in fraction.

  • volume_factor (float) – Volume factor.

  • recovery_factor (float, optional) – Recovery factor in fraction. Defaults to 1.

Returns:

Estimated volume in million barrels (MMbbl).

Return type:

float

quick_pp.ressum.sensitivity_analysis(area_bound: tuple, thickness_bound: tuple, porosity_bound: tuple, water_saturation_bound: tuple, volume_factor_bound: tuple)[source]

Sensitivity analysis for volumetric method. This function performs a Sobol sensitivity analysis to determine the influence of each input parameter on the final volume calculation and displays the results as tornado charts (both volume-based and sensitivity indices).

Parameters:
  • area_bound (tuple) – (min, max) for area.

  • thickness_bound (tuple) – (min, max) for thickness.

  • porosity_bound (tuple) – (min, max) for porosity.

  • water_saturation_bound (tuple) – (min, max) for water saturation.

  • volume_factor_bound (tuple) – (min, max) for the volume factor.

quick_pp.ressum.cutoffs_analysis(df, percentile=95)[source]

Perform sensitivity analysis on Vshale, PHIT and SWT cutoffs against hydrocarbon pore volume.

Parameters:
  • df (pd.DataFrame) – A DataFrame containing ‘VSHALE’, ‘PHIT’, and ‘SWT’ columns.

  • percentile (int, optional) – The percentile to use for determining the optimal cutoff point from the cumulative HCPV curve. Defaults to 95.

Returns:

A tuple containing the optimal cutoffs for VSHALE, PHIT, and SWT.

Return type:

tuple[float, float, float]

Rock Type module

quick_pp.rock_type.calc_rqi(pore, perm)[source]

Calculate RQI (Rock Quality Index) from Kozeny-Carman equation, based on Amaefule et al. (1993)

Parameters:
  • pore (np.ndarray or float) – Total porosity in fraction.

  • perm (np.ndarray or float) – Permeability in mD.

Returns:

The Rock Quality Index (RQI).

Return type:

np.ndarray or float

quick_pp.rock_type.calc_fzi(pore, perm)[source]

Calculate FZI (Flow Zone Indicator) from Kozeny-Carman equation, based on Amaefule et al. (1993)

Parameters:
  • pore (np.ndarray or float) – Total porosity in fraction.

  • perm (np.ndarray or float) – Permeability in mD.

Returns:

The Flow Zone Indicator (FZI).

Return type:

np.ndarray or float

quick_pp.rock_type.calc_fzi_perm(fzi, pore)[source]

Calculate permeability from FZI and porosity, based on Amaefule et al. (1993)

Parameters:
  • fzi (np.ndarray or float) – Flow Zone Indicator.

  • pore (np.ndarray or float) – Total porosity in fraction.

Returns:

Permeability in mD.

Return type:

np.ndarray or float

quick_pp.rock_type.calc_r35(pore, perm)[source]

Calculate Winland R35 from Kozeny-Carman equation, based on Winland (1979)

Parameters:
  • pore (np.ndarray or float) – Total porosity in fraction.

  • perm (np.ndarray or float) – Permeability in mD.

Returns:

The Winland R35 value.

Return type:

np.ndarray or float

quick_pp.rock_type.calc_r35_perm(r35, pore)[source]

Calculate permeability from Winland R35 and porosity, based on Winland (1979)

Parameters:
  • r35 (np.ndarray or float) – Winland R35 value.

  • pore (np.ndarray or float) – Total porosity in fraction.

Returns:

Permeability in mD.

Return type:

np.ndarray or float

quick_pp.rock_type.plot_rqi(cpore, cperm, cut_offs=None, rock_type=None, title='Rock Quality Index (RQI)')[source]

Generate a Rock Quality Index (RQI) cross-plot.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • cut_offs (list, optional) – List of RQI values to plot as lines. Defaults to None, which will use [0.1, 0.3, 0.5, 1.0].

  • rock_type (array, optional) – Array of rock types for coloring points. Defaults to None.

  • title (str, optional) – Plot title. Defaults to ‘Rock Quality Index (RQI)’.

quick_pp.rock_type.plot_fzi(cpore, cperm, cut_offs=None, rock_type=None, title='Flow Zone Indicator (FZI)')[source]

Generate a Flow Zone Indicator (FZI) cross-plot.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • cut_offs (list, optional) – List of FZI values to plot as lines. Defaults to np.arange(0.5, 5).

  • rock_type (array, optional) – Array of rock types for coloring points. Defaults to None.

  • title (str, optional) – Plot title. Defaults to ‘Flow Zone Indicator (FZI)’.

quick_pp.rock_type.plot_rfn(cpore, cperm, rock_type=None, title='Lucia RFN')[source]

Plot the Rock Fabric Number (RFN) lines on porosity and permeability cross plot. The permeability (mD) is calculated based on Lucia-Jenkins, 2003. ` perm = 10**(9.7892 - 12.0838 * log(RFN) + (8.6711 - 8.2965 * log(RFN)) * log(phi)) `

Parameters:
  • cpore (np.ndarray or float) – Core porosity in v/v.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • rock_type (array, optional) – Array of rock types for coloring points. Defaults to None.

  • title (str, optional) – Plot title. Defaults to ‘Lucia RFN’.

quick_pp.rock_type.plot_winland(cpore, cperm, cut_offs=None, rock_type=None, title='Winland R35')[source]

Plot the Winland R35 lines on porosity and permeability cross plot. The permeability (mD) is calculated based on Winland, 1972. ` perm = 10**((log(r35) - 0.732 + 0.864 * log(phi)) / 0.588) `

Parameters:
  • cpore (np.ndarray or float) – Core porosity in v/v.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • cut_offs (list, optional) – List of R35 values to plot as lines. Defaults to [.05, .1, .5, 2, 10, 100].

  • rock_type (array, optional) – Array of rock types for coloring points. Defaults to None.

  • title (str, optional) – Plot title. Defaults to ‘Winland R35’.

quick_pp.rock_type.plot_neuden_vsh(nphi, rhob, vshale_lines=None, shale_point=(0.45, 2.55), sand_point=(-0.035, 2.65), lime_point=(0.0, 2.71), dolo_point=(0.02, 2.87), fluid_point=(1.0, 1.0), rock_flag=None)[source]

Generate a Neutron-Density crossplot with Vshale lines for rock typing.

This plot helps in identifying lithology and visually estimating shale volume. It includes standard matrix lines for sandstone, limestone, and dolomite, and overlays lines of constant shale volume.

Parameters:
  • nphi (pd.Series or np.ndarray) – Neutron Porosity log values (v/v).

  • rhob (pd.Series or np.ndarray) – Bulk Density log values (g/cc).

  • shale_point (tuple, optional) – (NPHI, RHOB) coordinates of the 100% shale point. Defaults to (0.45, 2.55).

  • sand_point (tuple, optional) – (NPHI, RHOB) coordinates of the sandstone matrix. Defaults to (-0.035, 2.65).

  • lime_point (tuple, optional) – (NPHI, RHOB) coordinates of the limestone matrix. Defaults to (0.0, 2.71).

  • dolo_point (tuple, optional) – (NPHI, RHOB) coordinates of the dolomite matrix. Defaults to (0.02, 2.87).

  • rock_flag (pd.Series or np.ndarray, optional) – An array of values (e.g., GR, Vshale, or rock types) to color the data points. Defaults to None.

  • fluid_point (tuple, optional) – (NPHI, RHOB) coordinates of the fluid point (water). Defaults to (1.0, 1.0).

  • vshale_lines (list, optional) – List of Vshale fractions (0 to 1) to plot as lines. Defaults to [0, 0.25, 0.5, 0.75, 1.0].

quick_pp.rock_type.plot_fzi_log_log(cpore, cperm, cut_offs=None, rock_type=None, title='FZI Log-Log Plot', density=True)[source]

Generate a log-log plot of RQI vs. pore-to-solid volume ratio to identify rock types.

On this plot, data points belonging to the same rock type (i.e., same FZI) will fall along a straight line with a unit slope.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • cut_offs (list, optional) – List of FZI values to plot as lines. Defaults to np.arange(0.5, 5).

  • rock_type (array, optional) – Array of rock types for coloring points. Defaults to None.

  • title (str, optional) – Plot title. Defaults to ‘FZI Log-Log Plot’.

  • density (bool, optional) – If True, show data density with a 2D histogram and contours. Defaults to False.

quick_pp.rock_type.plot_fzi_histogram(cpore, cperm, bins='auto', cutoffs=None, title='Log(FZI) Histogram')[source]

Plot a histogram of Log(FZI) to identify modes and define cutoffs.

Different rock types should appear as distinct modes (peaks) in the histogram. The troughs between these modes can be used as objective cutoffs.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • bins (int or str, optional) – The number of bins for the histogram. Defaults to “auto”.

  • cutoffs (list, optional) – A list of Log(FZI) cutoff values to display as vertical lines. Defaults to None.

  • title (str, optional) – The title of the plot. Defaults to “Log(FZI) Histogram”.

quick_pp.rock_type.plot_ward_dendogram(X, p=10, title="Ward's Dendogram")[source]

Generate and display a Ward’s dendrogram for hierarchical clustering.

This function is useful for visualizing the hierarchical relationships within a dataset to identify natural groupings or clusters.

Parameters:
  • X (np.ndarray) – The input data array for clustering.

  • p (int, optional) – The number of clusters to display in the truncated dendrogram. Defaults to 10.

  • title (str, optional) – The title of the plot. Defaults to “Ward’s Dendogram”.

quick_pp.rock_type.plot_cumulative_probability(cpore, cperm, cutoffs=None, title='Cumulative Probability Plot')[source]

Plot cumulative probability to identify possible flow units.

This plot helps in identifying different flow units by visualizing the cumulative probability distribution of the Flow Zone Indicator (FZI).

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • cutoffs (list, optional) – A list of cutoff values to display as vertical lines. Defaults to None.

  • title (str, optional) – The title of the plot. Defaults to “Cumulative Probability Plot”.

quick_pp.rock_type.plot_lorenz_heterogeneity(cpore, cperm, title="Lorenz's Plot")[source]

Plot Lorenz’s plot to estimate heteroginity.

This plot is used to assess the degree of heterogeneity in a reservoir by comparing the cumulative distribution of porosity with that of permeability.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • title (str, optional) – The title of the plot. Defaults to “Lorenz’s Plot”.

quick_pp.rock_type.plot_modified_lorenz(cpore, cperm, title="Modified Lorenz's Plot")[source]

Plot Lorenz’s plot to identify possible flow units.

This is a variation of the Lorenz plot where data is sorted by the Flow Zone Indicator (FZI) to better delineate hydraulic flow units.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • title (str, optional) – The title of the plot. Defaults to “Modified Lorenz’s Plot”.

quick_pp.rock_type.estimate_pore_throat(pc, ift, theta)[source]

Estimate pore throat size from capillary pressure curve based on Washburn 1921.

Parameters:
  • pc (np.ndarray or float) – Capillary pressure in psi.

  • ift (float) – Interfacial tension in mN/m.

  • theta (float) – Contact angle in degree.

Returns:

Pore throat size in micrometer.

Return type:

np.ndarray or float

quick_pp.rock_type.estimate_vsh_gr(gr, min_gr=None, max_gr=None, alpha=0.1)[source]

Estimate volume of shale from gamma ray. If min_gr and max_gr are not provided, it will be automatically estimated.

Parameters:
  • gr (np.ndarray or float) – Gamma ray from well log.

  • min_gr (float, optional) – Minimum gamma ray value. Defaults to None.

  • max_gr (float, optional) – Maximum gamma ray value. Defaults to None.

  • alpha (float, optional) – Alpha value for min-max normalization. Defaults to 0.1.

Returns:

Volume of shale from gamma ray (VSH_GR).

Return type:

np.ndarray or float

quick_pp.rock_type.estimate_vsh_dn(phin, phid, phin_sh=0.35, phid_sh=0.05)[source]

Estimate volume of shale from neutron porosity and density porosity.

Parameters:
  • phin (np.ndarray or float) – Neutron porosity in fraction.

  • phid (np.ndarray or float) – Density porosity in fraction.

  • phin_sh (float, optional) – Neutron porosity for shale. Defaults to 0.35.

  • phid_sh (float, optional) – Density porosity for shale. Defaults to 0.05.

Returns:

Volume of shale.

Return type:

np.ndarray or float

quick_pp.rock_type.estimate_rock_flag_neuden(nphi, rhob, vsh_cutoffs=None, sand_point=(-0.035, 2.65), shale_point=(0.45, 2.55), fluid_point=(1.0, 1.0))[source]

Estimates rock type by calculating Vshale from a Neutron-Density crossplot and classifying it based on provided cutoffs.

This method determines the shale volume for each data point by its geometric position between a clean sand line and a 100% shale line. The calculated Vshale is then used to assign a rock type.

Parameters:
  • nphi (pd.Series or np.ndarray) – Neutron Porosity log values (v/v).

  • rhob (pd.Series or np.ndarray) – Bulk Density log values (g/cc).

  • vsh_cut_offs (list) – A list of Vshale cutoff values to define rock types.

  • sand_point (tuple, optional) – (NPHI, RHOB) coordinates of the clean sand matrix. Defaults to (-0.035, 2.65).

  • shale_point (tuple, optional) – (NPHI, RHOB) coordinates of the 100% shale point. Defaults to (0.45, 2.55).

  • fluid_point (tuple, optional) – (NPHI, RHOB) coordinates of the fluid point. Defaults to (1.0, 1.0).

Returns:

An array of integer rock type flags.

Return type:

np.ndarray

quick_pp.rock_type.rock_typing(curve, cut_offs=None, higher_is_better=True)[source]

Rock typing based on cutoffs.

Parameters:
  • curve (np.ndarray or float) – The curve to be used for rock typing.

  • cut_offs (list, optional) – 3 cutoffs to group the curve into 4 rock types. Defaults to [.1, .2, .3, .4].

  • higher_is_better (bool, optional) – Whether higher value of curve is better quality or not. Defaults to True.

Returns:

An array of rock type classifications.

Return type:

np.ndarray or float

quick_pp.rock_type.find_cutoffs(curve, no_of_cutoffs=3)[source]

Find optimal cutoffs for a given curve using KMeans clustering.

Parameters:
  • curve (pd.Series or np.ndarray) – The curve data to find cutoffs for.

  • no_of_cutoffs (int, optional) – The number of cutoffs to find. This will result in no_of_cutoffs + 1 clusters. Defaults to 3.

Returns:

An array of cutoff values.

Return type:

np.ndarray

quick_pp.rock_type.train_classification_model(data, input_features: list, target_feature: str, stratifier=None)[source]

Train a classification Random Forest model to predict a binary feature.

Parameters:
  • data (DataFrame) – Dataframe containing input and target features.

  • input_features (list) – List of input features.

  • target_feature (str) – The target feature.

  • stratifier (array, optional) – Stratifier for train-test split. Defaults to None.

Returns:

Trained model.

Return type:

RandomForestClassifier

quick_pp.rock_type.train_regression_model(data, input_features: list, target_feature: list, stratifier=None)[source]

Train a regression Random Forest model to predict a continuous feature.

Parameters:
  • data (DataFrame) – Dataframe containing input, target and stratifier features.

  • input_features (list) – List of input features.

  • target_feature (str) – The target feature.

  • stratifier (array, optional) – Stratifier for train-test split. Defaults to None.

Returns:

Trained model.

Return type:

RandomForestRegressor

quick_pp.rock_type.cluster_fzi(cpore, cperm, n_clusters=None, max_clusters=10)[source]

Determine rock types by applying k-Means clustering on the Flow Zone Indicator (FZI).

This function calculates Log(FZI), then uses k-Means to partition the data into a specified number of clusters (rock types). It returns the cluster assignments and descriptive statistics for each cluster.

Parameters:
  • cpore (np.ndarray or float) – Core porosity in fraction.

  • cperm (np.ndarray or float) – Core permeability in mD.

  • n_clusters (int, optional) – The number of rock types (clusters) to identify. If None, it will be auto-detected. Defaults to None.

  • max_clusters (int, optional) – The maximum number of clusters to consider for auto-detection. Defaults to 10.

Returns:

A tuple containing:
  • pd.Series: Cluster assignment for each data point.

  • pd.DataFrame: Mean and standard deviation of Log(FZI) for each cluster.

Return type:

tuple

quick_pp.rock_type.cluster_rock_types_from_logs(df, features=None, n_clusters=None, max_clusters=10, random_state=42)[source]

Clusters well log data into rock types using k-Means clustering.

This function takes a DataFrame with well log data, scales the features, and then applies k-Means to identify distinct rock types. If ‘WELL_NAME’ is in the DataFrame, scaling is performed on a per-well basis.

Parameters:
  • df (pd.DataFrame) – DataFrame containing the log data. Must include columns specified in features, and optionally ‘WELL_NAME’.

  • features (list, optional) – A list of feature columns to use for clustering. Defaults to [“GR”, “NPHI”, “RHOB”].

  • n_clusters (int, optional) – The number of rock types (clusters) to identify. If None, the optimal number of clusters will be determined using the Silhouette Score. Defaults to None.

Returns:

A Series containing the cluster assignment (rock type) for each data point.

NaN values are preserved where input logs had NaNs.

Return type:

pd.Series

Core Calibration module

quick_pp.core_analysis.poroperm_xplot(poro, perm, a=None, b=None, core_group=None, label='', log_log=False)[source]

Generate porosity-permeability cross plot.

Parameters:
  • poro (float) – Core porosity (frac).

  • perm (float) – Core permeability (mD).

  • a (float, optional) – a constant in perm=a*poro^b. Defaults to None.

  • b (float, optional) – b constant in perm=a*poro^b. Defaults to None.

  • core_group (array-like, optional) – Grouping for core samples to be used for coloring. Defaults to None.

  • label (str, optional) – Label for the data group. Defaults to ‘’.

  • log_log (bool, optional) – Whether to plot log-log or not. Defaults to False.

quick_pp.core_analysis.bvw_xplot(bvw, pc, a=None, b=None, label=None, ylim=None, log_log=False)[source]

Generate bulk volume water-capillary pressure cross plot.

Parameters:
  • bvw (float) – Calculated bulk volume water (frac) from core.

  • pc (float) – Capillary pressure (psi) from core.

  • a (float, optional) – a constant in pc=a*bvw^b. Defaults to None.

  • b (float, optional) – b constant in pc=a*bvw^b. Defaults to None.

  • label (str, optional) – Label for the data group. Defaults to ‘’.

  • ylim (tuple, optional) – Range for the y axis in (min, max) format. Defaults to None.

  • log_log (bool, optional) – Whether to plot log-log or not. Defaults to False.

quick_pp.core_analysis.pc_xplot(sw, pc, label=None, ylim=None)[source]

Generate Pc-Sw cross plot.

Parameters:
  • sw (float) – Core water saturation (frac).

  • pc (float) – Capillary pressure (psi) from core.

  • label (str, optional) – Label for the data group. Defaults to ‘’.

  • ylim (tuple, optional) – Range for the y axis in (min, max) format. Defaults to None.

quick_pp.core_analysis.pc_xplot_plotly(sw, pc, label=None, ylim=None, fig=Figure({'data': [], 'layout': {'template': '...'}}))[source]

Generate J-Sw cross plot using Plotly.

Parameters:
  • sw (float) – Core water saturation (frac).

  • pc (float) – Capillary pressure (psi).

  • label (str, optional) – Label for the data group. Defaults to ‘’.

  • ylim (tuple, optional) – Range for the y axis in (min, max) format. Defaults to None.

quick_pp.core_analysis.j_xplot(sw, j, a=None, b=None, core_group=None, label=None, log_log=False, ax=None, ylim=None)[source]

Generate J-Sw cross plot.

Parameters:
  • sw (float) – Core water saturation (frac).

  • j (float) – Calculated J value (unitless).

  • a (float, optional) – a constant in j=a*sw^b. Defaults to None.

  • b (float, optional) – b constant in j=a*sw^b. Defaults to None.

  • core_group (array-like, optional) – Grouping for core samples to be used for coloring. Defaults to None.

  • label (str, optional) – Label for the data group. Defaults to ‘’.

  • ylim (tuple, optional) – Range for the y axis in (min, max) format. Defaults to None.

  • log_log (bool, optional) – Whether to plot log-log or not. Defaults to False.

quick_pp.core_analysis.fit_j_curve(sw, j)[source]

Estimate a and b constants of best fit given core water saturation and J value.

Parameters:
  • sw (float) – Core water saturation (frac).

  • j (float) – Calculated J value (unitless).

Returns:

a and b constants from the best-fit curve.

Return type:

tuple

quick_pp.core_analysis.skelt_harrison_xplot(sw, pc, gw, ghc, a, b, c, d, core_group=None, label=None, ylim=None, ax=None)[source]

Generate Skelt-Harrison curve.

Parameters:
  • pc (float) – Capillary pressure (psi).

  • sw (float) – Core water saturation (frac).

  • h (float) – Height above free water level (ft).

  • a (float) – a constant from the best-fit curve. Related to Swirr.

  • b (float) – b constant from the best-fit curve. Related to HAFWL.

  • c (float) – c constant from the best-fit curve. Related to PTSD.

  • d (float) – d constant from the best-fit curve. Related to entry pressure.

quick_pp.core_analysis.skelt_harrison_func(h, a, b, c, d)[source]

Calculate water saturation using the Skelt-Harrison model.

This function models the relationship between water saturation and the height above the free water level using an exponential decay function.

Parameters:
  • h (float or np.array) – Height above free water level (ft).

  • a (float) – A constant related to irreducible water saturation (Swirr). It influences the maximum water saturation.

  • b (float) – A constant related to the height above free water level (HAFWL). It controls the rate of saturation change with height.

  • c (float) – A constant related to the pore throat size distribution (PTSD). It affects the shape of the saturation curve.

  • d (float) – A constant related to the entry pressure. It shifts the curve along the height axis.

Returns:

The calculated water saturation (fraction).

Return type:

float or np.array

quick_pp.core_analysis.fit_skelt_harrison_curve(sw, h)[source]

Estimate a and b constants of best fit given core water saturation and capillary pressure values.

Parameters:
  • sw (float) – Core water saturation (frac).

  • h (float) – Height above free water level (ft).

Returns:

a and b constants from the best-fit curve.

Return type:

tuple

quick_pp.core_analysis.perm_transform(poro, a, b)[source]

Transform porosity to permeability using a and b constants.

Parameters:
  • poro (float) – Core porosity (frac).

  • a (float) – a constant from the best-fit curve.

  • b (float) – b constant from the best-fit curve.

Returns:

Permeability (mD).

Return type:

float

quick_pp.core_analysis.fit_poroperm_curve(poro, perm)[source]

Estimate a and b constants of best fit given core porosity and permeability values.

Parameters:
  • poro (float) – Core porosity (frac).

  • perm (float) – Core permeability (mD).

Returns:

a and b constants from the best-fit curve.

Return type:

tuple

quick_pp.core_analysis.leverett_j(pc, ift, theta, perm, phit)[source]

Estimate Leverett J.

Parameters:
  • pc (float) – Capillary pressure (psi).

  • ift (float) – Interfacial tension (dynes/cm).

  • theta (float) – Wetting angle (degree).

  • perm (float) – Permeability (mD).

  • phit (float) – Total porosity (frac).

Returns:

Leverett J value.

Return type:

float

quick_pp.core_analysis.sw_skelt_harrison(depth, fwl, a, b, c, d)[source]

Estimate water saturation based on Skelt-Harrison.

Parameters:
  • depth (float) – True vertical depth.

  • fwl (float) – Free water level in true vertical depth.

  • a (float) – a constant from the best-fit curve.

  • b (float) – b constant from the best-fit curve.

  • c (float) – c constant from the best-fit curve.

  • d (float) – d constant from the best-fit curve.

Returns:

Water saturation.

Return type:

float

quick_pp.core_analysis.sw_lambda(phit, h, a, b, lamda)[source]

Estimate water saturation based on Lambda model (Thomeer-type Hyperbolic).

Parameters:
  • phit (float) – Total porosity in fraction.

  • h (float) – Height above free water level.

  • a (float) – A constant from the best-fit curve.

  • b (float) – B constant from the best-fit curve.

  • lamda (float) – Lambda constant from the best-fit curve, related to pore size distribution.

Returns:

Water saturation.

Return type:

float

quick_pp.core_analysis.sw_cuddy(phit, h, a, b)[source]

Estimate water saturation based on Cuddy’s.

Parameters:
  • sw (float) – Water saturation (frac).

  • phit (float) – Total porosity (frac).

  • h (float) – True vertical depth.

  • a (float) – Fitting parameter.

  • b (float) – Fitting parameter (negative value).

Returns:

Water saturation.

Return type:

float

quick_pp.core_analysis.sw_shf_leverett_j(perm, phit, depth, fwl, ift, theta, gw, ghc, a, b, phie=None)[source]

Estimate water saturation based on Leverett J function.

Parameters:
  • perm (float) – Permeability (mD).

  • phit (float) – Total porosity (frac).

  • depth (float) – True vertical depth (ft).

  • fwl (float) – Free water level in true vertical depth (ft).

  • ift (float) – Interfacial tension (dynes/cm).

  • theta (float) – Wetting angle (degree).

  • gw (float) – Water density (g/cc).

  • ghc (float) – Hydrocarbon density (g/cc).

  • a (float) – A constant from J function.

  • b (float) – B constant from J function.

  • phie (float) – Effective porosity (frac), required for clay bound water calculation. Defaults to None.

Returns:

Water saturation from saturation height function.

Return type:

float

quick_pp.core_analysis.sw_shf_cuddy(phit, depth, fwl, gw, ghc, a, b)[source]

Estimate water saturation based on Cuddy’s saturation height function.

Parameters:
  • phit (float) – Porosity (frac).

  • depth (float) – True vertical depth (ft).

  • fwl (float) – Free water level in true vertical depth (ft).

  • gw (float) – Water density (g/cc).

  • ghc (float) – Hydrocarbon density (g/cc).

  • a (float) – Fitting parameter.

  • b (float) – Fitting parameter (negative value).

Returns:

Water saturation from saturation height function.

Return type:

float

quick_pp.core_analysis.sw_shf_choo(perm, phit, phie, depth, fwl, ift, theta, gw, ghc, b0=0.4)[source]

Estimate water saturation based on Choo’s saturation height function.

Parameters:
  • perm (float) – Permeability (mD).

  • phit (float) – Total porosity (frac).

  • phie (float) – Effective porosity (frac).

  • depth (float) – True vertical depth (ft).

  • fwl (float) – Free water level in true vertical depth (ft).

  • ift (float) – Interfacial tension (dynes/cm).

  • theta (float) – Wetting angle (degree).

  • gw (float) – Water density (g/cc).

  • ghc (float) – Hydrocarbon density (g/cc).

  • b0 (float) – _description_. Defaults to 0.4.

Returns:

Water saturation from saturation height function.

Return type:

float

quick_pp.core_analysis.autocorrelate_core_depth(df, replace_ori=False)[source]

Automatically shift core depths to match log depths.

This function aligns core porosity (CPORE) with log porosity (PHIT) for each well in the DataFrame. It uses a hybrid approach combining Dynamic Time Warping (DTW) for alignment and machine learning models for correction.

The process is as follows: 1. Segmentation: Core data is clustered by depth proximity using DBSCAN to

identify continuous segments.

  1. Interpolation & Smoothing: Within each segment, sparse core porosity is interpolated to match log data resolution. Both core and log porosity signals are then smoothed to focus on trends.

  2. Weighted DTW Alignment: A weighted Dynamic Time Warping (DTW) is used to find the optimal alignment path between the two porosity signals. The weighting is achieved by adding a second feature channel that identifies peaks and troughs, guiding the alignment.

  3. Filtered Model Training: A RandomForestRegressor model is trained on the DTW alignment path. The training data is filtered to include only points where the proposed shift is within a plausible window, preventing the model from learning from extreme outliers.

  4. Correction & Post-processing: The model predicts the corrected depths. This shift is clipped to the window size. A spacing correction ensures that core samples are not artificially compressed.

  5. Finalization: Isotonic regression is applied across all corrected depths for the well to enforce strict monotonicity.

Parameters:
  • df (pd.DataFrame) – DataFrame containing well log and core data. Must include ‘WELL_NAME’, ‘DEPTH’, ‘PHIT’, ‘CPORE’, ‘CPERM’, and ‘CORE_ID’.

  • replace_ori (bool, optional) – If True, the original core data columns (CPORE, CPERM) will be overwritten with the corrected ones. If False, the original columns will be preserved with an ‘_ORI’ suffix. Defaults to False.

Returns:

  • A DataFrame with the original data merged with the depth-corrected core data.

  • A summary DataFrame detailing the depth shifts for each core sample.

Return type:

tuple[pd.DataFrame, pd.DataFrame]

quick_pp.core_analysis.apply_autocorrelation_correction(data, shifted_core_data, replace_core_data=False)[source]

Applies the depth correction to the core data and merges it back into the main DataFrame.

This function takes the original well data and the core data with corrected depths, then merges them. It can either replace the original core data columns or preserve them with an ‘_ORI’ suffix.

Parameters:
  • data (pd.DataFrame) – The original DataFrame for a single well.

  • shifted_core_data (pd.DataFrame) – A DataFrame containing the core data with ‘DEPTH_CORRECTED’ and ‘DEPTH_SHIFT’ columns from the autocorrelation process.

  • replace_core_data (bool, optional) – If True, the original core data columns (CPORE, CPERM) will be overwritten. If False, they will be preserved with an ‘_ORI’ suffix. Defaults to False.

Returns:

The merged DataFrame with depth-corrected core data.

Return type:

pd.DataFrame

quick_pp.core_analysis.revert_autocorrelation_core_depth(df)[source]

Reverts the core depth autocorrelation by restoring original depths and data.

This function undoes the changes made by autocorrelate_core_depth. It looks for columns with the ‘_ORI’ suffix, which are created during the correction process to store the original data. It restores the original depth, porosity, and permeability values and removes the columns added during correction.

Parameters:

df (pd.DataFrame) – A DataFrame that has been processed by autocorrelate_core_depth. It is expected to contain columns like ‘DEPTH_CORRECTED’, ‘CPORE_ORI’, etc.

Returns:

A DataFrame with the core data reverted to its original

state before depth correction.

Return type:

pd.DataFrame

quick_pp.core_analysis._plot_correction_xplot(df)[source]

Plots a crossplot comparing log porosity (PHIT) with original and corrected core porosity (CPORE), showing R-squared and RMSE for both.

Parameters:

df (pd.DataFrame) – DataFrame containing ‘PHIT’, ‘CPORE’, ‘CPORE_ORI’, and ‘CORE_ID’.

quick_pp.core_analysis._plot_autocorrelation_results(well_name, log_data, original_core, corrected_core, alignment_df)[source]

Visualize the results of the core depth correction using Plotly.

This helper function generates a two-panel plot for quality control: 1. Porosity Alignment: Shows log porosity, original core porosity, and

depth-corrected core porosity versus depth. Lines connect original to corrected points to visualize the shifts.

  1. DTW Alignment: Plots the DTW path, showing how original core depths were mapped to log depths. A 1:1 line indicates no shift.

Parameters:
  • well_name (str) – The name of the well being plotted.

  • log_data (pd.DataFrame) – DataFrame with log data (‘DEPTH’, ‘PHIT’).

  • original_core (pd.DataFrame) – DataFrame with original core data.

  • corrected_core (pd.DataFrame) – DataFrame with depth-corrected core data.

  • alignment_df (pd.DataFrame) – DataFrame containing the DTW alignment path.

quick_pp.core_analysis.restructure_scal_data(df_wide)[source]

Restructures a SCAL dataset from a wide format (multiple Pc/Sw columns per depth) to a long format (one Pc/Sw pair per row).

Parameters:

df_wide (pd.DataFrame) – The input DataFrame in wide format.

Returns:

The restructured DataFrame in long format.

Return type:

pd.DataFrame

quick_pp.core_analysis.string_to_int_hash(s)[source]

Converts a string to a stable integer hash of at most 4 digits (0-9999).

This function uses a SHA256 hash to ensure that the same string always produces the same integer, which is useful for creating reproducible color mappings or short identifiers.

Parameters:

s (str) – The input string to hash.

Returns:

An integer between 0 and 9999, or None if the input is NaN.

Return type:

int or None

quick_pp.core_analysis.normalize_sw(sw)[source]

Normalizes water saturation (Sw) values to a range between 0 and 1.

This function scales the input water saturation values such that the minimum value becomes 0 and the maximum value becomes 1.

Args: sw (np.ndarray or pd.Series): Array or Series of water saturation values.

Returns: np.ndarray or pd.Series: Normalized water saturation values.

quick_pp.core_analysis.auto_cluster_scal_data(core_data)[source]

Automatically clusters core samples into rock types based on J-function parameters.

This function first calculates the ‘a’ and ‘b’ parameters of the J-curve for each individual core sample. It then uses K-Means clustering on these parameters to group the samples into a specified number of clusters (rock types). If the number of clusters is not provided, it determines the optimal number using the Elbow method.

Parameters:

core_data (pd.DataFrame) – DataFrame with SCAL data. Must include ‘Well’, ‘Sample’, ‘SWN’, and ‘J’ columns.

Returns:

The input DataFrame with an added ‘ROCK_FLAG’ column containing

the cluster label for each sample.

Return type:

pd.DataFrame

quick_pp.core_analysis.auto_j_params(core_data, excluded_samples=None, cluster_by=None)[source]

Automatically calculates J-function parameters (a, b) for each rock type.

This function groups the data by ‘ROCK_FLAG’, fits a J-curve for each group, and returns the best-fit parameters ‘a’ and ‘b’ along with the RMSE. It can also create sub-groups within each rock type for more granular parameterization.

Parameters:
  • core_data (pd.DataFrame) – DataFrame containing ‘ROCK_FLAG’, ‘SWN’, and ‘J’ columns.

  • excluded_samples (list, optional) – A list of ‘Sample’ names to exclude from the calculation. Defaults to [].

  • cluster_by (list, optional) – A list of column names to create sub-groups within each ‘ROCK_FLAG’. If provided, parameters will be calculated for each unique combination of ‘ROCK_FLAG’ and the cluster_by columns. Defaults to None.

Returns:

A list of dictionaries, where each dictionary contains the

group identifiers (e.g., ‘ROCK_FLAG’) and the J-parameters (‘a’, ‘b’, ‘rmse’).

Return type:

list

quick_pp.core_analysis.auto_group_core_description(core_data, geo_abbrv=None, word_cat=None, special_case_desc=None)[source]

Groups core descriptions into standardized categories using NLP and clustering.

The function follows a multi-step process: 1. It first identifies and categorizes special descriptions (e.g., “NO PLUG POSSIBLE”)

based on the special_case_desc dictionary.

  1. For the remaining descriptions, it expands common geological abbreviations (e.g., “ss” -> “sandstone”) using the geo_abbrv dictionary.

  2. It then uses TF-IDF to vectorize the cleaned text and DBSCAN to cluster similar descriptions together.

  3. Finally, it generates a structured, descriptive name for each cluster (e.g., “sandstone_fine_grained”) by selecting the most representative term from each category defined in word_cat.

Parameters:
  • core_data (pd.DataFrame) – DataFrame containing a ‘CORE_DESC’ column with textual core descriptions.

  • geo_abbrv (dict, optional) – Dictionary mapping geological abbreviations to their full terms. Defaults to Config.CORE_GEO_ABBREVIATIONS.

  • word_cat (dict, optional) – Dictionary categorizing geological terms for structured naming. Defaults to Config.CORE_WORD_CATEGORIES.

  • special_case_desc (dict, optional) – Dictionary for special descriptions that bypass clustering. Defaults to Config.CORE_SPECIAL_CASE_DESCRIPTIONS.

Returns:

The input DataFrame with an added ‘CORE_DESC_GRP’ column

containing the generated group names.

Return type:

pd.DataFrame

quick_pp.core_analysis.plot_ptsd_by_prt(core_data, ift, theta, no_of_rocks=5)[source]

Plots Pore Throat Size Distribution (PTSD) for each Petrophysical Rock Type (PRT).

This function calculates the pore throat radius from capillary pressure data and plots the derivative of water saturation with respect to the log of the radius (dSw/dLogR) against the log of the radius. This provides a visual representation of the pore throat size distribution for different rock types.

Parameters:
  • core_data (pd.DataFrame) – DataFrame with core data, including ‘Well’, ‘Sample’, ‘PC_RES’, ‘SW’, and ‘ROCK_FLAG’.

  • ift (float) – Interfacial tension (dynes/cm).

  • theta (float) – Contact angle (degrees).

  • no_of_rocks (int, optional) – The number of rock types to plot. Defaults to 5.

Returns:

The input DataFrame with added columns ‘R’, ‘LOG_R’, and ‘DSW’.

Return type:

pd.DataFrame

quick_pp.core_analysis.plot_pc_by_prt(core_data, ymax=10)[source]

Generates a grid of Pc-Sw plots, one for each Reservoir Rock Type (RRT).

This function creates subplots to visualize the capillary pressure (Pc) versus water saturation (Sw) relationship for each rock type present in the dataset.

Parameters:
  • core_data (pd.DataFrame) – DataFrame containing core data, including ‘Well’, ‘Sample’, ‘ROCK_FLAG’, ‘SW’, and ‘PC_RES’.

  • ymax (int, optional) – The maximum limit for the y-axis (Pc). Defaults to 10.

quick_pp.core_analysis.plot_j_by_prt(core_data, mapped_fzi_params, ymax=10, log_log=False)[source]

Generates a grid of J-Sw plots, one for each Reservoir Rock Type (RRT).

This function creates subplots to visualize the Leverett J-function (J) versus normalized water saturation (SWN) for each rock type. It also overlays the best-fit J-curve using the provided parameters.

Parameters:
  • core_data (pd.DataFrame) – DataFrame containing core data, including ‘ROCK_FLAG’, ‘SWN’, and ‘J’.

  • mapped_fzi_params (list[dict]) – A list of dictionaries, where each dictionary contains the ‘a’ and ‘b’ parameters for the J-curve for a specific rock type, identified by a ‘ROCK_FLAG’ key.

  • ymax (int, optional) – The maximum limit for the y-axis (J). Defaults to 10.

  • log_log (bool, optional) – If True, both axes will be on a logarithmic scale. Defaults to False.

Fluid Type module

quick_pp.fluid_type.fit_pressure_gradient(tvdss, formation_pressure)[source]

Fit pressure gradient from formation pressure and true vertical depth subsea.

Parameters:
  • tvdss (array-like) – True vertical depth subsea.

  • formation_pressure (array-like) – Formation pressure.

Returns:

Gradient and intercept of the best-fit line.

Return type:

tuple

quick_pp.fluid_type.fluid_contact_plot(tvdss, formation_pressure, m, c, fluid_type: str = 'WATER', ylim: tuple = (5000, 3000), xlim: tuple = (1000, 5000), goc: float = 0, owc: float = 0, gwc: float = 0)[source]

Generate fluid contact plot which is used to determine the fluid contact in a well.

Parameters:
  • tvdss (array-like) – True vertical depth subsea.

  • formation_pressure (array-like) – Formation pressure.

  • m (float) – Gradient of the best-fit line.

  • c (float) – Intercept of the best-fit line.

  • fluid_type (str, optional) – Type of fluid. Defaults to ‘WATER’.

  • ylim (tuple, optional) – Y-axis limits for the plot. Defaults to (5000, 3000).

  • xlim (tuple, optional) – X-axis limits for the plot. Defaults to (1000, 5000).

  • goc (float, optional) – Gas-oil contact. Defaults to 0.

  • owc (float, optional) – Oil-water contact. Defaults to 0.

  • gwc (float, optional) – Gas-water contact. Defaults to 0.

Returns:

The function generates a plot but does not return any object.

Return type:

None

quick_pp.fluid_type.gas_composition_analysis(c1, c2, c3, ic4, nc4, ic5, nc5)[source]

Analyze hydrocarbon type based on gas composition (Haworth 1985).

Hydrocarbon type flag (HC_TYPE_FLAG) is classified into 6 categories: 0: Non Representative Sample 1: Non Productive Dry Gas 2: Potentially Productive Gas 3: Potentially Productive High GOR Oil 4: Potentially Productive Condensate 5: Potentially Productive Oil

Gas quality flag (GQ_FLAG) is classified into 2 categories: 0: Not within the range of 0.8 to 1.2 1: Within the range of 0.8 to 1.2

Parameters:
  • c1 (array-like) – Concentration of methane in ppm.

  • c2 (array-like) – Concentration of ethane in ppm.

  • c3 (array-like) – Concentration of propane in ppm.

  • ic4 (array-like) – Concentration of isobutane in ppm.

  • nc4 (array-like) – Concentration of normal butane in ppm.

  • ic5 (array-like) – Concentration of isopentane in ppm.

  • nc5 (array-like) – Concentration of normal pentane in ppm.

Returns:

Gas composition analysis.

Return type:

pd.DataFrame

quick_pp.fluid_type.fix_fluid_segregation(df: DataFrame) DataFrame[source]

Corrects fluid assignments in a DataFrame based on physical segregation.

This function processes a petrophysical evaluation DataFrame on a per-well, per-hydrocarbon-interval basis. It enforces the rule that within a continuous hydrocarbon column, gas should be found above oil. If any oil is flagged at or above the deepest occurrence of gas within an interval, it is re-assigned as gas.

The function modifies the DataFrame by creating ‘VOIL’ and ‘VGAS’ columns and adjusting their values. The original ‘VHC’ column is zeroed out where ‘VOIL’ or ‘VGAS’ are populated.

Parameters:

df (pd.DataFrame) – Input DataFrame containing well data, requiring at least ‘WELL_NAME’, ‘DEPTH’, ‘VHC’, ‘OIL_FLAG’, and ‘GAS_FLAG’ columns.

Returns:

The DataFrame with corrected fluid volume assignments.

Return type:

pd.DataFrame

Rock Physics module

QAQC module

quick_pp.qaqc.handle_outer_limit(data, fill=False)[source]

Replace values outside of predefined min/max limits with NaN or the limit value.

This function iterates through the columns of a DataFrame and, for each column defined in Config.VARS with ‘min’ or ‘max’ limits, it replaces out-of-range values.

Parameters:
  • data (pd.DataFrame) – The input DataFrame with log data to be processed.

  • fill (bool, optional) – If True, replaces out-of-range values with the min/max limit. If False, replaces them with NaN. Defaults to False.

Returns:

The DataFrame with out-of-range values handled.

Return type:

pd.DataFrame

quick_pp.qaqc.badhole_flagging(data, thold=4)[source]

Generate a BADHOLE flag based on caliper and bit size information.

This function first estimates the bit size for different depth intervals if not already provided, using a change-point detection algorithm on the caliper log. It then flags sections as ‘badhole’ where the absolute difference between the caliper reading and the bit size exceeds a specified threshold.

The bit size estimation is a modified approach based on the method described at https://hallau.world/post/bitsize-from-caliper/

Parameters:
  • data (pd.DataFrame) – The input DataFrame, which must contain ‘DEPTH’ and ‘CALI’ columns.

  • thold (int, optional) – The threshold for the difference between caliper and bit size to flag a badhole. Defaults to 4.

Returns:

The DataFrame with an added ‘BADHOLE’ flag column.

Return type:

pd.DataFrame

quick_pp.qaqc.neu_den_xplot_hc_correction(nphi, rhob, vsh_gr=None, dry_min1_point: tuple = (), dry_clay_point: tuple = (), water_point: tuple = (1.0, 1.0), corr_angle: float = 50, buffer=0.0)[source]

Correct neutron porosity and bulk density for hydrocarbon effects.

This function iteratively adjusts NPHI and RHOB logs in hydrocarbon-bearing zones, shifting them along a specified correction angle until the calculated shale volume from the neutron-density crossplot aligns with the shale volume derived from the gamma-ray log.

Parameters:
  • nphi (np.ndarray or float) – Neutron porosity log in fraction.

  • rhob (np.ndarray or float) – Bulk density log in g/cc.

  • vsh_gr (np.ndarray or float, optional) – Vshale from gamma ray log. Defaults to None.

  • dry_min1_point (tuple, optional) – NPHI and RHOB of the primary matrix mineral. Defaults to ().

  • dry_clay_point (tuple, optional) – NPHI and RHOB of dry clay. Defaults to ().

  • water_point (tuple, optional) – NPHI and RHOB of the formation water. Defaults to (1.0, 1.0).

  • corr_angle (float, optional) – Correction angle in degrees from the horizontal. Defaults to 50.

  • buffer (float, optional) – A buffer added to the lithology fraction for flagging. Defaults to 0.0.

Returns:

A tuple containing:
  • Corrected neutron porosity (NPHI).

  • Corrected bulk density (RHOB).

  • A flag indicating hydrocarbon presence (1 for HC, 0 otherwise).

Return type:

tuple[np.ndarray, np.ndarray, np.ndarray]

quick_pp.qaqc.neu_den_xplot_hc_correction_angle(rho_water=1.0, rho_hc=0.3, HI_hc=None)[source]

Estimate correction angle for neutron porosity and bulk density based on water and hydrocarbon density. The angle is measured from the east (horizontal) line.

Parameters:
  • rho_water (float, optional) – Fluid density, typically 0.8-1.2 g/cc. Defaults to 1.0.

  • rho_hc (float, optional) – Hydrocarbon density (gas: 0.1-0.3, oil: 0.4-0.8 g/cc). Defaults to 0.3.

  • HI_hc (float, optional) – Hydrogen Index of the hydrocarbon (gas: 0.2-0.7, oil: 0.8-1.0). If None, it is estimated as 2.2 * rho_hc. Defaults to None.

Returns:

The hydrocarbon correction angle in degrees.

Return type:

float

quick_pp.qaqc.den_correction(nphi, gr, vsh_gr=None, phin_sh=0.35, phid_sh=0.05, rho_ma=2.68, rho_water=1.0, alpha=0.05)[source]

Correct bulk density based on nphi and gamma ray.

Parameters:
  • nphi (np.ndarray or float) – Neutron porosity log in fraction.

  • gr (np.ndarray or float) – Gamma ray log in GAPI.

  • vsh_gr (np.ndarray or float, optional) – Pre-calculated Vshale from gamma ray. If None, it will be estimated. Defaults to None.

  • phin_sh (float, optional) – Neutron porosity of shale. Defaults to .35.

  • phid_sh (float, optional) – Density porosity of shale. Defaults to .05.

  • rho_ma (float, optional) – Matrix density. Defaults to 2.68.

  • rho_water (float, optional) – Fluid density. Defaults to 1.0.

  • alpha (float, optional) – Alpha value for gamma ray normalization if vsh_gr is not provided. Defaults to 0.05.

Returns:

Corrected bulk density.

Return type:

np.ndarray or float

quick_pp.qaqc.quick_qc(well_data, return_fig=False)[source]

Perform a quick quality control analysis on processed well data.

This function generates QC flags, calculates a reservoir summary, and optionally creates distribution and depth plots for key petrophysical properties. It is designed to process data for a single well.

Parameters:
  • well_data (pd.DataFrame) – The input DataFrame containing processed well log data.

  • return_fig (bool, optional) – If True, generates and returns matplotlib figures. Defaults to False.

Returns:

A tuple containing:
  • The input DataFrame with added ‘QC_FLAG’ and other flags.

  • A DataFrame summarizing key petrophysical properties.

  • A distribution plot figure (if return_fig is True, else None).

  • A depth plot figure (if return_fig is True, else None).

Return type:

tuple

quick_pp.qaqc.quick_compare(field_data, level='WELL', return_fig=False)[source]

Perform a quick comparison of petrophysical properties across multiple wells or zones.

This function iterates through the field data, performs a quick QC on each well, and aggregates the summary statistics. It can optionally generate a figure with box plots, histograms, and summary tables for key properties.

Parameters:
  • field_data (pd.DataFrame) – A DataFrame containing data for multiple wells.

  • level (str, optional) – The level of comparison, either ‘WELL’ or ‘ZONE’. Defaults to ‘WELL’.

  • return_fig (bool, optional) – Whether to return figure. Defaults to False.

Returns:

A tuple containing the comparison DataFrame and the generated figure (or None).

Return type:

tuple[pd.DataFrame, plt.Figure or None]

quick_pp.qaqc.extract_quick_stats(compare_df, flag='all')[source]

Extract descriptive statistics from a comparison DataFrame.

This function filters a comparison DataFrame (typically generated by quick_compare) by a specified flag and calculates summary statistics for key petrophysical properties.

Parameters:
  • compare_df (pd.DataFrame) – The input comparison DataFrame.

  • flag (str, optional) – The flag to filter the DataFrame by (e.g., ‘all’, ‘reservoir’, ‘pay’). Defaults to ‘all’.

Returns:

A DataFrame containing the descriptive statistics.

Return type:

pd.DataFrame

LAS Handler module

quick_pp.las_handler.read_las_files(las_files, depth_uom=None)[source]

Read and merge data and headers from multiple LAS files.

This function iterates through a list of LAS file objects, reads each one, and concatenates their curve data and header information into respective pandas DataFrames. It prioritizes reading with welly and uses a memory-mapped fallback for robustness.

Parameters:
  • las_files (list) – A list of file-like objects, each opened in binary mode.

  • depth_uom (str, optional) – The unit of measurement for the depth index, to be used by welly. Defaults to None.

Returns:

  • A DataFrame containing the merged curve data from all LAS files.

  • A DataFrame containing the merged header information from all LAS files.

Return type:

tuple[pd.DataFrame, pd.DataFrame]

quick_pp.las_handler.read_las_file_mmap(file_object, required_sets=['PEP'])[source]

Read a single LAS file using a memory-mapped approach for multi-set data.

This function parses LAS files, particularly those containing multiple data sets (e.g., from different logging runs), which standard parsers might mishandle. It employs memory-mapping for efficient file access and allows for the selective extraction of specified data sets.

Parameters:
  • file_object (file) – A file-like object opened in binary mode to be read.

  • required_sets (list, optional) – A list of data set identifiers to extract. Only data sets matching these identifiers will be processed. Defaults to [‘PEP’].

Returns:

A tuple containing:
  • A DataFrame containing the curve data.

  • A DataFrame containing the header information.

  • A welly.well.Well object representing the well.

Return type:

tuple[pd.DataFrame, pd.DataFrame, welly.well.Well]

quick_pp.las_handler.read_las_file_welly(file_object, depth_uom=None)[source]

Read a LAS file using the welly library.

This function reads a LAS file into a welly object and then processes it to extract curve data and header information into pandas DataFrames.

Parameters:
  • file_object (file) – A file-like object, whose .name attribute (file path) is used by welly.

  • depth_uom (str, optional) – The unit of measurement for the depth index, passed to welly for index creation. Defaults to None.

Returns:

  • A DataFrame containing the processed curve data.

  • A DataFrame containing the header information.

Return type:

tuple[pd.DataFrame, pd.DataFrame]

quick_pp.las_handler.pre_process(welly_object)[source]

Pre-process a welly object to extract and clean data.

This function takes a welly.well.Well object and performs the following pre-processing steps: 1. Converts the depth index into a ‘DEPTH’ column. 2. Replaces the LAS-defined NULL value with np.nan. 3. Inserts ‘WELL_NAME’ and ‘UWI’ columns at the beginning of the DataFrame.

Parameters:

welly_object (welly.well.Well) – The welly object to process.

Returns:

  • A DataFrame containing the processed curve data.

  • A DataFrame containing the header information.

Return type:

tuple[pd.DataFrame, pd.DataFrame]

quick_pp.las_handler.get_wellname_from_header(header_df)[source]

Extract the well name from the LAS header DataFrame.

Parameters:

header_df (pd.DataFrame) – The LAS header data.

Returns:

The well name, with slashes and spaces replaced by hyphens.

Return type:

str

quick_pp.las_handler.get_uwi_from_header(header_df)[source]

Extract the Unique Well Identifier (UWI) from the LAS header DataFrame.

If the UWI is not found, it falls back to using the well name.

Parameters:

header_df (pd.DataFrame) – The LAS header data.

Returns:

The UWI or well name, with slashes and spaces replaced by hyphens.

Return type:

str

quick_pp.las_handler.get_unit_from_header(header_df, mnemonic)[source]

Extract the unit for a specific curve mnemonic from the LAS header.

Parameters:
  • header_df (pd.DataFrame) – The LAS header data.

  • mnemonic (str) – The curve mnemonic to look for.

Returns:

The unit of the curve, or None if not found.

Return type:

str or None

quick_pp.las_handler.get_descr_from_header(header_df, mnemonic)[source]

Extract the description for a specific curve mnemonic from the LAS header.

Parameters:
  • header_df (pd.DataFrame) – The LAS header data.

  • mnemonic (str) – The curve mnemonic to look for.

Returns:

The description of the curve, or None if not found.

Return type:

str or None

quick_pp.las_handler.extract_dataset(section_dict)[source]

Extract a single dataset from a dictionary of LAS file sections.

This function is designed for LAS files with a single data set. It reconstructs the LAS file content from a dictionary of its sections, reads it using lasio and welly, and then applies pre-processing.

Parameters:

section_dict (dict) – A dictionary where keys are LAS section names (e.g., ‘WELL’, ‘CURVE’) and values are their content.

Returns:

A tuple containing the processed curve data, header data, and the welly object.

Return type:

tuple[pd.DataFrame, pd.DataFrame, welly.well.Well]

quick_pp.las_handler.concat_datasets(file_object, header_line_numbers, parameter_line_numbers, required_sets=None)[source]

Extract and concatenate specified datasets from a multi-set LAS file.

This function iterates through the parameter sections identified in a LAS file. For each section that matches the required_sets, it reconstructs a temporary single-set LAS file in memory, reads it, and concatenates the resulting data.

Parameters:
  • file_object (bytes) – The complete content of the LAS file as a bytes object.

  • header_line_numbers (list) – A list of tuples defining the start and end pointers for the main well header section.

  • parameter_line_numbers (list) – A list of tuples, each containing metadata about a ~Parameter section, including its set identifier and pointer location.

  • required_sets (list, optional) – A list of data set identifiers to extract and concatenate. Defaults to [‘PEP’].

Returns:

A tuple containing the concatenated curve data, the last header data, and the last welly object.

Return type:

tuple[pd.DataFrame, pd.DataFrame, welly.well.Well]

quick_pp.las_handler.check_index_consistent(welly_object)[source]

Check if the depth index of a welly object is consistent.

A consistent index means it is monotonically increasing with a constant step.

Parameters:

welly_object (welly.well.Well) – The welly object to check.

Returns:

True if the index is consistent, False otherwise.

Return type:

bool

quick_pp.las_handler.export_to_las(well_data, well_name, folder='', vars_units=None)[source]

Export a DataFrame of well data to a LAS file.

This function takes a pandas DataFrame containing well log data, sets the ‘DEPTH’ column as the index, and writes the data to a LAS 2.0 file.

Parameters:
  • well_data (pd.DataFrame) – The DataFrame containing the well log data. It must include a ‘DEPTH’ column.

  • well_name (str) – The name of the well, used for the output filename.

  • folder (str, optional) – The directory to save the LAS file in. Defaults to ‘’.

  • vars_units (dict, optional) – A dictionary mapping curve mnemonics to their units. If not provided, units are inferred from the configuration.

Utilities module

quick_pp.utils.r2_score(y_true: ndarray, y_pred: ndarray)[source]

Calculates the R-squared (coefficient of determination) between true and predicted values.

Parameters:
  • y_true (np.ndarray) – The ground truth values.

  • y_pred (np.ndarray) – The predicted values.

Returns:

The R-squared value.

Return type:

float

quick_pp.utils.root_mean_squared_error(y_true: ndarray, y_pred: ndarray)[source]

Calculates the Root Mean Squared Error (RMSE) between true and predicted values.

Parameters:
  • y_true (np.ndarray) – The ground truth values.

  • y_pred (np.ndarray) – The predicted values.

Returns:

The RMSE value.

Return type:

float

quick_pp.utils.robust_scale(series: Series, quantile_range=(25.0, 75.0))[source]

Scales a pandas Series using robust scaling (median and IQR).

Mirrors sklearn.preprocessing.RobustScaler behaviour for a single series: - uses the median and the IQR defined by quantile_range (defaults 25-75) - preserves NaNs when computing statistics - if IQR is zero or NaN, centering is applied but scaling is skipped

Parameters:
  • series (pd.Series) – The input pandas Series to be scaled.

  • quantile_range (tuple) – pair of percentiles (low, high) used to compute IQR.

Returns:

The scaled pandas Series (dtype float).

Return type:

pd.Series

quick_pp.utils.minmax_scale(series: Series)[source]

Scales a pandas Series to the range [0, 1] using min-max scaling.

Parameters:

series (pd.Series) – The input pandas Series to be scaled.

Returns:

The scaled pandas Series with values between 0 and 1.

Return type:

pd.Series

quick_pp.utils.length_a_b(A: tuple, B: tuple)[source]

Calculate the Euclidean distance between two points.

Parameters:
  • A (tuple) – Cartesian coordinates of point A.

  • B (tuple) – Cartesian coordinates of point B.

Returns:

The distance between points A and B.

Return type:

float

quick_pp.utils.line_intersection(line1: tuple, line2: tuple)[source]

Calculates the intersection of two lines.

This function is vectorized to handle arrays of points.

Parameters:
  • line1 (tuple) – A tuple of two points defining the first line, e.g., ((x1, y1), (x2, y2)). Coordinates can be single values or arrays.

  • line2 (tuple) – A tuple of two points defining the second line.

Returns:

A tuple of NumPy arrays (x, y) for the

intersection coordinates. If lines are parallel, coordinates will be np.nan.

Return type:

tuple[np.ndarray, np.ndarray]

quick_pp.utils.angle_between_lines(line1: tuple, line2: tuple)[source]

Calculates the convex angle between two lines in degrees.

Parameters:
  • line1 (tuple) – A tuple of two points defining the first line, e.g., ((x1, y1), (x2, y2)).

  • line2 (tuple) – A tuple of two points defining the second line.

Returns:

The angle between the two lines in degrees (between 0 and 90).

Return type:

float

quick_pp.utils.zone_flagging(data: DataFrame, min_zone_thickness: int = 150)[source]

Identify and flag sand zones based on shale volume.

This function uses a shale volume curve (VSHALE or estimated VSH_GR) to delineate reservoir zones. It identifies continuous sand intervals and merges smaller zones into larger adjacent ones based on a minimum thickness criterion.

Parameters:
  • data (pd.DataFrame) – The input DataFrame with well log data.

  • min_zone_thickness (int, optional) – The minimum number of data points for a zone to be considered valid. Defaults to 150.

Returns:

The DataFrame with added ‘ZONE_FLAG’ and updated ‘ZONES’ columns.

Return type:

pd.DataFrame

quick_pp.utils.power_law_func(x, a, b)[source]

Generic power law function.

Parameters:
  • x (np.ndarray or float) – Input variable.

  • a (float) – a constant.

  • b (float) – b constant.

Returns:

y = a * x^b

Return type:

np.ndarray or float

quick_pp.utils.inv_power_law_func(x, a, b)[source]

Generic power law function.

Parameters:
  • x (np.ndarray or float) – Input variable.

  • a (float) – a constant.

  • b (float) – b constant.

Returns:

y = a * x^-b

Return type:

np.ndarray or float

quick_pp.utils.straight_line_func(x, m, c)[source]

Generic straight line function.

Parameters:
  • x (np.ndarray or float) – Input variable.

  • m (float) – Slope of the line.

  • c (float) – Y intercept of the line.

Returns:

y = m * x + c

Return type:

np.ndarray or float

quick_pp.utils.min_max_line(feature, alpha: float = 0.05, auto_bin=False)[source]

Calculate the minimum and maximum trend lines for a given feature.

This function can optionally segment the data based on change points before fitting trend lines to each segment.

Parameters:
  • feature (np.ndarray or float) – Input feature to calculate the minimum and maximum line.

  • alpha (float, optional) – Correction in percentage. Defaults to 0.05.

  • auto_bin (bool, optional) – Automatically bin the feature. Defaults to False.

Returns:

A tuple containing the minimum and maximum trend lines.

Return type:

tuple[np.ndarray, np.ndarray]

quick_pp.utils.check_trend_line(minimum: bool, pivot: int, slope: float, y: array)[source]

Check if a trend line is valid and calculate its error.

This function, based on TrendLineAutomation by neurotrader888, computes the sum of squared differences between a trend line and the data, returning -1.0 if the line is invalid.

Parameters:
  • minimum (bool) – If True, checks for a minimum trend line (support); otherwise, a maximum (resistance).

  • pivot (int) – Anchor point of the trend line.

  • slope (float) – Slope of the trend line.

  • y (np.array) – Data to fit the trend line.

Returns:

The sum of squared differences, or -1.0 if the line is invalid.

Return type:

float

quick_pp.utils.optimize_slope(minimum: bool, pivot: int, init_slope: float, y: array)[source]

Optimize the slope of a trend line to best fit the data.

This function, based on TrendLineAutomation by neurotrader888, iteratively adjusts the slope to minimize the error while maintaining the line’s validity as either a support or resistance line.

Parameters:
  • minimum (bool) – If True, optimizes for a minimum trend line; otherwise, a maximum.

  • pivot (int) – Anchor point of the trend line.

  • init_slope (float) – Initial slope of the trend line.

  • y (np.array) – Data to fit the trend line.

Returns:

Tuple containing the slope and intercept of the optimized trend

Return type:

tuple

quick_pp.utils.fit_trendlines_single(data: array)[source]

Find the best-fit minimum and maximum trend lines for a single data segment.

This function, based on TrendLineAutomation by neurotrader888, uses a least-squares fit to find an initial trend and then optimizes for the tightest possible support and resistance lines.

Parameters:

data (np.ndarray) – The data segment to fit the trend lines to.

Returns:

A tuple of tuples containing the (slope, intercept) for the minimum and maximum trend lines.

Return type:

tuple

quick_pp.utils.remove_straights(log, window: int = 30, threshold: float = 0.001)[source]

Removes straight line sections from a log by replacing them with np.nan.

This function identifies flat or “stuck” tool readings by calculating the standard deviation over a rolling window. Where the standard deviation is below a given threshold, the original log values in that window are flagged for removal.

Parameters:
  • log (pd.Series or np.ndarray) – The input log data.

  • window (int, optional) – The size of the rolling window. Defaults to 30.

  • threshold (float, optional) – The standard deviation threshold below which a segment is considered straight. Defaults to 0.001.

Returns:

The log with straight sections replaced by np.nan.

Return type:

np.ndarray

quick_pp.utils.get_tvd(df, well_coords)[source]

Calculate true vertical depth (TVD) given well survey data.

Parameters:
  • df (pd.DataFrame) – A DataFrame with a ‘DEPTH’ column.

  • well_coords (pd.DataFrame) – A DataFrame with ‘md’, ‘incl’, and ‘azim’ columns for the deviation survey.

Returns:

An array of TVD values corresponding to the input depths.

Return type:

np.ndarray

quick_pp.utils.remove_outliers(curve)[source]

Removes outliers from a curve using the IQR method and forward fills the NaNs.

Parameters:

curve (np.ndarray) – The input curve data.

Returns:

The curve with outliers replaced by NaN and then forward filled.

Return type:

pd.Series

Plotter module

Machine Learning Modelling module