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)
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))
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
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 == ()
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)
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)
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))
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]))
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
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)
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))
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
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
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)
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
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)
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
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
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))
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))
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])
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']
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)
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()
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
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
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)), )
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)
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)