Пример #1
0
def frame_filter_lowpass(array,
                         mode='gauss',
                         median_size=5,
                         fwhm_size=5,
                         gauss_mode='conv'):
    """ Low-pass filtering of input frame depending on parameter *mode*. 
    
    Parameters
    ----------
    array : array_like
        Input array, 2d frame.
    mode : {'median', 'gauss'}, str optional
        Type of low-pass filtering.
    median_size : int, optional
        Size of the median box for filtering the low-pass median filter.
    fwhm_size : int, optional
        Size of the Gaussian kernel for the low-pass Gaussian filter.
    gauss_mode : {'conv', 'convfft'}, str optional
        'conv' uses the multidimensional gaussian filter from scipy.ndimage and
        'convfft' uses the fft convolution with a 2d Gaussian kernel.
    
    Returns
    -------
    filtered : array_like
        Low-pass filtered image.
        
    """
    if array.ndim != 2:
        raise TypeError('Input array is not a frame or 2d array.')

    if mode == 'median':
        # creating the low_pass filtered (median) image
        filtered = median_filter(array, int(median_size), mode='nearest')
    elif mode == 'gauss':
        # 2d Gaussian filter
        sigma = fwhm_size * gaussian_fwhm_to_sigma
        if gauss_mode == 'conv':
            filtered = gaussian_filter(array,
                                       sigma=sigma,
                                       order=0,
                                       mode='nearest')
        elif gauss_mode == 'convfft':
            # FFT Convolution with a 2d gaussian kernel created with Astropy.
            filtered = convolve_fft(array, Gaussian2DKernel(stddev=sigma))
        else:
            raise TypeError('2d Gaussian filter mode not recognized')
    else:
        raise TypeError('Low-pass filter mode not recognized')

    return filtered
Пример #2
0
def test_convolve_vs_smooth():
    axes = [
        MapAxis(np.logspace(0.0, 3.0, 3), interp="log"),
        MapAxis(np.logspace(1.0, 3.0, 4), interp="lin"),
    ]

    binsz = 0.05 * u.deg
    m = WcsNDMap.create(binsz=binsz, width=1.05 * u.deg, axes=axes)
    m.data[:, :, 10, 10] = 1.0

    desired = m.smooth(kernel="gauss", width=0.5 * u.deg, mode="constant")
    gauss = Gaussian2DKernel(10).array
    actual = m.convolve(kernel=gauss)
    assert_allclose(actual.data, desired.data, rtol=1e-3)
Пример #3
0
def test_compute_ts_map_downsampled(input_maps):
    """Minimal test of compute_ts_image"""
    kernel = Gaussian2DKernel(2.5)

    ts_estimator = TSMapEstimator(method="root brentq",
                                  error_method="conf",
                                  ul_method="conf")
    result = ts_estimator.run(input_maps, kernel=kernel, downsampling_factor=2)

    assert_allclose(result["ts"].data[99, 99], 1675.28, rtol=1e-2)
    assert_allclose(result["niter"].data[99, 99], 7)
    assert_allclose(result["flux"].data[99, 99], 1.02e-09, rtol=1e-2)
    assert_allclose(result["flux_err"].data[99, 99], 3.84e-11, rtol=1e-2)
    assert_allclose(result["flux_ul"].data[99, 99], 1.10e-09, rtol=1e-2)
Пример #4
0
def gaussian_kernel(data_shape, sigma, norm='max'):
    r"""Gaussian kernel

    This method produces a Gaussian kerenal of a specified size and dispersion

    Parameters
    ----------
    data_shape : tuple
        Desiered shape of the kernel
    sigma : float
        Standard deviation of the kernel
    norm : str {'max', 'sum', 'none'}, optional
        Normalisation of the kerenl (options are 'max', 'sum' or 'none')

    Returns
    -------
    np.ndarray kernel

    Examples
    --------
    >>> from modopt.math.stats import gaussian_kernel
    >>> gaussian_kernel((3, 3), 1)
    array([[ 0.36787944,  0.60653066,  0.36787944],
           [ 0.60653066,  1.        ,  0.60653066],
           [ 0.36787944,  0.60653066,  0.36787944]])

    >>> gaussian_kernel((3, 3), 1, norm='sum')
    array([[ 0.07511361,  0.1238414 ,  0.07511361],
           [ 0.1238414 ,  0.20417996,  0.1238414 ],
           [ 0.07511361,  0.1238414 ,  0.07511361]])

    """

    if not import_astropy:  # pragma: no cover
        raise ImportError('Astropy package not found.')

    if norm not in ('max', 'sum', 'none'):
        raise ValueError('Invalid norm, options are "max", "sum" or "none".')

    kernel = np.array(Gaussian2DKernel(sigma, x_size=data_shape[1],
                      y_size=data_shape[0]))

    if norm == 'max':
        return kernel / np.max(kernel)

    elif norm == 'sum':
        return kernel / np.sum(kernel)

    elif norm == 'none':
        return kernel
