Internal functions

Equation of State

JMD95

Density of Sea Water using the Jackett and McDougall 1995 [1] function

Functions:

rho :: computes in-situ density from salinity, potential temperature and

pressure (or depth)

rho_s_t :: compute the partial derivatives of in-situ density with

respect to salinity and potential temperature

rho_p :: compute the partial derivative of in-situ density with

respect to pressure (or depth)

Notes: To make Boussinesq versions of these functions, see neutralocean.eos.tools.make_bsq.

To make vectorized versions of these functions, see neutralocean.eos.tools.vectorize_eos.

[1]

Jackett and McDougall, 1995, JAOT 12[4], pp. 381-388

neutralocean.eos.jmd95.rho(s, t, p, pfac=1.0)[source]

Fast JMD95 [1] in-situ density.

Parameters:
sfloat

Practical salinity [PSS-78]

tfloat

Potential temperature [IPTS-68]

pfloat

Pressure [dbar]

pfacfloat, Optional

Multiplicative scaling factor applied to p. Default value is 1.0 [dbar-1]. See Notes.

Returns:
rhofloat

JMD95 in-situ density [kg m-3]

Notes

The Boussinesq version of this function is called with third input p as depth [m] and pfac = pfac_default * Pa2db * grav * rho_c where grav is the gravitational acceleration [m.s-2] rho_c is the Boussinesq reference density [kg.m-3], pfac_default = 1.0 [dbar-1] is the non-Boussinesq value of pfac Pa2db = 1e-4 [dbar.Pa-1]. Thus, p * Pa2db * grav * rho_c is the hydrostatic pressure [dbar] at depth p assuming the water column’s density was rho_c.

To create a Boussinesq version of this function that accepts 3 arguments (salinity, temperature, depth), use neutralocean.eos.tools.make_bsq.

This function is derived from densjmd95.m, documented below. Input checks and expansion of variables have been removed. That code used arrays to store coefficients, and also began by multiplying the input pressure by 10 (dbar -> bar). The coefficients, modified to not need this multiplication by 10, have been taken out of arrays and simply hardcoded into the later expressions. The polynomial calculations have also been optimized to favour faster, nested multiplications.

As such, the output of this function differs from the output of the original densjmd95.m function, though the difference is at the level of machine precision.

% DENSJMD95    Density of sea water
%=========================================================================
%
% USAGE:  dens = densjmd95(S,Theta,P)
%
% DESCRIPTION:
%    Density of Sea Water using Jackett and McDougall 1995 (JAOT 12)
%    polynomial (modified UNESCO polynomial).
%
% INPUT:  (all must have same dimensions)
%   S     = salinity    [psu      (PSS-78)]
%   Theta = potential temperature [degree C (IPTS-68)]
%   P     = pressure    [dbar]
%       (P may have dims 1x1, mx1, 1xn or mxn for S(mxn) )
%
% OUTPUT:
%   dens = density  [kg/m^3]
%
% AUTHOR:  Martin Losch 2002-08-09  (mlosch@mit.edu)

% Jackett and McDougall, 1995, JAOT 12(4), pp. 381-388

% created by mlosch on 2002-08-09
% $Header: /u/gcmpack/MITgcm/utils/matlab/densjmd95.m,v 1.2 2007/02/17 23:49:43 jmc Exp $
% $Name:  $
[1]

Jackett and McDougall, 1995, JAOT 12[4], pp. 381-388

neutralocean.eos.jmd95.rho_s_t(s, t, p, pfac=1.0)[source]

Fast salinity and potential temperature partial derivatives of JMD95 in-situ density

Parameters:
s, t, p, pfacfloat

See rho

Returns:
rho_sfloat

Partial derivative of JMD95 in-situ density with respect to practical salinity s [kg m-3 psu-1]

rho_tfloat

Partial derivative of JMD95 in-situ density with respect to potential temperature t [kg m-3 degC-1]

Notes

This function is derived from rho.

neutralocean.eos.jmd95.rho_p(s, t, p, pfac=1.0)[source]

Fast pressure derivative of JMD95 in-situ density.

Parameters:
s, t, p, pfacfloat

See rho

Returns:
rho_pfloat

Partial derivative of JMD95 in-situ density with respect to p [kg m-3 / [p]]

Notes

