Пример #1
0
def test_eval():
    """ Tests evaluation of Linear1D and Planar2D with different model_set_axis."""
    model = Linear1D(slope=[1, 2], intercept=[3, 4], n_models=2)
    p = Polynomial1D(1, c0=[3, 4], c1=[1, 2], n_models=2)

    assert_allclose(model(xx), p(xx))
    assert_allclose(model(x, model_set_axis=False), p(x, model_set_axis=False))

    with pytest.raises(ValueError):
        model(x)

    model = Linear1D(slope=[[1, 2]],
                     intercept=[[3, 4]],
                     n_models=2,
                     model_set_axis=1)
    p = Polynomial1D(1, c0=[[3, 4]], c1=[[1, 2]], n_models=2, model_set_axis=1)

    assert_allclose(model(xx.T), p(xx.T))
    assert_allclose(model(x, model_set_axis=False), p(x, model_set_axis=False))
    with pytest.raises(ValueError):
        model(xx)

    model = Planar2D(slope_x=[1, 2],
                     slope_y=[1, 2],
                     intercept=[3, 4],
                     n_models=2)
    y = model(xx, xx)

    assert y.shape == (2, 4)

    with pytest.raises(ValueError):
        model(x)
Пример #2
0
def test_model_axis_1():
    """
    Test that a model initialized with model_set_axis=1
    can be evaluated with model_set_axis=False.
    """
    model_axis = 1
    n_models = 2
    p1 = Polynomial1D(1, n_models=n_models, model_set_axis=model_axis)
    p1.c0 = [2, 3]
    p1.c1 = [1, 2]
    t1 = Polynomial1D(1, c0=2, c1=1)
    t2 = Polynomial1D(1, c0=3, c1=2)

    with pytest.raises(ValueError):
        p1(x)

    with pytest.raises(ValueError):
        p1(xx)

    y = p1(x, model_set_axis=False)
    assert y.shape[model_axis] == n_models
    assert_allclose(y[:, 0], t1(x))
    assert_allclose(y[:, 1], t2(x))

    y = p1(xx, model_set_axis=False)
    assert y.shape[model_axis] == n_models
    assert_allclose(y[:, 0, :], t1(xx))
    assert_allclose(y[:, 1, :], t2(xx))

    y = p1(xxx, model_set_axis=False)
    assert y.shape[model_axis] == n_models
    assert_allclose(y[:, 0, :, :], t1(xxx))
    assert_allclose(y[:, 1, :, :], t2(xxx))
Пример #3
0
def test_axis_0():
    """
    Test that a model initialized with model_set_axis=0
    can be evaluated with model_set_axis=False.
    """
    p1 = Polynomial1D(1, n_models=2, model_set_axis=0)
    p1.c0 = [2, 3]
    p1.c1 = [1, 2]
    t1 = Polynomial1D(1, c0=2, c1=1)
    t2 = Polynomial1D(1, c0=3, c1=2)

    with pytest.raises(ValueError):
        p1(x)

    y = p1(xx)
    assert len(y) == 2
    assert_allclose(y[0], t1(xx[0]))
    assert_allclose(y[1], t2(xx[1]))

    y = p1(x, model_set_axis=False)
    assert len(y) == 2
    assert_allclose(y[0], t1(x))
    assert_allclose(y[1], t2(x))

    y = p1(xx, model_set_axis=False)
    assert len(y) == 2
    assert_allclose(y[0], t1(xx))
    assert_allclose(y[1], t2(xx))
    y = p1(xxx, model_set_axis=False)
    assert_allclose(y[0], t1(xxx))
    assert_allclose(y[1], t2(xxx))
    assert len(y) == 2
