1# Various tests of models not related to evaluation, fitting, or parameters
2# pylint: disable=invalid-name, no-member
3import warnings
4
5import pytest
6
7from astropy import units as u
8from astropy.tests.helper import assert_quantity_allclose
9
10from astropy.modeling.models import Mapping, Pix2Sky_TAN, Gaussian1D
11from astropy.modeling import models
12from astropy.modeling.core import _ModelMeta
13
14
15def test_gaussian1d_bounding_box():
16    g = Gaussian1D(mean=3 * u.m, stddev=3 * u.cm, amplitude=3 * u.Jy)
17    bbox = g.bounding_box.bounding_box()
18    assert_quantity_allclose(bbox[0], 2.835 * u.m)
19    assert_quantity_allclose(bbox[1], 3.165 * u.m)
20
21
22def test_gaussian1d_n_models():
23    g = Gaussian1D(
24        amplitude=[1 * u.J, 2. * u.J],
25        mean=[1 * u.m, 5000 * u.AA],
26        stddev=[0.1 * u.m, 100 * u.AA],
27        n_models=2)
28    assert_quantity_allclose(g(1.01 * u.m), [0.99501248, 0.] * u.J)
29    assert_quantity_allclose(
30        g(u.Quantity([1.01 * u.m, 5010 * u.AA])), [0.99501248, 1.990025] * u.J)
31    # FIXME: The following doesn't work as np.asanyarray doesn't work with a
32    # list of quantity objects.
33    # assert_quantity_allclose(g([1.01 * u.m, 5010 * u.AA]),
34    #                            [ 0.99501248, 1.990025] * u.J)
35
36
37"""
38Test the "rules" of model units.
39"""
40
41
42def test_quantity_call():
43    """
44    Test that if constructed with Quanties models must be called with quantities.
45    """
46    g = Gaussian1D(mean=3 * u.m, stddev=3 * u.cm, amplitude=3 * u.Jy)
47
48    g(10 * u.m)
49
50    with pytest.raises(u.UnitsError):
51        g(10)
52
53
54def test_no_quantity_call():
55    """
56    Test that if not constructed with Quantites they can be called without quantities.
57    """
58    g = Gaussian1D(mean=3, stddev=3, amplitude=3)
59    assert isinstance(g, Gaussian1D)
60    g(10)
61
62
63def test_default_parameters():
64    # Test that calling with a quantity works when one of the parameters
65    # defaults to dimensionless
66    g = Gaussian1D(mean=3 * u.m, stddev=3 * u.cm)
67    assert isinstance(g, Gaussian1D)
68    g(10*u.m)
69
70
71def test_uses_quantity():
72    """
73    Test Quantity
74    """
75    g = Gaussian1D(mean=3 * u.m, stddev=3 * u.cm, amplitude=3 * u.Jy)
76
77    assert g.uses_quantity
78
79    g = Gaussian1D(mean=3, stddev=3, amplitude=3)
80
81    assert not g.uses_quantity
82
83    g.mean = 3 * u.m
84
85    assert g.uses_quantity
86
87
88def test_uses_quantity_compound():
89    """
90    Test Quantity
91    """
92    g = Gaussian1D(mean=3 * u.m, stddev=3 * u.cm, amplitude=3 * u.Jy)
93    g2 = Gaussian1D(mean=5 * u.m, stddev=5 * u.cm, amplitude=5 * u.Jy)
94
95    assert (g | g2).uses_quantity
96
97    g = Gaussian1D(mean=3, stddev=3, amplitude=3)
98    g2 = Gaussian1D(mean=5, stddev=5, amplitude=5)
99
100    comp = g | g2
101
102    assert not (comp).uses_quantity
103
104
105def test_uses_quantity_no_param():
106    comp = Mapping((0, 1)) | Pix2Sky_TAN()
107
108    assert comp.uses_quantity
109
110
111def _allmodels():
112    allmodels = []
113    for name in dir(models):
114        model = getattr(models, name)
115        if type(model) is _ModelMeta:
116            try:
117                m = model()
118            except Exception:
119                pass
120            allmodels.append(m)
121    return allmodels
122
123
124@pytest.mark.parametrize("m", _allmodels())
125def test_read_only(m):
126    """
127    input_units
128    return_units
129    input_units_allow_dimensionless
130    input_units_strict
131    """
132    with pytest.raises(AttributeError):
133        m.input_units = {}
134    with pytest.raises(AttributeError):
135        m.return_units = {}
136    with pytest.raises(AttributeError):
137        m.input_units_allow_dimensionless = {}
138    with pytest.raises(AttributeError):
139        m.input_units_strict = {}
140