def addmaskwedge(mask, r0, qlim=None, philim=None): ''' add a wedge to mask centered at x0, y0 note : need to fix. right now phi (hopefully) goes from -pi to pi but it could change if anything changes in mkpolar ''' Q, PHI = mkpolar(mask, x0=r0[0], y0=r0[1]) Q = radial_grid((r0[0], r0[1]), mask.shape) PHI = angle_grid((r0[0], r0[1]), mask.shape) PHI = PHI % (2 * np.pi) philim = np.array(philim) % (2 * np.pi) expression = np.ones_like(Q, dtype=bool) if qlim is not None: expression *= (Q >= qlim[0]) * (Q < qlim[1]) if philim is not None: if (philim[1] >= philim[0]): expression *= (PHI >= philim[0]) * (PHI < philim[1]) else: # special case where philim straddles the wrap around boundary expression *= (PHI >= philim[0]) | (PHI < philim[1]) w = np.where(expression) mask[w] *= 0
def mkrphibinstat(shape, origin, r_map=None, mask=None, statistic='mean', bins=(800, 300)): ''' Make the radial phi binned statistic. Allow for an rmap to be supplied ''' if origin is None: origin = (shape[0] - 1) / 2., (shape[1] - 1) / 2. if r_map is None: r_map = radial_grid(origin, shape) phi_map = angle_grid(origin, shape) shape = tuple(shape) if mask is not None: if mask.shape != shape: raise ValueError('"mask" has incorrect shape. ' ' Expected: ' + str(shape) + ' Received: ' + str(mask.shape)) mask = mask.reshape(-1) rphibinstat = BinnedStatistic2D(r_map.reshape(-1), phi_map.reshape(-1), statistic, bins=bins, mask=mask) return rphibinstat
def mkrbinstat(shape, origin, r_map=None, mask=None, statistic='mean', bins=800): ''' Make the radial binned statistic. Allow for an rmap to be supplied ''' if origin is None: origin = (shape[0] - 1) / 2, (shape[1] - 1) / 2 if r_map is None: r_map = radial_grid(origin, shape) if mask is not None: if mask.shape != shape: raise ValueError('"mask" has incorrect shape. ' ' Expected: ' + str(shape) + ' Received: ' + str(mask.shape)) mask = mask.reshape(-1) rbinstat = BinnedStatistic1D( r_map.reshape(-1), statistic, bins=bins, mask=mask, ) return rbinstat
def circular_average(calibrated_center, threshold=0, nx=100, pixel_size=(1, 1), min_x=None, max_x=None): """Circular average of the the image data The circular average is also known as the radial integration (adapted from scikit-beam.roi) Parameters ---------- image : array Image to compute the average as a function of radius calibrated_center : tuple The center of the image in pixel units argument order should be (row, col) mask : arrayint, optional Boolean array with 1s (and 0s) to be used (or not) in the average threshold : int, optional Ignore counts above `threshold` default is zero nx : int, optional number of bins in x defaults is 100 bins pixel_size : tuple, optional The size of a pixel (in a real unit, like mm). argument order should be (pixel_height, pixel_width) default is (1, 1) min_x : float, optional number of pixels Left edge of first bin defaults to minimum value of x max_x : float, optional number of pixels Right edge of last bin defaults to maximum value of x Returns ------- bin_centers : array The center of each bin in R. shape is (nx, ) ring_averages : array Radial average of the image. shape is (nx, ). """ # - create radial grid radial_val = utils.radial_grid(calibrated_center, self.data.shape, pixel_size) # - bin values of image based on the radial coordinates bin_edges, sums, counts = utils.bin_1D(np.ravel(radial_val * self.mask), np.ravel(self.data * self.mask), nx, min_x=min_x, max_x=max_x) th_mask = counts > threshold ring_averages = sums[th_mask] / counts[th_mask] ring_averages = sums[th_mask] / counts[th_mask] bin_centers = utils.bin_edges_to_centers(bin_edges)[th_mask] return bin_centers, ring_averages
def angular_average(image, calibrated_center,mask,threshold=0, nx=100, pixel_size=(1, 1), min_x=None, max_x=None): """Circular average of the the image data The circular average is also known as the radial integration (adapted from scikit-beam.roi) Parameters ---------- image : array Image to compute the average as a function of radius calibrated_center : tuple The center of the image in pixel units argument order should be (row, col) mask : arrayint, optional Boolean array with 1s (and 0s) to be used (or not) in the average threshold : int, optional Ignore counts above `threshold` default is zero nx : int, optional number of bins in x defaults is 100 bins pixel_size : tuple, optional The size of a pixel (in a real unit, like mm). argument order should be (pixel_height, pixel_width) default is (1, 1) min_x : float, optional number of pixels Left edge of first bin defaults to minimum value of x max_x : float, optional number of pixels Right edge of last bin defaults to maximum value of x Returns ------- bin_centers : array The center of each bin in R. shape is (nx, ) ring_averages : array Radial average of the image. shape is (nx, ). """ # - create radial grid radial_val = utils.radial_grid(calibrated_center, image.shape, pixel_size) # - create unitary mask (in case it's none) if mask is None: mask=np.ones(image.shape) # - bin values of image based on the radial coordinates bin_edges, sums, counts = utils.bin_1D(np.ravel(radial_val*mask), np.ravel(image*mask), nx, min_x=min_x, max_x=max_x) th_mask = counts > threshold ring_averages = sums[th_mask] / counts[th_mask] ring_averages = sums[th_mask] / counts[th_mask] bin_centers = utils.bin_edges_to_centers(bin_edges)[th_mask] return bin_centers, ring_averages
def qphiavg(image, q_map=None, phi_map=None, mask=None, bins=None, origin=None, range=None, statistic='mean'): ''' Octo 20, 2017 Yugang According to Julien's Suggestion Get from https://github.com/CFN-softbio/SciStreams/blob/master/SciStreams/processing/qphiavg.py With a small revision --> return three array rather than dict quick qphi average calculator. ignores bins for now ''' # TODO : replace with method that takes qphi maps # TODO : also return q and phi of this... # print("In qphi average stream") shape = image.shape if bins is None: bins = shape #print(bins) if origin is None: origin = (shape[0] - 1) / 2., (shape[1] - 1) / 2. from skbeam.core.utils import radial_grid, angle_grid if q_map is None: q_map = radial_grid(origin, shape) if phi_map is None: phi_map = angle_grid(origin, shape) expected_shape = tuple(shape) if mask is not None: if mask.shape != expected_shape: raise ValueError('"mask" has incorrect shape. ' ' Expected: ' + str(expected_shape) + ' Received: ' + str(mask.shape)) mask = mask.reshape(-1) rphibinstat = BinnedStatistic2D(q_map.reshape(-1), phi_map.reshape(-1), statistic=statistic, bins=bins, mask=mask, range=range) sqphi = rphibinstat(image.ravel()) qs = rphibinstat.bin_centers[0] phis = rphibinstat.bin_centers[1] return sqphi, qs, phis
def qphiavg(image, q_map=None, phi_map=None, mask=None, bins=None, origin=None, range=None, statistic='mean'): ''' quick qphi average calculator. ignores bins for now ''' # TODO : replace with method that takes qphi maps # TODO : also return q and phi of this... # print("In qphi average stream") shape = image.shape if bins is None: bins = shape #print(bins) if origin is None: origin = (shape[0] - 1) / 2., (shape[1] - 1) / 2. from skbeam.core.utils import radial_grid, angle_grid if q_map is None: q_map = radial_grid(origin, shape) if phi_map is None: phi_map = angle_grid(origin, shape) expected_shape = tuple(shape) if mask is not None: if mask.shape != expected_shape: raise ValueError('"mask" has incorrect shape. ' ' Expected: ' + str(expected_shape) + ' Received: ' + str(mask.shape)) mask = mask.reshape(-1) rphibinstat = BinnedStatistic2D(q_map.reshape(-1), phi_map.reshape(-1), statistic=statistic, bins=bins, mask=mask, range=range) sqphi = rphibinstat(image.ravel()) qs = rphibinstat.bin_centers[0] phis = rphibinstat.bin_centers[1] return sqphi, qs, phis
def test_binmap(): ''' These tests can be run in notebooks and the binmaps plotted. If this ever returns an error, it is suggested to plot the maps and see if they look sensible. ''' # generate fake data on the fly shape = np.array([100, 100]) R = radial_grid(shape/2, shape) Phi = angle_grid(shape/2., shape) img = R*np.cos(5*Phi) rs = RPhiBinnedStatistic(img.shape) binmap = rs.binmap.reshape((-1, img.shape[0], img.shape[1])) assert_array_almost_equal(binmap[0][40][::10], np.array([8, 6, 5, 4, 2, 2, 2, 4, 5, 6]))
def qphiavg(image, q_map=None, phi_map=None, mask=None, bins= None, origin=None, range=None, statistic='mean'): ''' Octo 20, 2017 Yugang According to Julien's Suggestion Get from https://github.com/CFN-softbio/SciStreams/blob/master/SciStreams/processing/qphiavg.py With a small revision --> return three array rather than dict quick qphi average calculator. ignores bins for now ''' # TODO : replace with method that takes qphi maps # TODO : also return q and phi of this... # print("In qphi average stream") shape = image.shape if bins is None: bins=shape #print(bins) if origin is None: origin = (shape[0] - 1) / 2., (shape[1] - 1) / 2. from skbeam.core.utils import radial_grid, angle_grid if q_map is None: q_map = radial_grid(origin, shape) if phi_map is None: phi_map = angle_grid(origin, shape) expected_shape = tuple(shape) if mask is not None: if mask.shape != expected_shape: raise ValueError('"mask" has incorrect shape. ' ' Expected: ' + str(expected_shape) + ' Received: ' + str(mask.shape)) mask = mask.reshape(-1) rphibinstat = BinnedStatistic2D(q_map.reshape(-1), phi_map.reshape(-1), statistic=statistic, bins=bins, mask=mask, range=range) sqphi = rphibinstat(image.ravel()) qs = rphibinstat.bin_centers[0] phis = rphibinstat.bin_centers[1] return sqphi, qs, phis
def _helper_check(pixel_list, inds, num_pix, edges, center, img_dim, num_qs): # recreate the indices using pixel_list and inds values ty = np.zeros(img_dim).ravel() ty[pixel_list] = inds # get the grid values from the center grid_values = utils.radial_grid(img_dim, center) # get the indices into a grid zero_grid = np.zeros((img_dim[0], img_dim[1])) for r in range(num_qs): vl = (edges[r][0] <= grid_values) & (grid_values < edges[r][1]) zero_grid[vl] = r + 1 # check the num_pixels num_pixels = [] for r in range(num_qs): num_pixels.append(int((np.histogramdd(np.ravel(grid_values), bins=1, range=[[edges[r][0], (edges[r][1] - 0.000001)]]))[0][0])) assert_array_equal(num_pix, num_pixels)
def _helper_check(pixel_list, inds, num_pix, edges, center, img_dim, num_qs): # recreate the indices using pixel_list and inds values ty = np.zeros(img_dim).ravel() ty[pixel_list] = inds # get the grid values from the center grid_values = utils.radial_grid(img_dim, center) # get the indices into a grid zero_grid = np.zeros((img_dim[0], img_dim[1])) for r in range(num_qs): vl = (edges[r][0] <= grid_values) & (grid_values < edges[r][1]) zero_grid[vl] = r + 1 # check the num_pixels num_pixels = [] for r in range(num_qs): num_pixels.append( int((np.histogramdd(np.ravel(grid_values), bins=1, range=[[edges[r][0], (edges[r][1] - 0.000001)]]))[0][0])) assert_array_equal(num_pix, num_pixels)
def test_radial_grid(): a = core.radial_grid((3, 3), (7, 7)) assert_equal(a[3, 3], 0) assert_equal(a[3, 4], 1)
import numpy as np from skbeam.core.image import construct_rphi_avg_image from skbeam.core.utils import angle_grid, radial_grid ####################################################### #CONFIGURATIONS shape = 800, 800 #size of the image #################################################### ANGLES = angle_grid((y0, x0), shape) RADII = radial_grid((y0, x0), shape) img = np.cos(ANGLES * 5)**2 * RADII**2 mask = np.ones_like((ANGLES)) mask[100:200] = 0 mask[:, 100:200] = 0 mask[:, 500:643] = 0 mask[70:130] = 0 img *= mask #### stream the img #### decide how to stream the img ### make sure that I calculate the correct size of the image