Esempio n. 1
0
def shell_model(major=50, minor=40, ratio=1.25, amp=0.5, pa=0, xcent=0,
                ycent=0, ring_large=None, ring_small=[40, 32]):
    '''
    Difference of Gaussians with the middle clipped to the background.
    '''

    gauss_model = \
        Gaussian2D(shell_max(amp, minor, ratio),
                   xcent, ycent, ratio*major, ratio*minor, theta=pa) - \
        Gaussian2D(shell_max(amp, minor, ratio),
                   xcent, ycent, major, minor, theta=pa)

    if ring_large is None and ring_small is None:
        return gauss_model
    elif ring_small is None and ring_large is not None:
        ring = Ellipse2D(True, xcent, ycent, ring_large[0], ring_large[1], pa)
    elif ring_small is not None and ring_large is None:
        ring = InvertedEllipse2D(True, xcent, ycent, ring_small[0],
                                 ring_small[1], pa)
    else:
        ring = \
            Ellipse2D(True, xcent, ycent, ring_large[0], ring_large[1], pa) - \
            Ellipse2D(True, xcent, ycent, ring_small[0], ring_small[1], pa)

    return gauss_model * ring
Esempio n. 2
0
def test_bounding_box():
    g = Gaussian2D() + Gaussian2D(2, .5, .1, 2, 3, 0)
    g.bounding_box = ((0, 1), (0, .5))
    y, x = np.mgrid[0:10, 0:10]
    y = y / 3.
    x = x / 3.
    val = g(x, y, with_bounding_box=True)
    compare = np.array([
        [2.93738984, 2.93792011, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [2.87857153, 2.88188761, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [2.70492922, 2.71529265, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [2.45969972, 2.47912103, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan],
        [np.nan, np.nan, np.nan, np.nan, np.nan,
         np.nan, np.nan, np.nan, np.nan, np.nan]])
    mask = ~np.isnan(val)
    assert_allclose(val[mask], compare[mask])
    val2 = g(x+2, y+2, with_bounding_box=True)
    assert np.isnan(val2).sum() == 100
Esempio n. 3
0
def prf_model(request):
    # use this instead of pytest.mark.parameterize as we use scipy and
    # it still calls that even if not HAS_SCIPY is set...
    prfs = [
        IntegratedGaussianPRF(sigma=1.2),
        Gaussian2D(x_stddev=2),
        prepare_psf_model(Gaussian2D(x_stddev=2), renormalize_psf=False)
    ]
    return prfs[request.param]
Esempio n. 4
0
    def test_deblend_multiple_sources_with_neighbor(self):
        g1 = Gaussian2D(100, 50, 50, 20, 5, theta=45)
        g2 = Gaussian2D(100, 35, 50, 5, 5)
        g3 = Gaussian2D(100, 60, 20, 5, 5)

        x = self.x
        y = self.y
        data = (g1 + g2 + g3)(x, y)
        segm = detect_sources(data, self.threshold, self.npixels)
        result = deblend_sources(data, segm, self.npixels)
        assert result.nlabels == 3
Esempio n. 5
0
 def setup_class(self):
     g1 = Gaussian2D(100, 50, 50, 5, 5)
     g2 = Gaussian2D(100, 35, 50, 5, 5)
     g3 = Gaussian2D(30, 70, 50, 5, 5)
     y, x = np.mgrid[0:100, 0:100]
     self.x = x
     self.y = y
     self.data = g1(x, y) + g2(x, y)
     self.data3 = self.data + g3(x, y)
     self.threshold = 10
     self.npixels = 5
     self.segm = detect_sources(self.data, self.threshold, self.npixels)
     self.segm3 = detect_sources(self.data3, self.threshold, self.npixels)
def test_fix_inputs():
    g1 = Gaussian2D(1, 0, 0, 1, 2)
    g2 = Gaussian2D(1.5, .5, -.2, .5, .3)
    sg1_1 = fix_inputs(g1, {1: 0})
    assert_allclose(sg1_1(0), g1(0, 0))
    assert_allclose(sg1_1([0, 1, 3]), g1([0, 1, 3], [0, 0, 0]))
    sg1_2 = fix_inputs(g1, {'x': 1})
    assert_allclose(sg1_2(1.5), g1(1, 1.5))
    gg1 = g1 & g2
    sgg1_1 = fix_inputs(gg1, {1: 0.1, 3: 0.2})
    assert_allclose(sgg1_1(0, 0), gg1(0, 0.1, 0, 0.2))
    sgg1_2 = fix_inputs(gg1, {'x0': -.1, 2: .1})
    assert_allclose(sgg1_2(1, 1), gg1(-0.1, 1, 0.1, 1))
    assert_allclose(sgg1_2(y0=1, y1=1), gg1(-0.1, 1, 0.1, 1))
Esempio n. 7
0
    def test_deblend_label_assignment(self):
        """
        Regression test to ensure newly-deblended labels are unique.
        """

        y, x = np.mgrid[0:201, 0:101]
        y0a = 35
        y1a = 60
        yshift = 100
        y0b = y0a + yshift
        y1b = y1a + yshift
        data = (Gaussian2D(80, 36, y0a, 8, 8)(x, y) +
                Gaussian2D(71, 58, y1a, 8, 8)(x, y) +
                Gaussian2D(30, 36, y1a, 7, 7)(x, y) +
                Gaussian2D(30, 58, y0a, 7, 7)(x, y) +
                Gaussian2D(80, 36, y0b, 8, 8)(x, y) +
                Gaussian2D(71, 58, y1b, 8, 8)(x, y) +
                Gaussian2D(30, 36, y1b, 7, 7)(x, y) +
                Gaussian2D(30, 58, y0b, 7, 7)(x, y))

        npixels = 5
        segm1 = detect_sources(data, 5.0, npixels)
        segm2 = deblend_sources(data,
                                segm1,
                                npixels,
                                mode='linear',
                                nlevels=32,
                                contrast=0.3)
        assert segm2.nlabels == 4
Esempio n. 8
0
 def evaluate(x, y, amplitude1, x_stddev1, y_stddev1, amplitude2, x_stddev2,
              y_stddev2, amplitude3, x_stddev3, y_stddev3, x_mean, y_mean,
              theta, offset):
     g1 = Gaussian2D(amplitude=amplitude1,
                     x_mean=x_mean,
                     y_mean=y_mean,
                     x_stddev=x_stddev1,
                     y_stddev=y_stddev1,
                     theta=theta)
     g1.amplitude.min = 0
     g2 = Gaussian2D(amplitude=amplitude2,
                     x_mean=x_mean,
                     y_mean=y_mean,
                     x_stddev=x_stddev2,
                     y_stddev=y_stddev2,
                     theta=theta)
     g2.amplitude.min = 0
     g3 = Gaussian2D(amplitude=amplitude3,
                     x_mean=x_mean,
                     y_mean=y_mean,
                     x_stddev=x_stddev3,
                     y_stddev=y_stddev3,
                     theta=theta)
     g3.amplitude.min = 0
     y1 = g1.evaluate(x,
                      y,
                      amplitude=amplitude1,
                      x_mean=x_mean,
                      y_mean=y_mean,
                      x_stddev=x_stddev1,
                      y_stddev=y_stddev1,
                      theta=theta)
     y2 = g2.evaluate(x,
                      y,
                      amplitude=amplitude2,
                      x_mean=x_mean,
                      y_mean=y_mean,
                      x_stddev=x_stddev2,
                      y_stddev=y_stddev2,
                      theta=theta)
     y3 = g3.evaluate(x,
                      y,
                      amplitude=amplitude3,
                      x_mean=x_mean,
                      y_mean=y_mean,
                      x_stddev=x_stddev3,
                      y_stddev=y_stddev3,
                      theta=theta)
     return y1 + y2 + y3 + offset
Esempio n. 9
0
    def spatial_model(self, emin=1 * u.TeV, emax=10 * u.TeV):
        """
        Source spatial model.
        """
        d = self.data
        morph_type = d['morph_type']
        pars = {}
        flux = self.spectral_model.integral(emin, emax)

        glon = Angle(d['glon']).wrap_at('180d')
        glat = Angle(d['glat']).wrap_at('180d')

        if morph_type == 'gauss':
            pars['x_mean'] = glon.value
            pars['y_mean'] = glat.value
            pars['x_stddev'] = d['morph_sigma'].value
            pars['y_stddev'] = d['morph_sigma'].value
            if not np.isnan(d['morph_sigma2']):
                pars['y_stddev'] = d['morph_sigma2'].value
            if not np.isnan(d['morph_pa']):
                # TODO: handle reference frame for rotation angle
                pars['theta'] = Angle(d['morph_pa'], 'deg').rad
            ampl = flux.to('cm-2 s-1').value
            pars['amplitude'] = ampl * 1 / (2 * np.pi * pars['x_stddev'] *
                                            pars['y_stddev'])
            return Gaussian2D(**pars)
        elif morph_type == 'shell':
            pars['amplitude'] = flux.to('cm-2 s-1').value
            pars['x_0'] = glon.value
            pars['y_0'] = glat.value
            pars['r_in'] = d['morph_sigma'].value * 0.8
            pars['width'] = 0.2 * d['morph_sigma'].value
            return Shell2D(**pars)
        elif morph_type == 'point':
            DEFAULT_POINT_EXTENSION = Angle('0.05 deg')
            pars['amplitude'] = flux.to('cm-2 s-1').value
            pars['x_mean'] = glon.value
            pars['y_mean'] = glat.value
            pars['x_stddev'] = DEFAULT_POINT_EXTENSION
            pars['y_stddev'] = DEFAULT_POINT_EXTENSION
            # TODO: make Delta2D work and use it here.
            return Gaussian2D(**pars)
        elif morph_type == 'none':
            raise NoDataAvailableError('No spatial model available: {}'.format(
                self.name))
        else:
            raise NotImplementedError(
                'Unknown spatial model: {!r}'.format(morph_type))
Esempio n. 10
0
    def _setup_model(self):
        """Setup a list of source models from an ``input_sherpa.cfg`` config file.
        """
        self.source_models = []

        # Read config file
        from astropy.extern.configobj.configobj import ConfigObj
        cfg = ConfigObj(self.cfg_file, file_error=True)

        # Set up model
        from astropy.modeling.models import Gaussian2D

        for source in cfg.keys():
            # TODO: Add other source models
            if cfg[source]['Type'] != 'NormGaussian':
                raise ValueError(
                    'So far only normgauss2d models can be handled.')
            sigma = gaussian_fwhm_to_sigma * float(cfg[source]['fwhm'])
            ampl = float(cfg[source]['ampl']) * 1 / (2 * np.pi * sigma**2)
            xpos = float(cfg[source]['xpos']) - 1
            ypos = float(cfg[source]['ypos']) - 1
            source_model = Gaussian2D(ampl,
                                      xpos,
                                      ypos,
                                      x_stddev=sigma,
                                      y_stddev=sigma)
            self.source_models.append(source_model)
Esempio n. 11
0
    def __init__(self,
                 stddev_maj,
                 stddev_min,
                 position_angle,
                 support_scaling=8,
                 **kwargs):
        self._model = Gaussian2D(1. / (2 * np.pi * stddev_maj * stddev_min),
                                 0,
                                 0,
                                 x_stddev=stddev_maj,
                                 y_stddev=stddev_min,
                                 theta=position_angle)

        try:
            from astropy.modeling.utils import ellipse_extent
        except ImportError:
            raise NotImplementedError("EllipticalGaussian2DKernel requires"
                                      " astropy 1.1b1 or greater.")

        max_extent = \
            np.max(ellipse_extent(stddev_maj, stddev_min, position_angle))
        self._default_size = \
            _round_up_to_odd_integer(support_scaling * 2 * max_extent)
        super(EllipticalGaussian2DKernel, self).__init__(**kwargs)
        self._truncation = np.abs(1. - 1 / self._array.sum())
Esempio n. 12
0
def test_image_model_oversampling():
    gm = Gaussian2D(x_stddev=3, y_stddev=3)

    osa = 3  #oversampling factor
    xg, yg = np.mgrid[-3:3.00001:(1 / osa), -3:3.00001:(1 / osa)]

    im = gm(xg, yg)
    assert im.shape[
        0] > 7  # should be obvious, but at least ensures the test is right
    imod_oversampled = FittableImageModel(im, oversampling=osa)

    assert np.allclose(imod_oversampled(0, 0), gm(0, 0))
    assert np.allclose(imod_oversampled(1, 1), gm(1, 1))
    assert np.allclose(imod_oversampled(-2, 1), gm(-2, 1))
    assert np.allclose(imod_oversampled(0.5, 0.5), gm(0.5, 0.5), rtol=.001)
    assert np.allclose(imod_oversampled(-0.5, 1.75), gm(-0.5, 1.75), rtol=.001)

    imod_wrongsampled = FittableImageModel(im)

    # now make sure that all *fails* without the oversampling
    assert np.allclose(imod_wrongsampled(0, 0),
                       gm(0, 0))  # except for at the origin
    assert not np.allclose(imod_wrongsampled(1, 1), gm(1, 1))
    assert not np.allclose(imod_wrongsampled(-2, 1), gm(-2, 1))
    assert not np.allclose(
        imod_wrongsampled(0.5, 0.5), gm(0.5, 0.5), rtol=.001)
    assert not np.allclose(
        imod_wrongsampled(-0.5, 1.75), gm(-0.5, 1.75), rtol=.001)
Esempio n. 13
0
def test_image_model():
    gm = Gaussian2D(x_stddev=3, y_stddev=3)
    xg, yg = np.mgrid[-2:3, -2:3]

    imod_nonorm = FittableImageModel(gm(xg, yg))
    assert np.allclose(imod_nonorm(0, 0), gm(0, 0))
    assert np.allclose(imod_nonorm(1, 1), gm(1, 1))
    assert np.allclose(imod_nonorm(-2, 1), gm(-2, 1))

    # now sub-pixel should *not* match, but be reasonably close
    assert not np.allclose(imod_nonorm(0.5, 0.5), gm(0.5, 0.5))
    # in this case good to ~0.1% seems to be fine
    assert np.allclose(imod_nonorm(0.5, 0.5), gm(0.5, 0.5), rtol=.001)
    assert np.allclose(imod_nonorm(-0.5, 1.75), gm(-0.5, 1.75), rtol=.001)

    imod_norm = FittableImageModel(gm(xg, yg), normalize=True)
    assert not np.allclose(imod_norm(0, 0), gm(0, 0))
    assert np.allclose(np.sum(imod_norm(xg, yg)), 1)

    imod_norm2 = FittableImageModel(gm(xg, yg),
                                    normalize=True,
                                    normalization_correction=2)
    assert not np.allclose(imod_norm2(0, 0), gm(0, 0))
    assert np.allclose(imod_norm(0, 0), imod_norm2(0, 0) * 2)
    assert np.allclose(np.sum(imod_norm2(xg, yg)), 0.5)
Esempio n. 14
0
def _fit_2dgaussian(data):
    """
    Fit a 2d Gaussian to data.

    Written as a replace for functionality that was removed from
    photutils.

    Keep this private so we don't have to support it....

    Copy/pasted from
    https://github.com/astropy/photutils/pull/1064/files#diff-9e64908ff7ac552845b4831870a749f397d73c681d218267bd9087c7757e6dd4R285
    """
    props = data_properties(data - np.min(data))

    init_const = 0.  # subtracted data minimum above
    init_amplitude = np.ptp(data)

    g_init = (Const2D(init_const) +
              Gaussian2D(amplitude=init_amplitude,
                         x_mean=props.xcentroid,
                         y_mean=props.ycentroid,
                         x_stddev=props.semimajor_sigma.value,
                         y_stddev=props.semiminor_sigma.value,
                         theta=props.orientation.value))

    fitter = LevMarLSQFitter()
    y, x = np.indices(data.shape)
    gfit = fitter(g_init, x, y, data)

    return gfit
Esempio n. 15
0
def test_centroids_nan_withmask(use_mask):
    xc_ref = 24.7
    yc_ref = 25.2
    model = Gaussian2D(2.4, xc_ref, yc_ref, x_stddev=5.0, y_stddev=5.0)
    y, x = np.mgrid[0:50, 0:50]
    data = model(x, y)
    data[20, :] = np.nan
    if use_mask:
        mask = np.zeros(data.shape, dtype=bool)
        mask[20, :] = True
        nwarn = 0
    else:
        mask = None
        nwarn = 1

    with warnings.catch_warnings(record=True) as warnlist:
        xc, yc = centroid_1dg(data, mask=mask)
        assert_allclose([xc, yc], [xc_ref, yc_ref], rtol=0, atol=1.e-3)
    assert len(warnlist) == nwarn
    if nwarn == 1:
        assert issubclass(warnlist[0].category, AstropyUserWarning)

    with warnings.catch_warnings(record=True) as warnlist:
        xc, yc = centroid_2dg(data, mask=mask)
        assert_allclose([xc, yc], [xc_ref, yc_ref], rtol=0, atol=1.e-3)
    assert len(warnlist) == nwarn
    if nwarn == 1:
        assert issubclass(warnlist[0].category, AstropyUserWarning)
Esempio n. 16
0
    def __init__(self, function, shape, **kwargs):

        if not isinstance(shape, tuple):
            if isinstance(shape, int):
                shape = (shape, shape)
        self.shape = shape
        self.center = ((self.shape[0] + 1) / 2, (self.shape[1] + 1) / 2)

        if function == 'Gaussian':
            if 'radius' in kwargs:
                # Copying the radius keyword argument into the proper Gaussian2D keywords
                kwargs['x_stddev'] = kwargs['radius']
                kwargs['y_stddev'] = kwargs['radius']
                del kwargs['radius']
            self.model = Gaussian2D(x_mean=self.center[0],
                                    y_mean=self.center[1],
                                    **kwargs)
        elif function == 'Airy':
            self.model = AiryDisk2D(x_0=self.center[0],
                                    y_0=self.center[1],
                                    **kwargs)
        else:
            raise ValueError(
                "Function value <{}> for Apodizer class is not recognized!".
                format(function))
Esempio n. 17
0
 def _make_gaussian_sources_image(self, table_bgstars, nsigma=6):
     "the one from photutils was too slow"
     image = np.zeros(self.image_shape_pix)
     for i in range(self.nstars_in_image):
         amplitude = table_bgstars['flux'][i] / (
             2. * np.pi * table_bgstars['x_stddev'][i] *
             table_bgstars['y_stddev'][i])
         x_mean = table_bgstars['x_mean'][i]
         y_mean = table_bgstars['y_mean'][i]
         x_stddev = table_bgstars['x_stddev'][i]
         y_stddev = table_bgstars['y_stddev'][i]
         gmodel = Gaussian2D(amplitude=amplitude,
                             x_mean=0,
                             y_mean=0,
                             x_stddev=x_stddev,
                             y_stddev=y_stddev,
                             theta=table_bgstars['theta'][i])
         x_range = self._get_range(mean_val=x_mean,
                                   sigma=x_stddev,
                                   nsigma=nsigma,
                                   axis='x')
         y_range = self._get_range(mean_val=y_mean,
                                   sigma=y_stddev,
                                   nsigma=nsigma,
                                   axis='y')
         dmodel = discretize_model(model=gmodel,
                                   x_range=tuple(x_range - x_mean),
                                   y_range=tuple(y_range - y_mean),
                                   mode='oversample',
                                   factor=self.psf_oversample)
         image[int(x_range[0]):int(x_range[1]),
               int(y_range[0]):int(y_range[1])] += dmodel.T
     return image
Esempio n. 18
0
def test_fix_inputs_invalid():
    g1 = Gaussian2D(1, 0, 0, 1, 2)
    with pytest.raises(ValueError):
        fix_inputs(g1, {'x0': 0, 0: 0})

    with pytest.raises(ValueError):
        fix_inputs(g1, (0, 1))

    with pytest.raises(ValueError):
        fix_inputs(g1, {3: 2})

    with pytest.raises(ValueError):
        fix_inputs(g1, {np.int32(3): 2})

    with pytest.raises(ValueError):
        fix_inputs(g1, {np.int64(3): 2})

    with pytest.raises(ValueError):
        fix_inputs(g1, {'w': 2})

    with pytest.raises(ModelDefinitionError):
        CompoundModel('#', g1, g1)

    with pytest.raises(ValueError):
        gg1 = fix_inputs(g1, {0: 1})
        gg1(2, y=2)

    with pytest.raises(ValueError):
        gg1 = fix_inputs(g1, {np.int32(0): 1})
        gg1(2, y=2)

    with pytest.raises(ValueError):
        gg1 = fix_inputs(g1, {np.int64(0): 1})
        gg1(2, y=2)
Esempio n. 19
0
    def __init__(self, type, shape=None, **kwargs):

        # Store input
        self.type = type
        self.shape = shape

        # Derive center of model shape
        if self.shape is None:
            self.center = (0, 0)
        else:
            self.center = ((self.shape[0] + 1) / 2, (self.shape[1] + 1) / 2)

        # Initialize model
        if 'gauss' in self.type.lower():
            if 'radius' in kwargs:
                # Copying the radius keyword argument into the proper Gaussian2D keywords
                kwargs['x_stddev'] = kwargs['radius']
                kwargs['y_stddev'] = kwargs['radius']
                del kwargs['radius']
            self.model = Gaussian2D(x_mean=self.center[0],
                                    y_mean=self.center[1],
                                    **kwargs)

        elif 'airy' in self.type.lower():
            self.model = AiryDisk2D(x_0=self.center[0],
                                    y_0=self.center[1],
                                    **kwargs)

        else:
            raise SpecklepyValueError('PSFModel',
                                      argname='type',
                                      argvalue=type,
                                      expected="either 'Gaussian' or 'Airy'")
Esempio n. 20
0
 def gaussian_psf(self, xstd, ystd, theta, boxsize, scale):
     """
     Gaussian PSF profile image
     
     Parameters
     ----------
     xstd: float
         Standard deviation of the Gaussian in x before rotating by theta
     ystd: float
         Standard deviation of the Gaussian in y before rotating by theta
     theta: float
         Rotation angle in radians.
         The rotation angle increases counterclockwise
     boxsize: float
         Size of image on a side for Moffat profile
     scale: float
         Pixel scale for image
     
     Returns
     -------
     zarray: numpy 3d array
         An array with length 3 for the first axis: PSF image, xgrid, ygrid
     """
     M = Gaussian2D()
     M.x_stddev.value = xstd
     M.y_stddev.value = ystd
     M.theta.value = theta
     xl, xh = (0.0 - boxsize / 2.0, 0.0 + boxsize / 2.0 + scale)
     yl, yh = (0.0 - boxsize / 2.0, 0.0 + boxsize / 2.0 + scale)
     x, y = (np.arange(xl, xh, scale), np.arange(yl, yh, scale))
     xgrid, ygrid = np.meshgrid(x, y)
     zarray = np.array([M(xgrid, ygrid), xgrid, ygrid])
     zarray[0] /= zarray[0].sum()
     return zarray
Esempio n. 21
0
def add_gaussian_holes(array, nholes=100, rad_max=30, rad_min=10,
                       return_info=False, hole_level=None):
    ylim, xlim = array.shape

    yy, xx = np.mgrid[-ylim/2:ylim/2, -xlim/2:xlim/2]

    xcenters = np.random.random_integers(-(xlim/2-rad_max),
                                         high=xlim/2-rad_max, size=nholes)
    ycenters = np.random.random_integers(-(ylim/2-rad_max),
                                         high=ylim/2-rad_max, size=nholes)
    radii = np.random.random_integers(rad_min, rad_max, size=nholes)

    if hole_level is None:
        # Choose random hole bkg levels
        bkgs = np.random.uniform(0.5, 0.75, size=nholes)
    else:
        bkgs = np.array([hole_level] * nholes, dtype=np.int)

    for x, y, radius, amp in zip(xcenters, ycenters, radii, bkgs):

        gauss = Gaussian2D.evaluate(yy, xx,
                                    amp, x, y, radius, radius, 0.0)

        array -= gauss

    if return_info:
        return array, np.vstack([ycenters+ylim/2, xcenters+xlim/2, radii])

    return array
Esempio n. 22
0
def test_compound_evaluate_double_shift():
    x = np.linspace(-5, 5, 10)
    y = np.linspace(-5, 5, 10)

    m1 = Gaussian2D(1, 0, 0, 1, 1, 1)
    m2 = Shift(1)
    m3 = Shift(2)
    m = Gaussian2D(1, 0, 0, 1, 1, 1) & Shift(1) & Shift(2)
    assert_array_equal(
        m.evaluate(x, y, x - 10, y + 20, 1, 0, 0, 1, 1, 1, 1, 2),
        [
            m1.evaluate(x, y, 1, 0, 0, 1, 1, 1),
            m2.evaluate(x - 10, 1),
            m3.evaluate(y + 20, 2),
        ],
    )
Esempio n. 23
0
def test_centroids(x_std, y_std, theta):
    model = Gaussian2D(2.4,
                       XCEN,
                       YCEN,
                       x_stddev=x_std,
                       y_stddev=y_std,
                       theta=theta)
    y, x = np.mgrid[0:50, 0:47]
    data = model(x, y)
    xc, yc = centroid_1dg(data)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)
    xc, yc = centroid_2dg(data)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)

    # test with errors
    error = np.sqrt(data)
    xc, yc = centroid_1dg(data, error=error)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)
    xc, yc = centroid_2dg(data, error=error)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)

    # test with mask
    mask = np.zeros(data.shape, dtype=bool)
    data[10, 10] = 1.e5
    mask[10, 10] = True
    xc, yc = centroid_1dg(data, mask=mask)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)
    xc, yc = centroid_2dg(data, mask=mask)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)
