Source code for featuremapper.analysis.raster

"""
Useful ElementOperations over Raster elements.
"""

import numpy as np

import param
from holoviews import CompositeOverlay, BoundingBox, Dimension
from holoviews import Image, Curve, VectorField
from holoviews.core import ElementOperation
from holoviews.operation.normalization import raster_normalization


[docs]class fft_power(ElementOperation): """ Given a Image element, compute the power of the 2D Fast Fourier Transform (FFT). """ output_type = Curve max_power = param.Number(default=1.0, doc=""" The maximum power value of the output power spectrum.""") group = param.String(default='FFT Power', doc=""" The group assigned to the output power spectrum.""") def _process(self, matrix, key=None): normfn = raster_normalization.instance() if self.p.input_ranges: matrix = normfn.process_element(matrix, key, *self.p.input_ranges) else: matrix = normfn.process_element(matrix, key) fft_spectrum = abs(np.fft.fftshift(np.fft.fft2(matrix.data - 0.5, s=None, axes=(-2, -1)))) fft_spectrum = 1 - fft_spectrum # Inverted spectrum by convention zero_min_spectrum = fft_spectrum - fft_spectrum.min() spectrum_range = fft_spectrum.max() - fft_spectrum.min() spectrum = (self.p.max_power * zero_min_spectrum) / spectrum_range l, b, r, t = matrix.bounds.lbrt() density = matrix.xdensity bounds = BoundingBox(radius=(density/2)/(r-l)) return Image(spectrum, bounds, label=matrix.label, group=self.p.group)
[docs]class vectorfield(ElementOperation): """ Given a Image with a single channel, convert it to a VectorField object at a given spatial sampling interval. The values in the Image are assumed to correspond to the vector angle in radians and the value is assumed to be cyclic. If supplied with an Overlay, the second sheetview in the overlay will be interpreted as the third vector dimension. """ output_type = VectorField rows = param.Integer(default=10, doc=""" The number of rows in the vector field.""") cols = param.Integer(default=10, doc=""" The number of columns in the vector field.""") group = param.String(default='Vectors', doc=""" The group assigned to the output vector field.""") def _process(self, view, key=None): if isinstance(view, CompositeOverlay) and len(view) >= 2: radians, lengths = view[0], view[1] else: radians, lengths = view, None cyclic_dim = radians.value_dimensions[0] if not cyclic_dim.cyclic: raise Exception("First input Image must be declared cyclic") l, b, r, t = radians.bounds.lbrt() X, Y = np.meshgrid(np.linspace(l, r, self.p.cols+2)[1:-1], np.linspace(b, t, self.p.rows+2)[1:-1]) vector_data = [] for x, y in zip(X.flat, Y.flat): components = (x,y, radians[x,y]) if lengths is not None: components += (lengths[x,y],) vector_data.append(components) value_dimensions = [Dimension('Angle', cyclic=True, range=cyclic_dim.range)] if lengths is not None: value_dimensions.append(Dimension('Magnitude')) print np.array(vector_data).shape return VectorField(np.array(vector_data), label=radians.label, group=self.p.group, value_dimensions=value_dimensions)

FeatureMapper

Table Of Contents

This Page