This function is derived from rho.

JMDFWG06

Density of Sea Water using the Jackett et al. (2006) [1] function

Functions:

rho :: computes in-situ density from salinity, potential temperature and

pressure (or depth)

rho_s_t :: compute the partial derivatives of in-situ density with

respect to salinity and potential temperature

rho_p :: compute the partial derivative of in-situ density with

respect to pressure (or depth)

Notes: To make Boussinesq versions of these functions, see neutralocean.eos.tools.make_bsq.

To make vectorized versions of these functions, see neutralocean.eos.tools.vectorize_eos.

[1]

Jackett, D. R., McDougall, T. J., Feistel, R., Wright, D. G., & Griffies, S. M. (2006). Algorithms for Density, Potential Temperature, Conservative Temperature, and the Freezing Temperature of Seawater. Journal of Atmospheric and Oceanic Technology, 23(12), 1709–1728. https://doi.org/10.1175/JTECH1946.1

History

Code adapted from MOM5.1 (Griffies et al) originally written in Fortran 2022 January 14 - David Hutchinson - Translated into python 2022 January 14 - Geoff Stanley - code optimization, partial derivatives, check vals

neutralocean.eos.jmdfwg06.rho(s, t, p, pfac=1.0)[source]
Parameters:
sfloat

Practical salinity [PSS-78]

tfloat

Potential temperature [ITS-90]

pfloat

Pressure [dbar]

pfacfloat, Optional

Multiplicative scaling factor applied to p. Default value is 1.0 [dbar-1]. See Notes.

Returns:
rhofloat

In-situ density [kg m-3]

Notes

The Boussinesq version of this function is called with third input p as depth [m] and pfac = pfac_default * Pa2db * grav * rho_c where grav is the gravitational acceleration [m.s-2] rho_c is the Boussinesq reference density [kg.m-3], pfac_default = 1.0 [dbar-1] is the non-Boussinesq value of pfac Pa2db = 1e-4 [dbar.Pa-1]. Thus, p * Pa2db * grav * rho_c is the hydrostatic pressure [dbar] at depth p assuming the water column’s density was rho_c.

To create a Boussinesq version of this function that accepts 3 arguments (salinity, temperature, depth), use neutralocean.eos.tools.make_bsq.

neutralocean.eos.jmdfwg06.rho_s_t(s, t, p, pfac=1.0)[source]
Parameters:
s, t, p, pfacfloat

See rho

Returns:
rho_sfloat

Partial derivative of in-situ density with respect to salinity [kg m-3 psu-1]

rho_tfloat

Partial derivative of in-situ density with respect to temperature [kg m-3 degC-1]

neutralocean.eos.jmdfwg06.rho_p(s, t, p, pfac=1.0)[source]
Parameters:
s, t, p, pfacfloat

See rho

Returns:
rho_pfloat

Partial derivative of in-situ density with respect to p [kg m-3 / [p]]

TEOS-10 GSW

Specific Volume using 75-term polyTEOS10-75t [1] approximation to the TEOS-10 Gibbs Sea Water standard [2]

Functions:

specvol :: compute specific volume from Absolute Salinity, Conservative Temperature and

pressure (or depth)

rho :: compute in-situ density as the reciprocol of specific volume

specvol_first_derivs :: compute first order partial derivatives of specvol

specvol_second_derivs :: compute second order partial derivatives of specvol

specvol_third_derivs :: compute third order partial derivatives of specvol

specvol_s_t :: compute the partial derivatives of specvol with respect to

Absolute Salinity and Conservative Temperature

specvol_p :: compute the partial derivative of specvol with respect to pressure

specvol_s_t_ss_st_tt_sp_tp :: compute various partial derivatives of specvol,

namely with respect to s, t, ss, st, tt, sp, tp.

specvol_s_t_ss_st_tt_sp_tp_sss_sst_stt_ttt_ssp_stp_ttp_spp_tpp :: compute various

partial derivatives of specvol, namely with respect to s, t, ss, st, tt, sp, tp, sss, sst, stt, ttt, ssp, stp, ttp, spp, tpp.

Notes: To make Boussinesq versions of these functions, see neutralocean.eos.tools.make_bsq.

To make vectorized versions of these functions which return scalar outputs, see neutralocean.eos.tools.vectorize_eos.

