Ejemplo n.º 1
0
def test_byhand_awav2vel():
    # AWAV
    CRVAL3A = (6560 * u.AA).to(u.m).value
    CDELT3A = (1.0 * u.AA).to(u.m).value
    CUNIT3A = 'm'
    CRPIX3A = 1.0
    # restwav MUST be vacuum
    restwl = air_to_vac(6562.81 * u.AA)
    RESTWAV = restwl.to(u.m).value
    CRVAL3V = (CRVAL3A * u.m).to(u.m / u.s, u.doppler_optical(restwl)).value
    CDELT3V = (CDELT3A * u.m * air_to_vac_deriv(CRVAL3A * u.m) /
               restwl) * constants.c
    CUNIT3V = 'm/s'

    mywcs = wcs.WCS(naxis=1)
    mywcs.wcs.ctype[0] = 'AWAV'
    mywcs.wcs.crval[0] = CRVAL3A
    mywcs.wcs.crpix[0] = CRPIX3A
    mywcs.wcs.cunit[0] = CUNIT3A
    mywcs.wcs.cdelt[0] = CDELT3A
    mywcs.wcs.restwav = RESTWAV
    mywcs.wcs.set()

    newwcs = convert_spectral_axis(
        mywcs, u.km / u.s,
        determine_ctype_from_vconv(mywcs.wcs.ctype[0], u.km / u.s, 'optical'))

    newwcs.wcs.set()
    assert newwcs.wcs.cunit[0] == 'm / s'
    np.testing.assert_almost_equal(
        newwcs.wcs.crval,
        air_to_vac(CRVAL3A * u.m).to(u.m / u.s,
                                     u.doppler_optical(restwl)).value)
    # Check that the cdelts match the expected cdelt, 1 angstrom / rest
    # wavelength (vac)
    np.testing.assert_almost_equal(newwcs.wcs.cdelt,
                                   CDELT3V.to(u.m / u.s).value)
    # Check that the reference wavelength is 2.81 angstroms up
    np.testing.assert_almost_equal(newwcs.wcs_pix2world((2.81, ), 0),
                                   0.0,
                                   decimal=3)

    # Go through a full-on sanity check:
    vline = 100 * u.km / u.s
    wave_line_vac = vline.to(u.AA, u.doppler_optical(restwl))
    wave_line_air = vac_to_air(wave_line_vac)

    pix_line_input = mywcs.wcs_world2pix((wave_line_air.to(u.m).value, ), 0)
    pix_line_output = newwcs.wcs_world2pix((vline.to(u.m / u.s).value, ), 0)

    np.testing.assert_almost_equal(pix_line_output, pix_line_input, decimal=4)
def test_byhand_awav2vel():
    # AWAV
    CRVAL3A = (6560*u.AA).to(u.m).value
    CDELT3A = (1.0*u.AA).to(u.m).value
    CUNIT3A = 'm'
    CRPIX3A = 1.0
    # restwav MUST be vacuum
    restwl = air_to_vac(6562.81*u.AA)
    RESTWAV = restwl.to(u.m).value
    CRVAL3V = (CRVAL3A*u.m).to(u.m/u.s,
                               u.doppler_optical(restwl)).value
    CDELT3V = (CDELT3A*u.m*air_to_vac_deriv(CRVAL3A*u.m)/restwl) * constants.c
    CUNIT3V = 'm/s'

    mywcs = wcs.WCS(naxis=1)
    mywcs.wcs.ctype[0] = 'AWAV'
    mywcs.wcs.crval[0] = CRVAL3A
    mywcs.wcs.crpix[0] = CRPIX3A
    mywcs.wcs.cunit[0] = CUNIT3A
    mywcs.wcs.cdelt[0] = CDELT3A
    mywcs.wcs.restwav = RESTWAV
    mywcs.wcs.set()


    newwcs = convert_spectral_axis(mywcs, u.km/u.s,
                                   determine_ctype_from_vconv(mywcs.wcs.ctype[0],
                                                              u.km/u.s,
                                                              'optical'))

    newwcs.wcs.set()
    assert newwcs.wcs.cunit[0] == 'm / s'
    np.testing.assert_almost_equal(newwcs.wcs.crval,
                                   air_to_vac(CRVAL3A*u.m).to(u.m/u.s,
                                                              u.doppler_optical(restwl)).value)
    # Check that the cdelts match the expected cdelt, 1 angstrom / rest
    # wavelength (vac)
    np.testing.assert_almost_equal(newwcs.wcs.cdelt, CDELT3V.to(u.m/u.s).value)
    # Check that the reference wavelength is 2.81 angstroms up
    np.testing.assert_almost_equal(newwcs.wcs_pix2world((2.81,), 0), 0.0, decimal=3)


    # Go through a full-on sanity check:
    vline = 100*u.km/u.s
    wave_line_vac = vline.to(u.AA, u.doppler_optical(restwl))
    wave_line_air = vac_to_air(wave_line_vac)

    pix_line_input = mywcs.wcs_world2pix((wave_line_air.to(u.m).value,), 0)
    pix_line_output = newwcs.wcs_world2pix((vline.to(u.m/u.s).value,), 0)

    np.testing.assert_almost_equal(pix_line_output, pix_line_input, decimal=4)
Ejemplo n.º 3
0
def Orion_PVDiagrams(
    filename="OMC1_TSPEC_H2S1_cube.fits",
    restwavelength=2.1218313 * u.um,
    cm=pl.cm.hot,
    start_fignum=0,
    min_valid=1e-16,
    displaymax=None,
    hlcolor="k",
    linename="H2 S(1) 1-0",
    dosave=True,
):
    cube = fits.getdata(filename)
    header = fits.getheader(filename)

    wavelength = ((-header["CRPIX3"] + np.arange(header["NAXIS3"]) + 1) * header["CD3_3"] + header["CRVAL3"]) * u.AA
    velocity = wavelength.to("km/s", u.doppler_optical(restwavelength))

    nvel = len(velocity)

    def make_pv(startx=196, starty=130, endx=267, endy=388, npts=250):
        pvd = np.empty([nvel, npts])
        for ii, (x, y) in enumerate(zip(np.linspace(startx, endx, npts), np.linspace(starty, endy, npts))):
            pvd[:, ii] = cube[:, y, x]
        return pvd

    for ii, (ex, ey) in enumerate(outflow_endpoints):
        dx = ex - sourceI[0]
        dy = ey - sourceI[1]
        angle = np.arctan2(dy, dx)
        cdelt = np.abs(header["CDELT1"] / np.cos(angle)) * 3600
        npts = (dx ** 2 + dy ** 2) ** 0.5
        # pixels are in FITS units
        pv = make_pv(endx=ex - 1, endy=ey - 1, startx=sourceI[0] - 1, starty=sourceI[1] - 1, npts=npts)
        fignum = start_fignum + ii / 3
        pl.figure(fignum)
        if ii % 3 == 0:
            pl.clf()
        ax = pl.subplot(3, 1, ii % 3 + 1)
        vmin, vmax = velocity.min().value, velocity.max().value
        pv[pv < 0] = np.nanmin(pv)
        pv[pv < min_valid] = min_valid
        pl.imshow(
            np.log10(pv),
            extent=[0, npts * cdelt, vmin, vmax],
            aspect=np.abs(cdelt) / 20 * (npts / 100),
            cmap=cm,
            vmax=displaymax,
            origin="lower",
        )
        pl.hlines(0, 0, npts * cdelt, color=hlcolor, linestyle="--")
        ax.set_xlabel('Offset (")')
        ax.set_ylabel("Velocity (km s$^{-1}$)")
        ax.set_title(linename + " Outflow Trace %i" % ii)
        ax.set_ylim(-200, 200)

        if dosave and ii % 3 == 2 or ii == len(outflow_endpoints) - 1:
            name = linename.replace(" ", "_").replace("(", "_").replace(")", "_")
            name = "".join([l for l in name if l in (string.ascii_letters + string.digits + "_-")])
            figname = name + "_%i.png" % fignum
            pl.savefig(figname.replace("__", "_"))
