camera_response.py#

This script estimates a camera’s spectral sensitivities from a set of samples (photos of a spectral light source) and spectral irradiance measurements of the light source. Results are saved in an H5 file.

camera_response.main(args=None, **kw)[source]#

Compute camera spectral sensitivity from spectral image stack samples.

If called without parameters, parses arguments from the command line. Arguments may be passed as a list of strings or as keyword arguments. E.g.:

main(['-i','samples.h5','--quiet'])
# or
main(input='samples.h5',quiet=True)
Parameters:
  • monochromator (-m, --monochromator, Path or MonochromatorSpectra) – monochromator spectral irradiance file.

  • input (-i, --input, Path or CameraSamples) – input samples h5 file

  • output (-o, --output, Path or CameraResponse) – output response h5 file

  • bootstrap (--bootstrap, int, default 100) – Number of bootstrapping iterations

  • method (--method, str, one of [‘ols’, ‘ridge’, ‘ridge-smooth’]) – Regression method

  • non_negative (--non-negative, bool, default False) – If True, use non-negative constrained regression.

  • target_r2 (-r2, --target-r2, float, default 0.999) – Target coefficient of determination. Controls bias-variance tradeoff (alpha) of ridge regression, helps prevent overfitting.

  • bandwidth (-b, --bandwidth, float) – Bandwidth for ridge-smooth. Default will be max of monochromator irradiance bandwidth or input sample spacing.

  • quiet (--quiet, bool) – suppress status messages

class camera_response.CameraResponse(path=None)[source]#

Load and save camera spectral response data.

Parameters:

pathNone or path to h5 file to load.

camera: str#

Camera name/description.

lens: str#

Lens name/description.

settings: str#

Camera and lens settings used.

label: str#

Short name to identify dataset.

wl: NDArray#

Spectral response wavelength. Shape (N).

wl_units: str#

Units of wl

mean: NDArray#

Mean spectral response. Shape (N,C)

std: NDArray#

Standard deviation of spectral response. Shape (N,C)

units: str#

Units of mean and std.

scale: float#

Scale applied to mean and std.

n: int#

number of bootstrap iterations used to compute mean and std.

R2: float#

Coefficient of determination of estimates_mean relative to samples_mean.

alpha: float#

Bias-variance tradeoff coefficient of the regression method.

method: str#

Regression method used to compute mean and std

samples_wl: NDArray#

Nominal wavelength of samples_mean, samples_std, estimates_mean, and estimates_std. Shape (M).

samples_units: str#

Units of samples_mean, samples_std, estimates_mean, and estimates_std.

samples_n: int#

Number of pixels averaged for each element of samples_mean and samples_std.

samples_mean: NDArray#

Mean pixel value for each sample image.

samples_std: NDArray#

Pixel standard deviation for each sample image.

estimates_mean: NDArray#

Mean of estimated pixel values across bootstrapping iterations

estimates_std: NDArray#

Std of estimated pixel values across bootstrapping iterations

estimates_n: int#

number of bootstrap iterations for estimates_mean and estimates_std.

normalize(mode: Literal['peak', 'total'] = 'peak')[source]#

Normalize peak or total response to 1. mode is 'peak' or 'total'

denormalize()[source]#

Remove scaling from normalize.

load(path: Path)[source]#

Load data from path.

save(path: Path)[source]#

Save data to path. Overwrites existing files.

camera_response.fwhm(x: array_like, y: array_like, axis: int = -1) numpy.ndarray[source]#

Measure FWHM along the given axis.

Measure the full-width at half-maximum (FWHM) along the given axis. Measures the difference in x where y is half of its maximum along axis

Parameters:
  • x – Data coordinate, must have same shape as y.

  • y – Data value, must have same shape as x.

  • axis – Dimension to measure width along.

Returns:

width – Shape as x and y but less one dimension for axis.

Return type:

ndarray

camera_response.find_peaks(x: array_like, y: array_like, axis: int = -1, threshold: float = 0.75) numpy.ndarray[source]#

Find x of peak y along an axis. Only works for monomodal data.

Finds the centroid of y[y > threshold*np.nanmax(y, axis)]

Parameters:
  • x – data coordinate. Must have same shape as y.

  • y – Data value. Must have same shape as x

  • axis – Dimension to integrate along for centroid

  • threshold – relative threshold of y to consider for peaks.

Returns:

peaksx coordinate of peaks in y along axis. Shape as x but less one dimension for axis.

Return type:

ndarray

camera_response.ols(X: ArrayLike, y: ArrayLike, return_estimate: bool = False, non_negative: bool = False) np.ndarray | Tuple[np.ndarray, np.ndarray][source]#

Ordinary least squares regression.

Solves \(\min_w||X w - y||_2^2\).

Parameters:
  • X (array_like[(n_samples, n_features)]) – Independent variables, input, feature vectors, or training data.

  • y (array_like[(n_samples, n_targets)]) – Dependent variables, output, or target values.

  • return_estimate – if True, also return estimate = X @ w.

  • non_negative – if True, constrain w to non-negative values.

Returns:

  • w (ndarray[(n_features, n_targets)]) – Feature weights

  • estimate (ndarray[(n_samples, n_targets)]) – Estimate of y for computing regression quality metrics such as R2. estimate = X @ w

