cape.util: Cape utilities

This module provides several utilities used throughout the Cape system, including SigmaMean() to compute statistical sampling error for iterative histories and readline() to process special space-or-comma-separated lines for run matrix files.

cape.util.BisectLinearFit(I, x, N1, N2, **kw)

Find window size that results in minimum linear-fit slope

Call:
>>> N, dx = BisectLinearFit(I, x, N1, N2, **kw)
Inputs:
I: np.ndarray[int | float]

Iteration indices (in case of non-uniform spacing)

x: np.ndarray[float]

Array of test values

N1: int

Minimum candidate window size

N2: int

Maximum candidate window size

Outputs:
N: int

Window size with flattest linear fit

dx: float

Absolute value of change in x over window N

Versions:
  • 20178-09-28 @ddalle: Version 1.0

cape.util.FitLinearSinusoid(x, y, w)

Find best fit of a line plus a sinusoid with a given frequency

The function returns the best fit for

\[y = a_0 + a_1x + a_2\cos(\omega x) + a_3\sin(\omega x)\]
Call:
>>> a = FitLinearSinusoid(x, y, w)
>>> a0, a1, a2, a3 = FitLinearSinusoid(x, y, w)
Inputs:
x: np.ndarray

Array of independent variable samples (e.g. iteration number)

y: np.ndarray

Signal to be fit

w: float

Specified frequency of the sinusoid

Outputs:
a: np.ndarray[float]

Array of a0, a1, a2, a3

a0: float

Constant offset

a1: float

Linear slope

a2: float

Magnitude of cosine signal

a3: float

Magnitude of sine signal

Versions:
  • 2017-09-29 @ddalle: Version 1.0

cape.util.GetBCBlock2(I)

Get largest rectangle of boundary conditions

Call:
>>> js, je, ks, ke = GetBCBlock(I)
Inputs:
I: np.ndarray[bool]
  • shape: (NJ,NK)

Matrix of whether or not each grid point is in the family

Outputs:
js: {None} | int

Start j-index of block

je: {None} | int

End j-index of block

ks: {None} | int

Start k-index of block

ke: {None} | int

End k-index of block

Versions:
  • 2017-02-08 @ddalle: Version 1.0

cape.util.GetBestFrequency(y, fs=1.0, **kw)

Get best frequency using scipy.signal.welch() if available

If SciPy is not available, use a crude count of how many times the signal crosses the mean value (with a window to avoid overcounting small oscillations right around the mean value). The dimensions of this output are such that the signal matches sinusoids such as \(\sin(\omega x)\). To meet this format, the output is 2 times the peak frequency from scipy.signal.welch().

Call:
>>> w = GetBestFrequency(y, fs=1.0)
Inputs:
y: np.ndarray shape=(n,)

Input signal to process

fs: {1.0} | float

Sampling frequency of y; usually 1 as in 1 per iteration

Outputs:
w: float

Dominant frequency

Versions:
  • 2017-09-29 @ddalle: Version 1.0

cape.util.GetTecplotCommand()

Return the Tecplot 360 command on the current system