Esempio n. 24
0
def create_model(model_name, amplitude, center, sigma):

    """
    This function ...
    :param model_name:
    :param amplitude:
    :param center:
    :param sigma:
    :return:
    """

    # 2D GAussian model
    if model_name == "gaussian":

        # Create the model
        model = Gaussian2D(amplitude=amplitude, x_mean=center.x, y_mean=center.y, x_stddev=sigma, y_stddev=sigma)

    # Airy disk model
    elif model_name == "airydisk":

        # Determine the radius
        radius = fitting.gaussian_sigma_to_airy_radius(sigma)

        # Create the model
        model = AiryDisk2D(amplitude=amplitude, x_0=center.x, y_0=center.y, radius=radius)

    # Invalid
    else: raise ValueError("Not a valid model")

    # Return the model
    return model
def test_indexing_on_instance():
    """Test indexing on compound model instances."""

    m = Gaussian1D(1, 0, 0.1) + Const1D(2)
    assert isinstance(m[0], Gaussian1D)
    assert isinstance(m[1], Const1D)
    assert m.param_names == ('amplitude_0', 'mean_0', 'stddev_0',
                             'amplitude_1')

    # Test parameter equivalence
    assert m[0].amplitude == 1 == m.amplitude_0
    assert m[0].mean == 0 == m.mean_0
    assert m[0].stddev == 0.1 == m.stddev_0
    assert m[1].amplitude == 2 == m.amplitude_1

    # Test that parameter value updates are symmetric between the compound
    # model and the submodel returned by indexing
    const = m[1]
    m.amplitude_1 = 42
    assert const.amplitude == 42
    const.amplitude = 137
    assert m.amplitude_1 == 137

    # Similar couple of tests, but now where the compound model was created
    # from model instances
    g = Gaussian1D(1, 2, 3, name='g')
    p = Polynomial1D(2, name='p')
    m = g + p
    assert m[0].name == 'g'
    assert m[1].name == 'p'
    assert m['g'].name == 'g'
    assert m['p'].name == 'p'

    poly = m[1]
    m.c0_1 = 12345
    assert poly.c0 == 12345
    poly.c1 = 6789
    assert m.c1_1 == 6789

    # Test negative indexing
    assert isinstance(m[-1], Polynomial1D)
    assert isinstance(m[-2], Gaussian1D)

    with pytest.raises(IndexError):
        m[42]

    with pytest.raises(IndexError):
        m['foobar']

    # Confirm index-by-name works with fix_inputs
    g = Gaussian2D(1, 2, 3, 4, 5, name='g')
    m = fix_inputs(g, {0: 1})
    assert m['g'].name == 'g'

    # Test string slicing
    A = Const1D(1.1, name='A')
    B = Const1D(2.1, name='B')
    C = Const1D(3.1, name='C')
    M = A + B * C
    assert_allclose(M['B':'C'](1), 6.510000000000001)