Пример #4
0
def test_shapes():
    p2 = Polynomial1D(1, n_models=3, model_set_axis=2)
    assert p2.c0.shape == ()
    assert p2.c1.shape == ()

    p1 = Polynomial1D(1, n_models=2, model_set_axis=1)
    assert p1.c0.shape == ()
    assert p1.c1.shape == ()

    p1 = Polynomial1D(1, c0=[1, 2], c1=[3, 4], n_models=2, model_set_axis=-1)
    assert p1.c0.shape == ()
    assert p1.c1.shape == ()

    e1 = [1, 2]
    e2 = [3, 4]

    a1 = np.array([[10, 20], [30, 40]])
    a2 = np.array([[50, 60], [70, 80]])

    t = TParModel([a1, a2], [e1, e2], n_models=2, model_set_axis=-1)
    assert t.coeff.shape == (2, 2)
    assert t.e.shape == (2, )

    t = TParModel([[a1, a2]], [[e1, e2]], n_models=2, model_set_axis=1)
    assert t.coeff.shape == (2, 2)
    assert t.e.shape == (2, )

    t = TParModel([a1, a2], [e1, e2], n_models=2, model_set_axis=0)
    assert t.coeff.shape == (2, 2)
    assert t.e.shape == (2, )

    t = TParModel([a1, a2], e=[1, 2], n_models=2, model_set_axis=0)
    assert t.coeff.shape == (2, 2)
    assert t.e.shape == ()
Пример #5
0
def test_model_set_axis_outputs():
    fitter = LinearLSQFitter()
    model_set = Polynomial2D(1, n_models=2, model_set_axis=2)
    y2, x2 = np.mgrid[:5, :5]
    # z = np.moveaxis([x2 + y2, 1 - 0.1 * x2 + 0.2 * y2]), 0, 2)
    z = np.rollaxis(np.array([x2 + y2, 1 - 0.1 * x2 + 0.2 * y2]), 0, 3)
    model = fitter(model_set, x2, y2, z)
    res = model(x2, y2, model_set_axis=False)
    assert z.shape == res.shape

    # Test initializing with integer model_set_axis
    # and evaluating with a different model_set_axis
    model_set = Polynomial1D(1,
                             c0=[1, 2],
                             c1=[2, 3],
                             n_models=2,
                             model_set_axis=0)
    y0 = model_set(xx)
    y1 = model_set(xx.T, model_set_axis=1)
    assert_allclose(y0[0], y1[:, 0])
    assert_allclose(y0[1], y1[:, 1])

    model_set = Polynomial1D(1,
                             c0=[[1, 2]],
                             c1=[[2, 3]],
                             n_models=2,
                             model_set_axis=1)
    y0 = model_set(xx.T)
    y1 = model_set(xx, model_set_axis=0)
    assert_allclose(y0[:, 0], y1[0])
    assert_allclose(y0[:, 1], y1[1])
    with pytest.raises(ValueError):
        model_set(x)
Пример #6
0
def _continuum_fit(spectrum: Spectrum1D, name="continuum") -> Polynomial1D:
    """
    Create a fixed, Polynomial1D model for the continuum of the passed spectrum.
    Uses specutils and exclusion regions to fit only to selected regions of the passed spectrum
    """
    # Select the exclusion regions based on whether this is a blue or red arm spectrum
    if min(spectrum.wavelength.value) < 5000:
        exclusion_regions = _b_e_exclusion_regions
    else:
        exclusion_regions = _r_e_exclusion_regions

    # It's a bit of a bodge, but this is the easiest way I could find for selecting/excluding regions for fitting.
    continuum_model = fit_generic_continuum(spectrum,
                                            model=Polynomial1D(degree=2),
                                            exclude_regions=exclusion_regions)

    # Create a new Polynomial1D with the same params (fixed)
    return Polynomial1D(degree=continuum_model.degree,
                        c0=continuum_model.c0,
                        c1=continuum_model.c1,
                        c2=continuum_model.c2,
                        fixed={
                            "c0": True,
                            "c1": True,
                            "c2": True
                        },
                        name=name)