Пример #5
0
    def _create_psf(self, **kwargs):
        """Set up psf model using `astropy.convolution`.
        """
        # Read psf info
        import json
        psf_data = json.load(open(self.psf_file))

        # Convert sigma and amplitude
        sigma_1 = gaussian_fwhm_to_sigma * psf_data['psf1']['fwhm']
        sigma_2 = gaussian_fwhm_to_sigma * psf_data['psf2']['fwhm']
        sigma_3 = gaussian_fwhm_to_sigma * psf_data['psf3']['fwhm']
        ampl_1 = psf_data['psf1']['ampl'] * 2 * np.pi * sigma_1 ** 2
        ampl_2 = psf_data['psf2']['ampl'] * 2 * np.pi * sigma_2 ** 2
        ampl_3 = psf_data['psf3']['ampl'] * 2 * np.pi * sigma_3 ** 2

        # Setup kernels
        from astropy.convolution import Gaussian2DKernel
        gauss_1 = Gaussian2DKernel(sigma_1, **kwargs)
        gauss_2 = Gaussian2DKernel(sigma_2, **kwargs)
        gauss_3 = Gaussian2DKernel(sigma_3, **kwargs)
        psf = gauss_1 * ampl_1 + gauss_2 * ampl_2 + gauss_3 * ampl_3
        psf.normalize()
        return psf
Пример #6
0
    def get_kernel(self, fov):
        # called by .apply_to() from the base PSF class

        pixel_scale = fov.header["CDELT1"] * u.deg.to(u.arcsec)
        pixel_scale = utils.quantify(pixel_scale, u.arcsec)
        wave = fov.wavelength

        ### add in the conversion to fwhm from seeing and wavelength here
        fwhm = self.meta["fwhm"] * u.arcsec / pixel_scale

        sigma = fwhm.value / 2.35
        kernel = Gaussian2DKernel(sigma, mode="center").array

        return kernel
def smooth_image(model: Image, width=1.0):
    """ Smooth an image with a kernel
    
    """
    
    assert type(model) == Image
    kernel = Gaussian2DKernel(width)
    
    cmodel = create_empty_image_like(model)
    cmodel.data[..., :, :] = convolve(model.data[0, 0, :, :], kernel, normalize_kernel=False)
    if type(kernel) is Gaussian2DKernel:
        cmodel.data *= 2 * numpy.pi * 1.5 ** 2
    
    return cmodel
Пример #8
0
    def convolve_spatial(self, fwhmx=None, fwhmy=None):

        if fwhmx is None and fwhmy is None:
            print("No convolution to be done with both FWHM as None")
            return
        elif fwhmx <= 0. and fwhmy <= 0.:
            print("No convolution to be done with FWHM <= 0")
            return

        if fwhmx > self.fwhmx:
            conv_fwhmx = np.sqrt(fwhmx**2 - self.fwhmx**2)
            reached_fwhmx = fwhmx
        else:
            print("Warning: objective FWHM_X smaller than present value")
            conv_fwhmx = 0.
            reached_fwhmx = self.fwhmx
        if fwhmy > self.fwhmy:
            conv_fwhmy = np.sqrt(fwhmy**2 - self.fwhmy**2)
            reached_fwhmy = fwhmy
        else:
            print("Warning: objective FWHM_Y smaller than present value")
            conv_fwhmy = 0.
            reached_fwhmy = self.fwhmy

        closvd = copy.deepcopy(self)
        print("LOSVD FWHM: XLOS[{0}] YLOS[{1}]".format(self.fwhmx, self.fwhmy))
        print("Starting the Convolution to reach FWHM: XCLOS[{0}] YCLOS[{1}]".
              format(reached_fwhmx, reached_fwhmy))
        print(
            "Convolving with quadratic residuals FWHM: DX[{0}] DY[{1}]".format(
                conv_fwhmx, conv_fwhmy))

        # Building the kernel
        kernel = Gaussian2DKernel(
            x_stddev=conv_fwhmx * gaussian_fwhm_to_sigma / self.stepx,
            y_stddev=conv_fwhmy * gaussian_fwhm_to_sigma / self.stepy)
        # Doing the convolution per image slice
        for k in range(self.losvd.shape[2]):
            closvd.losvd[:, :, k] = convolve(self.losvd[:, :, k], kernel)

        if self.err_losvd[0, 0] is not None:
            for k in range(self.losvd.shape[2]):
                closvd.err_losvd[:, :, k] = convolve(self.err_losvd[:, :, k],
                                                     kernel)

        closvd.fwhmx = reached_fwhmx
        closvd.fwhmy = reached_fwhmy

        # Returning the result
        return closvd