Esempio n. 26
0
def test_centroid_com_nan_withmask(use_mask):
    xc_ref = 24.7
    yc_ref = 25.2
    model = Gaussian2D(2.4, xc_ref, yc_ref, x_stddev=5.0, y_stddev=5.0)
    y, x = np.mgrid[0:50, 0:50]
    data = model(x, y)
    data[20, :] = np.nan
    if use_mask:
        mask = np.zeros(data.shape, dtype=bool)
        mask[20, :] = True
        nwarn = 0
        ctx = nullcontext()
    else:
        mask = None
        nwarn = 1
        ctx = pytest.warns(AstropyUserWarning,
                           match='Input data contains non-finite values')

    with ctx as warnlist:
        xc, yc = centroid_com(data, mask=mask)
    assert_allclose(xc, xc_ref, rtol=0, atol=1.e-3)
    assert yc > yc_ref
    if nwarn == 1:
        assert len(warnlist) == nwarn

    with pytest.warns(AstropyUserWarning,
                      match='Input data contains non-finite '
                      'values') as warnlist:
        xc, yc = centroid_quadratic(data, mask=mask)
    assert_allclose(xc, xc_ref, rtol=0, atol=0.15)
    assert len(warnlist) == 1
Esempio n. 27
0
def plot_gauss(x_loc, y_loc, S150, maj, min, PA):

    x_loc = int(round(x_loc))
    y_loc = int(round(y_loc))

    x_stddev = maj / (factor * reso * 3600.0)
    y_stddev = min / (factor * reso * 3600.0)

    gauss_func = Gaussian2D(amplitude=S150,
                            x_mean=0,
                            y_mean=0,
                            x_stddev=x_stddev,
                            y_stddev=y_stddev,
                            theta=pi / 2 + PA * (pi / 180.0))

    x_mesh, y_mesh = meshgrid(
        linspace(-edge_size, edge_size, edge_size * 2 + 1),
        linspace(-edge_size, edge_size, edge_size * 2 + 1))

    gauss = gauss_func(x_mesh, y_mesh)

    gauss *= S150 / gauss.sum()

    sky[-edge_size + y_loc:edge_size + 1 + y_loc,
        -edge_size + x_loc:edge_size + 1 + x_loc] += gauss
