Esempio n. 1
0
 def test_basis_func(self):
     p = Chebyshev([1, 2, 3])
     assert_equal(self.as_latex(p),
                  r'$x \mapsto 1.0\,{T}_{0}(x) + 2.0\,{T}_{1}(x) + 3.0\,{T}_{2}(x)$')
     # affine input - check no surplus parens are added
     p = Chebyshev([1, 2, 3], domain=[-1, 0])
     assert_equal(self.as_latex(p),
                  r'$x \mapsto 1.0\,{T}_{0}(1.0 + 2.0x) + 2.0\,{T}_{1}(1.0 + 2.0x) + 3.0\,{T}_{2}(1.0 + 2.0x)$')
Esempio n. 2
0
def dlfParamsdz(z, pPhiStar, pMStar, pAlpha, pBeta):

    dlog10phiStardz = T.deriv(T(pPhiStar))(1 + z)
    dmStardz = T.deriv(T(pMStar))(1 + z)
    dalphadz = T.deriv(T(pAlpha))(1 + z)

    h, f0, z0, a, b = pBeta
    zeta = np.log10((1.0 + z) / (1.0 + z0))
    dbetadz = (-f0 * (a * 10.0**((a - 1) * zeta) /
                      (1.0 + z0) + b * 10.0**((b - 1) * zeta) / (1.0 + z0)) /
               (10.0**(a * zeta) + 10.0**(b * zeta))**2)

    return dlog10phiStardz, dmStardz, dalphadz, dbetadz
Esempio n. 3
0
def get_Matrix(operator):
    M = np.zeros((N + 1, N + 1), dtype=complex)
    I = np.eye(N + 1)
    y = np.cos(np.linspace(2, N - 1, N - 2, dtype=float) * pi / N)
    for i in range(0, N + 1):
        T = Ch(I[i, :])
        M[i, 0] = T(-1.0)
        M[i, 1] = T.deriv(1)(-1.0) * Dy(-1.0, 1)
        M[i, 2:N] = operator(T, y)
        M[i, N] = T(1.0)
        #M[i,N]     = T.deriv(1)(1.0)*Dy(1.0,1)
    M = eliminate(M, 0)
    M = eliminate(M, 1)
    #M = eliminate(M,N-1)
    M = eliminate(M, N)
    return M[2:N, 2:N]
Esempio n. 4
0
 def fit(self):
     pixvals, wavelengths = self.get_table_values()
     mask = ~np.isnan(wavelengths)
     order = int(self.poly_order.text())
     if np.sum(~np.isnan(wavelengths)) < order:
         msg = "Not enough data points to perform fit!\n"
         msg += "Choose a lower polynomial order or identify more lines."
         QMessageBox.critical(None, 'Not enough data to fit', msg)
     else:
         p_fit = Chebyshev.fit(pixvals[mask],
                               wavelengths[mask],
                               order,
                               domain=[self.pix.min(),
                                       self.pix.max()])
         wave_solution = p_fit(self.pix)
         scatter = np.std(wavelengths[mask] - p_fit(pixvals[mask]))
         scatter_label = r"$\sigma_{\lambda} = %.2f$ Å" % scatter
         self.cheb_fit = p_fit
         self._scatter = scatter
         self._residuals = wavelengths - p_fit(pixvals)
         if self._fit_ref is None:
             fit_ref = self.ax2.plot(self.pix,
                                     wave_solution,
                                     color='RoyalBlue',
                                     label=scatter_label)
             self._fit_ref = fit_ref[0]
         else:
             self._fit_ref.set_ydata(wave_solution)
             self._fit_ref.set_label(scatter_label)
         self.update_plot()
         self.ax2.legend(handlelength=0.5, frameon=False)
         self.canvas.draw()
         self.canvas.setFocus()