Пример #7
0
def test_replace_submodel():
    """
    Replace a model in a Compound model
    """
    S1 = Shift(2, name='shift2') | Scale(
        3, name='scale3')  # First shift then scale
    S2 = Scale(2, name='scale2') | Shift(
        3, name='shift3')  # First scale then shift

    m = S1 & S2
    assert m(1, 2) == (9, 7)

    m2 = m.replace_submodel('scale3', Scale(4, name='scale4'))
    assert m2(1, 2) == (12, 7)
    assert m(1, 2) == (9, 7)
    # Check the inverse has been updated
    assert m2.inverse(12, 7) == (1, 2)

    # Produce the same result by replacing a single model with a compound
    m3 = m.replace_submodel('shift2', Shift(2) | Scale(2))
    assert m(1, 2) == (9, 7)
    assert m3(1, 2) == (18, 7)
    # Check the inverse has been updated
    assert m3.inverse(18, 7) == (1, 2)

    # Test with arithmetic model compunding operator
    m = S1 + S2
    assert m(1) == 14
    m2 = m.replace_submodel('scale2', Scale(4, name='scale4'))
    assert m2(1) == 16

    # Test with fix_inputs()
    R = fix_inputs(Rotation2D(angle=90, name='rotate'), {0: 1})
    m4 = S1 | R
    assert_allclose(m4(0), (-6, 1))

    m5 = m4.replace_submodel('rotate', Rotation2D(180))
    assert_allclose(m5(0), (-1, -6))

    # Check we get a value error when model name doesn't exist
    with pytest.raises(ValueError):
        m2 = m.replace_submodel('not_there', Scale(2))

    # And now a model set
    P = Polynomial1D(degree=1, n_models=2, name='poly')
    S = Shift([1, 2], n_models=2)
    m = P | S
    assert_array_equal(m([0, 1]), (1, 2))
    with pytest.raises(ValueError):
        m2 = m.replace_submodel('poly', Polynomial1D(degree=1, c0=1))
    m2 = m.replace_submodel('poly',
                            Polynomial1D(degree=1, c0=[1, 2], n_models=2))
    assert_array_equal(m2([0, 1]), (2, 4))
Пример #8
0
def test_negative_axis():
    p1 = Polynomial1D(1, c0=[1, 2], c1=[3, 4], n_models=2, model_set_axis=-1)
    t1 = Polynomial1D(1, c0=1, c1=3)
    t2 = Polynomial1D(1, c0=2, c1=4)

    with pytest.raises(ValueError):
        p1(x)

    with pytest.raises(ValueError):
        p1(xx)

    xxt = xx.T
    y = p1(xxt)
    assert_allclose(y[:, 0], t1(xxt[:, 0]))
    assert_allclose(y[:, 1], t2(xxt[:, 1]))
Пример #9
0
def trace_fit(layout, side='left', degree=1):
    '''Linear fit to describe edge of a spectral trace

    Parameters
    ----------
    layout : [table]
         a table describing a spectral trace
    side : [str]
         can be 'left', 'right' or 'centre'
    '''
    from astropy.modeling.models import Polynomial1D
    from astropy.modeling.fitting import LinearLSQFitter

    if side == 'left':
        xpt = layout['x1']
        ypt = layout['y1']
        name = 'left edge'
    elif side == 'centre':
        xpt = layout['x2']
        ypt = layout['y2']
        name = 'trace centre'
    elif side == 'right':
        xpt = layout['x3']
        ypt = layout['y3']
        name = 'right edge'
    else:
        raise ValueError('Side ' + str(side) + ' not recognized')

    pinit = Polynomial1D(degree=degree)
    fitter = LinearLSQFitter()
    edge_fit = fitter(pinit, ypt, xpt)
    edge_fit.name = name
    return edge_fit
Пример #10
0
def test_indexing_on_class():
    """
    Test indexing on compound model class objects, including cases where the
    submodels are classes, as well as instances, or both.
    """

    g = Gaussian1D(1, 2, 3, name='g')
    p = Polynomial1D(2, name='p')

    M = Gaussian1D + Const1D
    assert M[0] is Gaussian1D
    assert M[1] is Const1D
    assert M['Gaussian1D'] is M[0]
    assert M['Const1D'] is M[1]

    M = Gaussian1D + p
    assert M[0] is Gaussian1D
    assert isinstance(M['p'], Polynomial1D)

    m = g + p
    assert isinstance(m[0], Gaussian1D)
    assert isinstance(m[1], Polynomial1D)
    assert isinstance(m['g'], Gaussian1D)
    assert isinstance(m['p'], Polynomial1D)

    # 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']
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)
Пример #12
0
def test_linear_fit_model_set_common_weight():
    """Tests fitting multiple models simultaneously."""

    init_model = Polynomial1D(degree=2, c0=[1, 1], n_models=2)
    x = np.arange(10)
    y_expected = init_model(x, model_set_axis=False)
    assert y_expected.shape == (2, 10)

    # Add a bit of random noise
    with NumpyRNGContext(_RANDOM_SEED):
        y = y_expected + np.random.normal(0, 0.01, size=y_expected.shape)

    fitter = LinearLSQFitter()
    weights = np.ones(10)
    weights[[0, -1]] = 0
    fitted_model = fitter(init_model, x, y, weights=weights)
    assert_allclose(fitted_model(x, model_set_axis=False), y_expected,
                    rtol=1e-1)

    # Check that using null weights raises an error
    # ValueError: On entry to DLASCL parameter number 4 had an illegal value
    with pytest.raises(ValueError,
                       match='Found NaNs in the coefficient matrix'):
        with pytest.warns(RuntimeWarning,
                          match=r'invalid value encountered in.*divide'):
            fitted_model = fitter(init_model, x, y, weights=np.zeros(10))