All functions here are derived from gsw_specvol, documented below.

# gsw_specvol                            specific volume (75-term equation)
#==========================================================================
# 
# USAGE:  
#  specvol = gsw_specvol(SA,CT,p)
# 
# DESCRIPTION:
#  Calculates specific volume from Absolute Salinity, Conservative 
#  Temperature and pressure, using the computationally-efficient 75-term 
#  polynomial expression for specific volume (Roquet et al., 2015).
#
#  Note that the 75-term equation has been fitted in a restricted range of 
#  parameter space, and is most accurate inside the "oceanographic funnel" 
#  described in McDougall et al. (2003).  The GSW library function 
#  "gsw_infunnel(SA,CT,p)" is available to be used if one wants to test if 
#  some of one's data lies outside this "funnel".  
#
# INPUT:
#  SA  =  Absolute Salinity                                        [ g/kg ]
#  CT  =  Conservative Temperature (ITS-90)                       [ deg C ]
#  p   =  sea pressure                                             [ dbar ]
#         ( i.e. absolute pressure - 10.1325 dbar )
#
# OUTPUT:
#  specvol  =  specific volume                                   [ m^3/kg ]
#
# AUTHOR: 
#  Fabien Roquet, Gurvan Madec, Trevor McDougall & Paul Barker
#                                                      [ help@teos-10.org ]
#
# VERSION NUMBER: 3.06 (30th August, 2018)
# 
# REFERENCES:
#  IOC, SCOR and IAPSO, 2010: The international thermodynamic equation of 
#   seawater - 2010: Calculation and use of thermodynamic properties.  
#   Intergovernmental Oceanographic Commission, Manuals and Guides No. 56,
#   UNESCO (English), 196 pp.  Available from http://www.TEOS-10.org.  
# 
#  McDougall, T.J., D.R. Jackett, D.G. Wright and R. Feistel, 2003: 
#   Accurate and computationally efficient algorithms for potential 
#   temperature and density of seawater.  J. Atmos. Ocean. Tech., 20, 
#   730-741.
#
#  Roquet, F., G. Madec, T.J. McDougall, P.M. Barker, 2015: Accurate
#   polynomial expressions for the density and specifc volume of seawater
#   using the TEOS-10 standard. Ocean Modelling., 90, pp. 29-43.
#
#  This software is available from http://www.TEOS-10.org
# 
#==========================================================================
[1]

Roquet, F., G. Madec, T.J. McDougall, P.M. Barker, 2015: Accurate polynomial expressions for the density and specifc volume of seawater using the TEOS-10 standard. Ocean Modelling., 90, pp. 29-43.

[2]

McDougall, T.J. and P.M. Barker, 2011: Getting started with TEOS-10 and the Gibbs Seawater (GSW) Oceanographic Toolbox, 28pp., SCOR/IAPSO WG127, ISBN 978-0-646-55621-5.

neutralocean.eos.gsw.specvol(SA, CT, p, pfac=0.0001)[source]

GSW specific volume.

Parameters:
SAfloat

Absolute Salinity [g/kg]

CTfloat

Conservative Temperature (ITS-90) [deg C]

pfloat

sea pressure (i.e. absolute pressure - 10.1325 dbar) [dbar]

pfacfloat, Optional

Multiplicative scaling factor applied to p. Default value is 1e-4 [dbar-1]. See Notes.

Returns:
specvolfloat

Specific volume [m3 kg-1]

Notes

The Boussinesq version of this function is called with third input p as depth [m] and pfac = pfac_default * Pa2db * grav * rho_c where grav is the gravitational acceleration [m.s-2] rho_c is the Boussinesq reference density [kg.m-3], pfac_default = 1e-4 [dbar-1] is the non-Boussinesq value of pfac Pa2db = 1e-4 [dbar.Pa-1]. Thus, p * Pa2db * grav * rho_c is the hydrostatic pressure [dbar] at depth p assuming the water column’s density was rho_c.

To create a Boussinesq version of this function that accepts 3 arguments (salinity, temperature, depth), use neutralocean.eos.tools.make_bsq.

neutralocean.eos.gsw.specvol_first_derivs(SA, CT, p, pfac=0.0001)[source]

Calculate all first order partial derivatives of specific volume

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
vsfloat