Ejemplo n.º 4
0
    def test_with_spectral_unit(self, name, masktype):
        cube, data = cube_and_raw(name + '.fits')
        cube_freq = cube.with_spectral_unit(u.Hz)

        if masktype == BooleanArrayMask:
            mask = BooleanArrayMask(data>0, wcs=cube._wcs)
        elif masktype == LazyMask:
            mask = LazyMask(lambda x: x>0, cube=cube)
        elif masktype == FunctionMask:
            mask = FunctionMask(lambda x: x>0)
        elif masktype == CompositeMask:
            mask1 = FunctionMask(lambda x: x>0)
            mask2 = LazyMask(lambda x: x>0, cube)
            mask = CompositeMask(mask1, mask2)

        cube2 = cube.with_mask(mask)
        cube_masked_freq = cube2.with_spectral_unit(u.Hz)

        assert cube_freq._wcs.wcs.ctype[cube_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._wcs.wcs.ctype[cube_masked_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._mask._wcs.wcs.ctype[cube_masked_freq._mask._wcs.wcs.spec] == 'FREQ-W2F'

        # values taken from header
        rest = 1.42040571841E+09*u.Hz
        crval = -3.21214698632E+05*u.m/u.s
        outcv = crval.to(u.m, u.doppler_optical(rest)).to(u.Hz, u.spectral())

        assert_allclose(cube_freq._wcs.wcs.crval[cube_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(cube_masked_freq._wcs.wcs.crval[cube_masked_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(cube_masked_freq._mask._wcs.wcs.crval[cube_masked_freq._mask._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
Ejemplo n.º 5
0
    def test_with_spectral_unit(self, name, masktype, unit):
        cube, data = cube_and_raw(name + '.fits')
        cube_freq = cube.with_spectral_unit(unit)

        if masktype == BooleanArrayMask:
            mask = BooleanArrayMask(data>0, wcs=cube._wcs)
        elif masktype == LazyMask:
            mask = LazyMask(lambda x: x>0, cube=cube)
        elif masktype == FunctionMask:
            mask = FunctionMask(lambda x: x>0)
        elif masktype == CompositeMask:
            mask1 = FunctionMask(lambda x: x>0)
            mask2 = LazyMask(lambda x: x>0, cube)
            mask = CompositeMask(mask1, mask2)

        cube2 = cube.with_mask(mask)
        cube_masked_freq = cube2.with_spectral_unit(unit)

        assert cube_freq._wcs.wcs.ctype[cube_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._wcs.wcs.ctype[cube_masked_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._mask._wcs.wcs.ctype[cube_masked_freq._mask._wcs.wcs.spec] == 'FREQ-W2F'

        # values taken from header
        rest = 1.42040571841E+09*u.Hz
        crval = -3.21214698632E+05*u.m/u.s
        outcv = crval.to(u.m, u.doppler_optical(rest)).to(u.Hz, u.spectral())

        assert_allclose(cube_freq._wcs.wcs.crval[cube_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(cube_masked_freq._wcs.wcs.crval[cube_masked_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(cube_masked_freq._mask._wcs.wcs.crval[cube_masked_freq._mask._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
Ejemplo n.º 6
0
    def calibrate_flux(self, hdu):
        '''
        do flux calibration by undoing what the simulator did so far (as much as possible)
        input is the result of compute_snr()
        '''
        data = hdu.data * u.electron	# per dit, pixel, spectral channel, and M1-area

        mirr_list = self.cmds.mirrors_telescope
        mirr_area = np.pi / 4 * np.sum(mirr_list["Outer"]**2 - \
                                       mirr_list["Inner"]**2) * u.m**2

        data = data / (hdu.header['EXPTIME'] * u.s
                       * (np.mean(self.wavelen)*u.um * (1.5 *u.km/u.s) / const.c).to(u.um)
                       * mirr_area)
        # e-/s/um/m2

        # wavelengths of data cube
        det_wavelen = (self.det_velocities
                       * u.m/u.s).to(u.um, equivalencies=u.doppler_optical(self.restcoo))

        # interpolate transmission onto wavelength-grid of detector:
        trans = np.interp(det_wavelen.value, self.wavelen, self.transmission)

        data /= trans[:, np.newaxis, np.newaxis]

        data = (data * u.photon/u.electron).to(u.Jy,
                                               equivalencies=u.spectral_density(self.restcoo))

        data = data / (self.det_pixscale/1000. * u.arcsec)**2
        # Jy/arcsec2

        calhdu = fits.PrimaryHDU(data.value, header=hdu.header)
        calhdu.header['BUNIT'] = ('Jy/arcsec2', 'Jansky per arcsec**2')
        return calhdu
Ejemplo n.º 7
0
def test_mask_spectral_unit_functions():
    cube, data = cube_and_raw('adv.fits')

    # function mask should do nothing
    mask1 = FunctionMask(lambda x: x>0)
    mask_freq1 = mask1.with_spectral_unit(u.Hz)

    # lazy mask behaves like booleanarraymask
    mask2 = LazyMask(lambda x: x>0, cube=cube)
    mask_freq2 = mask2.with_spectral_unit(u.Hz)

    assert mask_freq2._wcs.wcs.ctype[mask_freq2._wcs.wcs.spec] == 'FREQ-W2F'

    # values taken from header
    rest = 1.42040571841E+09*u.Hz
    crval = -3.21214698632E+05*u.m/u.s
    outcv = crval.to(u.m, u.doppler_optical(rest)).to(u.Hz, u.spectral())

    assert_allclose(mask_freq2._wcs.wcs.crval[mask_freq2._wcs.wcs.spec],
                    outcv.to(u.Hz).value)

    # again, test that it works
    mask3 = CompositeMask(mask1,mask2)
    mask_freq3 = mask3.with_spectral_unit(u.Hz)

    mask_freq3 = CompositeMask(mask_freq1,mask_freq2)
    mask_freq_freq3 = mask_freq3.with_spectral_unit(u.Hz)
Ejemplo n.º 8
0
def test_basic():
    """
    basic test of equivalent width
    """
    survey = SkySurvey()
    import astropy.units as u
    survey["INTEN"] = survey["INTEN"].data * u.R

    ha_wave = 656.3 * u.nm
    optical_ha_equiv = u.doppler_optical(ha_wave)
    dv = (survey["VELOCITY"][0][1] - survey["VELOCITY"][0][0]) * u.km/u.s
    dlambda = (dv).to(u.AA, equivalencies=optical_ha_equiv) - \
        (0 * u.km/u.s).to(u.AA, equivalencies=optical_ha_equiv)

    survey["BKG"] = np.abs(np.random.randn(len(survey["INTEN"]))) * 100.
    survey["BKGSD"] = survey["BKG"] * .1


    ew, ew_error = survey.get_equivalent_width(continuum = survey["BKG"] / 22.8 * u.R / dlambda, 
        continuum_error = survey["BKGSD"] / 22.8 * u.R / dlambda, return_sigma = True)

    ew2, ew2_error = survey.get_equivalent_width(intensity = survey["INTEN"].data * u.R, 
        intensity_error = survey["ERROR"].data * u.R)

    assert np.allclose(ew.value, ew2.value)
Ejemplo n.º 9
0
def test_convert_to_unit(run_with_assert=False):
    for from_unit, to_unit, _, __ in u.doppler_optical(1 * u.Hz):
        sp = SpectroscopicAxis(np.linspace(-100, 100, 100),
                               unit=from_unit,
                               refX=23.2 * u.Hz,
                               velocity_convention='optical')
        sp.convert_to_unit(to_unit)
        if (run_with_assert):
            assert sp.unit == to_unit
    for from_unit, to_unit, _, __ in u.doppler_radio(1 * u.eV):
        sp = SpectroscopicAxis(np.linspace(-100, 100, 100),
                               unit=from_unit,
                               refX=23.2 * u.Hz,
                               velocity_convention='optical')
        sp.convert_to_unit(to_unit)
        if (run_with_assert):
            assert sp.unit == to_unit
    for from_unit, to_unit, _, __ in u.doppler_relativistic(1 * u.Angstrom):
        sp = SpectroscopicAxis(np.linspace(-100, 100, 100),
                               unit=from_unit,
                               refX=23.2 * u.Hz,
                               velocity_convention='relativistic')
        sp.convert_to_unit(to_unit)
        if (run_with_assert):
            assert sp.unit == to_unit
Ejemplo n.º 10
0
def test_equivalencies_3(velocity_convention):
    x = SpectroscopicAxis(np.arange(5),
                          unit=u.angstrom,
                          refX=3,
                          refX_unit='angstrom',
                          velocity_convention=velocity_convention)
    assert x.equivalencies == u.doppler_optical(3 * u.AA)
Ejemplo n.º 11
0
def cross_corr(spectrum,
               template,
               start_lam=-2,
               end_lam=2,
               n_steps=1000,
               sigma=None,
               spread_factor=10):
    """
    Cross-correlation of the spectrum and template.

    Parameters
    ----------
    spectrum : `~hipparchus.Spectrum`
        Spectrum object (may be an order of an echelle spectrum).
    template : `~hipparchus.Template`
        Template object to correlate against the spectrum.
    start_lam : float
        Start wavelength relative to mean wavelength
    end_lam : float
        End wavelength relative to mean wavelength
    n_steps : int
        Number of steps to compute the CCF over between ``start_lam`` and
        ``end_lam``
    sigma : float
        Gaussian smoothing filter width (standard deviation)
    spread_factor : float
        Gaussian smoothing filter width spread scaling factor

    Returns
    -------
    ccf : `~hipparchus.CCF`
        Cross-correlation object.
    """

    dx_range = np.linspace(start_lam, end_lam, n_steps)[:, np.newaxis]

    shifted_wavelengths = spectrum.wavelength - dx_range
    lam0 = spectrum.wavelength.mean() * u.Angstrom
    velocities = (lam0 + dx_range * u.Angstrom).to(u.km / u.s,
                                                   u.doppler_optical(lam0))

    if sigma is None:
        sigma = ((spectrum.wavelength[1] - spectrum.wavelength[0]) /
                 (template.wavelength[1] - template.wavelength[0]) /
                 spread_factor)

    smoothed_emission = gaussian_filter1d(template.emission, sigma)
    T = interp1d(template.wavelength,
                 smoothed_emission,
                 bounds_error=False,
                 fill_value=0)(shifted_wavelengths)

    x = np.repeat(spectrum.flux[:, np.newaxis], n_steps, axis=1).T

    ccf = np.average(x, weights=T, axis=1)
    return CCF(velocities, ccf, header=spectrum.header)
Ejemplo n.º 12
0
def test_compose_equivalencies():
    x = u.Unit("arcsec").compose(units=(u.pc,), equivalencies=u.parallax())
    assert x[0] == u.pc

    x = u.Unit("2 arcsec").compose(units=(u.pc,), equivalencies=u.parallax())
    assert x[0] == u.Unit(0.5 * u.pc)

    x = u.degree.compose(equivalencies=u.dimensionless_angles())
    assert u.Unit(u.degree.to(u.radian)) in x

    x = (u.nm).compose(units=(u.m, u.s), equivalencies=u.doppler_optical(0.55*u.micron))
    for y in x:
        if y.bases == [u.m, u.s]:
            assert y.powers == [1, -1]
            assert_allclose(
                y.scale,
                u.nm.to(u.m / u.s, equivalencies=u.doppler_optical(0.55 * u.micron)))
            break
    else:
        assert False, "Didn't find speed in compose results"
Ejemplo n.º 13
0
def test_compose_equivalencies():
    x = u.Unit("arcsec").compose(units=(u.pc,), equivalencies=u.parallax())
    assert x[0] == u.pc

    x = u.Unit("2 arcsec").compose(units=(u.pc,), equivalencies=u.parallax())
    assert x[0] == u.Unit(0.5 * u.pc)

    x = u.degree.compose(equivalencies=u.dimensionless_angles())
    assert u.Unit(u.degree.to(u.radian)) in x

    x = (u.nm).compose(units=(u.m, u.s), equivalencies=u.doppler_optical(0.55*u.micron))
    for y in x:
        if y.bases == [u.m, u.s]:
            assert y.powers == [1, -1]
            assert_allclose(
                y.scale,
                u.nm.to(u.m / u.s, equivalencies=u.doppler_optical(0.55 * u.micron)))
            break
    else:
        assert False, "Didn't find speed in compose results"
Ejemplo n.º 14
0
def test_mask_spectral_unit(name):
    cube, data = cube_and_raw(name + '.fits')
    mask = BooleanArrayMask(data, cube._wcs)
    mask_freq = mask.with_spectral_unit(u.Hz)

    assert mask_freq._wcs.wcs.ctype[mask_freq._wcs.wcs.spec] == 'FREQ-W2F'

    # values taken from header
    rest = 1.42040571841E+09*u.Hz
    crval = -3.21214698632E+05*u.m/u.s
    outcv = crval.to(u.m, u.doppler_optical(rest)).to(u.Hz, u.spectral())

    assert_allclose(mask_freq._wcs.wcs.crval[mask_freq._wcs.wcs.spec],
                    outcv.to(u.Hz).value)
Ejemplo n.º 15
0
def test_regions_spectral(data_adv):
    cube, data = cube_and_raw(data_adv)
    rf_cube = get_rest_value_from_wcs(cube.wcs).to("GHz",
                                                   equivalencies=u.spectral())

    # content of image.reg
    regpix = regions.RectanglePixelRegion(regions.PixCoord(0.5, 1),
                                          width=4,
                                          height=2)

    # Velocity range in doppler_optical same as that of the cube.
    vel_range_optical = u.Quantity([-318 * u.km / u.s, -320 * u.km / u.s])
    regpix.meta['range'] = list(vel_range_optical)
    sc1 = cube.subcube_from_regions([regpix])
    scsum1 = sc1.sum()

    freq_range = vel_range_optical.to("GHz",
                                      equivalencies=u.doppler_optical(rf_cube))
    regpix.meta['range'] = list(freq_range)
    sc2 = cube.subcube_from_regions([regpix])
    scsum2 = sc2.sum()

    regpix.meta['restfreq'] = rf_cube
    vel_range_gamma = freq_range.to("km/s",
                                    equivalencies=doppler_gamma(rf_cube))
    regpix.meta['range'] = list(vel_range_gamma)
    regpix.meta['veltype'] = 'GAMMA'
    sc3 = cube.subcube_from_regions([regpix])
    scsum3 = sc3.sum()

    vel_range_beta = freq_range.to("km/s", equivalencies=doppler_beta(rf_cube))
    regpix.meta['range'] = list(vel_range_beta)
    regpix.meta['veltype'] = 'BETA'
    sc4 = cube.subcube_from_regions([regpix])
    scsum4 = sc4.sum()

    vel_range_z = freq_range.to("km/s", equivalencies=doppler_z(rf_cube))
    regpix.meta['range'] = list(vel_range_z)
    regpix.meta['veltype'] = 'Z'
    sc5 = cube.subcube_from_regions([regpix])
    scsum5 = sc5.sum()

    dsum = data[1:-1, 1, :].sum()
    assert_allclose(scsum1, dsum)
    # Proves that the vel/freq conversion works
    assert_allclose(scsum1, scsum2)
    assert_allclose(scsum2, scsum3)
    assert_allclose(scsum3, scsum4)
    assert_allclose(scsum4, scsum5)
Ejemplo n.º 16
0
def test_regions_spectral():
    cube, data = cube_and_raw('adv.fits')
    rf_cube = get_rest_value_from_wcs(cube.wcs).to("GHz",
                                                         equivalencies=u.spectral())

    # content of image.reg
    regpix = regions.RectanglePixelRegion(regions.PixCoord(0.5, 1), width=4, height=2)

    # Velocity range in doppler_optical same as that of the cube.
    vel_range_optical = u.Quantity([-318 * u.km/u.s, -320 * u.km/u.s])
    regpix.meta['range'] = list(vel_range_optical)
    sc1 = cube.subcube_from_regions([regpix])
    scsum1 = sc1.sum()

    freq_range = vel_range_optical.to("GHz",
                                      equivalencies=u.doppler_optical(rf_cube))
    regpix.meta['range'] = list(freq_range)
    sc2 = cube.subcube_from_regions([regpix])
    scsum2 = sc2.sum()

    regpix.meta['restfreq'] = rf_cube
    vel_range_gamma = freq_range.to("km/s", equivalencies=doppler_gamma(rf_cube))
    regpix.meta['range'] = list(vel_range_gamma)
    regpix.meta['veltype'] = 'GAMMA'
    sc3 = cube.subcube_from_regions([regpix])
    scsum3 = sc3.sum()

    vel_range_beta = freq_range.to("km/s",
                                    equivalencies=doppler_beta(rf_cube))
    regpix.meta['range'] = list(vel_range_beta)
    regpix.meta['veltype'] = 'BETA'
    sc4 = cube.subcube_from_regions([regpix])
    scsum4 = sc4.sum()

    vel_range_z = freq_range.to("km/s",
                                    equivalencies=doppler_z(rf_cube))
    regpix.meta['range'] = list(vel_range_z)
    regpix.meta['veltype'] = 'Z'
    sc5 = cube.subcube_from_regions([regpix])
    scsum5 = sc5.sum()

    dsum = data[1:-1, 1, :].sum()
    assert_allclose(scsum1, dsum)
    # Proves that the vel/freq conversion works
    assert_allclose(scsum1, scsum2)
    assert_allclose(scsum2, scsum3)
    assert_allclose(scsum3, scsum4)
    assert_allclose(scsum4, scsum5)
Ejemplo n.º 17
0
def test_equivalency_context():
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        phase = u.Quantity(1., u.cycle)
        assert_allclose(np.exp(1j*phase), 1.)
        Omega = u.cycle / (1.*u.minute)
        assert_allclose(np.exp(1j*Omega*60.*u.second), 1.)
        # ensure we can turn off equivalencies even within the scope
        with pytest.raises(u.UnitsError):
            phase.to(1, equivalencies=None)

        # test the manager also works in the Quantity constructor.
        q1 = u.Quantity(phase, u.dimensionless_unscaled)
        assert_allclose(q1.value, u.cycle.to(u.radian))

        # and also if we use a class that happens to have a unit attribute.
        class MyQuantityLookalike(np.ndarray):
            pass

        mylookalike = np.array(1.).view(MyQuantityLookalike)
        mylookalike.unit = 'cycle'
        # test the manager also works in the Quantity constructor.
        q2 = u.Quantity(mylookalike, u.dimensionless_unscaled)
        assert_allclose(q2.value, u.cycle.to(u.radian))

    with u.set_enabled_equivalencies(u.spectral()):
        u.GHz.to(u.cm)
        eq_on = u.GHz.find_equivalent_units()
        with pytest.raises(u.UnitsError):
            u.GHz.to(u.cm, equivalencies=None)

    # without equivalencies, we should find a smaller (sub)set
    eq_off = u.GHz.find_equivalent_units()
    assert all(eq in set(eq_on) for eq in eq_off)
    assert set(eq_off) < set(eq_on)

    # Check the equivalency manager also works in ufunc evaluations,
    # not just using (wrong) scaling. [#2496]
    l2v = u.doppler_optical(6000 * u.angstrom)
    l1 = 6010 * u.angstrom
    assert l1.to(u.km/u.s, equivalencies=l2v) > 100. * u.km / u.s
    with u.set_enabled_equivalencies(l2v):
        assert l1 > 100. * u.km / u.s
        assert abs((l1 - 500. * u.km / u.s).to(u.angstrom)) < 1. * u.km/u.s
Ejemplo n.º 18
0
def test_equivalency_context():
    with u.set_enabled_equivalencies(u.dimensionless_angles()):
        phase = u.Quantity(1., u.cycle)
        assert_allclose(np.exp(1j*phase), 1.)
        Omega = u.cycle / (1.*u.minute)
        assert_allclose(np.exp(1j*Omega*60.*u.second), 1.)
        # ensure we can turn off equivalencies even within the scope
        with pytest.raises(u.UnitsError):
            phase.to(1, equivalencies=None)

        # test the manager also works in the Quantity constructor.
        q1 = u.Quantity(phase, u.dimensionless_unscaled)
        assert_allclose(q1.value, u.cycle.to(u.radian))

        # and also if we use a class that happens to have a unit attribute.
        class MyQuantityLookalike(np.ndarray):
            pass

        mylookalike = np.array(1.).view(MyQuantityLookalike)
        mylookalike.unit = 'cycle'
        # test the manager also works in the Quantity constructor.
        q2 = u.Quantity(mylookalike, u.dimensionless_unscaled)
        assert_allclose(q2.value, u.cycle.to(u.radian))

    with u.set_enabled_equivalencies(u.spectral()):
        u.GHz.to(u.cm)
        eq_on = u.GHz.find_equivalent_units()
        with pytest.raises(u.UnitsError):
            u.GHz.to(u.cm, equivalencies=None)

    # without equivalencies, we should find a smaller (sub)set
    eq_off = u.GHz.find_equivalent_units()
    assert all(eq in set(eq_on) for eq in eq_off)
    assert set(eq_off) < set(eq_on)

    # Check the equivalency manager also works in ufunc evaluations,
    # not just using (wrong) scaling. [#2496]
    l2v = u.doppler_optical(6000 * u.angstrom)
    l1 = 6010 * u.angstrom
    assert l1.to(u.km/u.s, equivalencies=l2v) > 100. * u.km / u.s
    with u.set_enabled_equivalencies(l2v):
        assert l1 > 100. * u.km / u.s
        assert abs((l1 - 500. * u.km / u.s).to(u.angstrom)) < 1. * u.km/u.s
Ejemplo n.º 19
0
    def test_with_spectral_unit(self, name, masktype, unit):
        cube, data = cube_and_raw(name + '.fits')
        cube_freq = cube.with_spectral_unit(unit)

        if masktype == BooleanArrayMask:
            # don't use data here:
            # data haven't necessarily been rearranged to the correct shape by
            # cube_utils.orient
            mask = BooleanArrayMask(cube.filled_data[:].value > 0,
                                    wcs=cube._wcs)
        elif masktype == LazyMask:
            mask = LazyMask(lambda x: x > 0, cube=cube)
        elif masktype == FunctionMask:
            mask = FunctionMask(lambda x: x > 0)
        elif masktype == CompositeMask:
            mask1 = FunctionMask(lambda x: x > 0)
            mask2 = LazyMask(lambda x: x > 0, cube)
            mask = CompositeMask(mask1, mask2)

        cube2 = cube.with_mask(mask)
        cube_masked_freq = cube2.with_spectral_unit(unit)

        assert cube_freq._wcs.wcs.ctype[cube_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._wcs.wcs.ctype[
            cube_masked_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._mask._wcs.wcs.ctype[
            cube_masked_freq._mask._wcs.wcs.spec] == 'FREQ-W2F'

        # values taken from header
        rest = 1.42040571841E+09 * u.Hz
        crval = -3.21214698632E+05 * u.m / u.s
        outcv = crval.to(u.m, u.doppler_optical(rest)).to(u.Hz, u.spectral())

        assert_allclose(cube_freq._wcs.wcs.crval[cube_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(
            cube_masked_freq._wcs.wcs.crval[cube_masked_freq._wcs.wcs.spec],
            outcv.to(u.Hz).value)
        assert_allclose(
            cube_masked_freq._mask._wcs.wcs.crval[
                cube_masked_freq._mask._wcs.wcs.spec],
            outcv.to(u.Hz).value)
Ejemplo n.º 20
0
def test_no_sigma():
    """
    test return sigma
    """
    survey = SkySurvey()
    import astropy.units as u
    survey["INTEN"] = survey["INTEN"].data * u.R

    ha_wave = 656.3 * u.nm
    optical_ha_equiv = u.doppler_optical(ha_wave)
    dv = (survey["VELOCITY"][0][1] - survey["VELOCITY"][0][0]) * u.km/u.s
    dlambda = (dv).to(u.AA, equivalencies=optical_ha_equiv) - \
        (0 * u.km/u.s).to(u.AA, equivalencies=optical_ha_equiv)

    survey["BKG"] = np.abs(np.random.randn(len(survey["INTEN"]))) * 100.
    survey["BKGSD"] = survey["BKG"] * .1
    ew = survey.get_equivalent_width(return_sigma = False)
    ew2, ew_error2 = survey.get_equivalent_width()

    assert np.allclose(ew.value, ew2.value)
Ejemplo n.º 21
0
    def __init__(self, mode='relativistic'):
        # HI restframe
        self.nu0 = 1420.4058
        self.nu0_u = self.nu0 * u.MHz

        # full mode for Minkowski space time
        if mode.lower() == 'relativistic':
            self.v_frame = u.doppler_relativistic(self.nu0_u)
        # radio definition
        elif mode.lower() == 'radio':
            self.v_frame = u.doppler_radio(self.nu0_u)
            # velo = c * (1. - nu/nu0)

        # optical definition
        elif mode.lower() == 'optical':
            self.v_frame = u.doppler_optical(self.nu0_u)

        self.mode = mode

        return None
def test_convert_to_unit(run_with_assert=False):
    for from_unit, to_unit, _, __ in u.doppler_optical(1 * u.Hz):
        sp = SpectroscopicAxis(
            np.linspace(-100, 100, 100), unit=from_unit, refX=23.2 * u.Hz, velocity_convention="optical"
        )
        sp.convert_to_unit(to_unit)
        if run_with_assert:
            assert sp.unit == to_unit
    for from_unit, to_unit, _, __ in u.doppler_radio(1 * u.eV):
        sp = SpectroscopicAxis(
            np.linspace(-100, 100, 100), unit=from_unit, refX=23.2 * u.Hz, velocity_convention="optical"
        )
        sp.convert_to_unit(to_unit)
        if run_with_assert:
            assert sp.unit == to_unit
    for from_unit, to_unit, _, __ in u.doppler_relativistic(1 * u.Angstrom):
        sp = SpectroscopicAxis(
            np.linspace(-100, 100, 100), unit=from_unit, refX=23.2 * u.Hz, velocity_convention="relativistic"
        )
        sp.convert_to_unit(to_unit)
        if run_with_assert:
            assert sp.unit == to_unit
Ejemplo n.º 23
0
    def slice_rv(self, bounds, rest):
        '''Return a portion of the spectrum between given radial velocity values

        Parameters
        ----------
        bounds : list of two quantities
            [lower bound, upper bound] in radial velocity
        rest : :class:`~astropy.quantity.Quantity`
            Rest wavelength/frequency of spectral feature
        
        Returns
        -------
        spec : :class:`~spectrum.Spectrum`
            spectrum that is limited to the range from bound[0] to bound[1]

        See also
        --------
        slice_disp
        '''
        equil = u.spectral()
        equil.extend(u.doppler_optical(rest))
        return self._slice_disp(bounds, equivalencies=equil)
Ejemplo n.º 24
0
def test_intensity_error_with_intensity():
    """
    test intensity error not provided but intensity provided
    """
    survey = SkySurvey()
    import astropy.units as u
    survey["INTEN"] = survey["INTEN"].data * u.R

    ha_wave = 656.3 * u.nm
    optical_ha_equiv = u.doppler_optical(ha_wave)
    dv = (survey["VELOCITY"][0][1] - survey["VELOCITY"][0][0]) * u.km/u.s
    dlambda = (dv).to(u.AA, equivalencies=optical_ha_equiv) - \
        (0 * u.km/u.s).to(u.AA, equivalencies=optical_ha_equiv)

    survey["BKG"] = np.abs(np.random.randn(len(survey["INTEN"]))) * 100.
    survey["BKGSD"] = survey["BKG"] * .1
    try:
        survey.get_equivalent_width(intensity = survey["INTEN"])
    except TypeError:
        assert True
    else:
        assert False
Ejemplo n.º 25
0
    def slice_rv(self, bounds, rest):
        '''Return a portion of the spectrum between given radial velocity values

        Parameters
        ----------
        bounds : list of two quantities
            [lower bound, upper bound] in radial velocity
        rest : :class:`~astropy.quantity.Quantity`
            Rest wavelength/frequency of spectral feature

        Returns
        -------
        spec : :class:`~spectrum.Spectrum`
            spectrum that is limited to the range from bound[0] to bound[1]

        See also
        --------
        slice_disp
        '''
        equil = u.spectral()
        equil.extend(u.doppler_optical(rest))
        return self._slice_disp(bounds, equivalencies=equil)
Ejemplo n.º 26
0
def test_intensity_error():
    """
    test intensity error providing
    """
    survey = SkySurvey()
    import astropy.units as u
    survey["INTEN"] = survey["INTEN"].data * u.R

    ha_wave = 656.3 * u.nm
    optical_ha_equiv = u.doppler_optical(ha_wave)
    dv = (survey["VELOCITY"][0][1] - survey["VELOCITY"][0][0]) * u.km/u.s
    dlambda = (dv).to(u.AA, equivalencies=optical_ha_equiv) - \
        (0 * u.km/u.s).to(u.AA, equivalencies=optical_ha_equiv)

    survey["BKG"] = np.abs(np.random.randn(len(survey["INTEN"]))) * 100.
    survey["BKGSD"] = survey["BKG"] * .1
    import astropy.units as u
    error = survey["ERROR"].data * u.R

    ew, ew_error = survey.get_equivalent_width(intensity_error = error)
    ew2, ew_error2 = survey.get_equivalent_width()

    assert np.allclose(ew.value, ew2.value)
Ejemplo n.º 27
0
    def test_with_spectral_unit(self, name, masktype, unit):
        cube, data = cube_and_raw(name + '.fits')
        cube_freq = cube.with_spectral_unit(unit)

        if masktype == BooleanArrayMask:
            # don't use data here:
            # data haven't necessarily been rearranged to the correct shape by
            # cube_utils.orient
            mask = BooleanArrayMask(cube.filled_data[:].value>0,
                                    wcs=cube._wcs)
        elif masktype == LazyMask:
            mask = LazyMask(lambda x: x>0, cube=cube)
        elif masktype == FunctionMask:
            mask = FunctionMask(lambda x: x>0)
        elif masktype == CompositeMask:
            mask1 = FunctionMask(lambda x: x>0)
            mask2 = LazyMask(lambda x: x>0, cube)
            mask = CompositeMask(mask1, mask2)

        cube2 = cube.with_mask(mask)
        cube_masked_freq = cube2.with_spectral_unit(unit)

        assert cube_freq._wcs.wcs.ctype[cube_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._wcs.wcs.ctype[cube_masked_freq._wcs.wcs.spec] == 'FREQ-W2F'
        assert cube_masked_freq._mask._wcs.wcs.ctype[cube_masked_freq._mask._wcs.wcs.spec] == 'FREQ-W2F'

        # values taken from header
        rest = 1.42040571841E+09*u.Hz
        crval = -3.21214698632E+05*u.m/u.s
        outcv = crval.to(u.m, u.doppler_optical(rest)).to(u.Hz, u.spectral())

        assert_allclose(cube_freq._wcs.wcs.crval[cube_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(cube_masked_freq._wcs.wcs.crval[cube_masked_freq._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
        assert_allclose(cube_masked_freq._mask._wcs.wcs.crval[cube_masked_freq._mask._wcs.wcs.spec],
                        outcv.to(u.Hz).value)
Ejemplo n.º 28
0
def test_ccf(seed, snr):
    # Make test reproducible:
    np.random.seed(seed)

    # Generate a wavelength grid:
    wl = np.arange(6800, 6900, 0.1)

    # Generate a pseudo-random absorption pattern
    absorption_pattern = gaussian_filter1d(0.1 * np.random.randn(len(wl)), 5)
    absorption_pattern = absorption_pattern - absorption_pattern.min()

    # Roll the absorption pattern offset by 3 indices
    index_offset = 3
    fl = np.ones_like(wl) - np.roll(absorption_pattern, index_offset)

    spectrum = Spectrum(wl, fl)

    emission = absorption_pattern / np.trapz(absorption_pattern, wl)
    template = Template(wl, emission)

    ccf = cross_corr(spectrum,
                     template,
                     start_lam=-10,
                     end_lam=10,
                     n_steps=100)

    # Check that S/N is approximately correct:
    assert abs(ccf.signal_to_noise - snr) < 1

    # Check that the estimated radial velocity is equivalent to index offset
    ref_wl = 6800 * u.Angstrom
    measured_velocity_offset = (
        ccf.rv.to(u.Angstrom, u.doppler_optical(ref_wl)) - ref_wl) / (
            (wl[1] - wl[0]) * u.Angstrom)

    assert_quantity_allclose(measured_velocity_offset, index_offset, atol=1e-2)
Ejemplo n.º 29
0
    def frequencies(self):
        if self._frequencies is None:
            specax = self.wcs.wcs.spec

            channels = np.arange(self.data.shape[::-1][specax])

            spec = self.spec_wcs.wcs_pix2world(channels, 0)[0]

            specc = spec * self.axis_units[specax]

            # Convert radio or optical velocities to frequencies
            if 'VRAD' in self.wcs.wcs.ctype[specax]:
                eq = u.doppler_radio(self.rest_frequency)
            elif 'VOPT' in self.wcs.wcs.ctype[specax]:
                eq = u.doppler_optical(self.rest_frequency)
            elif 'FREQ' in self.wcs.wcs.ctype[specax]:
                eq = []
            else:
                raise AttributeError(
                    'Unsupported spectral type {:s} in header.'.format(self.wcs.wcs.ctype[specax]))

            self._frequencies = specc.to(u.Hz, eq)

        return self._frequencies
def test_byhand_vopt():
    # VOPT: case "Z"
    CRVAL3F = 1.37847121643E+09
    CDELT3F = 9.764775E+04
    CUNIT3F = 'Hz'
    RESTWAVZ= 0.211061139
    #CTYPE3Z = 'VOPT-F2W'
    # This comes from Greisen 2006, but appears to be wrong: CRVAL3Z = 9.120000E+06
    CRVAL3Z = 9.120002206E+06
    CDELT3Z = -2.1882651E+04
    CUNIT3Z = 'm/s'

    crvalf = CRVAL3F * u.Unit(CUNIT3F)
    crvalv = CRVAL3Z * u.Unit(CUNIT3Z)
    restwav = RESTWAVZ * u.m
    cdeltf = CDELT3F * u.Unit(CUNIT3F)
    cdeltv = CDELT3Z * u.Unit(CUNIT3Z)

    # Forward: freq -> vopt
    # crval: (<Quantity 1378471216.43 Hz>, <Quantity 1378471216.43 Hz>, <Quantity 0.2174818410618759 m>, <Quantity 9120002.205689976 m / s>)
    # cdelt: (<Quantity 97647.75 Hz>, <Quantity 97647.75 Hz>, <Quantity -1.540591649098696e-05 m>, <Quantity -21882.652554887027 m / s>)
    #crvalv_computed = crvalf.to(CUNIT3R, u.doppler_radio(restwav))
    crvalw_computed = crvalf.to(u.m, u.spectral())
    crvalw_computed32 = crvalf.astype('float32').to(u.m, u.spectral())
    cdeltw_computed = -(cdeltf / crvalf**2)*constants.c
    cdeltw_computed_byfunction = cdelt_derivative(crvalf, cdeltf,
                                                  intype='frequency',
                                                  outtype='length',
                                                  rest=None)
    # this should be EXACT
    assert cdeltw_computed == cdeltw_computed_byfunction

    crvalv_computed = crvalw_computed.to(CUNIT3Z, u.doppler_optical(restwav))
    crvalv_computed32 = crvalw_computed32.astype('float32').to(CUNIT3Z, u.doppler_optical(restwav))
    #cdeltv_computed = (cdeltw_computed *
    #                   4*constants.c*crvalw_computed*restwav**2 /
    #                   (restwav**2+crvalw_computed**2)**2)
    cdeltv_computed = (cdeltw_computed / restwav)*constants.c
    cdeltv_computed_byfunction = cdelt_derivative(crvalw_computed,
                                                  cdeltw_computed,
                                                  intype='length',
                                                  outtype='speed',
                                                  rest=restwav,
                                                  linear=True)

    # Disagreement is 2.5e-7: good, but not really great...
    #assert np.abs((crvalv_computed-crvalv)/crvalv) < 1e-6
    assert_allclose(crvalv_computed, crvalv, rtol=1.e-2)
    assert_allclose(cdeltv_computed, cdeltv, rtol=1.e-2)

    # Round=trip test:
    # from velo_opt -> freq
    # (<Quantity 9120002.205689976 m / s>, <Quantity 0.2174818410618759 m>, <Quantity 1378471216.43 Hz>, <Quantity 1378471216.43 Hz>)
    # (<Quantity -21882.652554887027 m / s>, <Quantity -1.540591649098696e-05 m>, <Quantity 97647.75 Hz>, <Quantity 97647.75 Hz>)

    crvalw_computed = crvalv_computed.to(u.m, u.doppler_optical(restwav))
    cdeltw_computed = (cdeltv_computed/constants.c) * restwav
    cdeltw_computed_byfunction = cdelt_derivative(crvalv_computed,
                                                  cdeltv_computed,
                                                  intype='speed',
                                                  outtype='length',
                                                  rest=restwav,
                                                  linear=True)
    assert cdeltw_computed == cdeltw_computed_byfunction

    crvalf_computed = crvalw_computed.to(CUNIT3F, u.spectral())
    cdeltf_computed = -cdeltw_computed * constants.c / crvalw_computed**2

    assert_allclose(crvalf_computed, crvalf, rtol=1.e-3)
    assert_allclose(cdeltf_computed, cdeltf, rtol=1.e-3)

    cdeltf_computed_byfunction = cdelt_derivative(crvalw_computed, cdeltw_computed,
                                                  intype='length',
                                                  outtype='frequency',
                                                  rest=None)
    assert cdeltf_computed == cdeltf_computed_byfunction
Ejemplo n.º 31
0
def test_byhand_vopt():
    # VOPT: case "Z"
    CRVAL3F = 1.37847121643E+09
    CDELT3F = 9.764775E+04
    CUNIT3F = 'Hz'
    RESTWAVZ= 0.211061139
    #CTYPE3Z = 'VOPT-F2W'
    # This comes from Greisen 2006, but appears to be wrong: CRVAL3Z = 9.120000E+06
    CRVAL3Z = 9.120002206E+06
    CDELT3Z = -2.1882651E+04
    CUNIT3Z = 'm/s'

    crvalf = CRVAL3F * u.Unit(CUNIT3F)
    crvalv = CRVAL3Z * u.Unit(CUNIT3Z)
    restwav = RESTWAVZ * u.m
    cdeltf = CDELT3F * u.Unit(CUNIT3F)
    cdeltv = CDELT3Z * u.Unit(CUNIT3Z)

    # Forward: freq -> vopt
    # crval: (<Quantity 1378471216.43 Hz>, <Quantity 1378471216.43 Hz>, <Quantity 0.2174818410618759 m>, <Quantity 9120002.205689976 m / s>)
    # cdelt: (<Quantity 97647.75 Hz>, <Quantity 97647.75 Hz>, <Quantity -1.540591649098696e-05 m>, <Quantity -21882.652554887027 m / s>)
    #crvalv_computed = crvalf.to(CUNIT3R, u.doppler_radio(restwav))
    crvalw_computed = crvalf.to(u.m, u.spectral())
    crvalw_computed32 = crvalf.astype('float32').to(u.m, u.spectral())
    cdeltw_computed = -(cdeltf / crvalf**2)*constants.c
    cdeltw_computed_byfunction = cdelt_derivative(crvalf, cdeltf,
                                                  intype='frequency',
                                                  outtype='length',
                                                  rest=None)
    # this should be EXACT
    assert cdeltw_computed == cdeltw_computed_byfunction

    crvalv_computed = crvalw_computed.to(CUNIT3Z, u.doppler_optical(restwav))
    crvalv_computed32 = crvalw_computed32.astype('float32').to(CUNIT3Z, u.doppler_optical(restwav))
    #cdeltv_computed = (cdeltw_computed *
    #                   4*constants.c*crvalw_computed*restwav**2 /
    #                   (restwav**2+crvalw_computed**2)**2)
    cdeltv_computed = (cdeltw_computed / restwav)*constants.c
    cdeltv_computed_byfunction = cdelt_derivative(crvalw_computed,
                                                  cdeltw_computed,
                                                  intype='length',
                                                  outtype='speed',
                                                  rest=restwav,
                                                  linear=True)
    
    # Disagreement is 2.5e-7: good, but not really great...
    #assert np.abs((crvalv_computed-crvalv)/crvalv) < 1e-6
    assert_allclose(crvalv_computed, crvalv, rtol=1.e-2)
    assert_allclose(cdeltv_computed, cdeltv, rtol=1.e-2)

    # Round=trip test:
    # from velo_opt -> freq
    # (<Quantity 9120002.205689976 m / s>, <Quantity 0.2174818410618759 m>, <Quantity 1378471216.43 Hz>, <Quantity 1378471216.43 Hz>)
    # (<Quantity -21882.652554887027 m / s>, <Quantity -1.540591649098696e-05 m>, <Quantity 97647.75 Hz>, <Quantity 97647.75 Hz>)

    crvalw_computed = crvalv_computed.to(u.m, u.doppler_optical(restwav))
    cdeltw_computed = (cdeltv_computed/constants.c) * restwav
    cdeltw_computed_byfunction = cdelt_derivative(crvalv_computed,
                                                  cdeltv_computed,
                                                  intype='speed',
                                                  outtype='length',
                                                  rest=restwav,
                                                  linear=True)
    assert cdeltw_computed == cdeltw_computed_byfunction

    crvalf_computed = crvalw_computed.to(CUNIT3F, u.spectral())
    cdeltf_computed = -cdeltw_computed * constants.c / crvalw_computed**2

    assert_allclose(crvalf_computed, crvalf, rtol=1.e-3)
    assert_allclose(cdeltf_computed, cdeltf, rtol=1.e-3)
    
    cdeltf_computed_byfunction = cdelt_derivative(crvalw_computed, cdeltw_computed,
                                                  intype='length',
                                                  outtype='frequency',
                                                  rest=None)
    assert cdeltf_computed == cdeltf_computed_byfunction
Ejemplo n.º 32
0
def wave2doppler(w, w0):
    import astropy.units as u
    w0_equiv = u.doppler_optical(w0)
    w_equiv = w.to(u.km / u.s, equivalencies=w0_equiv)
    return w_equiv
Ejemplo n.º 33
0
    def __init__(self, filename, config, lambda0=0., verbose=False):
        '''Read datacube and WCS'''

        self.wide_figsize = matplotlib.rcParams['figure.figsize'].copy()
        self.wide_figsize[0] = self.wide_figsize[1]*16./9.
        self.verbose = verbose

	# separate our output from the bullshit printed by import
        print('============================================')

        self.filename = filename
        print("Source file ", filename)

        self.src_fits = fits.open(filename)
        self.src_cube = self.src_fits[0].data
        self.src_header = self.src_fits[0].header

        naxis3, naxis2, naxis1 = self.src_cube.shape
        print(naxis1, "x", naxis2, "pixels,", naxis3, "spectral channels")

        self.plotpix = np.asarray((naxis2//2, naxis1//2))

        # Parse the WCS keywords in primary HDU
        #del self.src_header['VELREF']	# no AIPS stuff, please
        self.wcs = wcs.WCS(self.src_header)

        pixscale1, pixscale2 = wcs.utils.proj_plane_pixel_scales(self.wcs)[0:2]
        pixscale1 = (pixscale1 * self.wcs.wcs.cunit[0]).to(u.mas)
        pixscale2 = (pixscale2 * self.wcs.wcs.cunit[1]).to(u.mas)
        #print("image pixscale from WCS:", pixscale1, pixscale2, "/pixel")

        self.src_pixscale = np.asarray((pixscale1.value, pixscale2.value))*u.mas
        if self.verbose:
            print("image pixscale:", self.src_pixscale, "per pixel")

        # Check flux units of data cube

        try:
            bunit = self.src_header['BUNIT']
            print("BUNIT:", bunit)
            if bunit.lower() == 'jy/pixel':
                #plt.semilogy(self.src_cube[:,111,100])
                #print(np.max(self.src_cube[:,111,100]))
                pixarea = (wcs.utils.proj_plane_pixel_area(self.wcs) *
                           self.wcs.wcs.cunit[0] *
                           self.wcs.wcs.cunit[1]).to(u.arcsec*u.arcsec)
                if self.verbose:
                    print("Pixel area is", pixarea)
                self.src_cube /= pixarea.value
                #plt.semilogy(self.src_cube[:,111,100])
                #plt.show()
                #print(np.max(self.src_cube[:,111,100]))
        except KeyError:
            print("Keyword BUNIT not found.  Assuming the data is in units of Jy/arcsec2")

        # make a Nlambda x 3 array
        crd = np.zeros((naxis3, 3))
        crd[:, 2] = np.arange(naxis3)

        # Convert pixel coordinates to world coordinates
        # Second argument is "origin" -- in this case 0-based coordinates
        world_coo = self.wcs.wcs_pix2world(crd, 0)[:, 2] * self.wcs.wcs.cunit[2]

        if self.verbose:
            print("CTYPES:", self.wcs.wcs.ctype)
            print("CUNITS:", self.wcs.wcs.cunit)

        if self.wcs.wcs.ctype[2] == 'VRAD' or self.wcs.wcs.ctype[2] == 'VOPT':
            print("WARNING: Your Fits header specifies the spectral axis as",
                  self.wcs.wcs.ctype[2])
            print("         We treat it as apparent radial velocity (VELO)")
            self.wcs.wcs.ctype[2] = 'VELO'

        if self.wcs.wcs.ctype[2] == 'VELO':
            #print("Velocities:",world_coo)
            # this should be in the header, shouldn't it?
            if lambda0 > 0.:
                restcoo = lambda0 * u.um	# unit of lambda0 must be micron
            elif self.wcs.wcs.restwav > 0:
                restcoo = (self.wcs.wcs.restwav * u.m).to(u.um)
            elif self.wcs.wcs.restfrq > 0:
                restcoo = (self.wcs.wcs.restfrq * u.Hz).to(u.um, equivalencies=u.spectral())
            else:
                raise RuntimeError("Cannot determine rest wavelength of velocity scale.")

            wavelen = restcoo * (1. + world_coo / const.c)
            #print("Wavelengths:",wavelen)
        elif self.wcs.wcs.ctype[2] == 'WAVE':
            # TODO: test me!
            wavelen = world_coo.to(u.um)
            restcoo = self.wcs.wcs.restwav * self.wcs.wcs.cunit[2]
        elif self.wcs.wcs.ctype[2] == 'FREQ':
            wavelen = world_coo.to(u.um, equivalencies=u.spectral())
            restcoo = self.wcs.wcs.restfrq * self.wcs.wcs.cunit[2]
        else:
            print("spectral axis is '", self.wcs.wcs.ctype[2], "'")
            raise NotImplementedError('spectral axis must have type VELO, WAVE, or FREQ')

        self.wavelen = wavelen.value	# should we store it with units?
        self.restcoo = restcoo		# RESTFRQ or RESTWAV with units

        if self.verbose:
            print("Wavelengths:", wavelen[0:3], "...", wavelen[-1])
            print("restfrq:", self.wcs.wcs.restfrq)
            print("restwav:", self.wcs.wcs.restwav)
            print("restcoo:", self.restcoo)
            #print("Rest wavelen:", restcoo.to(u.um, equivalencies=u.spectral()))

        in_velos = wavelen.to(u.m/u.s, equivalencies=u.doppler_optical(restcoo))
        step = 1.5 * u.km/u.s
        new3 = int((in_velos[-1] - in_velos[0]) / step)+1
        meanv = (in_velos[0] + in_velos[-1]) / 2.

        self.det_velocities = np.arange((meanv-step*(new3-1)/2.).to(u.m/u.s).value,
                                        (meanv+step*((new3-1)/2.+1)).to(u.m/u.s).value,
                                        step.to(u.m/u.s).value)

        if self.verbose:
            print("Source velocities (WCS):", in_velos[0], "...", in_velos[-1])
            #print(in_velos)
            print("new naxis3:", new3)
            #print("middle v:", meanv)
            print("Detector velocities:", self.det_velocities.shape,
                  self.det_velocities[0], "...", self.det_velocities[-1])

        # initialize the target cube, in case someone does not call transmission_emission()

        self.target_cube = self.src_cube
        self.target_hdr = self.src_header.copy()
        self.target_hdr['BUNIT'] = 'Jy/arcsec2'
        self.background = None

        self.transmission = 1.
        self.emission = None	# will be computed later

        # initialize SimCADO to set searchpaths
        #
        print("Reading config", config)
        self.cmds = sm.UserCommands(config)

        self.det_pixscale = self.cmds["SIM_DETECTOR_PIX_SCALE"] * 1000.	 # in mas/pixel

        if self.verbose:
            print("Detector pixel scale ", self.det_pixscale, " mas/pixel")
            print("Filter = ", self.cmds["INST_FILTER_TC"])	# should be open filter

        if np.max(self.src_pixscale.value) > self.det_pixscale:
            print("+------------------------------------------------------------------------------+")
            print("| WARNING: MAX. PIXEL SCALE OF INPUT CUBE IS LARGER THAN DETECTOR PIXEL SCALE! |")
            print("|", np.max(self.src_pixscale), "/pixel >",
                  self.det_pixscale, " mas/pixel")
            print("+------------------------------------------------------------------------------+")
Ejemplo n.º 34
0
def wave2doppler(w, w0):
    w0_equiv = u.doppler_optical(w0)
    w_equiv = w.to(u.km / u.s, equivalencies=w0_equiv)
    return w_equiv
Ejemplo n.º 35
0
def optical_velocity(self, unit):
    rest_freq = self._rest_wave.to(u.Hz, equivalencies=u.spectral())
    optical_equiv = u.doppler_optical(rest_freq)
    return self._sp_coord.to(unit, equivalencies=u.optical_equiv())
Ejemplo n.º 36
0
 def __init__(self):
     self.x = units.SpectroscopicAxis(np.arange(5), unit=u.angstrom, velocity_convention='optical', equivalencies=u.doppler_optical(3*u.AA))
     self.length = units.SpectroscopicAxis(np.arange(5), unit=u.nm)
     self.frequency = units.SpectroscopicAxis(np.arange(5), unit=u.GHz)
     self.speed =  units.SpectroscopicAxis(np.arange(5), unit=u.km/u.s)
Ejemplo n.º 37
0
def test_equivalencies_1():
    x = units.SpectroscopicAxis(np.arange(5), unit=u.angstrom, velocity_convention='optical', equivalencies=u.doppler_optical(3*u.AA))
    assert x.equivalencies is not None # == u.doppler_optical(3*u.AA)
Ejemplo n.º 38
0
def test_convert_to(unit_from, unit_to, convention, ref_unit):
    x = units.SpectroscopicAxis(np.arange(5), unit=u.angstrom, velocity_convention='optical', equivalencies=u.doppler_optical(3*u.AA))
    x.convert_to_unit(unit_to,convention=convention)
Ejemplo n.º 39
0
def plot_image_and_lines(cube,
                         wavs,
                         xrange,
                         yrange,
                         Hbeta_ref=None,
                         title='',
                         filename=None,
                         include_OIII=False):

    zpix = np.arange(0, cube.shape[0])
    lambda_delta = 5
    hbeta_z = np.where((np.array(wavs) > h_beta_std.value-lambda_delta)\
                       & (np.array(wavs) < h_beta_std.value+lambda_delta))[0]
    image = np.mean(cube[min(hbeta_z):max(hbeta_z) + 1, :, :], axis=0)

    spect = [
        np.mean(cube[z, yrange[0]:yrange[1] + 1, xrange[0]:xrange[1] + 1])
        for z in zpix
    ]
    i_peak = spect.index(max(spect))

    background_0 = models.Polynomial1D(degree=2)
    H_beta_0 = models.Gaussian1D(amplitude=500,
                                 mean=4861,
                                 stddev=1.,
                                 bounds={
                                     'mean': (4855, 4865),
                                     'stddev': (0.1, 5)
                                 })
    OIII4959_0 = models.Gaussian1D(amplitude=100,
                                   mean=4959,
                                   stddev=1.,
                                   bounds={
                                       'mean': (4955, 4965),
                                       'stddev': (0.1, 5)
                                   })
    OIII5007_0 = models.Gaussian1D(amplitude=200,
                                   mean=5007,
                                   stddev=1.,
                                   bounds={
                                       'mean': (5002, 5012),
                                       'stddev': (0.1, 5)
                                   })
    fitter = fitting.LevMarLSQFitter()
    if include_OIII is True:
        model0 = background_0 + H_beta_0 + OIII4959_0 + OIII5007_0
    else:
        model0 = background_0 + H_beta_0

    model0.mean_1 = wavs[i_peak]
    model = fitter(model0, wavs, spect)
    residuals = np.array(spect - model(wavs))

    plt.figure(figsize=(20, 8))

    plt.subplot(1, 4, 1)
    plt.title(title)
    norm = v.ImageNormalize(image,
                            interval=v.MinMaxInterval(),
                            stretch=v.LogStretch(1))
    plt.imshow(image, origin='lower', norm=norm)
    region_x = [
        xrange[0] - 0.5, xrange[1] + 0.5, xrange[1] + 0.5, xrange[0] - 0.5,
        xrange[0] - 0.5
    ]
    region_y = [
        yrange[0] - 0.5, yrange[0] - 0.5, yrange[1] + 0.5, yrange[1] + 0.5,
        yrange[0] - 0.5
    ]
    plt.plot(region_x, region_y, 'r-', alpha=0.5, lw=2)

    plt.subplot(1, 4, 2)
    if Hbeta_ref is not None:
        Hbeta_velocity = (model.mean_1.value * u.Angstrom).to(
            u.km / u.s, equivalencies=u.doppler_optical(Hbeta_ref))
        title = f'H-beta ({model.mean_1.value:.1f} A, v={Hbeta_velocity.value:.1f} km/s)'
    else:
        title = f'H-beta ({model.mean_1.value:.1f} A, sigma={model.stddev_1.value:.3f} A)'
    plt.title(title)
    w = [l for l in np.arange(4856, 4866, 0.05)]
    if Hbeta_ref is not None:
        vs = [(l * u.Angstrom).to(
            u.km / u.s, equivalencies=u.doppler_optical(Hbeta_ref)).value
              for l in wavs]
        plt.plot(vs, spect, drawstyle='steps-mid', label='data')
        vs = [(l * u.Angstrom).to(
            u.km / u.s, equivalencies=u.doppler_optical(Hbeta_ref)).value
              for l in w]
        plt.plot(vs, model(w), 'r-', alpha=0.7, label='Fit')
        plt.xlabel('Velocity (km/s)')
        plt.xlim(-200, 200)
    else:
        plt.plot(wavs, spect, drawstyle='steps-mid', label='data')
        plt.plot(w, model(w), 'r-', alpha=0.7, label='Fit')
        plt.xlabel('Wavelength (angstroms)')
        plt.xlim(4856, 4866)
    plt.grid()
    plt.ylabel('Flux')
    plt.legend(loc='best')

    plt.subplot(1, 4, 3)
    if include_OIII is True:
        title = f'OIII 4959 ({model.mean_2.value:.1f} A, sigma={model.stddev_2.value:.3f} A)'
    else:
        title = f'OIII 4959'
    plt.title(title)
    plt.plot(wavs, spect, drawstyle='steps-mid', label='data')
    w = [l for l in np.arange(4954, 4964, 0.05)]
    plt.plot(w, model(w), 'r-', alpha=0.7, label='Fit')
    plt.xlabel('Wavelength (angstroms)')
    plt.ylabel('Flux')
    plt.legend(loc='best')
    plt.xlim(4954, 4964)

    plt.subplot(1, 4, 4)
    if include_OIII is True:
        title = f'OIII 5007 ({model.mean_3.value:.1f} A, sigma={model.stddev_3.value:.3f} A)'
    else:
        title = f'OIII 5007'
    plt.title(title)
    plt.plot(wavs, spect, drawstyle='steps-mid', label='data')
    w = [l for l in np.arange(5002, 5012, 0.05)]
    plt.plot(w, model(w), 'r-', alpha=0.7, label='Fit')
    plt.xlabel('Wavelength (angstroms)')
    plt.ylabel('Flux')
    plt.legend(loc='best')
    plt.xlim(5002, 5012)

    if filename is not None:
        plt.savefig(filename, bbox_inches='tight', pad_inches=0.10)
    else:
        plt.show()

    return spect, model
Ejemplo n.º 40
0
import os
import logging
from datetime import datetime as dt

from astropy.io import fits
from astropy.wcs import WCS
from astropy.modeling import models, fitting
from astropy import units as u

import numpy as np
from matplotlib import pyplot as plt

from astropy import visualization as v

h_beta_std = 4861.3615 * u.Angstrom
H_beta_std_velocity = u.doppler_optical(h_beta_std)

##-------------------------------------------------------------------------
## Create logger object
##-------------------------------------------------------------------------
log = logging.getLogger('MyLogger')
log.setLevel(logging.DEBUG)
## Set up console output
LogConsoleHandler = logging.StreamHandler()
LogConsoleHandler.setLevel(logging.DEBUG)
LogFormat = logging.Formatter('%(asctime)s %(levelname)8s: %(message)s',
                              datefmt='%Y-%m-%d %H:%M:%S')
LogConsoleHandler.setFormatter(LogFormat)
log.addHandler(LogConsoleHandler)

##-------------------------------------------------------------------------
Ejemplo n.º 41
0
    def optical_velocities(self):
        if self._optical_velocities is None:
            opt_eq = u.doppler_optical(self.rest_frequency)
            self._optical_velocities = self.frequencies.to(u.km / u.s, opt_eq)

        return self._optical_velocities
Ejemplo n.º 42
0
def test_equivalencies_3(velocity_convention):
    x = SpectroscopicAxis(np.arange(5), unit=u.angstrom, refX=3, refX_unit='angstrom', velocity_convention=velocity_convention)
    assert x.equivalencies == u.doppler_optical(3*u.AA)
Ejemplo n.º 43
0
    def scale_to_detector(self):
        '''
        Scale to Detector pixels (spatially and spectrally)
        '''

        print()
        print("--------------------Scale to detector pixels--------------------")

        # First interpolate spectrally

        naxis3, naxis2, naxis1 = self.target_cube.shape

        in_velos = (self.wavelen * u.um).to(u.m/u.s,
                                            equivalencies=u.doppler_optical(self.restcoo))

        #print("Original velos:", in_velos[0], "...", in_velos[-1])

        out_velos = self.det_velocities
        #print("New velos:", out_velos.shape, out_velos[0], "...", out_velos[-1])
        #print(out_velos)

        scaled_cube = np.empty((len(out_velos), naxis2, naxis1),
                               self.target_cube[0, 0, 0].dtype)

        for i_x in range(naxis2):
            #print(i_x, end=' ',flush=True)
            for i_y in range(naxis1):
                intpol = interp1d(in_velos, self.target_cube[:, i_y, i_x],
                                  kind='linear', bounds_error=False,
                                  fill_value=0.)
                scaled_cube[:, i_y, i_x] = intpol(out_velos)
        #print()
        self.target_cube = scaled_cube

        self.wcs.wcs.ctype[2] = 'VELO'
        self.wcs.wcs.crpix[2] = 1
        self.wcs.wcs.crval[2] = out_velos[0]
        self.wcs.wcs.cdelt[2] = out_velos[1] - out_velos[0] # should be 1.5km/s
        self.wcs.wcs.cunit[2] = 'm/s'
        #
        # Now interpolate spatially
        #
        naxis3, naxis2, naxis1 = self.target_cube.shape
        if self.verbose:
            print("ScaleToDetector: naxis =", naxis1, naxis2, naxis3)

        in_x = np.arange(naxis1)
        in_y = np.arange(naxis2)
        #print(len(in_x))

        # TODO better: scale from the center of the img

        scale = self.src_pixscale.value / self.det_pixscale

        if self.verbose:
            print("image pixscale from WCS:", self.src_pixscale, "/pixel")
            print("Scale factor:", scale)

        self.plotpix = np.rint(self.plotpix * scale).astype(int)

        ## we need to scale the coord of the last pixel, not the pixel behind the end!
        #out_x = np.arange(round((naxis1-1)*scale[0])+1) / scale[0]
        #out_y = np.arange(round((naxis2-1)*scale[1])+1) / scale[1]

        # scale from the center of the image
        half1 = naxis1 // 2
        half2 = naxis2 // 2

        # scale the coord of the last pixel, not the pixel behind the end!
        out_x = np.arange(half1 - round(half1 * scale[1]) / scale[1],
                          half1 + round((half1 - 1) * scale[1]) / scale[1] + 1,
                          1. / scale[1])
        out_y = np.arange(half2 - round(half2 * scale[0]) / scale[0],
                          half2 + round((half2 - 1) * scale[0]) / scale[0] + 1,
                          1. / scale[0])

        scaled_cube = np.empty((naxis3, len(out_y), len(out_x)),
                               self.target_cube[0, 0, 0].dtype)

        for i in range(naxis3):
            # bilinear interpol
            interp = RectBivariateSpline(in_x, in_y, self.target_cube[i, :, :],
                                         kx=1, ky=1)
            scaled_cube[i, :, :] = interp(out_x, out_y, grid=True)

        if self.verbose:
            print("ScaleToDetector: new shape =", scaled_cube.shape)

        self.target_cube = scaled_cube

        # new_CRPIX = old_CRPIX * new_size/old_size
        #
        # old_pixscale = FoV/old_size
        # new_pixscale = FoV/new_size
        # scale = old_pixscale / new_pixscale = FoV/old_size * new_size/FoV = new_size/old_size
        #
        # new_CRPIX = old_CRPIX * scale
        #
        self.wcs.wcs.crpix[0] = round(self.wcs.wcs.crpix[0] * scale[0])	# or [1]?
        self.wcs.wcs.crpix[1] = round(self.wcs.wcs.crpix[1] * scale[1])

        self.wcs.wcs.cdelt[0] = -self.det_pixscale / 3600. / 1000.	# convert mas/pix to deg/pix
        self.wcs.wcs.cdelt[1] = self.det_pixscale / 3600. / 1000.
        self.wcs.wcs.cunit[0] = 'deg'
        self.wcs.wcs.cunit[1] = 'deg'

	# overwrite old WCS, but keep rest of the header
        for card in self.wcs.to_header().cards:
            self.target_hdr[card.keyword] = (card.value, card.comment)
Ejemplo n.º 44
0
 def setup_class(cls):
     cls.x = units.SpectroscopicAxis(np.arange(5), unit=u.angstrom, velocity_convention='optical', equivalencies=u.doppler_optical(3*u.AA))
     cls.length = units.SpectroscopicAxis(np.arange(5), unit=u.nm)
     cls.frequency = units.SpectroscopicAxis(np.arange(5), unit=u.GHz)
     cls.speed = units.SpectroscopicAxis(np.arange(5), unit=u.km/u.s)
     return cls
Ejemplo n.º 45
0
def create_model(line_centers, amp_guess=None,
                 center_guess=None, width_guess=None,
                 center_limits=None, width_limits=None,
                 center_fixed=None, width_fixed=None,
                 lambda_units=u.micron):
    """
    Function that allows for the creation of a generic model for a spectral region.
    Each line specified in 'line_names' must be included in the file 'lines.py'.
    Defaults for the amplitude guesses will be 1.0 for all lines.
    Defaults for the center guesses will be the observed wavelengths.
    Defaults for the line widths will be 100 km/s for narrow lines and 1000 km/s for the
    broad lines.
    All lines are considered narrow unless the name has 'broad' attached to the end of the name.
    """

    nlines = len(line_centers.keys())
    line_names = line_centers.keys()

    # Create the default amplitude guesses for the lines if necessary
    if amp_guess is None:
        amp_guess = {l: 1.0 for l in line_names}

    # Create arrays to hold the default line center and width guesses
    if center_guess is None:
        center_guess = {l: 0*u.km/u.s for l in line_names}
    if width_guess is None:
        width_guess = {l: 100.*u.km/u.s for l in line_names}

    # Loop through each line and create a model
    mods = []
    for i, l in enumerate(line_names):

        # Equivalency to convert to/from wavelength from/to velocity
        opt_conv = u.doppler_optical(line_centers[l])

        # Convert the guesses for the line center and width to micron
        center_guess_i = center_guess[l].to(lambda_units, equivalencies=opt_conv)

        if u.get_physical_type(width_guess[l].unit) == 'speed':

            width_guess_i = (width_guess[l].to(lambda_units,
                                               equivalencies=u.doppler_optical(center_guess_i)) -
                             center_guess_i)

        elif u.get_physical_type(width_guess[l].unit) == 'length':

            width_guess_i = width_guess[i].to(lambda_units)

        center_guess_i = center_guess_i.value
        width_guess_i = width_guess_i.value

        # Create the single Gaussian line model for the emission line
        mod_single = apy_mod.models.Gaussian1D(mean=center_guess_i, amplitude=amp_guess[l],
                                               stddev=width_guess_i, name=l)

        # Set the constraints on the parameters if necessary
        mod_single.amplitude.min = 0      # always an emission line

        if center_limits is not None:
            if center_limits[l][0] is not None:
                mod_single.mean.min = center_limits[l][0].to(lambda_units, equivalencies=opt_conv).value
            if center_limits[l][1] is not None:
                mod_single.mean.max = center_limits[l][1].to(lambda_units, equivalencies=opt_conv).value

        if width_limits is not None:
            if width_limits[l][0] is not None:
                mod_single.stddev.min = width_limits[l][0].to(lambda_units, equivalencies=opt_conv).value - line_centers[l].value
            else:
                mod_single.stddev.min = 0         # can't have negative width
            if width_limits[l][1] is not None:
                mod_single.stddev.max = width_limits[l][1].to(lambda_units, equivalencies=opt_conv).value - line_centers[l].value
        else:
            mod_single.stddev.min = 0

        # Set the fixed parameters
        if center_fixed is not None:
            mod_single.mean.fixed = center_fixed[l]
        if width_fixed is not None:
            mod_single.stddev.fixed = width_fixed[l]

        # Add to the model list
        mods.append(mod_single)

    # Create the combined model by adding all of the models together
    if nlines == 1:
        final_model = mods[0]
    else:
        final_model = mods[0]
        for m in mods[1:]:
            final_model += m

    return final_model
Ejemplo n.º 46
0
from __future__ import print_function
import pyspeckit
from astropy import units as u
sp = pyspeckit.Spectrum('G203.04+1.76_h2co.fits',wcstype='D')
sp.xarr.center_frequency._unit = u.Hz
sp.xarr = sp.xarr.as_unit('km/s', equivalencies=u.doppler_radio(sp.xarr.center_frequency))
sp.specfit(fittype='formaldehyde',multifit=True,usemoments=True,guesses=[-0.6,4,0.2],equivalencies=u.doppler_optical(sp.xarr.center_frequency))
sp.plotter(figure=2)
sp.crop(-5*u.km/u.s,15*u.km/u.s)
sp.specfit(fittype='formaldehyde',multifit=True,usemoments=True,guesses=[-0.6,4,0.2])
sp.specfit(fittype='formaldehyde',multifit=True,usemoments=True,guesses=[-0.6,4,0.2])
sp.specfit.plot_fit(show_components=True)
sp.plotter.savefig("h2co_11_h2cofit.png")
print("Line integral (Formaldehyde,11): ",sp.specfit.integral())
print("Direct Line integral (Formaldehyde,11): ",sp.specfit.integral(direct=True,return_error=True))

sp2 = pyspeckit.Spectrum('G203.04+1.76_h2co.fits',wcstype='V')
sp2.xarr.convert_to_unit('km/s')
sp2.crop(-5*u.km/u.s,15*u.km/u.s)
sp2.plotter(figure=3)
sp2.specfit.peakbgfit(negamp=True, vheight=False)
sp2.specfit.peakbgfit(negamp=True, vheight=False)
sp2.plotter.savefig("h2co_11_gaussfit.png")
print("Line integral (Gaussian,11): ",sp2.specfit.integral())
print("Direct Line integral (Gaussian,11): ",sp2.specfit.integral(direct=True,return_error=True))


sp22g = pyspeckit.Spectrum('G203.04+1.76_h2co_Tastar.fits',wcstype='V')
sp22g.specfit.peakbgfit(negamp=True)
sp22g.xarr = sp22g.xarr.as_unit('km/s')
sp22g.plotter(figure=5)