def convolve_spectrum(target_spec,
                      header,
                      kernel_type='gaussian',
                      pix_width=pix_width,
                      kernel_width=slit_width,
                      double_smooth=False):
    #pix_width =3
    #pix_width =20
    fluxes = np.copy(target_spec[1])
    wavelengths = np.copy(target_spec[0])
    if kernel_type == 'gaussian':
        #see_sig = float(header['SEE_SIG']) #sigma value of gaussian fit to do the
        #see_sig= sdss_scale_factor*see_sig
        see_sig = pix_width
        #see_kernel = conv.Gaussian1DKernel(see_sig, x_size = int(slit_width), mode = 'oversample')
        if int(kernel_width) % 2 == 0:
            kernel_width = kernel_width + 1
        else:
            pass
        see_kernel = conv.Gaussian1DKernel(see_sig,
                                           x_size=int(kernel_width),
                                           mode='oversample')
        see_kernel.normalize()
        spec_conv = conv.convolve(fluxes, see_kernel)
    elif kernel_type == 'sdss_match':
        see_sig = float(
            header['SEE_SIG'])  #sigma value of gaussian fit to do the
        conv_see_sig = np.sqrt(see_sig**2 - sdss_see_sig**2)
        print('sdss_see_sig', sdss_see_sig)
        print('see_sig', see_sig)
        print('conv_see_sig', conv_see_sig)
        #see_sig= sdss_scale_factor*see_sig
        conv_see_sig = conv_see_sig * sdss_scale_factor

        #see_kernel = conv.Gaussian1DKernel(see_sig, mode = 'oversample')
        see_kernel = conv.Gaussian1DKernel(conv_see_sig, mode='oversample')
        see_kernel.normalize()
        spec_conv = conv.convolve(fluxes, see_kernel)
        pix_kernel = conv.Box1DKernel(width=int(sdss_scale_factor * pix_width),
                                      mode='oversample')
        pix_kernel.normalize()
        spec_conv = conv.convolve(spec_conv, pix_kernel)
    elif kernel_type == 'box':
        pix_kernel = conv.Box1DKernel(width=int(pix_width), mode='oversample')
        pix_kernel.normalize()
        spec_conv = conv.convolve(fluxes, pix_kernel)
    else:
        print('something wrong with convolution attempt')
        pass
    spec_out = np.vstack([wavelengths, spec_conv])
    return spec_out
Ejemplo n.º 2
0
def mkolam(lam, dlsf, dslitlam, ofile, filfile, abmag):
    # Returns object "ofile" spectrum for a given LSF FWHM, and slit width.
    # The result is sampled in wavelength at the instrument pixel dispersion
    # Result does not include slitlosses. Normalized to ABmag in filter in "filfile"
    c=2.99792458e18   # Speed of light in [A/s]
    data=ascii.read(ofile, names=['col1', 'col2'])
    lam0=data['col1']
    olam0=data['col2']
    # interpolate to regular grid (finer between original file grid and lam)
    ddisp0=np.amin([np.median(lam0[1:len(lam0)-1]-lam0[0:len(lam0)-2]), np.median(lam[1:len(lam)-1]-lam[0:len(lam)-2])])
    lam1=np.arange(np.amin(lam0), np.amax(lam0), ddisp0)
    f=interp1d(lam0, olam0, fill_value='extrapolate')
    olam1=f(lam1)
    # convolve with LSF (Gaussian of FWHM=dlsf)
    gauss=conv.Gaussian1DKernel(stddev=dlsf/2.355/ddisp0, x_size=round_up_to_odd(10*dlsf/2.355/ddisp0))
    olam2=conv.convolve(olam1, gauss.array, boundary='extend')
    # convolve with slit (Top Hat of width=dslit)
    box=conv.Box1DKernel(dslitlam/ddisp0)
    olam3=conv.convolve(olam2, box.array, boundary='extend')
    # read filter curve and interpolate to object lambda grid
    datafil=ascii.read(filfile, names=['col1', 'col2'])
    lamfil0=datafil['col1']
    tfil0=datafil['col2']
    f=interp1d(lamfil0, tfil0, fill_value='extrapolate')
    tfil1=f(lam1)
    tfil1[lam1<=lamfil0.min()]=0 
    tfil1[lam1>=lamfil0.max()]=0
    lameff=np.trapz(lam1*tfil1*lam1, lam1)/np.trapz(tfil1*lam1, lam1)
    # normalize to ABmag in filter "filfile"
    monoflam0=np.trapz(olam3*tfil1*lam1, lam1)/np.trapz(tfil1*lam1, lam1)
    monoflam1=10.0**(-0.4*(abmag+48.6))*c/lameff**2
    olam4=olam3*monoflam1/monoflam0
    # interpolate to lam
    f=interp1d(lam1, olam4, fill_value='extrapolate')
    return f(lam)