Пример #9
0
def make_HSC_detect_mask(bin_msk,
                         img,
                         objects,
                         segmap,
                         r=10.0,
                         radius=1.5,
                         threshold=0.01):
    '''Make HSC detection and bright star mask, 
    based on HSC binary mask flags.
    
    Parameters:
    -----------
    bin_msk: 2-D np.array, can be loaded from HSC image cutouts
    objects: table, returned from sep.extract_obj
    segmap: 2-D np.array, returned from sep.extract_obj
    r: float, blow-up parameter
    radius: float, convolution radius
    threshold: float, threshold of making mask after convolution

    Returns:
    -----------
    HSC_detect_mask: 2-D boolean np.array
    
    See also:
    -----------------
    convert_HSC_binary_mask(bin_msk)
    '''
    import sep
    TDmask = convert_HSC_binary_mask(bin_msk)
    cen_mask = np.zeros(bin_msk.shape, dtype=np.bool)
    cen_obj = objects[segmap[int(bin_msk.shape[0] / 2.),
                             int(bin_msk.shape[1] / 2.)] - 1]

    fraction_radius = sep.flux_radius(img, cen_obj['x'], cen_obj['y'],
                                      10 * cen_obj['a'], 0.5)[0]
    ba = np.divide(cen_obj['b'], cen_obj['a'])
    sep.mask_ellipse(cen_mask,
                     cen_obj['x'],
                     cen_obj['y'],
                     fraction_radius,
                     fraction_radius * ba,
                     cen_obj['theta'],
                     r=r)
    from astropy.convolution import convolve, Gaussian2DKernel
    HSC_mask = (TDmask[:, :, 5]).astype(bool) * (
        ~cen_mask) + TDmask[:, :, 9].astype(bool)
    # Convolve the image with a Gaussian kernel with the width of 1.5 pixel
    cvl = convolve(HSC_mask.astype('float'), Gaussian2DKernel(radius))
    HSC_detect_mask = cvl >= threshold
    return HSC_detect_mask
Пример #10
0
def get_gauss_beam(fwhm, pixscale, band, nfwhm=5.0, oversamp=1):
    retext = round(fwhm * nfwhm / pixscale)
    if retext % 2 == 0:
        retext += 1

    bmsigma = fwhm / math.sqrt(8 * math.log(2))

    beam = Gaussian2DKernel(bmsigma / pixscale,
                            x_size=retext,
                            y_size=retext,
                            mode='oversample',
                            factor=oversamp)
    beam *= 1.0 / beam.array.max()
    return beam
    def maybe_interpolate_dead_pixels(self):
        if self.interpolate_dead_pixels:
            print('Interpolating dead pixels...')
            kernel = Gaussian2DKernel(1)

            not_valid_and_inside_brightfield = np.logical_and(
                np.logical_not(self.bvm), self.bmb)
            self.data[not_valid_and_inside_brightfield] = np.NaN
            # p = Pool(multiprocessing.cpu_count())
            # p.map(replace_nans, data)
            for i, da in enumerate(self.data):
                self.data[i] = interpolate_replace_nans(da.copy(), kernel)

            self.data = np.nan_to_num(self.data, copy=False)