Esempio n. 28
0
def test_centroid_com(x_std, y_std, theta):
    model = Gaussian2D(2.4, XCEN, YCEN, x_stddev=x_std, y_stddev=y_std,
                       theta=theta)
    y, x = np.mgrid[0:50, 0:47]
    data = model(x, y)
    xc, yc = centroid_com(data)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)

    xc, yc = centroid_quadratic(data)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=0.015)

    # test with mask
    mask = np.zeros(data.shape, dtype=bool)
    data[10, 10] = 1.e5
    mask[10, 10] = True
    xc, yc = centroid_com(data, mask=mask)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=1.e-3)

    xc, yc = centroid_quadratic(data, mask=mask)
    assert_allclose((xc, yc), (XCEN, YCEN), rtol=0, atol=0.015)

    # test with oversampling
    for oversampling in [4, (4, 6)]:
        if not hasattr(oversampling, '__len__'):
            _oversampling = (oversampling, oversampling)
        else:
            _oversampling = oversampling
        xc, yc = centroid_com(data, mask=mask, oversampling=oversampling)

        desired = [XCEN / _oversampling[0], YCEN / _oversampling[1]]
        assert_allclose((xc, yc), desired, rtol=0, atol=1.e-3)
Esempio n. 29
0
    def evaluate(x, y, constant, amplitude, x_mean, y_mean, x_stddev, y_stddev,
                 theta):
        """Two dimensional Gaussian plus constant function."""

        model = Const2D(constant)(x, y) + Gaussian2D(
            amplitude, x_mean, y_mean, x_stddev, y_stddev, theta)(x, y)
        return model