Partial derivative of specific volume w.r.t. SA [m3 kg-1 / (g/kg)]

vtfloat

Partial derivative of specific volume w.r.t. CT [m3 kg-1 / (deg C)]

vpfloat

Partial derivative of specific volume w.r.t. p [m3 kg-1 / [p]]

neutralocean.eos.gsw.specvol_second_derivs(SA, CT, p, pfac=0.0001)[source]

Calculate all second order partial derivatives of specific volume

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
vss, vst, vtt, vsp, vtp, vppfloat

Second order partial derivatives of specific volume w.r.t. SA * SA, SA * CT, CT * CT, SA * p, CT * p, respectively.

neutralocean.eos.gsw.specvol_third_derivs(SA, CT, p, pfac=0.0001)[source]

Calculate all third order partial derivatives of specific volume

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
vsss, vsst, vstt, vttt, vssp, vstp, vttp, vspp, vtppfloat

Third order partial derivatives of specific volume.

neutralocean.eos.gsw.specvol_s_t(SA, CT, p, pfac=0.0001)[source]

Partial derivatives of specific volume with respect to salinity & temperature

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
vsfloat

Partial derivative of specific volume w.r.t. SA [m3 kg-1 / (g/kg)]

vtfloat

Partial derivative of specific volume w.r.t. CT [m3 kg-1 / (deg C)]

neutralocean.eos.gsw.specvol_p(SA, CT, p, pfac=0.0001)[source]

Partial derivative of specific volume with respect to pressure

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
vpfloat

Partial derivative of specific volume w.r.t. p [m3 kg-1 / [p]]

neutralocean.eos.gsw.specvol_s_t_ss_st_tt_sp_tp(SA, CT, p, pfac=0.0001)[source]

Select partial derivatives of specific volume up to second order

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
s, t, ss, st, tt, sp, tpfloat

Partial derivatives of specific volume w.r.t. SA, CT, SA*SA, SA*CT, CT*CT, SA*p, CT*p.

neutralocean.eos.gsw.specvol_s_t_ss_st_tt_sp_tp_sss_sst_stt_ttt_ssp_stp_ttp_spp_tpp(SA, CT, p, pfac=0.0001)[source]

Select partial derivatives of specific volume up to third order

Parameters:
SA, CT, p, pfacfloat

See specvol

Returns:
vs, vt, vss, vst, vtt, vsp, vtp, vsss, vsst, vstt, vttt, vssp, vstp, vttp, vspp, vtppfloat

Partial derivatives of specific volume.

neutralocean.eos.gsw.rho(SA, CT, p, pfac=0.0001)[source]

(Vertical) Interpolation using Piecewise Polynomials (PP)

neutralocean.ppinterp.pval(x, C, d=0)[source]

Evaluate a (derivative of a) single polynomial.

Parameters:
xfloat

Evaluation site

Carray of float

Polynomial coefficients, starting with the highest order coefficient and ending with the coefficient of the constant term. The order of the polynomial is len(C).

dint, Default 0

Order of the derivative to evaluate. When 0, just evaluate the polynomial.

Returns:
yfloat

The polynomial (or its d’th derivative) evaluated at x.

neutralocean.ppinterp.lib.valid_range(X, k, K)[source]

Indices to the first finite value and to the first NaN after the former, along last dimension.

Parameters:
Xndarray

Input array possibly containing some NaN elements

Returns:
kndarray of int

k[n] is the smallest index such that X[n][k[n]] is finite. If X[i] is NaN for all i, then k[n] = len(X[n]).

Kndarray of int

If X[n][i] is NaN for all i > k[n], then K[n] = len(X[n]). If X[n][i] is finite for all i > k[n], then K[n] = len(X[n]). Otherwise, K[n] is the smallest index after k[n] such that X[n][K[n]] is NaN.

Notes

X[n][i] is non-NaN for i = k[n], ..., K[n] - 1. K[n] - k[n] is the size of the first contiguous block of valid values of X[n].

neutralocean.ppinterp.lib.valid_range_1(X)[source]

The index to the first finite value and to the first NaN after the former

Parameters:
X1D array

Input array possibly containing some NaN elements

Returns:
kint

First k such that X[k] is finite. If X[i] is NaN for all i, then k = len(X).

Kint