Пример #12
0
def get_gauss_beam(fwhm, pixscale, nfwhm=5.0, oversamp=1):
    """ Generate Gaussian kernel

    Parameters
    ----------
    fwhm: float
      FWHM of the Gaussian beam.

    pixscale: float
      Pixel scale, in same units as FWHM.

    nfwhm: float
      Number of fwhm (approximately) of each dimension of the output beam.

    oversamp: int
      Odd integer giving the oversampling to use when constructing the
      beam.  The beam is generated in pixscale / oversamp size pixels,
      then rebinned to pixscale.

    Notes
    -----
      The beam is normalized by having a value of 1 in the center.
      If oversampling is used, the returned array will be the sum over
      the neighborhood of this maximum, so will not be one.
    """

    if fwhm <= 0:
        raise ValueError("Invalid (negative) FWHM")
    if pixscale <= 0:
        raise ValueError("Invalid (negative) pixel scale")
    if nfwhm <= 0.0:
        raise ValueError("Invalid (non-positive) nfwhm")
    if fwhm / pixscale < 2.5:
        raise ValueError("Insufficiently well sampled beam")
    if oversamp < 1:
        raise ValueError("Invalid (<1) oversampling")

    retext = round(fwhm * nfwhm / pixscale)
    if retext % 2 == 0:
        retext += 1

    bmsigma = fwhm / math.sqrt(8 * math.log(2))

    beam = Gaussian2DKernel(bmsigma / pixscale,
                            x_size=retext,
                            y_size=retext,
                            mode='oversample',
                            factor=oversample)
    beam *= 1.0 / beam.array.max()
    return beam
Пример #13
0
    def _compute_asteroid_outlier_mask(self, correction):
        '''Finds a mask in a corrected cube, where there are extremely bright asteroids.'''

        b = np.copy(self.flux - correction)
        # Whiten by pixel time series std dev
        s = np.atleast_3d(np.nanstd(b, axis=(0))).transpose([2, 0, 1])

        # Sum in one dimension, remove median and find 3 sigma outliers
        ysum = np.nanmax(gaussian_filter(np.nan_to_num(b/s), (1.5, 1.5, 0)), axis=1)
        ymed = np.atleast_2d(np.nanmedian(ysum, axis=1)).T * np.ones(ysum.shape)
        yans = ysum - ymed > 3

        # Sum in other dimension, remove median and find 3 sigma outliers
        xsum = np.nanmax(gaussian_filter(np.nan_to_num(b/s), (1.5, 0, 1.5)), axis=2)
        xmed = np.atleast_2d(np.nanmedian(xsum, axis=1)).T * np.ones(xsum.shape)
        xans = xsum - xmed > 3

        # Convolve with 45 degree gaussians, to make sure if we miss a time stamp we have a shot of getting it.
        c1 = convolve(yans.astype(float), Gaussian2DKernel(1, 0.2, theta=-45))
        c2 = convolve(yans.astype(float), Gaussian2DKernel(1, 0.2, theta=45))
        yans = np.any([(c1 > 0.01), (c2 > 0.01)], axis=0)
        c1 = convolve(xans.astype(float), Gaussian2DKernel(1, 0.2, theta=-45))
        c2 = convolve(xans.astype(float), Gaussian2DKernel(1, 0.2, theta=45))
        xans = np.any([(c1 > 0.01), (c2 > 0.01)], axis=0)

        # Find where these two dimensions cross
        a = (np.atleast_3d(xans) | np.atleast_3d(yans).transpose([0, 2, 1]))

        # Weak Gaussian blur helps find real sources
        c = gaussian_filter(np.nan_to_num(b/s), (0, 0.5, 0.5))

        # Where there are sources in the image
        threshold = (c > 5*np.atleast_3d(np.nanstd(c, axis=(1,2))).transpose([1, 0, 2]))

        # Take any sources that are in the crosshairs and have high SNR.
        aper = threshold & a
        return ~aper
Пример #14
0
    def create_seg_map(self):
        '''
        Creates segmentation map, from original FLT file, that is used in 
        background subtraction and to fix cosmic rays.

        Parameters
        ----------
        self : object
            DashData object created from an individual IMA file.

        Output
        ------
        Segmentation Image : fits file
            Segmentation map
        Source List : .dat file
            List of sources and their properties
        '''

        flt = fits.open(self.flt_file_name)
        data = flt[1].data

        threshold = detect_threshold(data, nsigma=3.)

        sigma = 3.0 * gaussian_fwhm_to_sigma  # FWHM = 3.
        kernel = Gaussian2DKernel(sigma, x_size=3, y_size=3)
        kernel.normalize()
        segm = detect_sources(data,
                              threshold,
                              npixels=10,
                              filter_kernel=kernel)

        hdu = fits.PrimaryHDU(segm.data)
        if not os.path.exists('segmentation_maps'):
            os.mkdir('segmentation_maps')
        hdu.writeto(('segmentation_maps/{}_seg.fits').format(self.root),
                    overwrite=True)

        # Create source list
        cat = source_properties(data, segm)

        tbl = cat.to_table()
        tbl['xcentroid'].info.format = '.2f'
        tbl['ycentroid'].info.format = '.2f'
        tbl['cxx'].info.format = '.2f'
        tbl['cxy'].info.format = '.2f'
        tbl['cyy'].info.format = '.2f'

        ascii.write(tbl,
                    'segmentation_maps/{}_source_list.dat'.format(self.root))
