def __init__(self, dshape, kshape, norm=False, frozen=True, center=None, args=[], kwargs={}, do_pad=False, pad_mask=None, origin=None): if origin is None: origin = numpy.zeros(len(kshape)) self.dshape = dshape self.kshape = kshape self.kernel = None self.skshape = None self.norm = norm self.origin = origin self.frozen = frozen self.center = center self.args = args self.kwargs = kwargs self.renorm_shape = None self.renorm = None self.do_pad = do_pad self.pad_mask = pad_mask self.frac = None self._tcd = tcdData() NoNewAttributesAfterInit.__init__(self)
def test_convolve_combined_1d(): """Try to replicate the logic of test_psf1d_step_v2 from sherpa/tests/test_instrument.py """ smdl = StepLo1D() smdl.xcut = 100 smdl.ampl = 10 gsmooth = Gauss1D() x = np.arange(0, 200, 0.5) data = smdl(x) kernel = gsmooth(x) kernel /= kernel.sum() tcd = _psf.tcdData() y = tcd.convolve(data, kernel, data.shape, kernel.shape, [0]) # So the output is not easy to describe analytically, hence # we just check parts of it. # assert y[(x >= 19.5) & (x <= 100)] == pytest.approx([10] * 162, abs=1e-4) assert y[x >= 119] == pytest.approx([0] * 162, abs=1e-4) # check that the x <= 19 values are in ascending order y1 = y[x <= 19] assert (y1[1:] > y1[:-1]).all() # and now with the kernel internally stored y2 = tcd.convolve(data, kernel, data.shape, kernel.shape, [0]) assert y2 == pytest.approx(y)
def test_tcdData_convolve_error_3d(): out = _psf.tcdData() data = [1, 2, 3, 4, 5, 6, 7, 8] kernel = [1, 2, 2, 1] with pytest.raises(TypeError) as te: out.convolve(data, kernel, [2, 2, 2], [2, 2, 1], [0, 0, 0]) assert str(te.value) == 'Padding dimension not supported'
def test_tcdData_convolve_error4(): out = _psf.tcdData() data = [1, 2, 3, 2] kernel = [1, 2, 2] with pytest.raises(TypeError) as te: out.convolve(data, kernel, [2, 2], [2, 2], [0, 0]) assert str(te.value) == 'input array sizes do not match dimensions, kernel size: 3 vs kernel dim: 4'
def test_tcdData_convolve_error2(center): out = _psf.tcdData() data = [1, 2, 3, 4] kernel = [1, 2, 2, 1] with pytest.raises(TypeError) as te: out.convolve(data, kernel, [2, 2], [2, 2], center) assert str(te.value) == 'input array sizes do not match, dims_kern: 2 vs center: 1'
def test_tcdData_convolve_error1(): out = _psf.tcdData() data = [1, 2, 3] kernel = [1, 2, 2, 1] with pytest.raises(TypeError) as te: out.convolve(data, kernel, [3], [2, 2], [0]) assert str(te.value) == 'input array sizes do not match, dims_src: 1 vs dims_kern: 2'
def test_create_tcdData(): """Check we get an object with the expected methods""" expected = ['clear_kernel_fft', 'convolve'] out = _psf.tcdData() found = [n for n in dir(out) if not n.startswith('_')] assert found == expected
def __init__(self, dshape, kshape, norm=False, frozen=True, center=None, args=[], kwargs={}, do_pad=False, pad_mask=None, origin=None): if origin is None: origin = numpy.zeros(len(kshape)) self.dshape = dshape self.kshape = kshape self.kernel = None self.skshape = None self.norm = norm self.origin = origin self.frozen = frozen self.center = center self.args = args self.kwargs = kwargs self.renorm_shape = None self.renorm = None self.do_pad = do_pad self.pad_mask = pad_mask self.frac = None self._tcd = tcdData() NoNewAttributesAfterInit.__init__(self)
def test_convolve_simple_1d(): """Very-low-level test""" data = np.asarray([0, 0, 0, 1, 2, 4, 3, 0, 0, 1, 0]) kernel = np.asarray([2, 4, 1]) tcd = _psf.tcdData() out = tcd.convolve(data, kernel, data.shape, kernel.shape, [0]) # As the kernel is not normalized, we know the output is larger than # the input: data.sum() == 11, kernel.sum() == 7. This isn't # really needed given the check against np.convolve, but keep # in as a check. # assert out.sum() == pytest.approx(11 * 7) # the convolution doesn't quite match numpy.convolve expected = np.convolve(data, kernel, mode='same') expected = np.roll(expected, 1) assert out == pytest.approx(expected) # and now with the kernel internally stored out2 = tcd.convolve(data, kernel, data.shape, kernel.shape, [0]) assert out2 == pytest.approx(out)
def __setstate__(self, state): state['_tcd'] = tcdData() self.__dict__.update(state)
def __init__(self, kernel, name='conv'): self.kernel = kernel self.name = name self._tcd = tcdData() Model.__init__(self, name)
def __setstate__(self, state): state['_tcd'] = tcdData() self.__dict__.update(state)
def __init__(self, kernel, name='conv'): self.kernel = kernel self.name = name self._tcd = tcdData() Model.__init__(self, name)
def ismooth(image, kernel, origin=None, norm=True): """Convolve image with a kernel. If norm is True then the kernel will be divided by its total before convolution. To use the kernel as is, set norm to False (the kernel is always converted to have a datatype of float64 before use). origin is the center to use for the kernel; if set to None then the center of the kernel is used. It is given using the numpy indexing scheme, so (yval,xval). To avoid offsets between the input and output image the kernel should have odd dimensions. Non-finite pixels in either the image or kernel are replaced by 0. Any such pixels in the input image are set back to NaN in the output image, but the presence of such values in the kernel image are ignored. """ if image.ndim != 2: raise ValueError("ismooth() input image must be 2D, send {0}D".format( image.ndim)) if kernel.ndim != 2: raise ValueError("ismooth() input kernel must be 2D, send {0}D".format( kernel.ndim)) # convolve takes the dimensionality with X first not last ishape = image.shape is2 = (ishape[1], ishape[0]) kshape = kernel.shape knx = kshape[1] kny = kshape[0] ks2 = (knx, kny) tcd = psf.tcdData() tcd.clear_kernel_fft() cimage = np.nan_to_num(image.flatten()) if norm: nkernel = kernel * 1.0 / kernel.sum() else: nkernel = kernel * 1.0 if origin is None: # We use the same center for even or odd image sizes kcx = knx // 2 kcy = kny // 2 kcen = (kcx, kcy) else: kcen = (origin[1], origin[0]) out = tcd.convolve(cimage, np.nan_to_num(nkernel.flatten()), is2, ks2, kcen) out = out.reshape(ishape) out[np.isnan(image)] = np.nan return out