Пример #13
0
def _models_with_units():
    m1 = _ExampleModel() & _ExampleModel()
    m2 = _ExampleModel() + _ExampleModel()
    p = Polynomial1D(1)
    p._input_units = {'x': u.m / u.s}
    p._return_units = {'y': u.m / u.s}
    m3 = _ExampleModel() | p
    m4 = fix_inputs(m1, {'x0': 1})
    m5 = fix_inputs(m1, {0: 1})

    models = [m1, m2, m3, m4, m5]
    input_units = [{'x0': u.Unit("m"), 'x1': u.Unit("m")},
                   {'x': u.Unit("m")},
                   {'x': u.Unit("m")},
                   {'x1': u.Unit("m")},
                   {'x1': u.Unit("m")}
                   ]

    return_units = [{'y0': u.Unit("m / s"), 'y1': u.Unit("m / s")},
                    {'y': u.Unit("m / s")},
                    {'y': u.Unit("m / s")},
                    {'y0': u.Unit("m / s"), 'y1': u.Unit("m / s")},
                    {'y0': u.Unit("m / s"), 'y1': u.Unit("m / s")}
                    ]
    return np.array([models, input_units, return_units], dtype=object).T
Пример #14
0
def get_mask(weigh):
    '''
    Get mask for an array of spectra using a polynomial for the weight array
    and finding dips from that polynomial model.
    '''
    mask = np.zeros(weigh.shape, dtype=bool)
    P = Polynomial1D(3)
    
    # Select values that are not extreme outliers (watch for nans so use nanmedian)
    wmask = weigh > 0.3 * np.nanmedian(weigh)
    
    # Fit Polynomial
    fit = fitter(P, def_wave[wmask], weigh[wmask])
    
    # Mask values below 80% of the fit
    mask = weigh < 0.8 * fit(def_wave)
    
    # Mask neighbor pixels as well because they tend to have issues but don't meet
    # the threshold.  This is a conservative step, but it is done for robustness
    # rather than completeness
    mask[1:] += mask[:-1]
    mask[:-1] += mask[1:]
    
    # Mask additionally spectra whose average weight is less than 5%
    if np.nanmedian(weigh) < 0.05:
        mask = True
    return mask
Пример #15
0
 def test_linear_1d_separate_weights_axis_1(self):
     model = Polynomial1D(1, model_set_axis=1)
     fitter = LinearLSQFitter()
     model = fitter(model, self.x1, self.y1.T,
                    weights=self.w1[..., np.newaxis])
     assert_allclose(model.c0, 0.5, atol=1e-12)
     assert_allclose(model.c1, 2.5, atol=1e-12)
Пример #16
0
def test_compound_custom_inverse():
    """
    Test that a compound model with a custom inverse has that inverse applied
    when the inverse of another model, of which it is a component, is computed.
    Regression test for https://github.com/astropy/astropy/issues/3542
    """

    poly = Polynomial1D(1, c0=1, c1=2)
    scale = Scale(1)
    shift = Shift(1)

    model1 = poly | scale
    model1.inverse = poly

    # model1 now has a custom inverse (the polynomial itself, ignoring the
    # trivial scale factor)
    model2 = shift | model1

    assert_allclose(model2.inverse(1), (poly | shift.inverse)(1))

    # Make sure an inverse is not allowed if the models were combined with the
    # wrong operator, or if one of the models doesn't have an inverse defined
    with pytest.raises(NotImplementedError):
        (shift + model1).inverse

    with pytest.raises(NotImplementedError):
        (model1 & poly).inverse
Пример #17
0
 def test_linear_1d_separate_weights(self):
     model = Polynomial1D(1)
     fitter = LinearLSQFitter()
     model = fitter(model, self.x1, self.y1,
                    weights=self.w1[np.newaxis, ...])
     assert_allclose(model.c0, 0.5, atol=1e-12)
     assert_allclose(model.c1, 2.5, atol=1e-12)