Esempio n. 5
0
def test_floordiv(Poly):
    c1 = list(random((4, )) + .5)
    c2 = list(random((3, )) + .5)
    c3 = list(random((2, )) + .5)
    p1 = Poly(c1)
    p2 = Poly(c2)
    p3 = Poly(c3)
    p4 = p1 * p2 + p3
    c4 = list(p4.coef)
    assert_poly_almost_equal(p4 // p2, p1)
    assert_poly_almost_equal(p4 // c2, p1)
    assert_poly_almost_equal(c4 // p2, p1)
    assert_poly_almost_equal(p4 // tuple(c2), p1)
    assert_poly_almost_equal(tuple(c4) // p2, p1)
    assert_poly_almost_equal(p4 // np.array(c2), p1)
    assert_poly_almost_equal(np.array(c4) // p2, p1)
    assert_poly_almost_equal(2 // p2, Poly([0]))
    assert_poly_almost_equal(p2 // 2, 0.5 * p2)
    assert_raises(TypeError, op.floordiv, p1, Poly([0],
                                                   domain=Poly.domain + 1))
    assert_raises(TypeError, op.floordiv, p1, Poly([0],
                                                   window=Poly.window + 1))
    if Poly is Polynomial:
        assert_raises(TypeError, op.floordiv, p1, Chebyshev([0]))
    else:
        assert_raises(TypeError, op.floordiv, p1, Polynomial([0]))
Esempio n. 6
0
def test_mod(Poly):
    # This checks commutation, not numerical correctness
    c1 = list(random((4, )) + .5)
    c2 = list(random((3, )) + .5)
    c3 = list(random((2, )) + .5)
    p1 = Poly(c1)
    p2 = Poly(c2)
    p3 = Poly(c3)
    p4 = p1 * p2 + p3
    c4 = list(p4.coef)
    assert_poly_almost_equal(p4 % p2, p3)
    assert_poly_almost_equal(p4 % c2, p3)
    assert_poly_almost_equal(c4 % p2, p3)
    assert_poly_almost_equal(p4 % tuple(c2), p3)
    assert_poly_almost_equal(tuple(c4) % p2, p3)
    assert_poly_almost_equal(p4 % np.array(c2), p3)
    assert_poly_almost_equal(np.array(c4) % p2, p3)
    assert_poly_almost_equal(2 % p2, Poly([2]))
    assert_poly_almost_equal(p2 % 2, Poly([0]))
    assert_raises(TypeError, op.mod, p1, Poly([0], domain=Poly.domain + 1))
    assert_raises(TypeError, op.mod, p1, Poly([0], window=Poly.window + 1))
    if Poly is Polynomial:
        assert_raises(TypeError, op.mod, p1, Chebyshev([0]))
    else:
        assert_raises(TypeError, op.mod, p1, Polynomial([0]))
Esempio n. 7
0
def varPlot(fig, pca, x, bestFit):
    lim_w = numpy.argmax(numpy.abs(bestFit), axis=0)
    min_w = numpy.argmin(bestFit, axis=0)
    max_w = numpy.argmax(bestFit, axis=0)
    print "min: %s" % (min_w)
    print "max: %s" % (max_w)
    print "lim: %s" % (lim_w)

    if x == None:
        x = numpy.arange(bestFit.shape[0])
    ii = numpy.argsort(x)

    for i in range(pca.n_components):
        if i == 0:
            pRef = p = fig.add_subplot(pca.n_components,1,i+1)
        else:
            p = fig.add_subplot(pca.n_components,1,i+1, sharex=pRef)
        p.locator_params(axis='y', nbins=4)
        p.plot(x[ii], bestFit[ii,i], '+')

        p.hlines(0, *p.get_xlim(), color='r', alpha=0.5)
        t = T.fit(x[ii], bestFit[ii,i], 1)
        pt = t(x[ii])
        p.plot(x[ii], pt)

        p.plot(x[min_w[i]], bestFit[min_w[i],i], 'r*')
        p.plot(x[max_w[i]], bestFit[max_w[i],i], 'r*')
        
    return min_w, max_w, lim_w
Esempio n. 8
0
def get_fit(data, name='c', id_var=None):
    """Fit a curve to data for variable deviations."""
    # Change to long format
    try:
        data = data.melt(id_vars=id_var)
    except KeyError:
        data = data.melt()

    # Drop missing values
    data = data.dropna()

    # Take all x and y data
    x_data = data.variable.values.astype(np.float)
    y_data = data.value.values.astype(np.float)

    #  #Fit x and y data with 4th degree polynomial
    # z = np.polyfit(x_data.astype(np.float), y_data.astype(np.float), 4)
    # f = np.poly1d(z)
    # x_curve = data.variable.unique()
    # y_curve = f(x_curve)

    # !!!! Chebyshev polynomial
    c_fit = Chebyshev.fit(x_data, y_data, 5, domain=[0, 1])
    x_curve = data.variable.unique()
    y_curve = c_fit(x_curve)
    # !!!! End

    # Create DF from obtained fit
    curve = pd.DataFrame(index=[name], columns=x_curve.astype(int), data=np.reshape(y_curve, (-1, len(y_curve))))
    return curve
Esempio n. 9
0
    def set_level(self):
        self.status_bar.showMessage('calculating levels...')
        f = cv2.calcHist([self.foct_data.flatten()], [0], None, [256],
                         [0, 256])
        f = f[:, 0].astype(int)

        # fit vars
        # only want to fit right of max peak
        max_loc = f.argmax()
        f_fmax = f[max_loc:]
        x_max = np.linspace(max_loc, 255, num=len(f_fmax))

        # fit a polynomial of order
        order = 50
        poly_fit = T.fit(x_max, f_fmax, order)

        # get real roots
        roots = np.real_if_close(poly_fit.deriv(2).roots())
        roots = roots[np.isreal(roots)].real
        # get roots to right of max peak
        roots = roots[((roots >= max_loc) & (roots < 256))]

        up_thresh = int(roots[((poly_fit(roots) / f.max()) < 0.15).argmax()])

        # get lower thresh
        r_f = np.arange(len(f)) > f.argmax()
        up_f = (f / f.max() < 0.002)

        low_thresh = (r_f & up_f).argmax()

        self.setLevels(up_thresh, low_thresh)

        self.status_bar.clearMessage()
        self.status_bar.showMessage('Done!', 3000)
Esempio n. 10
0
def fit_2dwave_solution(pixtab2d, deg=5):
    # Transpose the input table cause it's easier and faster
    # to iterate over rows than columns:
    tab2d = pixtab2d.T
    fit_table2d = np.zeros_like(tab2d)
    col = np.arange(pixtab2d.shape[0])
    for num, points in enumerate(tab2d):
        # Median filter each column
        med_col, mask = median_filter_data(points)

        # Fit Cheb. poly to each filtered column
        try:
            cheb_polyfit = Chebyshev.fit(col[mask],
                                         points[mask],
                                         deg=deg,
                                         domain=(col.min(), col.max()))
        except:
            print(
                "Something went wrong in Chebyshev polynomial fitting. Here's the input:"
            )
            print("x:", col[mask])
            print("y:", points[mask])
            print("degree:", deg)
            print("domain: %r  %r" % (col.min(), col.max()))
            raise
        finally:
            np.savetxt('pixtable_2d_dump.dat', pixtab2d)

        # Insert back into the fit_table
        fit_table2d[num] = cheb_polyfit(col)

    # Transpose back to original orientation of the pixel table
    return fit_table2d.T
Esempio n. 11
0
def test_split_rect_1():
    # two functions from https://stackoverflow.com/a/9997374
    def ccw(A,B,C):
        return (C[1]-A[1]) * (B[0]-A[0]) > (B[1]-A[1]) * (C[0]-A[0])

    # Return true if line segments AB and CD intersect
    def intersect(A,B,C,D):
        return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)

    mesh = om.read_trimesh('../data/rect.obj')
    mesh_pts = mesh.points()
    mesh_edges = mesh.ev_indices()
    
    x = np.linspace(-1, 1, 101)
    y = T.basis(5)(x)
    
    # export Chebyshev polynomial
    pts = np.zeros((x.size, 3))
    pts[:, 0] = x
    pts[:, 1] = y
    mu.write_obj_lines('../data/curve_Chebyshev.obj', pts, [np.arange(pts.shape[0])])

    edges = [np.array([0,0], 'i')]
    ratios = [0.0]
    for i in range(1, x.size-2):
        A = np.array([x[i], y[i]])
        B = np.array([x[i+1], y[i+1]])
        temp_x = []
        temp_e = []
        temp_u = []
        for e in mesh_edges:
            C = mesh_pts[e[0], :2]
            D = mesh_pts[e[1], :2]
            if intersect(A, B, C, D):
                # A = (x1, y1), B = (x2, y2)    
                # C = (x3, y3), D = (x4, y4)
                u = ((A[0]-C[0])*(A[1]-B[1])-(A[1]-C[1])*(A[0]-B[0]))/((A[0]-B[0])*(C[1]-D[1])-(A[1]-B[1])*(C[0]-D[0]))
                temp_e.append(e)
                temp_u.append(u)
                temp_x.append(C[0]*(1-u)+D[0]*u)
        order = np.argsort(np.array(temp_x))
        edges.extend([temp_e[i] for i in order])
        ratios.extend([temp_u[i] for i in order])
    edges.append(np.array([2,2], 'i'))
    ratios.append(0.0)
    edges = np.array(edges, 'i')
    #print(ratios)
    ratios = np.array(ratios, 'd')
    
    pts0 = mesh_pts[edges[:, 0], :]
    pts1 = mesh_pts[edges[:, 1], :]
    pts = np.multiply(pts0, 1.-ratios[:, np.newaxis]) + \
        np.multiply(pts1, ratios[:, np.newaxis])
    mu.write_obj_lines('../data/curve.obj', pts, [np.arange(pts.shape[0])])
    # print(on_edges, ratios)
    mesh, curve_idx = mu.split_mesh_complete(mesh.points(),
                                    mesh.face_vertex_indices(),
                                    edges, ratios)
    # print(curve_idx)
    om.write_mesh('../data/mesh_split.obj', mesh)
Esempio n. 12
0
    def test_approximation(self):
        def powx(x, p):
            return x**p

        x = np.linspace(0, 2, 10)
        for deg in range(0, 10):
            for t in range(0, deg + 1):
                p = Chebyshev.interpolate(powx, deg, domain=[0, 2], args=(t, ))
                assert_almost_equal(p(x), powx(x, t), decimal=12)
Esempio n. 13
0
def chebyshev_approximation(fun, degree, R=4.0):
    bases = chebyshev_bases(degree)
    approx_coeffs = []
    for i in range(len(bases)):
        approx_coeffs.append(
            quad(lambda x: fun(R * x) * bases[i](x) / np.sqrt(1 - x**2), -1,
                 1)[0])
    std_coefs = Chebyshev(approx_coeffs).convert(kind=Polynomial).coef
    return np.power(1 / R, range(degree + 1)) * std_coefs
Esempio n. 14
0
    def _create_Tderiv(self, k, n):
        r"""Create the n'th derivative of the k'th Chebyshev polynomial."""
        if not self._use_mp:
            return ChebyshevT.basis(k).deriv(n)
        else:
            if n == 0:
                return lambda x: mp.chebyt(k, x)
            # Since the Chebyshev derivatives attain high values near the
            # borders +-1 and usually are subtracted to obtain small values,
            # minimizing their relative error (i.e. fixing the number of
            # correct decimal places (dps)) is not enough to get precise
            # results. Hence, the below `moredps` variable is set to higher
            # values close to the border.
            extradps = 5
            pos = mp.fprod(
                [mp.mpf(k**2 - p**2) / (2 * p + 1) for p in range(n)])
            neg = (-1)**(k + n) * pos
            if n == 1:

                def dTk(x):
                    with mp.extradps(extradps):
                        x = clip(x, -1.0, 1.0)
                        if mp.almosteq(x, mp.one): return pos
                        if mp.almosteq(x, -mp.one): return neg
                        moredps = max(
                            0,
                            int(-math.log10(
                                min(abs(x - mp.one), abs(x + mp.one))) / 2))
                        moredps = min(moredps, 100)
                        with mp.extradps(moredps):
                            t = mp.acos(x)
                            return k * mp.sin(k * t) / mp.sin(t)

                return dTk
            if n == 2:

                def ddTk(x):
                    with mp.extradps(extradps):
                        x = clip(x, -1.0, 1.0)
                        if mp.almosteq(x, mp.one): return pos
                        if mp.almosteq(x, -mp.one): return neg
                        moredps = max(
                            0,
                            int(-math.log10(
                                min(abs(x - mp.one), abs(x + mp.one))) * 1.5) +
                            2)
                        moredps = min(moredps, 100)
                        with mp.extradps(moredps):
                            t = mp.acos(x)
                            s = mp.sin(t)
                            return -k**2 * mp.cos(k * t) / s**2 + k * mp.cos(
                                t) * mp.sin(k * t) / s**3

                return ddTk
            raise NotImplementedError(
                'Derivatives of order > 2 not implemented.')
Esempio n. 15
0
    def test_approximation(self):

        def powx(x, p):
            return x**p

        x = np.linspace(0, 2, 10)
        for deg in range(0, 10):
            for t in range(0, deg + 1):
                p = Chebyshev.interpolate(powx, deg, domain=[0, 2], args=(t,))
                assert_almost_equal(p(x), powx(x, t), decimal=12)
Esempio n. 16
0
def fit_background_image(data, order_bg=3, xmin=0, xmax=None, kappa=10, fwhm_scale=3):
    """
    Fit background in 2D spectral data. The background is fitted along the spatial rows by a Chebyshev polynomium.

    Parameters
    ==========
    data : np.array(M, N)
        Data array holding the input image

    order_bg : integer  [default=3]
        Order of the Chebyshev polynomium to fit the background

    xmin, xmax : integer  [default=0, None]
        Mask out pixels below xmin and above xmax

    fwhm_scale : float  [default=3]
        Number of FWHM below and above centroid of auto-detected trace
        that will be masked out during fitting.

    kappa : float  [default=10]
        Threshold for masking out cosmic rays etc.

    Returns
    =======
    bg2D : np.array(M, N)
        Background model of the 2D frame, same shape as input data.
    """
    x = np.arange(data.shape[1])
    if xmax is None:
        xmax = len(x)
    if xmax < 0:
        xmax = len(x) + xmax
    SPSF = np.nanmedian(data, 0)
    noise = 1.5*mad(SPSF)
    peaks, properties = signal.find_peaks(SPSF, prominence=kappa*noise, width=3)
    mask = (x >= xmin) & (x <= xmax)
    for num, center in enumerate(peaks):
        width = properties['widths'][num]
        x1 = center - width*fwhm_scale
        x2 = center + width*fwhm_scale
        obj = (x >= x1) * (x <= x2)
        mask &= ~obj

    bg2D = np.zeros_like(data)
    for i, row in enumerate(data):
        # Median filter the data to remove outliers:
        med_row = median_filter(row, 15)
        noise = mad(row)*1.4826
        this_mask = mask * (np.abs(row - med_row) < 10*noise)
        if np.sum(this_mask) > order_bg+1:
            bg_model = Chebyshev.fit(x[this_mask], row[this_mask], order_bg, domain=[x.min(), x.max()])
            bg2D[i] = bg_model(x)

    return bg2D
Esempio n. 17
0
def chebyshev_approximation(fun, degree=4, is_zero=None):
    bases = chebyshev_bases(degree)
    approx_coeffs = []
    for i in range(len(bases)):
        if is_zero is None or not is_zero(i):
            approx_coeffs.append(
                quad(lambda x: fun(x) * bases[i](x) / np.sqrt(1 - x**2),
                     -1, 1)[0])
        else:
            approx_coeffs.append(0)
    return Chebyshev(approx_coeffs).convert(kind=Polynomial).coef
Esempio n. 18
0
def subtract_arc_background(arc2D, deg=5):
    """Subtract continuum background in arc line frames"""
    if arc2D.dtype not in [np.float64, np.float32]:
        arc2D = arc2D.astype(np.float64)
    pix = np.arange(arc2D.shape[1])
    bg2d = np.zeros_like(arc2D)
    for i, row in enumerate(arc2D):
        med1d, mask1d = median_filter_data(row)
        cheb_fit = Chebyshev.fit(pix[mask1d], row[mask1d], deg=deg)
        bg1d = cheb_fit(pix)
        bg2d[i] = bg1d
    bg_sub2d = arc2D - bg2d
    return bg_sub2d, bg2d
Esempio n. 19
0
def test_divmod(Poly):
    # This checks commutation, not numerical correctness
    c1 = list(random((4, )) + .5)
    c2 = list(random((3, )) + .5)
    c3 = list(random((2, )) + .5)
    p1 = Poly(c1)
    p2 = Poly(c2)
    p3 = Poly(c3)
    p4 = p1 * p2 + p3
    c4 = list(p4.coef)
    quo, rem = divmod(p4, p2)
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(p4, c2)
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(c4, p2)
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(p4, tuple(c2))
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(tuple(c4), p2)
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(p4, np.array(c2))
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(np.array(c4), p2)
    assert_poly_almost_equal(quo, p1)
    assert_poly_almost_equal(rem, p3)
    quo, rem = divmod(p2, 2)
    assert_poly_almost_equal(quo, 0.5 * p2)
    assert_poly_almost_equal(rem, Poly([0]))
    quo, rem = divmod(2, p2)
    assert_poly_almost_equal(quo, Poly([0]))
    assert_poly_almost_equal(rem, Poly([2]))
    assert_raises(TypeError, divmod, p1, Poly([0], domain=Poly.domain + 1))
    assert_raises(TypeError, divmod, p1, Poly([0], window=Poly.window + 1))
    if Poly is Polynomial:
        assert_raises(TypeError, divmod, p1, Chebyshev([0]))
    else:
        assert_raises(TypeError, divmod, p1, Polynomial([0]))
Esempio n. 20
0
def detrending(time, flux, err, pl):

    fluxTrue = np.isfinite(flux)
    index = np.where(fluxTrue == True)[0]
    flux_nan = flux[index]
    time = time[index]
    err_nan = err[index]
    time_nan = (time - min(time))

    time_nan, flux_nan = zip(*sorted(zip(time_nan, flux_nan)))
    time_nan = np.array(time_nan)
    flux_nan = np.array(flux_nan)

    p = T.fit(time_nan, flux_nan, pl)
    flux_model = p(time_nan)
    flux_detrended = (flux_nan - flux_model)
    flux_detrended = flux_detrended + 1

    return time_nan, flux_nan, flux_model, flux_detrended, err_nan
Esempio n. 21
0
def test_sub(Poly):
    # This checks commutation, not numerical correctness
    c1 = list(random((4, )) + .5)
    c2 = list(random((3, )) + .5)
    p1 = Poly(c1)
    p2 = Poly(c2)
    p3 = p1 - p2
    assert_poly_almost_equal(p2 - p1, -p3)
    assert_poly_almost_equal(p1 - c2, p3)
    assert_poly_almost_equal(c2 - p1, -p3)
    assert_poly_almost_equal(p1 - tuple(c2), p3)
    assert_poly_almost_equal(tuple(c2) - p1, -p3)
    assert_poly_almost_equal(p1 - np.array(c2), p3)
    assert_poly_almost_equal(np.array(c2) - p1, -p3)
    assert_raises(TypeError, op.sub, p1, Poly([0], domain=Poly.domain + 1))
    assert_raises(TypeError, op.sub, p1, Poly([0], window=Poly.window + 1))
    if Poly is Polynomial:
        assert_raises(TypeError, op.sub, p1, Chebyshev([0]))
    else:
        assert_raises(TypeError, op.sub, p1, Polynomial([0]))
Esempio n. 22
0
def check_add(Poly):
    # This checks commutation, not numerical correctness
    c1 = list(random((4,)) + .5)
    c2 = list(random((3,)) + .5)
    p1 = Poly(c1)
    p2 = Poly(c2)
    p3 = p1 + p2
    assert_poly_almost_equal(p2 + p1, p3)
    assert_poly_almost_equal(p1 + c2, p3)
    assert_poly_almost_equal(c2 + p1, p3)
    assert_poly_almost_equal(p1 + tuple(c2), p3)
    assert_poly_almost_equal(tuple(c2) + p1, p3)
    assert_poly_almost_equal(p1 + np.array(c2), p3)
    assert_poly_almost_equal(np.array(c2) + p1, p3)
    assert_raises(TypeError, p1.__add__, Poly([0], domain=Poly.domain + 1))
    assert_raises(TypeError, p1.__add__, Poly([0], window=Poly.window + 1))
    if Poly is Polynomial:
        assert_raises(TypeError, p1.__add__, Chebyshev([0]))
    else:
        assert_raises(TypeError, p1.__add__, Polynomial([0]))
Esempio n. 23
0
def test_mul(Poly):
    c1 = list(random((4, )) + .5)
    c2 = list(random((3, )) + .5)
    p1 = Poly(c1)
    p2 = Poly(c2)
    p3 = p1 * p2
    assert_poly_almost_equal(p2 * p1, p3)
    assert_poly_almost_equal(p1 * c2, p3)
    assert_poly_almost_equal(c2 * p1, p3)
    assert_poly_almost_equal(p1 * tuple(c2), p3)
    assert_poly_almost_equal(tuple(c2) * p1, p3)
    assert_poly_almost_equal(p1 * np.array(c2), p3)
    assert_poly_almost_equal(np.array(c2) * p1, p3)
    assert_poly_almost_equal(p1 * 2, p1 * Poly([2]))
    assert_poly_almost_equal(2 * p1, p1 * Poly([2]))
    assert_raises(TypeError, op.mul, p1, Poly([0], domain=Poly.domain + 1))
    assert_raises(TypeError, op.mul, p1, Poly([0], window=Poly.window + 1))
    if Poly is Polynomial:
        assert_raises(TypeError, op.mul, p1, Chebyshev([0]))
    else:
        assert_raises(TypeError, op.mul, p1, Polynomial([0]))
Esempio n. 24
0
 def test_dimensions(self):
     for deg in range(1, 5):
         assert_(Chebyshev.interpolate(self.f, deg).degree() == deg)
import matplotlib.pyplot as plt
from numpy.polynomial import Chebyshev as T
x = np.linspace(-2, 2, 100)
for i in range(6):
    ax = plt.plot(x, T.basis(i)(x), lw=2, label="T_%d" % i)
# ...
plt.legend(loc="lower right")
# <matplotlib.legend.Legend object at 0x3b3ee10>
plt.show()
Esempio n. 26
0
def T(n_):
    return Chebyshev(np.append(np.zeros(n_), 1))
import numpy as np
import matplotlib.pyplot as plt
from numpy.polynomial import Chebyshev as T
np.random.seed(11)
x = np.linspace(0, 2*np.pi, 20)
y = np.sin(x) + np.random.normal(scale=.1, size=x.shape)
p = T.fit(x, y, 5)
plt.plot(x, y, 'o')
# [<matplotlib.lines.Line2D object at 0x2136c10>]
xx, yy = p.linspace()
plt.plot(xx, yy, lw=2)
# [<matplotlib.lines.Line2D object at 0x1cf2890>]
p.domain
# array([ 0.        ,  6.28318531])
p.window
# array([-1.,  1.])
plt.show()
import matplotlib.pyplot as plt
from numpy.polynomial import Chebyshev as T
x = np.linspace(-1, 1, 100)
for i in range(6): ax = plt.plot(x, T.basis(i)(x), lw=2, label="T_%d"%i)
# ...
plt.legend(loc="upper left")
# <matplotlib.legend.Legend object at 0x3b3ee10>
plt.show()
Esempio n. 29
0
 def test_dimensions(self):
     for deg in range(1, 5):
         assert_(Chebyshev.interpolate(self.f, deg).degree() == deg)
Esempio n. 30
0
from numpy.polynomial import Chebyshev as T

x = 10*np.random.rand(100)
y = 0.1*np.random.randn(100) + sin(x)
plot(x,y,'.')

fit = T.fit(x,y,10)
xx, yy = fit.linspace(100)
plot(xx,yy)

fit_x = fit.deriv(1)
fit_xx = fit.deriv(2)
plot(*fit_x.linspace(100))
plot(*fit_xx.linspace(100))

fit = T.fit(x,y,50)
xx, yy = fit.linspace(100)
Esempio n. 31
0
def find_apertures(data,
                   scan_step=100,
                   align_deg=2,
                   degree=4,
                   mode='normal',
                   figpath='images'):
    """Find order locations for CFHT/ESPaDOnS data.

    Args:
        data ():
        scan_step (int):
        align_deg (int):
        degree (int):
        mode (normal):
        figpath (str):

    """

    # prepare for figures
    if mode == 'debug':
        dbgpath = 'debug'
        if not os.path.exists(dbgpath):
            os.mkdir(dbgpath)
        plot_alignfit = True
        plot_orderfit = True
        plot_detection = True
        figname_alignfit = lambda x1: os.path.join(
            dbgpath, 'alignfit_{:04d}.png'.format(x1))
        figname_orderfit = lambda iorder: os.path.join(
            dbgpath, 'orderfit_{:03d}.png'.format(iorder))
        figname_detection = os.path.join(dbgpath, 'order_detection.png')
    else:
        plot_alignfit = False
        plot_orderfit = False
        plot_detection = False
    plot_orderalign = True
    plot_allorders = True
    figname_orderalign = os.path.join(figpath, 'order_alignment.png')
    figname_allorders = os.path.join(figpath, 'order_all.png')

    ny, nx = data.shape
    allx = np.arange(nx)

    def forward(x, p):
        deg = len(p) - 1
        res = p[0]
        for i in range(deg):
            res = res * x + p[i + 1]
        return res

    def forward_der(x, p):
        deg = len(p) - 1
        p_der = [(deg - i) * p[i] for i in range(deg)]
        return forward(x, p_der)

    def backward(y, p):
        x = y
        for ite in range(20):
            dy = forward(x, p) - y
            y_der = forward_der(x, p)
            dx = dy / y_der
            x = x - dx
            if (np.abs(dx) < 1e-7).all():
                break
        return x

    def fitfunc(p, interfunc, n):
        #return p[-2]*interfunc(forward(np.arange(n), p[0:-2]))+p[-1]
        return interfunc(forward(np.arange(n), p[0:-1])) + p[-1]

    def resfunc(p, interfunc, flux0, mask=None):
        res_lst = flux0 - fitfunc(p, interfunc, flux0.size)
        if mask is None:
            mask = np.ones_like(flux0, dtype=np.bool)
        return res_lst[mask]

    x0 = ny // 2
    x_lst = {-1: [], 1: []}
    param_lst = {-1: [], 1: []}
    x1 = x0
    direction = -1
    icol = 0

    all_order_param_lst = {}
    all_aligned_x_lst = {}

    if plot_orderalign:
        fig0 = plt.figure(figsize=(12, 6), dpi=200)
        ax0 = fig0.add_axes([0.07, 0.1, 0.4, 0.8])
        ax1 = fig0.add_axes([0.53, 0.1, 0.4, 0.8])
    while (True):
        #flux1 = np.mean(logdata[x1-2:x1+3, :], axis=0)
        flux1 = np.mean(data[x1 - 2:x1 + 3, :], axis=0)

        # fix negative values in cross-section
        negmask = flux1 < 0
        if negmask.sum() > 0:
            message = 'Negative values in Col {}: {}'.format(x1, allx[negmask])
            f = intp.InterpolatedUnivariateSpline(allx[~negmask],
                                                  flux1[~negmask],
                                                  k=1,
                                                  ext='const')
            flux1 = f(allx)

        logflux1 = np.log(flux1)

        if icol == 0:
            logflux1_center = logflux1
            if plot_orderalign:
                ax0.plot(np.arange(nx), (logflux1 - 1) * 100 + x1,
                         color='C0',
                         lw=0.6)
                ax1.plot(np.arange(nx), (logflux1 - 1) * 100 + x1,
                         color='C0',
                         lw=0.6)

            all_order_param_lst[x1] = find_order_locations(flux1, x1)
            all_aligned_x_lst[x1] = allx

        else:

            p0 = [0.0 for i in range(align_deg + 1)]
            p0[-3] = 1.0
            #p0 = [0.0 for i in range(deg+2)]
            #p0[-4] = 1.0
            interfunc = intp.InterpolatedUnivariateSpline(np.arange(
                logflux1.size),
                                                          logflux1,
                                                          k=3,
                                                          ext=3)
            mask = np.ones_like(logflux0, dtype=np.bool)
            clipping = 5.
            maxiter = 10
            for i in range(maxiter):
                param, _ = opt.leastsq(resfunc,
                                       p0,
                                       args=(interfunc, logflux0, mask))
                res_lst = resfunc(param, interfunc, logflux0)
                std = res_lst.std()
                mask1 = res_lst < clipping * std
                mask2 = res_lst > -clipping * std
                new_mask = mask1 * mask2
                if new_mask.sum() == mask.sum():
                    break
                mask = new_mask
                p0 = param

            if plot_alignfit:
                figalg = plt.figure(dpi=200)
                axa1 = figalg.add_subplot(211)
                axa2 = figalg.add_subplot(212)
                axa1.plot(logflux0, lw=0.5, label='Template')
                axa1.plot(logflux1, lw=0.5, label='Flux')
                axa1.plot(fitfunc(param, interfunc, logflux0.size),
                          lw=0.5,
                          label='Shifted Flux')
                axa2.plot(resfunc(param, interfunc, logflux0), lw=0.5)
                axa1.set_xlim(0, nx - 1)
                axa2.set_xlim(0, nx - 1)
                axa1.set_ylim(1, 10)
                axa1.legend(loc='lower center', ncol=3)
                title = 'Order Alignment for Column {:04d}'.format(x1)
                figalg.suptitle(title)
                figname = figname_alignfit(x1)
                figalg.savefig(figname)
                plt.close(figalg)
                message = 'savefig: "{}": {}'.format(figname, title)
                logger.info(message)

            param_lst[direction].append(param[0:-1])
            #param_lst[direction].append(param[0:-2])

            aligned_allx = allx.copy()
            for param in param_lst[direction][::-1]:
                aligned_allx = backward(aligned_allx, param)

            if plot_orderalign:
                ax0.plot(allx, (logflux1 - 1) * 100 + x1,
                         color='k',
                         alpha=0.2,
                         lw=0.6)
                ax1.plot(aligned_allx, (logflux1 - 1) * 100 + x1,
                         color='k',
                         alpha=0.2,
                         lw=0.6)

            all_order_param_lst[x1] = find_order_locations(flux1,
                                                           x1,
                                                           aligned_allx,
                                                           mode=mode)
            all_aligned_x_lst[x1] = aligned_allx

        x1 += direction * scan_step
        if x1 <= 10:
            # turn to the other direction
            direction = +1
            x1 = x0 + direction * scan_step
            x_lst[direction].append(x1)
            logflux0 = logflux1_center
            icol += 1
            continue
        elif x1 >= ny - 20:
            # scan ends
            break
        else:
            x_lst[direction].append(x1)
            logflux0 = logflux1
            icol += 1
            continue

    if plot_orderalign:
        title = 'Order Alignment'
        fig0.suptitle(title)
        fig0.savefig(figname_orderalign)
        plt.close(fig0)
        message = 'savefig: "{}": {}'.format(figname_orderalign, title)
        logger.info(message)

    aligned_bound_lst = []
    all_aligned_order_param_lst = {}
    for x1, order_param_lst in sorted(all_order_param_lst.items()):
        aligned_x = all_aligned_x_lst[x1]

        aligned_bound_lst.append(
            (math.floor(aligned_x[0]), math.ceil(aligned_x[-1])))

        f = intp.InterpolatedUnivariateSpline(allx, aligned_x, k=3)

        # find aligned order param
        aligned_order_param_lst = [(f(i1), f(i2), f(v1), f(v2), f(v3))
                                   for i1, i2, v1, v2, v3 in order_param_lst]
        all_aligned_order_param_lst[x1] = aligned_order_param_lst

    aligned_peakAB_lst = []
    aligned_peakA_lst = []
    aligned_peakB_lst = []
    for x1, aligned_order_param_lst in sorted(
            all_aligned_order_param_lst.items()):
        for _, _, newv1, newv2, newv3 in aligned_order_param_lst:
            aligned_peakAB_lst.append(newv1)
            aligned_peakA_lst.append(newv2)
            aligned_peakB_lst.append(newv3)

    minx = min(aligned_bound_lst, key=lambda item: item[0])[0]
    maxx = max(aligned_bound_lst, key=lambda item: item[1])[1]
    bins = np.arange(minx, maxx + 1, 1)
    histAB, _ = np.histogram(aligned_peakAB_lst, bins=bins)
    histA, _ = np.histogram(aligned_peakA_lst, bins=bins)
    histB, _ = np.histogram(aligned_peakB_lst, bins=bins)
    binx = bins[0:-1] + np.diff(bins) / 2

    # find allsize_lst, which is the number of columns scanned in each
    # cross-disp pixels
    allsize_lst = np.zeros(maxx - minx)
    for (x1, x2) in aligned_bound_lst:
        xlst = np.ones(x2 - x1)
        # add zeros in the beginning
        xlst = np.insert(xlst, 0, [0] * (x1 - minx))
        # add zeros in the end
        xlst = np.append(xlst, [0] * (maxx - x2))
        allsize_lst += xlst
    # normalize the histogram
    norm_histAB = histAB / allsize_lst
    norm_histA = histA / allsize_lst
    norm_histB = histB / allsize_lst

    if plot_detection:
        # fig5 is the order detection figure
        fig5 = plt.figure(figsize=(10, 5), dpi=150)
        ax51 = fig5.add_subplot(211)
        ax52 = fig5.add_subplot(212)
        ax51.fill_between(binx, histAB, color='C1', step='mid', alpha=0.6)
        ax51.fill_between(binx, histA, color='C0', step='mid', alpha=0.6)
        ax51.fill_between(binx, histB, color='C3', step='mid', alpha=0.6)
        ax51.step(binx, allsize_lst)
        ax52.fill_between(binx, norm_histAB, color='C1', step='mid', alpha=0.6)
        ax52.fill_between(binx, norm_histA, color='C0', step='mid', alpha=0.6)
        ax52.fill_between(binx, norm_histB, color='C3', step='mid', alpha=0.6)
        y1, y2 = ax52.get_ylim()

    # get group list
    idx = np.where(norm_histAB > 1e-5)[0]
    groupAB_lst = np.split(idx, np.where(np.diff(idx) > 2)[0] + 1)
    centAB_lst = [
        (binx[group] * norm_histAB[group]).sum() / (norm_histAB[group].sum())
        for group in groupAB_lst
    ]
    cumnAB_lst = [norm_histAB[group].sum() for group in groupAB_lst]

    idx = np.where(norm_histA > 1e-5)[0]
    groupA_lst = np.split(idx, np.where(np.diff(idx) > 2)[0] + 1)
    centA_lst = [
        (binx[group] * norm_histA[group]).sum() / (norm_histA[group].sum())
        for group in groupA_lst
    ]
    cumnA_lst = [norm_histA[group].sum() for group in groupA_lst]

    idx = np.where(norm_histB > 1e-5)[0]
    groupB_lst = np.split(idx, np.where(np.diff(idx) > 2)[0] + 1)
    centB_lst = [
        (binx[group] * norm_histB[group]).sum() / (norm_histB[group].sum())
        for group in groupB_lst
    ]
    cumnB_lst = [norm_histB[group].sum() for group in groupB_lst]

    x1_lst = [x0]
    for direction in [1, -1]:
        for x1 in x_lst[direction]:
            x1_lst.append(x1)

    order_AB_lst = {}
    order_A_lst = {}
    order_B_lst = {}
    iorder = 0
    for group, cent, cumn, groupA, centA, cumnA, groupB, centB, cumnB in zip(
            groupAB_lst,
            centAB_lst,
            cumnAB_lst,
            groupA_lst,
            centA_lst,
            cumnA_lst,
            groupB_lst,
            centB_lst,
            cumnB_lst,
    ):
        if cumn < 0.3:
            continue

        xlst, yABlst, yAlst, yBlst = [], [], [], []

        for x1 in x1_lst:
            order_param_lst = all_order_param_lst[x1]
            aligned_order_param_lst = all_aligned_order_param_lst[x1]

            for (_, _, v1, v2, v3), (_, _, newv1, newv2,
                                     newv3) in zip(order_param_lst,
                                                   aligned_order_param_lst):
                if binx[group[0]] - 1 < newv1 < binx[group[-1]] + 1:
                    xlst.append(x1)
                    yABlst.append(v1)
                    yAlst.append(v2)
                    yBlst.append(v3)
                    break
        xlst = np.array(xlst)
        yABlst = np.array(yABlst)
        yAlst = np.array(yAlst)
        yBlst = np.array(yBlst)

        # sort again
        idx = xlst.argsort()
        xlst = xlst[idx]
        yABlst = yABlst[idx]
        yAlst = yAlst[idx]
        yBlst = yBlst[idx]
        order_AB_lst[iorder] = (xlst, yABlst)
        order_A_lst[iorder] = (xlst, yAlst)
        order_B_lst[iorder] = (xlst, yBlst)
        iorder += 1

    # plot in order detection figure
    if plot_detection:
        for group in groupAB_lst:
            i1, i2 = group[0], group[-1]
            ax52.fill_betweenx([y1, y2],
                               binx[i1],
                               binx[i2],
                               color='C3',
                               alpha=0.1)
        ax52.set_ylim(y1, y2)
        ax51.set_xlim(minx, maxx)
        ax52.set_xlim(minx, maxx)

        fig5.savefig(figname_detection)
        plt.close(fig5)
        message = 'savefig: "{}": Order detections'.format(figname_detection)
        logger.info(message)

    aperture_set = ApertureSet(shape=(ny, nx))
    aperture_set_A = ApertureSet(shape=(ny, nx))
    aperture_set_B = ApertureSet(shape=(ny, nx))

    # plot all order position in a single figure
    if plot_allorders:
        figall = plt.figure(figsize=(14, 7), dpi=200)
        axall = figall.add_axes([0.1, 0.05, 0.8, 0.85])

    ######### fit order positions and pack them to ApertureSet ##########
    for iorder in sorted(order_AB_lst.keys()):
        xlst_AB, ylst_AB = order_AB_lst[iorder]
        xlst_A, ylst_A = order_A_lst[iorder]
        xlst_B, ylst_B = order_B_lst[iorder]

        ##################### Parse Center of Fiber A & B ################
        fitmask = np.ones_like(xlst_AB, dtype=np.bool)
        maxiter = 10
        for nite in range(maxiter):
            poly = Chebyshev.fit(xlst_AB[fitmask],
                                 ylst_AB[fitmask],
                                 deg=degree)
            yres = ylst_AB - poly(xlst_AB)
            std = yres[fitmask].std()
            new_fitmask = (yres > -3 * std) * (yres < 3 * std)
            if new_fitmask.sum() == fitmask.sum():
                break
            fitmask = new_fitmask

        aperture_loc = ApertureLocation(direct='y', shape=(ny, nx))
        aperture_loc.set_position(poly)
        aperture_set[iorder] = aperture_loc

        color = 'C1'
        label = 'Fiber A+B'
        if plot_allorders:
            axall.scatter(xlst_AB,
                          ylst_AB,
                          s=15,
                          color='none',
                          edgecolor=color)
            axall.scatter(xlst_AB[fitmask],
                          ylst_AB[fitmask],
                          s=15,
                          color=color)
            # prepare newx, newy, and m (mask) for plotting a smooth line
            newx = np.arange(0, ny)
            newy = poly(newx)
            m = (newy >= 0) * (newy < nx)
            axall.plot(newx[m], newy[m], '-', color='C0', lw=0.7)

        if plot_orderfit:
            # plot position fitting of each order
            # initialize fig
            figm = plt.figure(dpi=150)
            axm1 = figm.add_axes([0.1, 0.4, 0.8, 0.50])
            axm2 = figm.add_axes([0.1, 0.1, 0.8, 0.25])

            axm1.scatter(xlst_AB, ylst_AB, s=10, color='none', edgecolor=color)
            axm1.scatter(xlst_AB[fitmask], ylst_AB[fitmask], s=10, color=color)
            axm1.plot(newx[m], newy[m], '-', color=color, lw=0.7, label=label)
            # plot fitting residuals
            yres_AB = ylst_AB - poly(xlst_AB)
            axm2.scatter(xlst_AB, yres_AB, s=10, color='none', edgecolor=color)
            axm2.scatter(xlst_AB[fitmask], yres_AB[fitmask], s=10, color=color)

        ######################## Parse Fiber A ########################
        fitmask = np.ones_like(xlst_A, dtype=np.bool)
        maxiter = 10
        for nite in range(maxiter):
            poly = Chebyshev.fit(xlst_A[fitmask], ylst_A[fitmask], deg=degree)
            yres = ylst_A - poly(xlst_A)
            std = yres[fitmask].std()
            new_fitmask = (yres > -3 * std) * (yres < 3 * std)
            if new_fitmask.sum() == fitmask.sum():
                break
            fitmask = new_fitmask

        aperture_loc = ApertureLocation(direct='y', shape=(ny, nx))
        aperture_loc.set_position(poly)
        aperture_set_A[iorder] = aperture_loc

        color = 'C0'
        label = 'Fiber A'
        if plot_allorders:
            axall.scatter(xlst_A, ylst_A, s=15, color='none', edgecolor=color)
            axall.scatter(xlst_A[fitmask], ylst_A[fitmask], s=15, color=color)
            # prepare newx, newy, and m (mask) for plotting a smooth line
            newx = np.arange(0, ny)
            newy = poly(newx)
            m = (newy >= 0) * (newy < nx)
            axall.plot(newx[m], newy[m], '-', color='C0', lw=0.7)

        if plot_orderfit:
            # plot position fitting of each order
            axm1.scatter(xlst_A, ylst_A, s=10, color='none', edgecolor=color)
            axm1.scatter(xlst_A[fitmask], ylst_A[fitmask], s=10, color=color)
            axm1.plot(newx[m], newy[m], '-', color=color, lw=0.7, label=label)
            # plot fitting residuals
            yres_A = ylst_A - poly(xlst_A)
            axm2.scatter(xlst_A, yres_A, s=10, color='none', edgecolor=color)
            axm2.scatter(xlst_A[fitmask], yres_A[fitmask], s=10, color=color)

        ########################### Parse Fiber B #######################
        fitmask = np.ones_like(xlst_B, dtype=np.bool)
        maxiter = 10
        for nite in range(maxiter):
            poly = Chebyshev.fit(xlst_B[fitmask], ylst_B[fitmask], deg=degree)
            yres = ylst_B - poly(xlst_B)
            std = yres[fitmask].std()
            new_fitmask = (yres > -3 * std) * (yres < 3 * std)
            if new_fitmask.sum() == fitmask.sum():
                break
            fitmask = new_fitmask

        aperture_loc = ApertureLocation(direct='y', shape=(ny, nx))
        aperture_loc.set_position(poly)
        aperture_set_B[iorder] = aperture_loc

        color = 'C3'
        label = 'Fiber B'
        if plot_allorders:
            axall.scatter(xlst_B, ylst_B, s=15, color='none', edgecolor=color)
            axall.scatter(xlst_B[fitmask], ylst_B[fitmask], s=15, color=color)
            # prepare newx, newy, and m (mask) for plotting a smooth line
            newx = np.arange(0, ny)
            newy = poly(newx)
            m = (newy >= 0) * (newy < nx)
            axall.plot(newx[m], newy[m], '-', color='C0', lw=0.7)

        if plot_orderfit:
            # plot position fitting of each order
            axm1.scatter(xlst_B, ylst_B, s=10, color='none', edgecolor=color)
            axm1.scatter(xlst_B[fitmask], ylst_B[fitmask], s=10, color=color)
            axm1.plot(newx[m], newy[m], '-', color=color, lw=0.7, label=label)
            # plot fitting residuals
            yres_B = ylst_B - poly(xlst_B)
            axm2.scatter(xlst_B, yres_B, s=10, color='none', edgecolor=color)
            axm2.scatter(xlst_B[fitmask], yres_B[fitmask], s=10, color=color)

            # decorate and save the order fit figure
            axm1.set_xlim(0, ny - 1)
            axm2.set_xlim(0, ny - 1)
            legend = axm1.legend(loc='upper center', ncol=3)
            title = 'Position fitting of Order {:03d}'.format(iorder)
            figm.suptitle(title)
            figname = figname_orderfit(iorder)
            figm.savefig(figname)
            plt.close(figm)
            message = 'savefig: "{}": {}'.format(figname, title)
            logger.info(message)

        ####################################################################

    # decoration of all order figure
    if plot_allorders:
        axall.grid(True, ls='--', lw=0.5)
        axall.set_axisbelow(True)
        axall.set_xlim(0, ny - 1)
        axall.set_ylim(0, nx - 1)
        axall.set_aspect(1)
        figall.savefig(figname_allorders)
        plt.close(figall)
        message = 'savefig: "{}": All order positions'.format(
            figname_allorders)
        logger.info(message)

    return aperture_set, aperture_set_A, aperture_set_B
newdata =p([4,6])
print(newdata)
print(newdata.integ())
print(newdata.integ(1))
print(newdata.integ(lbnd=-1))
print(newdata.integ(lbnd=-1, k=1))
print("\n")
exa=p([1,2,3])
print(exa.deriv(1))

import matplotlib.pyplot as plt
from numpy.polynomial import Chebyshev as T
x = np.linspace(-1, 1, 100)
#x= np.linspace(-2,2,100)
for i in range(5):
    ax = plt.plot(x, T.basis(i)(x), lw=2, label="$T_%d$"%i)
plt.legend()
plt.show()



np.random.seed(11)
x = np.linspace(0, 2*np.pi, 20)
y = np.sin(x) + np.random.normal(scale=.1, size=x.shape)
p = T.fit(x, y, 5)
plt.plot(x, y, 'o')
xx, yy = p.linspace()
plt.plot(xx, yy, lw=2)
p.domain
p.window
plt.show()
Esempio n. 33
0
#figure_width = 0.35*text_width
#figure_height = 0.75*figure_width #(figure_width / golden_ratio) #figure_width

figure_width = 0.75*text_width
figure_height = (figure_width / golden_ratio) #figure_width
figure_size = [figure_width, figure_height]
config.load_config_medium()

#fig = plt.figure(figsize=figure_size, dpi=100)
fig, axes = plt.subplots(nrows=1, ncols=1, sharex=True, sharey=True, squeeze=False, figsize=figure_size, dpi=100)
ax = axes[0][0]
x = np.linspace(-1, 1, 100)

for i in range(6):
    ax.plot(x, T.basis(i)(x), lw=1.0, color=colors[i], label="$t_%d(x)$"%i)
    #ax.plot(x, pow(x, i), lw=1.0, color=colors[i], label="$x^%d$"%i)

ax.set_xlabel(r"$x$")
ax.set_ylabel(r"$t_n(x)$", rotation=90)
ax.set_xlim(-1.1, 1.1)
ax.set_ylim(-1.1, 1.1)
ax.xaxis.labelpad = 5
ax.yaxis.labelpad = 2

# Shrink current axis's height by 10% on the bottom
#box = ax.get_position()
#ax.set_position([box.x0, box.y0 - 0.1*box.height, box.width, 0.9*box.height]) #left, bottom, width, height

plt.subplots_adjust(top=0.85, left=0.12, bottom=0.12, right=0.98)  # Legend on top
Esempio n. 34
0
def apply_transform(img2D,
                    pix,
                    fit_table2d,
                    ref_table,
                    err2D=None,
                    mask2D=None,
                    header={},
                    order_wl=4,
                    log=False,
                    N_out=None,
                    interpolate=True):
    """
    Apply 2D wavelength transformation to the input image

    img2D : array, shape(M, N)
        Input 2D spectrum oriented with dispersion along x-axis!

    pix : array, shape (N)
        Input pixel array along dispersion axis.

    fit_table2d : array, shape(M, L)
        Fitted wavelength solutions from corresponding arc-line frame
        for L fitted reference lines.

    ref_table : array, shape(L, 2)
        Reference table for the given setup with two columns:
            pixel  and  wavelength in Å

    err2D : array, shape(M, N)
        Associated error array, must be same shape as `img2D`

    header : FITS Header or dict
        The FITS header corresponding to `img2D`, or a dictionary

    order_wl : int
        Polynomial order used for wavelength fit as a function of input pixel
        A Chebyshev polynomium is used to fit the solution for each row in img2D.

    log : bool  [default=False]
        Use logarithmic binning in wavelength?

    N_out : int
        Number of output pixels along dispersion axis.
        If `None` is given, the default is to use the same number
        of pixels as in the input image.

    interpolate : bool  [default=True]
        Interpolate the image onto new grid or use sub-pixel shifting

    Returns
    -------
    img2D_tr : array, shape(M, N_out)
        Transformed 2D spectrum with wavelength along x-axis.

    wl : array, shape(N_out)
        Coresponding wavelength array along x-axis.

    hdr_tr : FITS Header or dict
        Updated FITS Header or dictionary with wavelength information
    """
    msg = list()
    # Define wavelength grid at midpoint:
    if N_out is None:
        N_out = img2D.shape[1]
    else:
        if not interpolate:
            N_out = img2D.shape[1]
            msg.append("[WARNING] - Interpolation turned off!")
            msg.append("[WARNING] - N_out was given: %i" % N_out)
            msg.append(
                "[WARNING] - Cannot change sampling without interpolating")

    pix_in = pix
    cen = fit_table2d.shape[0] // 2
    ref_wl = ref_table[:, 1]
    central_solution = Chebyshev.fit(fit_table2d[cen],
                                     ref_wl,
                                     deg=order_wl,
                                     domain=[pix_in.min(),
                                             pix_in.max()])
    wl_central = central_solution(pix_in)
    wl_residuals = np.std(ref_wl - central_solution(fit_table2d[cen]))
    msg.append("          - Residuals of wavelength solution: %.2f Å" %
               wl_residuals)
    if log:
        wl = np.logspace(np.log10(wl_central.min()),
                         np.log10(wl_central.max()), N_out)
        hdr_tr = header.copy()
        hdr_tr['CRPIX1'] = 1
        hdr_tr['CDELT1'] = np.diff(np.log10(wl))[0]
        hdr_tr['CRVAL1'] = np.log10(wl[0])
        hdr_tr['CTYPE1'] = 'LOGLAM  '
        hdr_tr['CUNIT1'] = 'Angstrom'
        msg.append(
            "          - Creating logarithmically sampled wavelength grid")
        msg.append("          - Sampling: %.3f  (logÅ/pix)" %
                   np.diff(np.log10(wl))[0])
    else:
        wl = np.linspace(wl_central.min(), wl_central.max(), N_out)
        hdr_tr = header.copy()
        hdr_tr['CRPIX1'] = 1
        hdr_tr['CDELT1'] = np.diff(wl)[0]
        hdr_tr['CRVAL1'] = wl[0]
        hdr_tr['CTYPE1'] = 'LINEAR  '
        hdr_tr['CUNIT1'] = 'Angstrom'
        msg.append("          - Creating linearly sampled wavelength grid")
        msg.append("          - Sampling: %.3f  (Å/pix)" % np.diff(wl)[0])

    # Calculate the maximum curvature of the arc lines:
    max_curvature = table2D_max_curvature(fit_table2d)
    msg.append("          - Maximum curvature of arc lines: %.3f pixels" %
               max_curvature)
    if max_curvature < 0.1:
        interpolate = False
        msg.append(
            "          - Maximum curvature less than 1/10 pixel. No need to interpolate the data"
        )

    if interpolate:
        img2D_tr = np.zeros((img2D.shape[0], N_out))
        err2D_tr = np.zeros((img2D.shape[0], N_out))
        mask2D_tr = np.zeros((img2D.shape[0], N_out))
        for i, row in enumerate(img2D):
            # - fit the chebyshev polynomium
            solution_row = Chebyshev.fit(fit_table2d[i],
                                         ref_wl,
                                         deg=order_wl,
                                         domain=[pix_in.min(),
                                                 pix_in.max()])
            wl_row = solution_row(pix_in)
            if np.diff(wl_row)[0] < 0:
                # Wavelengths are decreasing: Flip arrays
                row = row[::-1]
                wl_row = wl_row[::-1]
                flip_array = True
            else:
                flip_array = False

            # -- interpolate the data onto the fixed wavelength grid
            if err2D is not None:
                err_row = err2D[i]
                if flip_array:
                    err_row = err_row[::-1]
                interp_row, interp_err = spectres.spectres(wl,
                                                           wl_row,
                                                           row,
                                                           spec_errs=err_row,
                                                           verbose=False,
                                                           fill=0.)
                err2D_tr[i] = interp_err
            else:
                interp_row = spectres.spectres(wl,
                                               wl_row,
                                               row,
                                               verbose=False,
                                               fill=0.)

            mask_row = mask2D[i]
            mask_int = np.interp(wl, wl_row, mask_row)
            mask2D_tr[i] = np.ceil(mask_int).astype(int)
            img2D_tr[i] = interp_row
    else:
        img2D_tr = img2D
        err2D_tr = err2D
        mask2D_tr = mask2D
    output_msg = "\n".join(msg)
    return img2D_tr, err2D_tr, mask2D_tr, wl, hdr_tr, output_msg
Esempio n. 35
0
def chebyshev_approximation_alt(func, deg, a=-4, b=4):
    return Chebyshev.interpolate(func, deg,
                                 domain=[a, b]).convert(kind=Polynomial).coef
Esempio n. 36
0
def chebyshev_basis(k):
    for i in range(len(CHEBYSHEV_BASIS), k + 1):
        coeffs = np.zeros(i + 1)
        coeffs[-1] = (1. + np.sign(i)) / np.pi
        CHEBYSHEV_BASIS.append(Chebyshev(coeffs))
    return CHEBYSHEV_BASIS[k]
Esempio n. 37
0
def wavecal_1d(input_fname,
               pixtable_fname,
               *,
               output,
               order_wl=None,
               log=False,
               N_out=None,
               linearize=True):
    """Apply wavelength calibration to 1D spectrum"""
    msg = list()

    pixtable = np.loadtxt(pixtable_fname)
    msg.append("          - Loaded pixel table: %s" % pixtable_fname)
    if order_wl is None:
        order_wl, found_in_file = get_order_from_file(pixtable_fname)
        if found_in_file:
            msg.append("          - Loaded polynomial order from file: %i" %
                       order_wl)
        else:
            msg.append("          - Using default polynomial order: %i" %
                       order_wl)
    else:
        msg.append("          - Using polynomial order: %i" % order_wl)

    if log:
        linearize = True

    # Load input data:
    hdu_list = fits.open(input_fname)
    msg.append("          - Loaded spectrum: %s" % input_fname)
    output_hdu = fits.HDUList()
    for hdu in hdu_list[1:]:
        wl_unit = hdu.columns['WAVE'].unit
        if wl_unit and wl_unit.lower() in ['angstrom', 'nm', 'a', 'aa']:
            msg.append(
                " [ERROR]  - Spectrum is already wavelength calibrated.")
            msg.append("")
            output_msg = "\n".join(msg)
            return output_msg
        tab = hdu.data
        hdr = hdu.header
        pix = tab['WAVE']
        flux1d = tab['FLUX']
        err1d = tab['ERR']

        if N_out is None:
            N_out = len(pix)
        else:
            if N_out != len(pix):
                linearize = True

        # Fit wavelength solution
        solution = Chebyshev.fit(pixtable[:, 0],
                                 pixtable[:, 1],
                                 deg=order_wl,
                                 domain=[pix.min(), pix.max()])
        wl = solution(pix)
        res = np.std(pixtable[:, 1] - solution(pixtable[:, 0]))
        msg.append(
            "          - Fitting wavelength solution with polynomium of order: %i"
            % order_wl)
        msg.append(
            "          - Standard deviation of wavelength residuals: %.3f Å" %
            res)
        hdr['CUNIT1'] = 'Angstrom'
        hdr['WAVERES'] = (np.round(res, 2), "RMS of wavelength residuals")
        if linearize:
            if log:
                msg.append(
                    "          - Interpolating spectrum onto logarithmic grid")
                wl_new = np.logspace(np.log10(wl.min()), np.log10(wl.max()),
                                     N_out)
                dv = np.diff(wl_new)[0] / wl_new[0] * 299792.
                dlog = np.diff(np.log10(wl_new))[0]
                msg.append("          - wavelength step: %.3f  [log(Å)]" %
                           dlog)
                msg.append("          - wavelength step: %.1f  [km/s]" % dv)
            else:
                msg.append(
                    "          - Interpolating spectrum onto linear grid")
                wl_new = np.linspace(wl.min(), wl.max(), N_out)
                dl = np.diff(wl_new)[0]
                msg.append("          - wavelength step: %.3f  [Å]" % dl)

            if np.diff(wl)[0] < 0:
                # Wavelengths are decreasing: Flip arrays
                flux1d = flux1d[::-1]
                wl = wl[::-1]
                err1d = err1d[::-1]
            interp_flux, interp_err = spectres.spectres(wl_new,
                                                        wl,
                                                        flux1d,
                                                        spec_errs=err1d,
                                                        verbose=False,
                                                        fill=0.)
            final_wl = wl_new
        else:
            msg.append(
                "          - Using raw input grid, no interpolation used.")
            msg.append("[WARNING] - Wavelength steps may not be constant!")
            final_wl = wl
            interp_flux = flux1d
            interp_err = err1d

        col_wl = fits.Column(name='WAVE',
                             array=final_wl,
                             format='D',
                             unit=hdr['CUNIT1'])
        col_flux = fits.Column(name='FLUX',
                               array=interp_flux,
                               format='D',
                               unit=hdr['BUNIT'])
        col_err = fits.Column(name='ERR',
                              array=interp_err,
                              format='D',
                              unit=hdr['BUNIT'])
        output_tab = fits.BinTableHDU.from_columns([col_wl, col_flux, col_err],
                                                   header=hdr)
        output_hdu.append(output_tab)

    output_hdu.writeto(output, overwrite=True)
    msg.append(" [OUTPUT] - Saving wavelength calibrated 1D spectrum: %s" %
               output)
    msg.append("")
    output_msg = "\n".join(msg)
    return output_msg