Ejemplo n.º 3
0
def mkslam(lam, dlsf, dslitlam, sfile):
    # Returns sky surface brightness spectrum for a given moon phase, LSF FWHM, and slit width.
    # The result is convolved with LSF+slit and sampled at wavelengths in lam
    data = ascii.read(sfile)
    # trim to lrange only
    lam0 = data['col1'][(data['col1'] > np.amin(lam)) *
                        (data['col1'] < np.amax(lam))]
    slam0 = data['col2'][(data['col1'] > np.amin(lam)) *
                         (data['col1'] < np.amax(lam))]
    # interpolate to regular grid
    ddisp0 = np.median(lam0[1:len(lam0) - 1] - lam0[0:len(lam0) - 2])
    lam1 = np.arange(np.amin(lam0), np.amax(lam0), ddisp0)
    f = interp1d(lam0, slam0, fill_value='extrapolate')
    slam1 = f(lam1)
    # convolve with LSF (Gaussian of FWHM=dlsf)
    gauss = conv.Gaussian1DKernel(stddev=dlsf / 2.355 / ddisp0,
                                  x_size=round_up_to_odd(10 * dlsf / 2.355 /
                                                         ddisp0))
    slam2 = conv.convolve(slam1, gauss.array, boundary='extend')
    # convolve with slit (Top Hat of width=dslit)
    box = conv.Box1DKernel(dslitlam / ddisp0)
    slam3 = conv.convolve(slam2, box.array, boundary='extend')
    # interpolate to lam
    f = interp1d(lam1, slam3, fill_value='extrapolate')
    return f(lam)
Ejemplo n.º 4
0
def mkklam(lam, dlsf, dslitlam, klamfile):
    # Returns atmospheric extinction coefficient sampled at wavelengths in "lam"
    # The klam curve is convolved to the spectrograph LSF and the slit width before sampling it
    #data=ascii.read('/Users/gblancm/work/LCO/lcoetc/database/sky/klam.dat')
    data = ascii.read(klamfile)
    # trim to lrange only
    lam0 = data['col1'][(data['col1'] > np.amin(lam)) *
                        (data['col1'] < np.amax(lam))]
    klam0 = data['col2'][(data['col1'] > np.amin(lam)) *
                         (data['col1'] < np.amax(lam))]
    # interpolate to regular grid
    ddisp0 = np.median(lam0[1:len(lam0) - 1] - lam0[0:len(lam0) - 2])
    lam1 = np.arange(np.amin(lam0), np.amax(lam0), ddisp0)
    f = interp1d(lam0, klam0, fill_value='extrapolate')
    klam1 = f(lam1)
    # convolve with LSF (Gaussian of FWHM=dlsf)
    gauss = conv.Gaussian1DKernel(stddev=dlsf / 2.355 / ddisp0,
                                  x_size=round_up_to_odd(10 * dlsf / 2.355 /
                                                         ddisp0))
    klam2 = conv.convolve(klam1, gauss.array, boundary='extend')
    # convolve with slit (Top Hat of width=dslit)
    box = conv.Box1DKernel(dslitlam / ddisp0)
    klam3 = conv.convolve(klam2, box.array, boundary='extend')
    # interpolate to lam
    f = interp1d(lam1, klam3, fill_value='extrapolate')
    return f(lam)
