def runtimesAbel(nArray, nMeasure, method, order): runtimes = np.zeros(nArray.shape[0]) runtimesPre = np.zeros(nArray.shape[0]) for ii in range(nArray.shape[0]): dataIn = np.ones(nArray[ii]) T = np.empty(nMeasure) for jj in range(nMeasure): t0 = ti.time() abelObj = oa.Abel(nArray[ii], 1, 0., 1., method = method, order = order) t1 = ti.time() T[jj] = t1-t0 runtimesPre[ii] = np.sum(T)/nMeasure abelObj = oa.Abel(nArray[ii], 1, 0., 1., method = method, order = order) t0 = ti.time() for jj in range(nMeasure): dataOut = abelObj.execute(dataIn) t1 = ti.time() runtimes[ii] = (t1-t0)/nMeasure return (runtimesPre, runtimes)
def errorAbel(nData, method, order): dx = 1./(nData-1); xx = np.linspace(0., 1., nData) dataIn = 3./8.*np.pi*(1-xx**2)**2 dataAna = np.sqrt(1-xx**2)**3 abelObj = oa.Abel(nData, 1, 0., dx, method = method, order = order) dataOut = abelObj.execute(dataIn) abserr = dataOut-dataAna relerr = np.abs(abserr/np.clip(dataAna, 1.e-300, None)) return (xx, abserr, relerr, dataOut, dataAna)
def convergenceAbel(nArray, method, order): conv = np.empty(nArray.shape[0]) for ii in range(nArray.shape[0]): nData = nArray[ii] dx = 1./(nData-1); xx = np.linspace(0., 1., nData) dataIn = 3./8.*np.pi*(1-xx**2)**2 abelObj = oa.Abel(nData, 1, 0., dx, method = method, order = order) dataOut = abelObj.execute(dataIn) dataAna = np.sqrt(1-xx**2)**3 conv[ii] = np.sqrt(np.sum(((dataOut[:-1]-dataAna[:-1])/dataAna[:-1])**2)/(nData-1)) return conv
def errorAbel(nData, method, order): dx = 1. / (nData - 1) xx = np.linspace(0., 1., nData) sig = 1. / 3. dataIn = 1. / sig / np.sqrt(2 * np.pi) * np.exp(-0.5 * xx**2 / sig**2) dataAna = 2.*1./sig/np.sqrt(2*np.pi)*np.exp(-0.5*xx**2/sig**2) * \ np.sqrt(np.pi/2.)*sig*erf(np.sqrt(1**2-xx**2)/np.sqrt(2.)/sig) abelObj = oa.Abel(nData, -1, 0., dx, method=method, order=order) dataOut = abelObj.execute(dataIn) abserr = dataOut - dataAna relerr = np.abs(abserr / np.clip(dataAna, 1.e-300, None)) return (xx, abserr, relerr, dataOut, dataAna)
def convergenceAbel(nArray, method, order): conv = np.empty(nArray.shape[0]) for ii in range(nArray.shape[0]): nData = nArray[ii] dx = 1. / (nData - 1) xx = np.linspace(0., 1., nData) sig = 1. / 3. dataIn = 1. / sig / np.sqrt(2 * np.pi) * np.exp(-0.5 * xx**2 / sig**2) abelObj = oa.Abel(nData, -1, 0., dx, method=method, order=order) dataOut = abelObj.execute(dataIn) dataAna = 2./sig/np.sqrt(2*np.pi)*np.exp(-0.5*xx**2/sig**2) * \ np.sqrt(np.pi/2.)*sig*erf(np.sqrt(1**2-xx**2)/np.sqrt(2.)/sig) conv[ii] = np.sqrt( np.sum( ((dataOut - dataAna) / np.clip(dataAna, 1.e-300, None))**2) / nData) return conv
def helper_test_method(nData, forwardBackward, shift, methods, orders, rtol): for method, order in it.product(methods, orders): xMax = 3.5 sig = 1. stepSize = xMax / (nData - 1) abelObj = oa.Abel(nData, forwardBackward, shift, stepSize, method=method, order=order) xx = np.linspace(shift * stepSize, xMax, nData) dataIn = np.exp(-0.5 * xx**2 / sig**2) if forwardBackward == -1: dataOutAna = dataIn * np.sqrt(2 * np.pi) * sig * erf( np.sqrt((xMax**2 - xx**2) / 2) / sig) elif forwardBackward == 1: dataOutAna = dataIn / np.sqrt(2 * np.pi) / sig * erf( np.sqrt((xMax**2 - xx**2) / 2) / sig) elif forwardBackward == 2: dataOutAna = dataIn / np.sqrt(2 * np.pi) / sig * erf( np.sqrt((xMax**2 - xx**2) / 2) / sig) dataIn = -xx / sig**2 * np.exp(-0.5 * xx**2 / sig**2) else: raise NotImplementedError('Test not implemented.') dataOut = abelObj.execute(dataIn) assert dataOut[-1] == 0. np.testing.assert_allclose(dataOut[:-1], dataOutAna[:-1], rtol=rtol) return None
# Line styles linestyles = ['-', '--', '-.', ':','-', '--', '-.', ':','-', '--', '-.', ':'] lw = 2 ############################################################################################################################################ # Parameters nData = 40 shift = 0. xMax = 3.5 sig = 1. stepSize = xMax/(nData-1) forwardBackward = -1 # Forward transform, similar definition ('-1' = forward) as in FFT libraries. # Create Abel transform object, which does all precomputation possible without knowing the exact data. abelObj = openAbel.Abel(nData, forwardBackward, shift, stepSize) # Input data xx = np.linspace(shift*stepSize, xMax, nData) dataIn = np.exp(-0.5*xx**2/sig**2) # Forward Abel transform and analytical result. # We show both the analytical result of a truncated Gaussian and a standard Gaussian to show # that some error is due to truncation. dataOut = abelObj.execute(dataIn) dataOutAna = dataIn*np.sqrt(2*np.pi)*sig dataOutAnaTrunc = dataIn*np.sqrt(2*np.pi)*sig*erf(np.sqrt((xMax**2-xx**2)/2)/sig) # Plotting fig, axarr = mpl.subplots(2, 1, sharex=True)
def openAbel_transform(image, dr=1, direction='inverse', **kwargs): r"""Wrapper for the openAbel implementations of Abel transforms. This function performs the transform on only one "right-side" image. :: .. note:: Image should be a right-side image, like this: :: . +-------- +--------+ . | * | * | . | * | * | <---------- im . | * | * | . +-------- o--------+ . | * | * | . | * | * | . | * | * | . +-------- +--------+ In accordance with all PyAbel methods the image center ``o`` is defined to be mid-pixel i.e. an odd number of columns, for the full image. For the full image transform, use the :class:``abel.Transform``. Inverse Abel transform: :: iAbel = abel.Transform(image, method='openAbel').transform Forward Abel transform: :: fAbel = abel.Transform(image, direction='forward', method='openAbel').transform Parameters ---------- image : 1D or 2D numpy array Right-side half-image (or quadrant). See figure below. dr : float Sampling size, used for Jacobian scaling. Default: `1` (appliable for pixel images). direction : string 'forward' or 'inverse' ``forward`` or ``inverse`` Abel transform. Default: 'inverse'. Returns ------- aim : 1D or 2D numpy array forward/inverse Abel transform half-image """ image = np.atleast_2d(image) # 2D input image aim = np.empty_like(image) # Abel transform array rows, cols = image.shape if direction == 'forward': forwardBackward = -1 else: forwardBackward = 1 if kwargs.get('method') == None: method = 3 else: method = kwargs.get('method') if kwargs.get('order') == None: order = 2 else: order = kwargs.get('order') try: abelObj = openAbel.Abel(cols, forwardBackward, 0., dr, method=method, order=order) for ii in range(rows): aim[ii, :] = abelObj.execute(image[ii, :]) except: raise if rows == 1: aim = aim[0] # flatten to a vector return aim
# Parameters nData = 40 shift = 0. xMax = 3.5 sig = 1. stepSize = xMax/(nData-1) forwardBackward = -1 # Forward transform, similar definition ('1' = backward) as in FFT libraries. # Create Abel transform object for three different methods and orders. # Some methods ignore the order keyword argument, and for the normal user # only method = 3 and order = 2 to order = 5 are recommended. # Higher orders require data outside the integration domain to be stable. # For more information see the documentation. abelObj0 = openAbel.Abel(nData, forwardBackward, shift, stepSize, method = 2, order = 2) abelObj1 = openAbel.Abel(nData, forwardBackward, shift, stepSize, method = 3, order = 5) abelObj2 = openAbel.Abel(nData, forwardBackward, shift, stepSize, method = 3, order = 11) # Input data xx = np.linspace(shift*stepSize, xMax, nData) dataIn = np.exp(-0.5*xx**2/sig**2) xxExt = np.linspace(shift*stepSize, xMax+5*stepSize, nData+5) # floor((order-1)/2) extra points at right end dataInExt = np.exp(-0.5*xxExt**2/sig**2) # Backward transform and analytical result dataOut0 = abelObj0.execute(dataIn) dataOut1 = abelObj1.execute(dataIn) dataOut2 = abelObj2.execute(dataInExt, leftBoundary = 2, rightBoundary = 3) # 2 means use even symmetry, 3 means input extra points. dataOutAna = dataIn*np.sqrt(2*np.pi)*sig*erf(np.sqrt((xMax**2-xx**2)/2)/sig)
# Line styles linestyles = ['-', '--', '-.', ':','-', '--', '-.', ':','-', '--', '-.', ':'] lw = 2 ############################################################################################################################################ # Parameters nData = 80 xMax = 1. shift = 0. sig = 1./4. stepSize = xMax/(nData-1) forwardBackward = 2 noiseAmp = 0.01 abelObj = openAbel.Abel(nData, forwardBackward, shift, stepSize) # Backward Abel transform where user inputs derivative # No filtering der = np.asarray([0.5, 0., -0.5])/stepSize xx = np.linspace(-stepSize*(der.shape[0]-1)/2, xMax+stepSize*(der.shape[0]-1)/2, nData+(der.shape[0]-1)) dataIn = np.exp(-0.5*xx**2/sig**2) np.random.seed(2202) dataInWithNoise = dataIn + noiseAmp*np.random.randn(nData+(der.shape[0]-1)) # Take derivatives dataInD = np.convolve(dataInWithNoise, der, mode = 'valid') # Backward transform dataOutNoFilter = abelObj.execute(dataInD)
def test_methodNotImplemented(): oa.Abel(10, -1, 0., 1., method = -1)