If X[i] is NaN for all i > k, then K = len(X). If X[i] is finite for all i > k, then K = len(X). Otherwise, K is the first index after k such that X[K] is NaN.

Notes

X[i] is non-NaN for i = k, ..., K - 1. K - k is the size of the first contiguous block of valid values of X.

neutralocean.ppinterp.lib.valid_range_1_two(X, Y)[source]

Indices bounding the first contiguous block of valid data in two 1D arrays

Parameters:
X, Y1D array

Input arrays of the same length, possibly containing some NaN elements

Returns:
kint

First k such that X[k] and Y[k] are finite. If X[i] or Y[i] is NaN for all i, then k = len(X).

Kint

If X[i] or Y[i] is NaN for all i > k, then K = len(X). If X[i] and Y[i] are finite for all i > k, then K = len(X). Otherwise, K is the first index after k such that X[K] or Y[K] is NaN.

Notes

X[i] and Y[i] are both non-NaN for i = k, ..., K - 1. K - k is the size of the first contiguous block of valid pairs of values of (X, Y).

neutralocean.ppinterp.linear.linear_coeffs(X, Y)[source]

Piecewise Polynomial Coefficients for a linear interpolant

Parameters:
Xndarray

Independent variable. Must be same dimensions as Y, with any dimension possibly a singleton: that is, must be broadcastable to the size of Y.

X must be monotonically increasing in its last dimension. That is, X[*i,:] should be monotonically increasing for any i tuple indexing all but the last dimension.

Yndarray

Dependent variable. Must be same dimensions as X, with any dimension possibly a singleton: that is, must be broadcastable to the size of X.

Returns:
Yppcndarray

Coefficients for a linear interpolant of Y to X.

Notes

If X and Y have NaN’s, only the first contiguous block of non-NaN data between both X and Y is used.

Evaluate the piecewise polynomial at x as

>>> y = ppval(x, X, Yppc)
neutralocean.ppinterp.linear.linear_interp(x, X, Y, d, y)[source]
neutralocean.ppinterp.pchip.pchip_coeffs(X, Y)[source]

Piecewise Polynomial Coefficients for a PCHIP (Piecewise Cubic Hermite Interpolating Polynomial)

Parameters:
Xndarray

Independent variable. Must be same dimensions as Y, with any dimension possibly a singleton: that is, must be broadcastable to the size of Y.

X must be monotonically increasing in its last dimension. That is, X[*i,:] should be monotonically increasing for any i tuple indexing all but the last dimension.

Yndarray

Dependent variable. Must be same dimensions as X, with any dimension possibly a singleton: that is, must be broadcastable to the size of X.

Returns:
Yppcndarray

Coefficients for a PCHIP interpolant of Y to X.

Notes

If X and Y have NaN’s, only the first contiguous block of non-NaN data between both X and Y is used.

Evaluate the piecewise polynomial at x as

>>> y = ppval(x, X, Yppc)
neutralocean.ppinterp.pchip.pchip_interp(x, X, Y, d=0)[source]

Root finding in 1D

Functions for finding the zero of a univariate function.

neutralocean.fzero.brent_guess(f, x, A, B, t, args=())[source]

Find a zero of a function within a given range, starting from a guess

Parameters:
ffunction

Continuous function of a single variable.

xfloat

initial guess for a root

A, Bfloat

Range within which to search, satisfying A < B

tfloat

Tolerance for convergence.

argstuple

Additional arguments, beyond the optimization argument, to be passed to f. Pass () when f is univariate.

Returns:
float

Value of x where f(x) ~ 0.

neutralocean.fzero.brent(f, a, b, t, args=())[source]

Find a zero of a univariate function within a given range

This is a bracketed root-finding method, so f(a) and f(b) must differ in sign. If they do, a root is guaranteed to be found.

Parameters:
ffunction

Continuous function of a single variable.

a, bfloat

Range within which to search, satisfying a < b and ideally f(a) * f(b) <= 0

tfloat

Tolerance for convergence.

argstuple

Additional arguments, beyond the optimization argument, to be passed to f. Pass () when f is univariate.

Returns:
float

Value of x where f(x) ~ 0.

Notes

f should be a @numba.njit’ed function (when this function is njit’ed).

neutralocean.fzero.guess_to_bounds(f, x, A, B, args=())[source]