Пример #15
0
    def vue_spatial_convolution(self, *args):
        """
        Use astropy convolution machinery to smooth the spatial dimensions of
        the data cube.
        """

        size = float(self.stddev)
        cube = self._selected_data.get_object(cls=SpectralCube)
        # Extend the 2D kernel to have a length 1 spectral dimension, so that
        # we can do "3d" convolution to the whole cube
        kernel = np.expand_dims(Gaussian2DKernel(size), 0)

        # TODO: in vuetify >2.3, timeout should be set to -1 to keep open
        #  indefinitely
        snackbar_message = SnackbarMessage(
            "Smoothing spatial slices of cube...",
            loading=True,
            timeout=0,
            sender=self)
        self.hub.broadcast(snackbar_message)

        convolved_data = convolve(cube.hdu.data, kernel)
        # Create a new cube with the old metadata. Note that astropy
        # convolution generates values for masked (NaN) data, but we keep the
        # original mask here.
        newcube = SpectralCube(data=convolved_data,
                               wcs=cube.wcs,
                               mask=cube.mask,
                               meta=cube.meta,
                               fill_value=cube.fill_value)

        label = f"Smoothed {self._selected_data.label} spatial stddev {size}"

        if label in self.data_collection:
            snackbar_message = SnackbarMessage(
                "Data with selected stddev already exists, canceling operation.",
                color="error",
                sender=self)
            self.hub.broadcast(snackbar_message)

            return

        self.data_collection[label] = newcube

        snackbar_message = SnackbarMessage(
            f"Data set '{self._selected_data.label}' smoothed successfully.",
            color="success",
            sender=self)
        self.hub.broadcast(snackbar_message)
Пример #16
0
def get_gaussian_psf_template(pixel_fwhm=3., nbin=5, normalization='max'):
    nc = 25
    psfnew = Gaussian2DKernel((pixel_fwhm / 2.355) * nbin,
                              x_size=125,
                              y_size=125).array.astype(np.float32)

    if normalization == 'max':
        print('Normalizing PSF by kernel maximum')
        psfnew /= np.max(psfnew)
        psfnew /= 4 * np.pi * (pixel_fwhm / 2.355)**2
    else:
        print('Normalizing PSF by kernel sum')
        psfnew *= nc
    cf = psf_poly_fit(psfnew, nbin=nbin)
    return psfnew, cf, nc, nbin
Пример #17
0
def test_image():
    # Test dataset parameters
    x_size_kernel, y_size_kernel = (11, 11)
    x_size_image, y_size_image = (31, 31)
    total_excess = 100
    total_background = 1000
    ones = np.ones((x_size_image, y_size_image))

    # Create test dataset
    kernel = Gaussian2DKernel(3, x_size=x_size_kernel,
                              y_size=y_size_kernel).array
    excess = total_excess * Gaussian2DKernel(
        3, x_size=x_size_image, y_size=y_size_image).array
    background = total_background * ones / ones.sum()
    counts = excess + background
    images = dict(counts=counts, background=background)

    probability = matched_filter.probability_image(images, kernel)
    # TODO: try to get a verified result
    assert_allclose(probability.max(), 0.48409238192500076)

    significance = matched_filter.significance_image(images, kernel)
    # TODO: try to get a verified result
    assert_allclose(significance.max(), 7.2493488182450569)
Пример #18
0
def detect_sources(pattern):# extracts the light sources from the image (basing on sigma, FWHM, thrsholds...) 
    rot = rotate_img(pattern)
    threshold = detect_threshold(rot, nsigma=2.)
    sigma = 3.0 * gaussian_fwhm_to_sigma  # FWHM = 3.
    kernel = Gaussian2DKernel(sigma, x_size=3, y_size=3)
    kernel.normalize()
    mean, median, std = sigma_clipped_stats(rot, sigma=3)
    daofind = DAOStarFinder(fwhm=3.0, threshold=5.*std)
    sources = daofind(rot - median)
    for col in sources.colnames:
        sources[col].info.format = '%.8g'  # for consistent table output
   # Pixel coordinates of the sources
    x1 = np.array(sources['xcentroid'])
    y1 = np.array(sources['ycentroid'])
    return(x1,y1)
