File: test_discretize.py

package info (click to toggle)
python-astropy 1.3-8~bpo8%2B2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 44,292 kB
  • sloc: ansic: 160,360; python: 137,322; sh: 11,493; lex: 7,638; yacc: 4,956; xml: 1,796; makefile: 474; cpp: 364
file content (169 lines) | stat: -rw-r--r-- 5,666 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# Licensed under a 3-clause BSD style license - see LICENSE.rst
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import itertools

import numpy as np
from numpy.testing import assert_allclose

from ...tests.helper import pytest

from ..utils import discretize_model
from ...modeling.functional_models import (
    Gaussian1D, Box1D, MexicanHat1D, Gaussian2D, Box2D, MexicanHat2D)
from ...modeling.tests.example_models import models_1D, models_2D
from ...modeling.tests.test_models import create_model

try:
    import scipy  # pylint: disable=W0611
    HAS_SCIPY = True
except ImportError:
    HAS_SCIPY = False


modes = ['center', 'linear_interp', 'oversample']
test_models_1D = [Gaussian1D, Box1D, MexicanHat1D]
test_models_2D = [Gaussian2D, Box2D, MexicanHat2D]


@pytest.mark.parametrize(('model_class', 'mode'), list(itertools.product(test_models_1D, modes)))
def test_pixel_sum_1D(model_class, mode):
    """
    Test if the sum of all pixels corresponds nearly to the integral.
    """
    if model_class == Box1D and mode == "center":
        pytest.skip("Non integrating mode. Skip integral test.")
    parameters = models_1D[model_class]
    model = create_model(model_class, parameters)

    values = discretize_model(model, models_1D[model_class]['x_lim'], mode=mode)
    assert_allclose(values.sum(), models_1D[model_class]['integral'], atol=0.0001)


@pytest.mark.parametrize('mode', modes)
def test_gaussian_eval_1D(mode):
    """
    Discretize Gaussian with different modes and check
    if result is at least similar to Gaussian1D.eval().
    """
    model = Gaussian1D(1, 0, 20)
    x = np.arange(-100, 101)
    values = model(x)
    disc_values = discretize_model(model, (-100, 101), mode=mode)
    assert_allclose(values, disc_values, atol=0.001)


@pytest.mark.parametrize(('model_class', 'mode'), list(itertools.product(test_models_2D, modes)))
def test_pixel_sum_2D(model_class, mode):
    """
    Test if the sum of all pixels corresponds nearly to the integral.
    """
    if model_class == Box2D and mode == "center":
        pytest.skip("Non integrating mode. Skip integral test.")

    parameters = models_2D[model_class]
    model = create_model(model_class, parameters)

    values = discretize_model(model, models_2D[model_class]['x_lim'],
                              models_2D[model_class]['y_lim'], mode=mode)
    assert_allclose(values.sum(), models_2D[model_class]['integral'], atol=0.0001)


@pytest.mark.parametrize('mode', modes)
def test_gaussian_eval_2D(mode):
    """
    Discretize Gaussian with different modes and check
    if result is at least similar to Gaussian1D.eval()
    """
    model = Gaussian2D(1, 0, 0, 20, 20)
    x = np.arange(-100, 101)
    y = np.arange(-100, 101)
    x, y = np.meshgrid(x, y)
    values = model(x, y)
    disc_values = discretize_model(model, (-100, 101), (-100, 101), mode=mode)
    assert_allclose(values, disc_values, atol=0.001)


@pytest.mark.skipif('not HAS_SCIPY')
def test_subpixel_gauss_1D():
    """
    Test subpixel accuracy of the oversample mode with gaussian 1D model.
    """
    gauss_1D = Gaussian1D(1, 0, 0.1)
    values = discretize_model(gauss_1D, (-1, 2), mode='integrate', factor=100)
    assert_allclose(values.sum(), np.sqrt(2 * np.pi) * 0.1, atol=0.00001)


@pytest.mark.skipif('not HAS_SCIPY')
def test_subpixel_gauss_2D():
    """
    Test subpixel accuracy of the oversample mode with gaussian 2D model.
    """
    gauss_2D = Gaussian2D(1, 0, 0, 0.1, 0.1)
    values = discretize_model(gauss_2D, (-1, 2), (-1, 2), mode='integrate', factor=100)
    assert_allclose(values.sum(), 2 * np.pi * 0.01, atol=0.00001)

def test_discretize_callable_1d():
    """
    Test discretize when a 1d function is passed.
    """
    def f(x):
        return x ** 2
    y = discretize_model(f, (-5, 6))
    assert_allclose(y, np.arange(-5, 6) ** 2)

def test_discretize_callable_2d():
    """
    Test discretize when a 2d function is passed.
    """
    def f(x, y):
        return x ** 2 + y ** 2
    actual = discretize_model(f, (-5, 6), (-5, 6))
    y, x = (np.indices((11, 11)) - 5)
    desired = x ** 2 + y ** 2
    assert_allclose(actual, desired)

def test_type_exception():
    """
    Test type exception.
    """
    with pytest.raises(TypeError) as exc:
        discretize_model(float(0), (-10, 11))
    assert exc.value.args[0] == 'Model must be callable.'

def test_dim_exception_1d():
    """
    Test dimension exception 1d.
    """
    def f(x):
        return x ** 2
    with pytest.raises(ValueError) as exc:
        discretize_model(f, (-10, 11), (-10, 11))
    assert exc.value.args[0] == "y range specified, but model is only 1-d."

def test_dim_exception_2d():
    """
    Test dimension exception 2d.
    """
    def f(x, y):
        return x ** 2 + y ** 2
    with pytest.raises(ValueError) as exc:
        discretize_model(f, (-10, 11))
    assert exc.value.args[0] == "y range not specified, but model is 2-d"

def test_float_x_range_exception():
    def f(x, y):
        return x ** 2 + y ** 2
    with pytest.raises(ValueError) as exc:
        discretize_model(f, (-10.002, 11.23))
    assert exc.value.args[0] == ("The difference between the upper an lower"
                                 " limit of 'x_range' must be a whole number.")

def test_float_y_range_exception():
    def f(x, y):
        return x ** 2 + y ** 2
    with pytest.raises(ValueError) as exc:
        discretize_model(f, (-10, 11), (-10.002, 11.23))
    assert exc.value.args[0] == ("The difference between the upper an lower"
                                 " limit of 'y_range' must be a whole number.")