Ejemplo n.º 5
0
def box_smooth(spectrum, width):
    """
    Smooth a `~specutils.Spectrum1D` instance based on a `astropy.convolution.Box1DKernel` kernel.

    Parameters
    ----------
    spectrum : `~specutils.Spectrum1D`
        The spectrum object to which the smoothing will be applied.
    width : number
        The width of the kernel, in pixels, as defined in `astropy.convolution.Box1DKernel`

    Returns
    -------
    spectrum : `~specutils.Spectrum1D`
        Output `~specutils.Spectrum1D` which a copy of the one passed in with the updated flux.

    Raises
    ------
    ValueError
       In the case that ``width`` is not the correct type or value.

    """
    # Parameter checks
    if not isinstance(width, (int, float)) or width <= 0:
        raise ValueError('The width parameter, {}, must be a number greater than 0'.format(
                width))

    # Create the gaussian kernel
    box1d_kernel = convolution.Box1DKernel(width)

    # Call and return the convolution smoothing.
    return convolution_smooth(spectrum, box1d_kernel)
Ejemplo n.º 6
0
def smooth(values):
    #kern = convolution.Gaussian1DKernel(config.smooth_parameter)
    kern = convolution.Box1DKernel(config.smooth_parameter)
    print "smooth with:", kern
    return convolution.convolve(values,
                                kern,
                                normalize_kernel=True,
                                boundary="extend")
Ejemplo n.º 7
0
def to_new_fwhm_box1d(ll, ss, width, nsamp=3):
    """ Use box kernel to convolve down and resample spectrum """

    nres = np.round(width/dl)
    npix = np.int(np.round(nres/nsamp))
    # print("Width of {0:1.4f} is {1:1.2f} pix".format(width, nres))
    kernel = CC.Box1DKernel(nres)
    sp = scipy_convolve(ss, kernel, mode='same', method='direct')

    return ll, sp, npix
Ejemplo n.º 8
0
def Signal_Analysis(x, y, params):
    #Create fit using initial parameters
    #Stop fit from wandering onto random spikes of noise
    bound_centre = (params[0] - 15, params[0] + 15)
    bound_width = (params[3] - 2, params[3] + 30)
    #bound_amp = (0,params[1]),'amplitude_L': bound_amp
    bound_parameters = {'x_o': bound_centre, 'fwhm_G': bound_width}
    fit_init = models.Voigt1D(params[0],
                              params[1],
                              params[2],
                              params[3],
                              bounds=bound_parameters)
    fit = fitting.LevMarLSQFitter()
    fitted_model = fit(fit_init, x, y)
    #Get value for fit peak (amplitude_L is not applicable)
    peak = abs(min(fitted_model(x)))
    #Post-Processing
    #Formula for voight width is found Olivero 1977
    fwhm_V = (fitted_model.fwhm_L / 2) + m.sqrt((fitted_model.fwhm_L**2) / 4 +
                                                fitted_model.fwhm_G**2)
    window_length = (1 / 3) * fwhm_V
    if window_length > 1:
        box_window = convolution.Box1DKernel(window_length)
        y = convolution.convolve(y, box_window)
    else:
        window_length = 2
        box_window = convolution.Box1DKernel(window_length)
        y = convolution.convolve(y, box_window)

    #Signal-to-Noise
    baseline = y - fitted_model(
        x
    )  #not cheating....just to find the sigma of the non-peak reason lazily
    noise = stats.mad_std(baseline)
    snr = abs(peak) / noise
    if snr > 4:
        peak = min(y)
        snr = abs(peak) / noise
    else:
        pass

    return y, fitted_model, snr