Пример #19
0
    def test_to_sunpy_map_invalid_pixel_size(self):
        m = n = 32
        u = generate_uv(m)
        v = generate_uv(m)
        u, v = np.meshgrid(u, v)
        uv = np.array([u, v]).reshape(2, m * n) / unit.arcsec

        header = {'crval1': 0, 'crval2': 0, 'cdelt1': 1, 'cdelt2': 1}
        data = Gaussian2DKernel(stddev=2, x_size=n, y_size=m).array
        mp = Map((data, header))

        vis = Visibility.from_map(mp, uv)

        with pytest.raises(ValueError):
            vis.to_map((m, n), pixel_size=[1, 2, 3] * unit.arcsec)
Пример #20
0
def test_compute_ts_map_downsampled(input_maps):
    """Minimal test of compute_ts_image"""
    kernel = Gaussian2DKernel(2.5)

    ts_estimator = TSMapEstimator(method='root brentq',
                                  n_jobs=4,
                                  error_method='conf',
                                  ul_method='conf')
    result = ts_estimator.run(input_maps, kernel=kernel, downsampling_factor=2)

    assert_allclose(result['ts'].data[99, 99], 1675.28, rtol=1e-2)
    assert_allclose(result['niter'].data[99, 99], 7)
    assert_allclose(result['flux'].data[99, 99], 1.02e-09, rtol=1e-2)
    assert_allclose(result['flux_err'].data[99, 99], 3.84e-11, rtol=1e-2)
    assert_allclose(result['flux_ul'].data[99, 99], 1.10e-09, rtol=1e-2)
Пример #21
0
 def test_filtering(self):
     from astropy.convolution import Gaussian2DKernel
     FWHM2SIGMA = 1.0 / (2.0 * np.sqrt(2.0 * np.log(2.0)))
     filter_kernel = Gaussian2DKernel(2.*FWHM2SIGMA, x_size=3, y_size=3)
     error = np.sqrt(IMAGE)
     props1 = source_properties(IMAGE, SEGM, error=error)
     props2 = source_properties(IMAGE, SEGM, error=error,
                                filter_kernel=filter_kernel.array)
     p1, p2 = props1[0], props2[0]
     keys = ['source_sum', 'source_sum_err']
     for key in keys:
         assert p1[key] == p2[key]
     keys = ['semimajor_axis_sigma', 'semiminor_axis_sigma']
     for key in keys:
         assert p1[key] != p2[key]
Пример #22
0
def get_kernel(res_t, res_c, pix_c):
    """Get smoothing kernel"""

    fwhm_factor = np.sqrt(8 * np.log(2))
    gaussian_width = ((res_t**2 - res_c**2)**0.5 / pix_c / fwhm_factor)

    print("[INFO] Current pixel size of %0.1f arcsec" % (pix_c))
    print("[INFO] Current resolution of %0.1f arcsec" % (res_c))
    print("[INFO] Target resolution of %0.1f arcsec" % (res_t))
    print("[INFO] Smoothing with gaussian of %0.1f arcsec" %
          (gaussian_width * pix_c * fwhm_factor))

    kernel = Gaussian2DKernel(gaussian_width)

    return kernel