Пример #18
0
def fit_diffs(x, y, ndegree=2, noexp=False):
    """
    Fit the average DN versus 2pt differences with a model that accounts
    for the non-linearities and RSCD exponential decay at beginning of ramp

    Parameters
    ----------
    x : ndarray
        average DN values for each 2pt difference

    y : ndarray
        2pt differences

    ndegree : int
        degree of polynomial for fit

    noexp : boolean
        set to true to only do a polynomial (no exponential)

    Returns
    -------
    mod : astropy model
        fitted model
    """
    # print(min(x))

    if noexp:
        mod_init = Polynomial1D(degree=ndegree)
    else:
        mod_init = (
            Shift(offset=5000.0, bounds={"offset": [-100000.0, 20000.0]})
            | Exponential1D(
                x_0=-1000.0,
                amplitude=2500.0,
                bounds={"amplitude": [100.0, 100000.0], "x_0": [-10000.0, -0.1]},
            )
        ) + Polynomial1D(degree=ndegree)

    fit = LevMarLSQFitter()

    mod = fit(mod_init, x, y, maxiter=10000)

    # print(mod)

    # exit()

    return mod
Пример #19
0
    def poly_solution(self, order):
        from astropy.modeling.fitting import LinearLSQFitter
        from astropy.modeling.models import Polynomial1D

        poly = Polynomial1D(order)
        ftr = LinearLSQFitter()
        poly = ftr(poly, list(self.linepixtowl.keys()),
                   list(self.linepixtowl.values()))
        return poly
Пример #20
0
def test_model_axis_2():
    """
    Test that a model initialized with model_set_axis=2
    can be evaluated with model_set_axis=False.
    """
    p1 = Polynomial1D(1,
                      c0=[[[1, 2, 3]]],
                      c1=[[[10, 20, 30]]],
                      n_models=3,
                      model_set_axis=2)
    t1 = Polynomial1D(1, c0=1, c1=10)
    t2 = Polynomial1D(1, c0=2, c1=20)
    t3 = Polynomial1D(1, c0=3, c1=30)

    with pytest.raises(ValueError):
        p1(x)

    with pytest.raises(ValueError):
        p1(xx)

    y = p1(x, model_set_axis=False)
    assert y.shape == (1, 4, 3)
    assert_allclose(y[:, :, 0].flatten(), t1(x))
    assert_allclose(y[:, :, 1].flatten(), t2(x))
    assert_allclose(y[:, :, 2].flatten(), t3(x))

    p2 = Polynomial2D(1,
                      c0_0=[[[0, 1, 2]]],
                      c0_1=[[[3, 4, 5]]],
                      c1_0=[[[5, 6, 7]]],
                      n_models=3,
                      model_set_axis=2)
    t1 = Polynomial2D(1, c0_0=0, c0_1=3, c1_0=5)
    t2 = Polynomial2D(1, c0_0=1, c0_1=4, c1_0=6)
    t3 = Polynomial2D(1, c0_0=2, c0_1=5, c1_0=7)

    assert p2.c0_0.shape == ()
    y = p2(x, x, model_set_axis=False)
    assert y.shape == (1, 4, 3)
    # These are columns along the 2nd axis.
    assert_allclose(y[:, :, 0].flatten(), t1(x, x))
    assert_allclose(y[:, :, 1].flatten(), t2(x, x))
    assert_allclose(y[:, :, 2].flatten(), t3(x, x))
Пример #21
0
def test_linearlsqfitter():
    """
    Issue #7159
    """
    p = Polynomial1D(1, n_models=2, model_set_axis=1)

    # Generate data for fitting 2 models and re-stack them along the last axis:
    y = np.array([2 * x + 1, x + 4])
    y = np.rollaxis(y, 0, -1).T

    f = LinearLSQFitter()
    # This seems to fit the model_set correctly:
    fit = f(p, x, y)
    model_y = fit(x, model_set_axis=False)

    m1 = Polynomial1D(1, c0=fit.c0[0][0], c1=fit.c1[0][0])
    m2 = Polynomial1D(1, c0=fit.c0[0][1], c1=fit.c1[0][1])
    assert_allclose(model_y[:, 0], m1(x))
    assert_allclose(model_y[:, 1], m2(x))