The preference is

  1. "tec360EX"

  2. "tec360"`

  3. "tecplot"

An exception is raised if none of these commands can be found.

Call:
>>> cmd = cape.util.GetTecplotCommand()
Outputs:
cmd: str

Name of the command to the current ‘tec360’ command

Versions:
  • 2015-03-02 @ddalle: Version 1.0

  • 2021-03-01 @ddalle: Version 1.1; avoid /dev/null

  • 2022-05-11 @ddalle: Version 2.0; use shutil.which()

cape.util.RangeString(rng)

Convert a list of integers to a string like “1-10,12,14-15”

Call:
>>> txt = RangeString(rng)
Inputs:
rng: list[int]

Range of integers

Outputs:
txt: str

Formatted string combining contiguous ranges with "-"

Versions:
  • 2016-10-20 @ddalle: Version 1.0

cape.util.SearchSinusoidFit(x, y, N1, N2, **kw)

Find best window size to minimize the slope of a linear+sine fit

Call:
>>> F = SearchSinusoidFit(x, y, N1, N2, **kw)
Inputs:
x: np.ndarray

Independent variable samples (e.g. iteration numbers)

y: np.ndarray

Signal to be fit

N1: int

Minimum candidate window size

N2: int

Maximum candidate window size

Outputs:
F: dict

Dictionary of fit coefficients and statistics

F[‘n’], n: int

Number of iterations in selected window

F[‘mu’]: float

Mean value over the window of size n

F[‘w’], w: float

Estimated dominant frequency over the window

F[‘a’], a, [a0, a1, a2, a3]: np.ndarray

List of line+sinusoid fit coefficients

a0: float

Constant offset of best line+sinusoid fit

a1: float

Linear slope of best line+sinusoid fit

a2: float

Amplitude of cosine contribution to line+sinusoid fit

a3: float

Amplitude of sine contribution to line+sinusoid fit

F[‘sig’]: float

Raw standard deviation over window of size n

F[‘eps’], eps: float

Sampling error; see SigmaMean()

F[‘dy’], dy: float

Drift over the window, equal to a1*n

F[‘u’]: float

Uncertainty estimate based on dy and 3*eps

F[‘np’]: float

Number of dominant-frequency periods in window

Versions:
  • 2017-09-29 @ddalle: Version 1.0

cape.util.SearchSinusoidFitRange(x, y, nAvg, nMax=None, dn=None, nMin=0, **kw)

Find best window size to minimize the slope of a linear+sine fit

Call:
>>> F = SearchSinusoidFitRange(x, y, nAvg, nMax, dn=None, **kw)
Inputs:
x: np.ndarray

Independent variable samples (e.g. iteration numbers)

y: np.ndarray

Signal to be fit

nAvg: int

Minimum candidate window size

nMax: {nAvg} | int

Maximum candidate window size

dn: {nAvg} | int

Candidate interval size

nMin: {0} | int

First iteration allowed in the window

Outputs:
F: dict

Dictionary of fit coefficients and statistics

F[‘n’], n: int

Number of iterations in selected window

F[‘mu’]: float

Mean value over the window of size n

F[‘w’], w: float

Estimated dominant frequency over the window

F[‘a’], a, [a0, a1, a2, a3]: np.ndarray

List of line+sinusoid fit coefficients

a0: float

Constant offset of best line+sinusoid fit

a1: float

Linear slope of best line+sinusoid fit

a2: float

Amplitude of cosine contribution to line+sinusoid fit

a3: float

Amplitude of sine contribution to line+sinusoid fit

F[‘sig’]: float

Raw standard deviation over window of size n

F[‘eps’], eps: float

Sampling error; see SigmaMean()

F[‘dy’], dy: float

Drift over the window, equal to a1*n

F[‘u’]: float

Uncertainty estimate based on dy and 3*eps

F[‘np’]: float

Number of dominant-frequency periods in window

Versions:
  • 2017-09-29 @ddalle: Version 1.0

cape.util.SigmaMean(x)

Calculate standard deviation of mean of an array of values

Specifically, this returns the standard deviation of an array generated in the following way. If you created 100 sets with the same statistical properties as x and created an array X which contained the means of each of those 100 sets, the purpose of this function is to estimate what the standard deviation of X would be.

Call:
>>> sig = cape.util.SigmaMean(x)
Inputs:
x: numpy.ndarray | list

Array of points

Outputs:
sig: float

Estimated standard deviation of the mean

Versions:
  • 2015-02-21 @ddalle: Version 1.0

cape.util.SplitLineGeneral(line)

Split a string that uses commas and/or spaces as delimiters

Call:
>>> V = SplitLineGeneral(line)
Inputs:
line: str

Text with commas, spaces, or a combination as delimiters

Outputs:
V: list[str]

List of values split by delimiters

Versions:
  • 2016-12-29 @ddalle: Version 1.0

cape.util.TrimUnused(T)

Remove any node numbers that are not used

For example:

[[1, 4, 5], [4, 8, 90]] --> [[1, 2, 3], [2, 6, 7]]
Call:
>>> U = cape.util.TrimUnused(T)
Inputs:
T: np.ndarray[int]

Nodal index matrix or similar

Outputs:
U: np.ndarray[int]

Nodal matrix with nodes 1 to n with same dimensions as T

Versions:
  • 2017-02-10 @ddalle: Version 1.0

  • 2017-03-30 @ddalle: Version 1.1; from Tri

cape.util.denone(x)

Replace None with [] to avoid iterative problems

Call:
>>> y = cape.util.denone(x)
Inputs:
x: any

Any variable

Outputs:
y: any

Same as x unless x is None, then []

Versions:
  • 2015-03-09 @ddalle: Version 1.0

cape.util.get_xlim(ha, xpad=0.05, **kw)

Calculate appropriate x-limits to include all lines in a plot

Plotted objects in the classes matplotlib.lines.Lines2D are checked.

Call:
>>> xmin, xmax = get_xlim(ha, pad=0.05)
Inputs:
ha: matplotlib.axes.AxesSubplot

Axis handle

xpad: float

Extra padding to min and max values to plot.

xm: float

Padding on minimum side

xp: float

Padding on maximum side

Outputs:
xmin: float

Minimum x coordinate including padding

xmax: float

Maximum x coordinate including padding

Versions:
  • 2015-07-06 @ddalle: Version 1.0

cape.util.get_xlim_ax(ha, xpad=0.05, **kw)

Calculate appropriate x-limits to include all lines in a plot

Plotted objects in the classes matplotlib.lines.Lines2D are checked.

This version is specialized for equal-aspect ratio axes.

Call:
>>> xmin, xmax = get_xlim_ax(ha, pad=0.05)
Inputs:
ha: matplotlib.axes.AxesSubplot

Axis handle

xpad: float

Extra padding to min and max values to plot.

xm: float

Padding on minimum side

xp: float

Padding on maximum side

Outputs:
xmin: float

Minimum x coordinate including padding

xmax: float

Maximum x coordinate including padding

Versions:
  • 2015-07-06 @ddalle: Version 1.0

cape.util.get_ylim(ha, ypad=0.05, **kw)

Calculate appropriate y-limits to include all lines in a plot

Plotted objects in the classes matplotlib.lines.Lines2D and matplotlib.collections.PolyCollection are checked.

Call:
>>> ymin, ymax = get_ylim(ha, ypad=0.05, ym=None, yp=None)
Inputs:
ha: matplotlib.axes.AxesSubplot

Axis handle

ypad: {0.05} | float

Extra padding to min and max values to plot

ym: float

Padding on minimum side

yp: float

Padding on maximum side

Outputs:
ymin: float

Minimum y coordinate including padding

ymax: float

Maximum y coordinate including padding

Versions:
  • 2015-07-06 @ddalle: Version 1.0

  • 2016-06-10 @ddalle: Moved to cape.util

cape.util.get_ylim_ax(ha, ypad=0.05, **kw)

Calculate appropriate y-limits to include all lines in a plot

Plotted objects in the classes matplotlib.lines.Lines2D and matplotlib.collections.PolyCollection are checked.

This version is specialized for equal-aspect ratio axes.

Call:
>>> ymin, ymax = get_ylim_ax(ha, ypad=0.05, ym=None, yp=None)
Inputs:
ha: matplotlib.axes.AxesSubplot

Axis handle

ypad: {0.05} | float

Extra padding to min and max values to plot

ym: float

Padding on minimum side

yp: float

Padding on maximum side

Outputs:
ymin: float

Minimum y coordinate including padding

ymax: float

Maximum y coordinate including padding

Versions:
  • 2015-07-06 @ddalle: Version 1.0

  • 2016-06-10 @ddalle: Moved to cape.util

cape.util.islist(x)

Check if an object is a list or not

Call:
>>> q = cape.util.islist(x)
Inputs:
x: any

Any variable

Outputs:
q: bool

Whether or not x is in [list or ndarray]

Versions:
  • 2015-06-01 @ddalle: Version 1.0

cape.util.readline(f, comment='#')

Read line that is nonempty and not a comment

Call:
>>> line = readline(f, comment='#')
Inputs:
f: file

File instance

comment: str

Character(s) that begins a comment

Outputs:
line: str

Nontrivial line or ‘’ if at end of file

Versions:
  • 2015-11-19 @ddalle: Version 1.0

cape.util.stackcol(cols)

Create a matrix out of vectors that are assumed to be columns

Call:
>>> A = stackcols(cols)
Inputs:
cols: list | tuple

List of vectors

cols[0]: list | np.ndarray

First column vector

Outputs:
A: np.ndarray

Matrix with A[:,0]==cols[0], A[:,1]==cols[1], etc.

Versions:
  • 2017-02-17 @ddalle: Version 1.0