Пример #23
0
def convolveImages(HSTImageObject,radioImageObject):
	FWHMconst = 2.355
	fwhmHSTArcSec = 0.18 

	sigmaHSTPixInALMA = (fwhmHSTArcSec/FWHMconst)/(radioImageObject.pixScaleArcSec)
	sigmaHSTPixInHST = (fwhmHSTArcSec/FWHMconst)/(HSTImageObject.pixScaleArcSec)

	sigmaMajALMAPixInHST = (radioImageObject.bmajArcSec/FWHMconst)/HSTImageObject.pixScaleArcSec
	sigmaMinALMAPixInHST = (radioImageObject.bminArcSec/FWHMconst)/HSTImageObject.pixScaleArcSec
	thetaALMADegree = radioImageObject.bpa

	sigmaMajALMAPixInALMA = (radioImageObject.bmajArcSec/FWHMconst)/radioImageObject.pixScaleArcSec
	sigmaMinALMAPixInALMA = (radioImageObject.bmajArcSec/FWHMconst)/radioImageObject.pixScaleArcSec

	beamALMAInHST = Gaussian2DKernel(x_stddev = sigmaMajALMAPixInHST, y_stddev=sigmaMinALMAPixInHST, theta = ((thetaALMADegree +90) * np.pi)/180,x_size = HSTImageObject.imageSize[0],y_size = HSTImageObject.imageSize[1])
	beamALMAInALMA= Gaussian2DKernel(x_stddev = sigmaMajALMAPixInALMA, y_stddev=sigmaMinALMAPixInALMA, theta = ((thetaALMADegree +90) * np.pi)/180,x_size = radioImageObject.imageSize[0],y_size = radioImageObject.imageSize[1])
	
	psfHSTInALMA = Gaussian2DKernel(x_stddev = sigmaHSTPixInALMA, y_stddev=sigmaHSTPixInALMA, theta = 0, x_size = radioImageObject.imageSize[0], y_size = radioImageObject.imageSize[1])
	psfHSTInHST = Gaussian2DKernel(x_stddev = sigmaHSTPixInHST, y_stddev=sigmaHSTPixInHST, theta = 0, x_size = HSTImageObject.imageSize[0], y_size = HSTImageObject.imageSize[1] )

	convolvedUV = convolve_fft(HSTImageObject.data,beamALMAInHST,allow_huge=True)
	convolvedALMA = convolve_fft(radioImageObject.data,psfHSTInALMA,allow_huge=True)

	return convolvedUV, convolvedALMA
Пример #24
0
def gaussian_deriv_kernel(axis=0, stddev=3.0, oned=False):
    if oned:
        gauss = Gaussian1DKernel(stddev)
    else:
        gauss = Gaussian2DKernel(stddev)
    x = np.linspace(0, gauss.shape[axis] - 1, gauss.shape[axis])
    dkernel = deriv_central(gauss.array, x, axis=axis)
    if not oned:
        if axis == 0:
            dkernel = dkernel[:, 1:-1]
        elif axis == 1:
            dkernel = dkernel[1:-1, :]
        return dkernel / abs(dkernel).sum()
    else:
        return dkernel