Пример #22
0
def test_linear_fit_model_set_errors():
    init_model = Polynomial1D(degree=2, c0=[1, 1], n_models=2)
    x = np.arange(10)
    y = init_model(x, model_set_axis=False)

    fitter = LinearLSQFitter()
    with pytest.raises(ValueError):
        fitter(init_model, x[:5], y)
    with pytest.raises(ValueError):
        fitter(init_model, x, y[:, :5])
Пример #23
0
def test_indexing_on_instance():
    """Test indexing on compound model instances."""

    M = Gaussian1D + Const1D
    m = M(1, 0, 0.1, 2)
    assert isinstance(m[0], Gaussian1D)
    assert isinstance(m[1], Const1D)
    assert isinstance(m['Gaussian1D'], Gaussian1D)
    assert isinstance(m['Const1D'], Const1D)

    # 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

    # Ensure this did *not* modify the original models we used as templates
    assert p.c0 == 0
    assert p.c1 == 0

    # 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']
Пример #24
0
    def test_bkg_doesnt_explode(self):
        """
        Check this goes through the motions
        """

        m = Polynomial1D(2)

        x = np.arange(0, 10, 0.1)
        y = 2 + 0.5 * x + 3 * x**2
        bkg = x

        sfit = SherpaFitter(statistic="cash", estmethod='covariance')
        sfit(m, x, y, bkg=bkg)
Пример #25
0
    def setup_class(self):
        self.model = Polynomial1D(2)
        self.x = np.arange(0, 10, 0.1)

        self.params = (2, 0.5, 3)
        # a simple polynomial
        self.y = self.params[0]
        self.y += self.params[1] * self.x
        self.y += self.params[2] * self.x**2

        self.y += np.random.uniform(-0.1, 0.1, self.x.size)

        sfit = SherpaFitter(statistic="cash", estmethod='covariance')
        sfit(self.model, self.x, self.y)
        self.sampler = sfit.get_sampler()
Пример #26
0
def test_tabular_in_compound():
    """
    Issue #7411 - evaluate should not change the shape of the output.
    """
    t = Tabular1D(points=([1, 5, 7],), lookup_table=[12, 15, 19],
                  bounds_error=False)
    rot = Rotation2D(2)
    p = Polynomial1D(1)
    x = np.arange(12).reshape((3, 4))
    # Create a compound model which does ot execute Tabular.__call__,
    # but model.evaluate and is followed by a Rotation2D which
    # checks the exact shapes.
    model = p & t | rot
    x1, y1 = model(x, x)
    assert x1.ndim == 2
    assert y1.ndim == 2
Пример #27
0
def trace_fibres(data,
                 slice_positions,
                 slice_width,
                 polynomial_order=2,
                 spectral_axis=0,
                 first_peak_position=None,
                 peak_kwargs={}):

    if polynomial_order >= len(slice_positions):
        warn(
            "Polynomial order ({}) >= number of slices ({}), under-constrained."
            .format(polynomial_order, len(slice_positions)))

    try:
        # Convert CCDData or similar to masked array
        data = np.ma.array(data.data, mask=data.mask)
    except AttributeError:
        data = np.ma.array(data)

    slice_half_width = slice_width // 2
    slice_peaks = []

    for i, slice_position in enumerate(slice_positions):
        start = slice_position - slice_half_width
        stop = slice_position + slice_half_width + 1
        if spectral_axis == 0:
            data_slice = data[start:stop, :]
        else:
            data_slice = data[:, start:stop]
        projection = data_slice.sum(axis=spectral_axis)
        if first_peak_position:
            peak_kwargs.update({'first_peak_position': first_peak_position})
        peaks = find_taipan_peaks(projection, **peak_kwargs)
        # Store first peak from peak finder to use for next slice
        first_peak_position = peaks.data[0]
        slice_peaks.append(peaks)

    slice_peaks = np.array(slice_peaks)
    n_fibres = slice_peaks.shape[1]

    traces_init = Polynomial1D(degree=polynomial_order,
                               n_models=n_fibres,
                               c0=slice_peaks[0])
    trace_fitter = LinearLSQFitter()
    traces = trace_fitter(traces_init, slice_positions, slice_peaks.T)

    return traces