Search for a range containing a sign change, expanding geometrically outwards from the initial guess.

This is used as a first step in zero-finding, providing a small search range for the Brent algorithm.

Parameters:
ffunction

Continuous function of a single variable. Note f(x) should be real valued (no NaN’s) on the entire interval [A, B]; unexpected behaviour may result otherwise.

xfloat

Central point for starting the search

A, Bfloat

Lower and upper bounds, containing x, within which to search for a zero.

argstuple

Additional arguments beyond the optimization argument. Pass () when f is univariate.

Returns:
a, bfloat

Lower and upper bounds within which f(x) changes sign.

Library functions

neutralocean.lib.find_first_nan(a, axis=-1)[source]

The index to the first NaN along a given axis

Parameters:
andarray

Input array possibly containing some NaN elements

axisint, Default -1

Axis along which to find the first NaN

Returns:
kndarray of int

For each 1D array a1 of a in the dimension axis, k gives: the index to the first NaN of a1, or 0 if a1 has no NaNs, or a.shape[axis] if a1 is all NaN.

For example, with a being 3D and axis = -1: If all a[i,j,:] are NaN, then k[i,j] = 0. If all a[i,j,:] are not NaN, then k[i,j] = a.shape[-1]. Otherwise, K = k[i,j] is the smallest int such that a[i,j,K-1] is not NaN and a[i,j,K] is NaN.

Notes

This is similar to (and faster than) numpy.argmax(numpy.isnan(a), axis), but differs for indices along which a is all NaN: this output contains a.shape[axis] whereas the argmax approach contains 0.

neutralocean.lib.val_at(T, k)[source]

Evaluate nD array at given indices along its last dimension

Parameters:
Tndarray

Input array. Can be 1D or nD.

kint or ndarray

Index at which to evaluate T along its last dimension. Can be an int or (n-1)D.

Returns:
Tkndarray

The input T evaluated with its last index equal to k.

Notes

If T is 3D and k is 2D, then Tk[i,j] = T[i,j,k[i,j]] for each valid (i,j).

If T is 1D and k is 2D, then Tk[i,j] = T[k[i,j]] for each valid (i,j).

If T is 3D and k is an int, then Tk[i,j] = T[i,j,k] for each valid (i,j).

Examples

Evaluate temperature, having data in each water column, at the bottom grid cell

>>> T = np.empty((3, 2, 10))  # (longitude, latitude, depth), let us say
>>> T[..., :] = np.arange(10, 0, -1)  # decreasing along depth dim from 10 to 1
>>> T[0, 0, :] = np.nan  # make cast (0,0) be land
>>> T[0, 1, 3:] = np.nan  # make cast (0,1) be only 3 ocean cells deep
>>> n_good = find_first_nan(T)
>>> val_at(T, n_good - 1)
array([[nan,  8.], [ 1.,  1.], [ 1.,  1.]])

Evaluate the depth at the bottom grid cell

>>> Z = np.linspace(0, 4500, 10)  # grid cell centre's are at depths 0, 500, 1000, ..., 4500.
>>> val_at(Z, n_good - 1)  # Z doesn't have NaN structure, so use n_good from T as above
array([[  nan, 1000.], [4500., 4500.], [4500., 4500.]])
neutralocean.lib.take_fill(a, idx, fillval=nan)[source]

Like numpy.take but fills with nan when indices are out of range

Parameters:
andarray

input data

idx1d array

linear indices to elements of a

Returns:
bndarray

The i’th element of b (in linear order) is the idx[i]’th element of a, (in linear order), or nan if idx[i] < 0. Same shape as idx.

neutralocean.lib.aggsum(a, idx, n)[source]

Aggregate data into groups and sum each group.

Parameters:
aarray

Input data to be aggregated into groups and summed.

idxarray of int

Group label for each element of a. To exclude element i of a from any group, let idx[i] be a negative int. Must be same size as a.

nint

Number of groups, including empty groups. As this is also the length of b, must satisfy n >= np.max(idx) + 1.

Returns:
barray

The sum of each group of data from a.

Notes

This is a simple implementation of numpy_groupies.aggregate. See https://github.com/ml31415/numpy-groupies/

neutralocean.lib.xr_to_np(S)[source]

Convert xarray into numpy array