Source code for litholog.wentworth

"""
Utility functions for Wentworth/Krumbein logarithmic grainsize scale.

See this link for a nice chart:
    https://en.wikipedia.org/wiki/Grain_size#/media/File:Wentworth_scale.png
"""
import numpy as np
from math import floor, ceil

# Reference diameter (mm)
D0 = 1.0

# (name : upper PSI limit) ... upper limits taken as inclusive
fine_scale = [
    ('colloid', -10),
    ('clay',    -8),
    ('vf_silt', -7),
    ('f_silt',  -6),
    ('m_silt',  -5),
    ('c_silt',  -4),
    ('vf_sand', -3),
    ('f_sand',  -2),
    ('m_sand',  -1),
    ('c_sand',   0),
    ('vc_sand',  1),
    ('vf_gravel',2),
    ('f_gravel', 3),
    ('m_gravel', 4),
    ('c_gravel', 5),
    ('vc_gravel',6),
    ('cobble',   8),
    ('boulder',  None)  # anything bigger than 8
]

medium_scale = [
    ('mud',     -4),
    ('vf_sand', -3),
    ('f_sand',  -2),
    ('m_sand',  -1),
    ('c_sand',   0),
    ('vc_sand',  1),
    ('gravel',   6),
    ('cobble',   8),
    ('boulder', None)
]

coarse_scale = [
    ('clay',  -8),
    ('silt',  -4),
    ('sand',   1),
    ('gravel', 6),
    ('cobble', 8),
    ('boulder', None)
]

#wentworth_names, wentworth_psis = zip(*wentworth_scale)

# PSI functions
[docs]def gs2psi(gs): # TODO: handle zeros? if type(gs) is list: gs = np.array(gs) return np.log2(gs / D0)
[docs]def psi2gs(psi): return D0 * 2**psi
[docs]def psi2phi(psi): return -psi
# PHI functions
[docs]def gs2phi(gs): return -np.log2(gs / D0)
[docs]def phi2gs(phi): return D0 * 2**(-phi)
[docs]def phi2psi(phi): return -phi
# Name funcs
[docs]def psi2name(psi, scale=fine_scale): """Map single `psi` value to Wentworth bin name.""" for name, upper_psi in scale[:-1]: if psi <= upper_psi: return name return scale[-1][0]
[docs]def phi2name(phi): return psi2name(-phi)
[docs]def gs2name(gs): return psi2name(gs2psi(gs))
""" def psirange2names(min_psi, max_psi, return_tick_locs=False): min_idx = wentworth_names.index(psi2name(min_psi)) max_idx = wentworth_names.index(psi2name(max_psi)) max_idx = min(max_idx, len(wentworth_names)-2) names = wentworth_names[min_idx:max_idx+1] return wentworth_names[min_idx:max_idx+1] class WentworthAxis(): def __init__(self, scale='fine', fig_width=1.5, aspect=10): self.scale = wentworth_scale_coarse if scale == 'coarse' else wentworth_scale_fine self.names, self.psis = zip(*self.scale) # change this... index won't work like that self.lower_psi = self.psis[self.names.index(min_bin_name)] if min_bin_name else floor(min(gs_psi)) self.upper_psi = self.psis[self.names.index(max_bin_name)] if max_bin_name else ceil(max(gs_psi)) def transform(self, gs_psi): pass def prepare_ax(self, ax): ax.set_xlim([0.0, self.upper_psi - self.lower_psi]) """ if __name__ == '__main__': #psi = [x for _, x in wentworth_scale[:-1]] + [9] #for x in psi: # print(x, psi2phi(x), psi2name(x), psi2gs(x)) pass