Ejemplo n.º 9
0
def to_new_fwhm_box1d(ll, ss, width, nsamp=3):
    """ Use box kernel to convolve down and resample spectrum """

    dl = np.median(np.diff(ll))
    nres = width / dl  # The number of pixels in ll that constitute a slit
    # The number of pixels in ll that make one pixel in the observed spectrum
    npix = np.int(np.round(nres / nsamp))
    print("Width of {0:1.4f} is {1:1.2f} pix".format(width, nres))
    kernel = CC.Box1DKernel(np.round(nres))
    sp = scipy_convolve(ss, kernel, mode='same', method='direct')

    return ll, sp, npix
Ejemplo n.º 10
0
def mklinelam(lam, dlsf, dslitlam, linelam, lineflux, linefwhm):
    instsigma=np.sqrt(dlsf**2+dslitlam**2)/2.355 # rough estimate of instrumental sigma
    sigma=np.max([linefwhm/2.355, instsigma/2]) # set floor of line width to half instrumental to avoid sampling problems
    linelam1=lineflux/(np.sqrt(2)*sigma)*np.exp(-1*(lam-linelam)**2/(2*sigma**2))
    # convolve with LSF (Gaussian of FWHM=dlsf)
    ddisp0=np.median(lam[1:len(lam)-1]-lam[0:len(lam)-2])
    gauss=conv.Gaussian1DKernel(stddev=dlsf/2.355/ddisp0, x_size=round_up_to_odd(10*dlsf/2.355/ddisp0))
    linelam2=conv.convolve(linelam1, gauss.array, boundary='extend')
    # convolve with slit (Top Hat of width=dslit)
    box=conv.Box1DKernel(dslitlam/ddisp0)
    linelam3=conv.convolve(linelam2, box.array, boundary='extend')
    return linelam3
Ejemplo n.º 11
0
def mklinelam(lam, dlsf, dslitlam, linelam, lineflux, linefwhm):
    sigma = linefwhm / 2.355
    linelam1 = lineflux / (np.sqrt(2) * sigma) * np.exp(-1 *
                                                        (lam - linelam)**2 /
                                                        (2 * sigma**2))
    # convolve with LSF (Gaussian of FWHM=dlsf)
    ddisp0 = np.median(lam[1:len(lam) - 1] - lam[0:len(lam) - 2])
    gauss = conv.Gaussian1DKernel(stddev=dlsf / 2.355 / ddisp0,
                                  x_size=round_up_to_odd(10 * dlsf / 2.355 /
                                                         ddisp0))
    linelam2 = conv.convolve(linelam1, gauss.array, boundary='extend')
    # convolve with slit (Top Hat of width=dslit)
    box = conv.Box1DKernel(dslitlam / ddisp0)
    linelam3 = conv.convolve(linelam2, box.array, boundary='extend')
    return linelam3
Ejemplo n.º 12
0
def test_smooth_box_good(simulated_spectra, width):
    """
    Test Box1DKernel smoothing with correct parmaeters.

    Width values need to be a number greater than 0.
    """

    # Create the original spectrum
    spec1 = simulated_spectra.s1_um_mJy_e1
    flux_original = spec1.flux

    # Calculate the smoothed flux using Astropy
    box_kernel = convolution.Box1DKernel(width)
    flux_smoothed_astropy = convolution.convolve(flux_original, box_kernel)

    # Calculate the box smoothed
    spec1_smoothed = box_smooth(spec1, width)
    compare_flux(spec1_smoothed.flux.value, flux_smoothed_astropy, flux_original.value)

    # Check the input and output units
    assert spec1.wavelength.unit == spec1_smoothed.wavelength.unit
    assert spec1.flux.unit == spec1_smoothed.flux.unit
Ejemplo n.º 13
0
 def __smoothData(self, spec):
     windowsize = 3
     kernel = astcov.Box1DKernel(windowsize)
     sspec = astcov.convolve(spec, kernel)
     return sspec