Esempio n. 30
0
    def test_centroid_sources():
        theta = np.pi / 6.
        model = Gaussian2D(2.4, XCEN, YCEN, x_stddev=3.2, y_stddev=5.7,
                           theta=theta)
        y, x = np.mgrid[0:50, 0:47]
        data = model(x, y)
        error = np.ones(data.shape, dtype=float)
        mask = np.zeros(data.shape, dtype=bool)
        mask[10, 10] = True
        xpos = [25.]
        ypos = [26.]
        xc, yc = centroid_sources(data, xpos, ypos, box_size=21, mask=mask)
        assert_allclose(xc, (25.67,), atol=1e-1)
        assert_allclose(yc, (26.18,), atol=1e-1)

        xc, yc = centroid_sources(data, xpos, ypos, error=error, box_size=11,
                                  centroid_func=centroid_1dg)
        assert_allclose(xc, (25.67,), atol=1e-1)
        assert_allclose(yc, (26.41,), atol=1e-1)

        with pytest.raises(ValueError):
            centroid_sources(data, 25, [[26]], box_size=11)
        with pytest.raises(ValueError):
            centroid_sources(data, [[25]], 26, box_size=11)
        with pytest.raises(ValueError):
            centroid_sources(data, 25, 26, box_size=(1, 2, 3))
        with pytest.raises(ValueError):
            centroid_sources(data, 25, 26, box_size=None, footprint=None)
        with pytest.raises(ValueError):
            centroid_sources(data, 25, 26, footprint=np.ones((3, 3, 3)))

        def test_func(data):
            return data
        with pytest.raises(ValueError):
            centroid_sources(data, [25], 26, centroid_func=test_func)
Esempio n. 31
0
def add_gaussian_peaks(array, nholes=100, rad_max=30, rad_min=10):
    ylim, xlim = array.shape

    yy, xx = np.mgrid[-ylim/2:ylim/2, -xlim/2:xlim/2]

    xcenters = np.random.random_integers(-(xlim/2-rad_max),
                                         high=xlim/2-rad_max, size=nholes)
    ycenters = np.random.random_integers(-(ylim/2-rad_max),
                                         high=ylim/2-rad_max, size=nholes)
    radii = np.random.random_integers(rad_min, rad_max, size=nholes)

    for x, y, radius in zip(xcenters, ycenters, radii):
        amp = np.random.uniform(0.5, 0.75)

        gauss = Gaussian2D.evaluate(yy, xx,
                                    amp, x, y, radius, radius, 0.0)

        array += gauss

    return array