def test_BinnedStatistics1D(): x = np.linspace(0, 2 * np.pi, 100) values = np.sin(x * 5) for stat, stat_f in stats_list: bs = BinnedStatistic1D(x, statistic=stat, bins=10) bs_f = BinnedStatistic1D(x, statistic=stat_f, bins=10) ref, edges, _ = scipy.stats.binned_statistic(x, values, statistic=stat, bins=10) assert_array_equal(bs(values), ref) assert_array_almost_equal(bs_f(values), ref) assert_array_equal(edges, bs.bin_edges) assert_array_equal(edges, bs_f.bin_edges) rbinstat = BinnedStatistic1D(x) # make sure wrong shape is caught with assert_raises(ValueError): rbinstat(x[:-2]) # try with same shape, should be fine rbinstat(x)
def circavg(image, q_map=None, r_map=None, bins=None, mask=None, **kwargs): ''' computes the circular average.''' # TODO : could avoid creating a mask to save time if mask is None: mask = np.ones_like(image) # figure out bins if necessary if bins is None: # guess q pixel bins from r_map if r_map is not None: # choose 1 pixel bins (roughly, not true at very high angles) # print("rmap not none, mask shape : {}, rmap shape : # {}".format(mask.shape, r_map.shape)) pxlst = np.where(mask == 1) nobins = int(np.max(r_map[pxlst]) - np.min(r_map[pxlst]) + 1) # print("rmap is not none, decided on {} bins".format(nobins)) else: # crude guess, I'll be off by a factor between 1-sqrt(2) or so # (we'll have that factor less bins than we should) # arbitrary number nobins = int(np.maximum(*(image.shape)) // 4) # here we assume the rbins uniform bins = nobins # rbinstat = RadialBinnedStatistic(image.shape, bins=nobins, # rpix=r_map, statistic='mean', mask=mask) rbinstat = BinnedStatistic1D(r_map.reshape(-1), statistic='mean', bins=nobins, mask=mask.ravel()) bin_centers = rbinstat(q_map.ravel()) bins = center2edge(bin_centers) # now we use the real rbins, taking into account Ewald curvature # rbinstat = RadialBinnedStatistic(image.shape, bins=bins, rpix=q_map, # statistic='mean', mask=mask) # print("qmap shape : {}".format(q_map.shape)) # print("number bins : {}".format(bins)) # print("mask shape : {}".format(mask.shape)) rbinstat = BinnedStatistic1D(q_map.reshape(-1), statistic='mean', bins=bins, mask=mask.ravel()) sqy = rbinstat(image.ravel()) sqx = rbinstat.bin_centers # get the error from the shot noise only # NOTE : variance along ring could also be interesting but you # need to know the correlation length of the peaks in the rings... (if # there are peaks) rbinstat.statistic = "sum" noperbin = rbinstat(mask.ravel()) sqyerr = np.sqrt(rbinstat(image.ravel())) sqyerr /= np.sqrt(noperbin) # the error is just the bin widths/2 here sqxerr = np.diff(rbinstat.bin_edges) / 2. return dict(sqx=sqx, sqy=sqy, sqyerr=sqyerr, sqxerr=sqxerr)
def generate_map_bin(geo, img_shape): """Create a q map and the pixel resolution bins Parameters ---------- geo : pyFAI.geometry.Geometry instance The calibrated geometry img_shape : tuple, optional The shape of the image, if None pull from the mask. Defaults to None. Returns ------- q : ndarray The q map qbin : ndarray The pixel resolution bins """ r = geo.rArray(img_shape) q = geo.qArray(img_shape) / 10 # type: np.ndarray q_dq = geo.deltaQ(img_shape) / 10 # type: np.ndarray pixel_size = [getattr(geo, a) for a in ["pixel1", "pixel2"]] rres = np.hypot(*pixel_size) rbins = np.arange(np.min(r) - rres / 2., np.max(r) + rres / 2., rres / 2.) rbinned = BinnedStatistic1D(r.ravel(), statistic=np.max, bins=rbins) qbin_sizes = rbinned(q_dq.ravel()) qbin_sizes = np.nan_to_num(qbin_sizes) qbin = np.cumsum(qbin_sizes) qbin[0] = np.min(q_dq) if np.max(q) > qbin[-1]: qbin[-1] = np.max(q) return q, qbin
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 generate_binner(geo, img_shape, mask=None): r = geo.rArray(img_shape) q = geo.qArray(img_shape) / 10 # type: np.ndarray q_dq = geo.deltaQ(img_shape) / 10 # type: np.ndarray pixel_size = [getattr(geo, a) for a in ['pixel1', 'pixel2']] rres = np.hypot(*pixel_size) rbins = np.arange(np.min(r) - rres / 2., np.max(r) + rres / 2., rres / 2.) # This is only called once, use the function version rbinned = BinnedStatistic1D(r.ravel(), statistic=np.max, bins=rbins, ) qbin_sizes = rbinned(q_dq.ravel()) qbin_sizes = np.nan_to_num(qbin_sizes) qbin = np.cumsum(qbin_sizes) if mask is not None: mask = mask.flatten() return BinnedStatistic1D(q.flatten(), bins=qbin, mask=mask)
def test_BinnedStatistics1D(): x = np.linspace(0, 2 * np.pi, 100) values = np.sin(x * 5) for stat, stat_f in stats_list: bs = BinnedStatistic1D(x, statistic=stat, bins=10) bs_f = BinnedStatistic1D(x, statistic=stat_f, bins=10) ref, edges, _ = scipy.stats.binned_statistic(x, values, statistic=stat, bins=10) assert_array_equal(bs(values), ref) assert_array_almost_equal(bs_f(values), ref) assert_array_equal(edges, bs.bin_edges) assert_array_equal(edges, bs_f.bin_edges)
def convert_Qmap(img, qx_map, qy_map=None, bins=None, rangeq=None, origin=None, mask=None, statistic='mean'): """Y.G. Nov 3@CHX Convert a scattering image to a qmap by giving qx_map and qy_map Return converted qmap, x-coordinates and y-coordinates """ if qy_map is not None: if rangeq is None: qx_min, qx_max = qx_map.min(), qx_map.max() qy_min, qy_max = qy_map.min(), qy_map.max() rangeq = [[qx_min, qx_max], [qy_min, qy_max]] #rangeq = [qx_min,qx_max , qy_min,qy_max] if bins is None: bins = qx_map.shape if mask is not None: m = mask.ravel() else: m = None b2d = BinnedStatistic2D(qx_map.ravel(), qy_map.ravel(), statistic=statistic, bins=bins, mask=m, range=rangeq) remesh_data, xbins, ybins = b2d( img.ravel()), b2d.bin_centers[0], b2d.bin_centers[1] else: if rangeq is None: qx_min, qx_max = qx_map.min(), qx_map.max() rangeq = [qx_min, qx_max] if bins is None: bins = [qx_map.size] #print( rangeq, bins ) if mask is not None: m = mask.ravel() else: m = None b1d = BinnedStatistic1D(qx_map.ravel(), bins=bins, mask=m) remesh_data = b1d(img.ravel()) #print('Here') xbins = b1d.bin_centers ybins = None return remesh_data, xbins, ybins
def generate_binner(geo, img_shape=None, mask=None): """Create a pixel resolution BinnedStats1D instance Parameters ---------- geo : pyFAI.geometry.Geometry instance The calibrated geometry img_shape : tuple, optional The shape of the image, if None pull from the mask. Defaults to None. mask : ndarray, optional The mask to be applied, if None no mask is applied. Defaults to None. Returns ------- BinnedStatistic1D : The configured instance of the binner. """ if img_shape is None: img_shape = mask.shape r = geo.rArray(img_shape) q = geo.qArray(img_shape) / 10 # type: np.ndarray q_dq = geo.deltaQ(img_shape) / 10 # type: np.ndarray pixel_size = [getattr(geo, a) for a in ['pixel1', 'pixel2']] rres = np.hypot(*pixel_size) rbins = np.arange(np.min(r) - rres / 2., np.max(r) + rres / 2., rres / 2.) # This is only called once, use the function version` rbinned = BinnedStatistic1D(r.ravel(), statistic=np.max, bins=rbins, ) qbin_sizes = rbinned(q_dq.ravel()) qbin_sizes = np.nan_to_num(qbin_sizes) qbin = np.cumsum(qbin_sizes) qbin[0] = np.min(q_dq) if np.max(q) > qbin[-1]: qbin[-1] = np.max(q) if mask is not None: mask = mask.flatten() return BinnedStatistic1D(q.flatten(), bins=qbin, mask=mask)
def map_to_binner(pixel_map, bins, mask=None): """Transforms pixel map and bins into a binner Parameters ---------- pixel_map: np.ndarray The map between pixels and values bins: np.ndarray The bins to use in the binner mask: np.ndarray, optional The mask for the pixel map Returns ------- BinnedStatistic1D: The binner """ if mask is not None: mask = mask.flatten() return BinnedStatistic1D(pixel_map.flatten(), bins=bins, mask=mask)