Ejemplo n.º 14
0
def pre_whiten(time,
               flux,
               unc_flux,
               period,
               kind="supersmoother",
               which="phased",
               phaser=None):
    """Phase a lightcurve and then smooth it.

    Inputs
    ------
    time, flux, unc_flux: array_like

    period: float
        period to whiten by

    kind: string, optional
        type of smoothing to use. Defaults to "supersmoother."
        Other types are "boxcar", "linear"

    which: string, optional
        whether to smooth the "phased" lightcurve (default) or the "full"
        lightcurve.

    phaser: Float, optional (default=None)
        if kind="boxcar", phaser is the Half-width of the smoothing window.
        if kind="supersmoother", phaser is alpha (the "bass enhancement").

    Outputs
    -------
    white_flux, white_unc, smoothed_flux: arrays

    """

    # print(which, period, phaser)

    # phase the LC by the period
    if period is not None:
        # phased_time = utils.phase(time, period)
        phased_time = (time % period)
    else:
        phased_time = time

    if kind.lower() == "supersmoother":

        if phaser is None:
            logging.info("Phaser not set! "
                         "Set phaser=alpha (bass-enhancement value "
                         "for supersmoother) if desired.")

        if which.lower() == "phased":
            # Instantiate the supersmoother model object with the input period
            model = supersmoother.SuperSmoother(period=period)

            # Set up base arrays for phase for the fit
            x_vals = np.linspace(0, max(phased_time) * 1.001, 1000)

            # Run a fit for the y phase
            y_fit = model.fit(phased_time, flux, unc_flux).predict(x_vals)

        elif which.lower() == "full":
            # Instantiate the supersmoother model object with the input period
            model = supersmoother.SuperSmoother(alpha=phaser)

            # Set up base arrays for time for the fit
            x_vals = np.linspace(min(time), max(time), 1000)

            # run a fit for the y values
            y_fit = model.fit(time, flux, unc_flux).predict(x_vals)

        else:
            logging.warning("unknown which %s !!!", which)

    elif kind.lower() == "boxcar":

        if phaser is None:
            logging.info("Phaser not set! "
                         "Set phaser to the width of the smoothing "
                         "box in pixels!")

        if which.lower() == "phased":
            # sort the phases
            sort_locs = np.argsort(phased_time)
            x_vals = phased_time[sort_locs]
            flux_to_fit = flux[sort_locs]

        elif which.lower() == "full":
            x_vals = time
            flux_to_fit = flux
        else:
            logging.warning("unknown which %s !!!", which)

        # Use astropy's convolution function!
        boxcar_kernel = convolution.Box1DKernel(width=phaser,
                                                mode="linear_interp")
        y_fit = convolution.convolve(flux_to_fit,
                                     boxcar_kernel,
                                     boundary="wrap")

    elif kind == "linear":

        if which != "full":
            logging.warning("Linear smoothing only allowed for full "
                            "lightcurve! Switching to full mode.")
            which = "full"

        # Fit a line to the data
        pars = np.polyfit(time, flux, deg=1)
        m, b = pars
        smoothed_flux = m * time + b

    else:
        logging.warning("unknown kind %s !!!", kind)

    if (kind == "supersmoother") or (kind == "boxcar"):
        # Interpolate back onto the original time array
        interp_func = interpolate.interp1d(x_vals, y_fit)

        if which.lower() == "phased":
            # try:
            smoothed_flux = interp_func(phased_time)
            # except ValueError:
            #     # print(min(x_vals),max(x_vals))
            #     # print(min(phased_time),max(phased_time))
            #     smoothed_flux = np.ones_like(phased_time)
            #     smoothed_flux[1:-1] = interp_func(phased_time[1:-1])
            #     smoothed_flux[0] = smoothed_flux[1]
            #     smoothed_flux[-1] = smoothed_flux[-2]
        elif which.lower() == "full":
            smoothed_flux = interp_func(time)
        else:
            logging.warning("unknown which %s !!!", which)

    # Whiten the input flux by subtracting the smoothed version
    # The smoothed flux represents the "bulk trend"
    white_flux = flux - smoothed_flux
    white_unc = unc_flux

    return white_flux, white_unc, smoothed_flux
Ejemplo n.º 15
0
 def smooth_spec(x):
     kernel = convolution.Box1DKernel(nsmooth)
     return convolution.convolve(x, kernel)