camera_response.ridge_general(X: ArrayLike, y: ArrayLike, M: ArrayLike, return_estimate: bool = False, non_negative: bool = False) np.ndarray | Tuple[np.ndarray, np.ndarray][source]#

Generalized ridge regression with regularization (Tikhonov) matrix M.

Solves \(\min_w||X w - y||_2^2 + ||M w||_2^2\) using \(w = (X^\trans X + M^\trans M)^{-1} X^\trans y\)

Non-negative solutions are found by iterative minimization.

Parameters:
  • X (array_like[(n_samples, n_features)]) – Independent variables, input, feature vectors, or training data.

  • y (array_like[(n_samples, n_targets)]) – Dependent variables, output, or target values.

  • M (array_like[(n_regularizer, n_features)]) – Regularization (Tikhonov) matrix.

  • return_estimate – if True, also return estimate = X @ w.

  • non_negative – if True, constrain w to non-negative values.

Returns:

  • w (ndarray[(n_features, n_targets)]) – Feature weights

  • estimate (ndarray[(n_samples, n_targets)]) – Estimate of y for computing regression quality metrics such as R2. estimate = X @ w

camera_response.ridge(X: ArrayLike, y: ArrayLike, alpha: float = 1.0, return_estimate: bool = False, non_negative: bool = False) np.ndarray | Tuple[np.ndarray, np.ndarray][source]#

Ridge regression.

Solves \(\min_w||X w - y||_2^2 + \alpha||w||_2^2\) using ridge_general.

Parameters:
  • X (array_like[(n_samples, n_features)]) – Independent variables, input, feature vectors, or training data.

  • y (array_like[(n_samples, n_targets)]) – Dependent variables, output, or target values.

  • alpha (float) – Regularization strength.

  • return_estimate – if True, also return estimate = X @ w.

  • non_negative – if True, constrain w to non-negative values.

Returns:

  • w (ndarray[(n_features, n_targets)]) – Feature weights

  • estimate (ndarray[(n_samples, n_targets)]) – Estimate of y for computing regression quality metrics such as R2. estimate = X @ w

camera_response.ridge_smooth(X: ArrayLike, y: ArrayLike, alpha: float = 1.0, beta: float = 1.0, filt: ArrayLike = [1, -1], return_estimate: bool = False, non_negative: bool = False) np.ndarray | Tuple[np.ndarray, np.ndarray][source]#

Ridge regression with a smoothness constraint.

Solves \(\min_w||X w - y||_2^2 + \alpha||w||_2^2 + \beta||h*w||_2^2\) using ridge_general. In this case, \(h*w\) represents the convolution of filt with w along the n_features axis.

Conceptually, applying a high-pass filter to \(w\) as a regularization term will penalize solutions with high-frequency content, resulting in a smooth solution.

Parameters:
  • X (array_like[(n_samples, n_features)]) – Independent variables, input, feature vectors, or training data.

  • y (array_like[(n_samples, n_targets)]) – Dependent variables, output, or target values.

  • alpha (float) – Regularization strength.

  • beta (float) – Filter strength

  • filt (array_like[(n_taps,)]) – Finite impulse response filter. Should be a high-pass filter to ensure a smooth filter.

  • return_estimate – if True, also return estimate = X @ w.

  • non_negative – if True, constrain w to non-negative values.

Returns:

  • w (ndarray[(n_features, n_targets)]) – Feature weights

  • estimate (ndarray[(n_samples, n_targets)]) – Estimate of y for computing regression quality metrics such as R2. estimate = X @ w

camera_response.bootstrap(R: Callable[[ArrayLike, ArrayLike, ...], Tuple[np.ndarray, np.ndarray]], X_mean: ArrayLike, X_std: ArrayLike, y_mean: ArrayLike, y_std: ArrayLike, n: int = 100, rng: np.random.Generator | None = None, **kw) Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, float][source]#

Perform a bootstrapped regression

The regression R(X,y,return_estimate=True,**kw) will be perfomed n times, each time sampling X = rng.normal(X_mean, X_std) and y = rng.normal(y_mean, y_std).

Parameters:
  • R – The regression method, such as ols, ridge, ridge_smooth. It must accept the keyword argument ‘return_estimate’.

  • X_mean (array_like[(n_samples, n_features)]) – Mean of X distribution.

  • X_std (array_like[(n_samples, n_features)]) – Standard deviation of X distribution.

  • y_mean (array_like[(n_samples, n_targets)]) – Mean of y distribution.

  • y_std (array_like[(n_samples, n_targets)]) – Standard deviation of y distribution.

  • n – Number of bootstrap iterations

  • rng – a numpy random number generator. Defaults to numpy.random.default_rng().

  • **kw – Any extra keyword arguments are passed to R

Returns:

  • w_mean (ndarray[(n_features, n_targets)]) – Mean of the feature weights w over all bootstrap iterations

  • w_std (ndarray[(n_features, n_targets)]) – Standard deviation of the feature weights w over all bootstrap iterations

  • estimate_mean (ndarray[(n_samples, n_targets)]) – Mean of estimate = X @ w over all bootstrap iterations

  • estimate_std (ndarray[(n_samples, n_targets)]) – Standard deviation of estimate over all bootstrap iterations.

  • R2 – Coefficient of variation between y_mean and estimate_mean