Пример #28
0
def test_compound_evaluate(expr):
    """
    Tests that compound evaluate function produces the same
    result as the models with the operator applied
    """
    x = np.linspace(-5, 5, 10)
    # Some evaluate functions assume that inputs are numpy arrays or quantities including Const1D
    p1 = np.array([1, 2, 3, 4, 1, 2])
    p2 = np.array([1, 0, 0.5])

    model1 = Polynomial1D(5)
    model2 = Gaussian1D(2, 1, 5)
    compound = expr(model1, model2)

    assert_array_equal(
        compound.evaluate(x, *p1, *p2),
        expr(model1.evaluate(x, *p1), model2.evaluate(x, *p2)),
    )
Пример #29
0
def test_linear_fit_model_set_weights():
    """Tests fitting multiple models simultaneously."""

    init_model = Polynomial1D(degree=2, c0=[1, 1], n_models=2)
    x = np.arange(10)
    y_expected = init_model(x, model_set_axis=False)
    assert y_expected.shape == (2, 10)

    # Add a bit of random noise
    with NumpyRNGContext(_RANDOM_SEED):
        y = y_expected + np.random.normal(0, 0.01, size=y_expected.shape)

    weights = np.ones_like(y)
    # Put a null weight for the min and max values
    weights[[0, 1], weights.argmin(axis=1)] = 0
    weights[[0, 1], weights.argmax(axis=1)] = 0
    fitter = LinearLSQFitter()
    fitted_model = fitter(init_model, x, y, weights=weights)
    assert_allclose(fitted_model(x, model_set_axis=False),
                    y_expected,
                    rtol=1e-1)

    # Check that using null weights raises an error
    weights[0] = 0
    with pytest.raises(ValueError,
                       match='Found NaNs in the coefficient matrix'):
        with pytest.warns(RuntimeWarning,
                          match=r'invalid value encountered in.*divide'):
            fitted_model = fitter(init_model, x, y, weights=weights)

    # Now we mask the values where weight is 0
    with pytest.warns(RuntimeWarning,
                      match=r'invalid value encountered in.*divide'):
        fitted_model = fitter(init_model,
                              x,
                              np.ma.array(y, mask=np.isclose(weights, 0)),
                              weights=weights)
    # Parameters for the first model are all NaNs
    assert np.all(np.isnan(fitted_model.param_sets[:, 0]))
    assert np.all(np.isnan(fitted_model(x, model_set_axis=False)[0]))
    # Second model is fitted correctly
    assert_allclose(fitted_model(x, model_set_axis=False)[1],
                    y_expected[1],
                    rtol=1e-1)
Пример #30
0
def test_NIRCAMForwardRowGrismDispersion():
    xmodels = [
        Polynomial1D(1, c0=0.59115385, c1=0.00038615),
        Polynomial1D(1, c0=-0.16596154, c1=0.00019308)
    ]
    ymodels = [Polynomial1D(1, c0=0., c1=0.), Polynomial1D(1, c0=0., c1=0.)]
    lmodels = [
        Polynomial1D(1, c0=2.4, c1=2.6),
        Polynomial1D(1, c0=2.4, c1=2.6)
    ]
    model = transforms.NIRCAMForwardRowGrismDispersion([1, 2], lmodels,
                                                       xmodels, ymodels)

    x0 = 913.7
    y0 = 15.5
    order = 1

    slit = create_slit(model, x0, y0, order)

    expected = np.array([[
        3.03973415, 3.04073814, 3.04174213, 3.04274612, 3.04375011, 3.0447541
    ], [3.03973415, 3.04073814, 3.04174213, 3.04274612, 3.04375011, 3.0447541],
                         [
                             3.03973415, 3.04073814, 3.04174213, 3.04274612,
                             3.04375011, 3.0447541
                         ],
                         [
                             3.03973415, 3.04073814, 3.04174213, 3.04274612,
                             3.04375011, 3.0447541
                         ],
                         [
                             3.03973415, 3.04073814, 3.04174213, 3.04274612,
                             3.04375011, 3.0447541
                         ],
                         [
                             3.03973415, 3.04073814, 3.04174213, 3.04274612,
                             3.04375011, 3.0447541
                         ]])

    # refactored call
    x, y = grid_from_bounding_box(slit.meta.wcs.bounding_box)
    wavelength = compute_wavelength_array(
        slit
    )  # x, y, np.zeros(x.shape)  +x0, np.zeros(y.shape)+y0, np.zeros(x.shape)+order)
    assert_allclose(wavelength, expected)

    with pytest.raises(ValueError):
        slit = create_slit(model, x0, y0, 3)
        compute_wavelength_array(slit)