Пример #25
0
def restore_cube(model: Image, psf: Image, residual=None, **kwargs) -> Image:
    """ Restore the model image to the residuals

    :params psf: Input PSF
    :return: restored image

    """
    assert isinstance(model, Image), "Type is %s" % (type(model))
    assert isinstance(psf, Image), "Type is %s" % (type(psf))
    assert residual is None or isinstance(
        residual, Image), "Type is %s" % (type(residual))

    restored = copy_image(model)

    npixel = psf.data.shape[3]
    sl = slice(npixel // 2 - 7, npixel // 2 + 8)

    size = get_parameter(kwargs, "psfwidth", None)

    if size is None:
        # isotropic at the moment!
        try:
            fit = fit_2dgaussian(psf.data[0, 0, sl, sl])
            if fit.x_stddev <= 0.0 or fit.y_stddev <= 0.0:
                log.debug(
                    'restore_cube: error in fitting to psf, using 1 pixel stddev'
                )
                size = 1.0
            else:
                size = max(fit.x_stddev, fit.y_stddev)
                log.debug('restore_cube: psfwidth = %s' % (size))
        except:
            log.debug(
                'restore_cube: warning in fit to psf, using 1 pixel stddev')
            size = 1.0
    else:
        log.debug('restore_cube: Using specified psfwidth = %s' % (size))

    # By convention, we normalise the peak not the integral so this is the volume of the Gaussian
    norm = 2.0 * numpy.pi * size**2
    gk = Gaussian2DKernel(size)
    for chan in range(model.shape[0]):
        for pol in range(model.shape[1]):
            restored.data[chan, pol, :, :] = norm * convolve(
                model.data[chan, pol, :, :], gk, normalize_kernel=False)
    if residual is not None:
        restored.data += residual.data
    return restored
Пример #26
0
def convolved_grid(N1d: int = 16,
                   border: int = 64,
                   size: int = 1024,
                   kernel: Union[Kernel2D, None] = Gaussian2DKernel(x_stddev=1, x_size=201, y_size=201),
                   perturbation: float = 0.,
                   seed: int = 1000) -> Tuple[np.ndarray, Table]:
    """
    Place point sources on a regular image grid and convolve with a kernel to simulate PSF.
    No noise, distortion etc.

    :param N1d:  Grid of N1d x N1d Stars will be generated
    :param border: how many pixels on the edge to leave empty
    :param kernel: What to convolve the point sources with
    :param perturbation: random uniform offset to star positions
    :param seed: RNG initializer
    :return: image, input catalogue
    """
    # Kernel should always be an odd image or else we introduce some shift in the image
    np.random.seed(seed)

    data = np.zeros((size, size))

    idx_float = np.linspace(0 + border, size - border, N1d)
    x_float = np.tile(idx_float, reps=(N1d, 1))
    y_float = x_float.T.copy()  # just a view of x_float
    # these two modify same array...
    x_float += np.random.uniform(0, perturbation, x_float.shape)
    y_float += np.random.uniform(0, perturbation, y_float.shape)

    x, x_frac = np.divmod(x_float, 1)
    y, y_frac = np.divmod(y_float, 1)
    x, y = x.astype(int), y.astype(int)
    # Y U so ugly sometimes PEP8?
    data[y, x] = (1 - x_frac) * (1 - y_frac)
    # noinspection PyRedundantParentheses
    data[y + 1, x] = (1 - x_frac) * (y_frac)
    # noinspection PyRedundantParentheses
    data[y, x + 1] = (x_frac) * (1 - y_frac)
    data[y + 1, x + 1] = y_frac * x_frac

    if kernel is not None:
        # noinspection PyTypeChecker
        data = convolve_fft(data, kernel)
    # TODO the no-zeros seem like an awful hack
    data = data / np.max(data) + 0.001  # normalize and add tiny offset to have no zeros in data
    fluxes = np.ones(x.size)
    table = Table((x_float.ravel(), y_float.ravel(), fluxes, flux_to_magnitude(fluxes)), names=COLUMN_NAMES)
    return data, table
Пример #27
0
def replacenans_2d_interpolate(data):
    """Interpolate over nans within array using astropy interpolate_replace_nans function
    
        Input: 
            data = np.array of data values
        Output: 
            data_out = np.array of data value with no nan values"""

    # We smooth with a Gaussian kernel with x_stddev=1 (and y_stddev=1)
    # It is a 9x9 array
    kernel = Gaussian2DKernel(x_stddev=1)

    # create a "fixed" image with NaNs replaced by interpolated values
    data_out = interpolate_replace_nans(data, kernel)

    return data_out
Пример #28
0
def make_significance_image():
    """Make significance = sqrt(TS) image using a Gaussian kernel.
    """
    gauss_kernel_sigma = 5  # pix
    header = fits.getheader(REF_IMAGE)
    counts = fits.getdata(COUNTS_IMAGE)
    background = fits.getdata(BACKGROUND_IMAGE)
    exposure = 1e11 * np.ones_like(counts, dtype='float32')
    kernel = Gaussian2DKernel(gauss_kernel_sigma)

    print('Computing TS image ...')
    result = compute_ts_map(counts, background, exposure, kernel)
    print('TS map computation took: {}'.format(result.runtime))

    print('Writing {}'.format(TS_IMAGES))
    result.write(TS_IMAGES, header=header, overwrite=True)
Пример #29
0
    def _daofind_kernel(self):
        """
        The DAOFind kernel, a 2D circular Gaussian normalized to have
        zero sum.
        """
        size = self._kernel_size
        kernel = Gaussian2DKernel(self.kernel_sigma, x_size=size,
                                  y_size=size).array
        kernel /= np.max(kernel)
        kernel *= self._kernel_mask

        # normalize the kernel to zero sum
        npixels = self._kernel_mask.sum()
        denom = np.sum(kernel**2) - (np.sum(kernel)**2 / npixels)
        return (((kernel - (kernel.sum() / npixels)) / denom) *
                self._kernel_mask)
Пример #30
0
    def test_dftmap_decentered(self, m, n, pos):
        data = Gaussian2DKernel(stddev=2, x_size=m, y_size=n).array
        data2 = shift(data, (pos[1], pos[0]))

        ut = (np.arange(m) - m / 2 + 0.5) * (1 / m)
        vt = -1.0 * (np.arange(n) - n / 2 + 0.5) * (1 / n)
        u, v = np.meshgrid(ut, vt)
        uv = np.array([u, v]).reshape(2, m * n)
        dft_data = Visibility.dft_map(data2, uv, center=pos)
        idft_data = Visibility.idft_map(dft_data, np.zeros((m, n)), uv)
        assert np.allclose(data, idft_data)

        dft_data2 = Visibility.dft_map(data, uv)
        idft_data2 = Visibility.idft_map(dft_data2, np.zeros((m, n)), uv,
                                         pos)
        assert np.allclose(idft_data2, data2)