示例#1
0
    def test_magnitudes(self, spec_name, filters):
        sp = Spextrum(spec_name)
        filter1 = filters[0]
        filter2 = filters[1]
        mag1 = sp.get_magnitude(filter_curve=filter1)
        mag2 = sp.get_magnitude(filter_curve=filter2)

        assert np.isclose(mag1.value, mag2.value, atol=0.3)
示例#2
0
    def test_correct_scaling(self, unit):
        sp1 = Spextrum("kc96/s0").scale_to_magnitude(amplitude=14 * unit,
                                                     filter_curve="r")
        sp2 = Spextrum("kc96/s0").scale_to_magnitude(amplitude=15 * unit,
                                                     filter_curve="r")

        flux1 = sp1(sp1.waveset[(sp1.waveset.value > 6231 - 200)
                                & (sp1.waveset.value < 6231 + 200)]).value
        flux2 = sp2(sp2.waveset[(sp2.waveset.value > 6231 - 200)
                                & (sp2.waveset.value < 6231 + 200)]).value

        mean = np.mean(flux1 / flux2)
        assert np.isclose(mean, 10**0.4)
示例#3
0
    def test_ref_spectrum_is_right(self, unit):
        sp1 = Spextrum.flat_spectrum(amplitude=10 * unit)
        sp2 = Spextrum.flat_spectrum(amplitude=11 * unit)
        if unit == u.mag:
            flux1 = sp1(sp1.waveset[(sp1.waveset.value > 7000 - 200)
                                    & (sp1.waveset.value < 7000 + 200)]).value
            flux2 = sp2(sp2.waveset[(sp2.waveset.value > 7000 - 200)
                                    & (sp2.waveset.value < 7000 + 200)]).value

        else:
            waves = np.arange(1000, 1e4, 1) * u.AA
            flux1 = sp1(waves)
            flux2 = sp2(waves)

        mean = np.mean(flux1 / flux2)
        assert np.isclose(mean, 10**0.4)
示例#4
0
    def test_vega2ab(self, filt):
        """
        test if the convertion between AB and Vega is correct
        conversions taken from:  http://www.astronomy.ohio-state.edu/~martini/usefuldata.html

        absolute tolerance set to 0.15 mag to account for filter differences

        Parameters
        ----------
        filt: str
            name of the filter
        """
        ab2vega = {
            "U": 0.79,  # magAB - magVega taken from
            "B": -0.09,  #
            "V": 0.02,
            "R": 0.21,
            "I": 0.45,
            "J": 0.91,
            "H": 1.39,
            "Ks": 1.85
        }

        sp = Spextrum.flat_spectrum(amplitude=0 * u.ABmag)

        magAB = sp.get_magnitude(filt, system_name="AB")
        magVega = sp.get_magnitude(filt, system_name="vega")

        diff = (magAB.value - magVega.value)

        assert np.isclose(diff, ab2vega[filt], atol=0.15)
示例#5
0
    def test_hz2angstrom(self):

        waves = np.array([1, 2, 3]) * u.Hz
        flux = np.array([1, 1, 2]) * units.FLAM

        sp = Spextrum.from_arrays(waves, flux)

        inwaves = c.value / waves.value
        outwaves = sp.waveset.to(u.m).value

        assert np.isclose(inwaves[::-1], outwaves).all()
示例#6
0
def data_cube(
        sed,  # The SED of the galaxy,
        z=0,  # redshift
        mag=15,  # magnitude
        filter_name="g",  # passband
        wmin=None,
        wmax=None,
        plate_scale=0.2,  # the plate scale "/pix
        r_eff=10,  # effective radius
        n=4,  # sersic index
        ellip=0.1,  # ellipticity
        theta=0,  # position angle
        vmax=100,
        sigma=100,
        extend=2):  # extend in units of r_eff):
    """
    Creates a datacube for a galaxy

    """
    if isinstance(mag, u.Quantity) is False:
        mag = mag * u.ABmag
    if isinstance(plate_scale, u.Quantity) is False:
        plate_scale = plate_scale * u.arcsec
    if isinstance(r_eff, u.Quantity) is False:
        r_eff = r_eff * u.arcsec
    if isinstance(vmax, u.Quantity) is False:
        vmax = vmax * u.km / u.s
    if isinstance(sigma, u.Quantity) is False:
        sigma = sigma * u.km / u.s
    if isinstance(sed, str):
        sp = Spextrum(sed).redshift(z=z)
        scaled_sp = sp.scale_to_magnitude(amplitude=mag,
                                          filter_name=filter_name)
    elif isinstance(sed, Spextrum):
        scaled_sp = sed

    if wmin is None:
        wmin = np.min(scaled_sp.waveset)
    elif isinstance(wmin, u.Quantity) is False:
        wmin = wmin * u.AA
    else:
        wmin = wmin.to(u.AA)

    if wmax is None:
        wmax = np.max(scaled_sp.waveset)
    elif isinstance(wmax, u.Quantity) is False:
        wmax = wmax * u.AA
    else:
        wmax = wmax.to(u.AA)

    scaled_sp = scaled_sp[(scaled_sp.waveset > wmin)
                          & (scaled_sp.waveset < wmax)]
    image_size = 2 * (r_eff.value * extend / plate_scale.value
                      )  # TODO: Needs unit check
    x_0 = image_size // 2
    y_0 = image_size // 2

    x, y = np.meshgrid(np.arange(image_size), np.arange(image_size))
    gal = GalaxyBase(x=x,
                     y=y,
                     x_0=x_0,
                     y_0=y_0,
                     r_eff=r_eff.value / plate_scale.value,
                     amplitude=1,
                     n=n,
                     ellip=ellip,
                     theta=theta,
                     vmax=vmax,
                     sigma=sigma)

    intensity = gal.intensity
    velocity = gal.velocity.value
    dispersion = gal.dispersion.value
    w, h = intensity.shape
    length = scaled_sp.waveset.shape
    header = fits.Header({
        "NAXIS": 3,
        "NAXIS1": 2 * x_0 + 1,
        "NAXIS2": 2 * y_0 + 1,
        "NAXIS3": length,
        "CRPIX1": w // 2,
        "CRPIX2": h // 2,
        "CRPIX3": 1.0,
        "CRVAL1": 0,
        "CRVAL2": 0,
        "CRVAL3": np.min(scaled_sp.waveset),
        "CDELT1": -1 * plate_scale.to(u.deg).value,
        "CDELT2": plate_scale.to(u.deg).value,
        "CUNIT1": "DEG",
        "CUNIT2": "DEG",
        "CUNIT3": "Angstrom",
        "CTYPE1": 'RA---TAN',
        "CTYPE2": 'DEC--TAN',
        "CTYPE3": "AWAV",
        "SPEC_REF": 0
    })

    for i in range(image_size):
        for j in range(image_size):
            sp = scaled_sp.redshift(vel=velocity[i, j]).smooth(
                sigma=dispersion[i, j]) * intensity[i, j]
示例#7
0
 def test_sum_spectra(self):
     sp1 = Spextrum("kc96/s0")
     sp2 = Spextrum("pickles/a0v")
     sp = sp1 + sp2
     assert isinstance(sp, Spextrum)
示例#8
0
 def test_flat_spectrum(self, unit):
     sp = Spextrum.flat_spectrum(amplitude=10 * unit)
     assert isinstance(sp, Spextrum)
示例#9
0
class TestSpextrumInstances:
    """
    This class tests whether each method return the correct instances
    it also tests whether the methods are functional
    but it doesn't test for correct outputs see cls:TestSpextrum for that
    """

    sp = Spextrum("kc96/s0")

    def test_load(self, sp=sp):
        assert isinstance(sp, Spextrum)

    def test_sub_class(self):
        assert issubclass(Spextrum, SourceSpectrum)

    def test_redshift(self, sp=sp):

        sp2 = sp.redshift(z=1)
        assert isinstance(sp2, Spextrum)

    def test_add_emi_lines(self, sp=sp):
        sp2 = sp.add_emi_lines([5000, 6000], [10, 20], [1e-15, 2e-15])
        assert isinstance(sp2, Spextrum)

    def test_add_abs_lines(self, sp=sp):
        sp2 = sp.add_abs_lines([5000, 6000], [15, 20], [10, 12])
        assert isinstance(sp2, Spextrum)

    @pytest.mark.parametrize("unit", [u.mag, u.STmag, u.ABmag])
    def test_flat_spectrum(self, unit):
        sp = Spextrum.flat_spectrum(amplitude=10 * unit)
        assert isinstance(sp, Spextrum)

    def test_mul_with_scalar(self, sp=sp):
        sp2 = sp * 2
        assert isinstance(sp2, Spextrum)

    def test_sum_spectra(self):
        sp1 = Spextrum("kc96/s0")
        sp2 = Spextrum("pickles/a0v")
        sp = sp1 + sp2
        assert isinstance(sp, Spextrum)

    def test_scale_to_magnitude(self, sp=sp):
        sp2 = sp.scale_to_magnitude(amplitude=15 * u.ABmag, filter_curve="g")
        assert isinstance(sp2, Spextrum)

    def test_rebin_spectra(self, sp=sp):
        new_waves = np.linspace(np.min(sp.waveset), np.max(sp.waveset), 100)
        sp2 = sp.rebin_spectra(new_waves=new_waves)
        assert isinstance(sp2, Spextrum)

    def test_get_magnitude(self):
        sp = Spextrum("pickles/a0v")
        mag = sp.get_magnitude("elt/micado/Y", system_name="AB")
        assert isinstance(mag, u.Quantity)

    def test_black_body_spectrum(self):
        sp = Spextrum.black_body_spectrum(filter_curve="g")
        assert isinstance(sp, Spextrum)

    def test_photons_in_range(self):
        sp = Spextrum.black_body_spectrum(filter_curve="g")
        counts = sp.photons_in_range(wmin=4000, wmax=5000)
        assert isinstance(counts, u.Quantity)

    def test_smooth(self):
        sp = Spextrum.black_body_spectrum(filter_curve="g")
        sp2 = sp.smooth(10 * (u.m / u.s))
        assert isinstance(sp2, Spextrum)

    def test_redden(self):
        sp = Spextrum.black_body_spectrum(filter_curve="r")
        sp2 = sp.redden("calzetti/starburst", Ebv=0.1)
        assert isinstance(sp2, Spextrum)

    def test_deredden(self):
        sp = Spextrum.black_body_spectrum(filter_curve="F110W")
        sp2 = sp.redden("gordon/smc_bar", Ebv=0.1)
        assert isinstance(sp2, Spextrum)

    def testing_nesting(self):

        sp = Spextrum("kc96/s0").redshift(z=1).\
            scale_to_magnitude(amplitude=15*u.ABmag, filter_curve="g").\
            redden("calzetti/starburst", Ebv=0.1)
        assert isinstance(sp, Spextrum)
示例#10
0
 def test_photons_in_range(self):
     sp = Spextrum.black_body_spectrum(filter_curve="g")
     counts = sp.photons_in_range(wmin=4000, wmax=5000)
     assert isinstance(counts, u.Quantity)
示例#11
0
def galaxy3d(
        sed,  # The SED of the galaxy,
        z=0,  # redshift
        mag=15,  # magnitude
        filter_name="g",  # passband
        plate_scale=0.2,  # the plate scale "/pix
        r_eff=10,  # effective radius
        n=4,  # sersic index
        ellip=0.1,  # ellipticity
        theta=0,  # position angle
        vmax=100,
        sigma=100,
        extend=2,  # extend in units of r_eff
        ngrid=10):  # griding parameter
    """
    Creates a source object of a galaxy described by its Sersic index and other
    parameters. It also generates a velocity field (set by vmax) and
    a velocity dispersion map (set by sigma).

    The maps are binned according to the ngrid parameter, higher ngrid will create
    finer binned fields but it may increase the computation time.

    The ngrid parameter does not specify the number of bins. A ngrid=10 will create
    around 40 independent regions whilst a ngrid of 100 will create around 2300 regions

    This function is ideal for spectroscopy

    Parameters
    ----------
    sed : str or Spextrum
        SED of the galaxy, it can be a string or a Spextrum object, in the later case it won't
        be re-escaled.
    z : float
        redshift of the galaxy
    mag : float
        magnitude of the galaxy. The spectrum will be re-escaled to this magnitude
    filter_name : str
        name of the filter where the magnitude is measured
    plate_scale : float
        the scale of the image in arcsec/pixel
    r_eff : float
        effective radius of the galaxy in arcsec. It accepts astropy.units
    n : float
        Sersic index of the galaxy
    ellip : float
        ellipticity of the galaxy
    theta : float
        position angle of the galaxy
    vmax : float
        maximum rotation velocity of the galaxy
    sigma : float
        velocity dispersion of the galaxy

    extend : float
        Size of the image in units of r_eff

    ngrid : int
        gridding parameter for creating of the galaxy

    Returns
    -------
    src : scopesim.Source

    """

    if isinstance(mag, u.Quantity) is False:
        mag = mag * u.ABmag
    if isinstance(plate_scale, u.Quantity) is False:
        plate_scale = plate_scale * u.arcsec
    if isinstance(r_eff, u.Quantity) is False:
        r_eff = r_eff * u.arcsec
    if isinstance(vmax, u.Quantity) is False:
        vmax = vmax * u.km / u.s
    if isinstance(sigma, u.Quantity) is False:
        sigma = sigma * u.km / u.s
    if isinstance(sed, str):
        sp = Spextrum(sed).redshift(z=z)
        scaled_sp = sp.scale_to_magnitude(amplitude=mag,
                                          filter_curve=filter_name)
    elif isinstance(sed, Spextrum):
        scaled_sp = sed

    r_eff = r_eff.to(u.arcsec)
    plate_scale = plate_scale.to(u.arcsec)
    vmax = vmax.to(u.km / u.s)
    sigma = sigma.to(u.km / u.s)

    image_size = 2 * (r_eff.value * extend / plate_scale.value
                      )  # TODO: Needs unit check
    print(image_size, r_eff)
    x_0 = image_size // 2
    y_0 = image_size // 2

    x, y = np.meshgrid(np.arange(image_size), np.arange(image_size))

    galaxy = GalaxyBase(x=x,
                        y=y,
                        x_0=x_0,
                        y_0=y_0,
                        r_eff=r_eff.value / plate_scale.value,
                        amplitude=1,
                        n=n,
                        ellip=ellip,
                        theta=theta,
                        vmax=vmax,
                        sigma=sigma)

    intensity = galaxy.intensity
    velocity = galaxy.velocity.value
    dispersion = galaxy.dispersion.value
    masks = galaxy.get_masks(ngrid=ngrid)
    w, h = intensity.shape
    header = fits.Header({
        "NAXIS": 2,
        "NAXIS1": 2 * x_0 + 1,
        "NAXIS2": 2 * y_0 + 1,
        "CRPIX1": w // 2,
        "CRPIX2": h // 2,
        "CRVAL1": 0,
        "CRVAL2": 0,
        "CDELT1": -1 * plate_scale.to(u.deg).value,
        "CDELT2": plate_scale.to(u.deg).value,
        "CUNIT1": "DEG",
        "CUNIT2": "DEG",
        "CTYPE1": 'RA---TAN',
        "CTYPE2": 'DEC--TAN',
        "SPEC_REF": 0
    })

    src = Source()
    src.fields = []
    src.spectra = []
    total_flux = np.sum(intensity)

    hdulist = []

    for i, m in enumerate(masks):
        data = m * intensity
        factor = np.sum(data) / total_flux

        masked_vel = np.ma.array(velocity, mask=m == 0)
        masked_sigma = np.ma.array(dispersion, mask=m == 0)
        med_vel = np.ma.median(masked_vel)
        med_sig = np.ma.median(masked_sigma)

        spec = scaled_sp.redshift(vel=med_vel).smooth(sigma=med_sig) * factor

        header["SPEC_REF"] = i
        hdu = fits.ImageHDU(data=data, header=header)
        hdulist.append(hdu)
        src.spectra.append(spec)

    src.fields = fits.HDUList(hdulist)

    return src
示例#12
0
 def test_black_body_spectrum(self):
     sp = Spextrum.black_body_spectrum(filter_curve="g")
     assert isinstance(sp, Spextrum)
示例#13
0
 def test_wrong_load(self):
     with pytest.raises(ValueError) as e_info:
         sp = Spextrum("kc96/wrong_name")
示例#14
0
    def testing_nesting(self):

        sp = Spextrum("kc96/s0").redshift(z=1).\
            scale_to_magnitude(amplitude=15*u.ABmag, filter_curve="g").\
            redden("calzetti/starburst", Ebv=0.1)
        assert isinstance(sp, Spextrum)
示例#15
0
 def test_deredden(self):
     sp = Spextrum.black_body_spectrum(filter_curve="F110W")
     sp2 = sp.redden("gordon/smc_bar", Ebv=0.1)
     assert isinstance(sp2, Spextrum)
示例#16
0
 def test_redden(self):
     sp = Spextrum.black_body_spectrum(filter_curve="r")
     sp2 = sp.redden("calzetti/starburst", Ebv=0.1)
     assert isinstance(sp2, Spextrum)
示例#17
0
 def test_smooth(self):
     sp = Spextrum.black_body_spectrum(filter_curve="g")
     sp2 = sp.smooth(10 * (u.m / u.s))
     assert isinstance(sp2, Spextrum)
示例#18
0
def galaxy(
        sed,  # The SED of the galaxy
        z=0,  # redshift
        mag=15,  # magnitude
        filter_name="g",  # passband
        plate_scale=0.1,  # the plate scale "/pix
        r_eff=2.5,  # effective radius
        n=4,  # sersic index
        ellip=0.1,  # ellipticity
        theta=0,  # position angle
        extend=2):  # extend in units of r_eff
    """
    Creates a source object of a galaxy described by its Sersic index and other
    parameters.

    This function is ideal for imaging

    Parameters
    ----------
    sed : str or Spextrum
    z : float
        redshift of the galaxy
    r_eff : float
        effective radius of the galaxy in arcsec, it accepts astropy.units
    mag : float
        magnitude of the galaxy, it accepts astropy.units
    filter_name : str
        name of the filter where the magnitude refer to
    plate_scale : float
        the scale in arcsec/pixel of the instrument
    n : float
        Sersic index of the galaxy
    ellip : float
        ellipticity of the galaxy
    theta : float
        position angle of the galaxy
    extend : float
        Size of the image in units of r_eff


    Returns
    -------
    src : scopesim.Source
    """

    if isinstance(mag, u.Quantity) is False:
        mag = mag * u.ABmag
    if isinstance(plate_scale, u.Quantity) is False:
        plate_scale = plate_scale * u.arcsec
    if isinstance(r_eff, u.Quantity) is False:
        r_eff = r_eff * u.arcsec
    if isinstance(sed, str):
        sp = Spextrum(sed).redshift(z=z)
        scaled_sp = sp.scale_to_magnitude(amplitude=mag,
                                          filter_curve=filter_name)
    elif isinstance(sed, (Spextrum)):
        scaled_sp = sed

    r_eff = r_eff.to(u.arcsec)
    plate_scale = plate_scale.to(u.arcsec)

    image_size = 2 * (r_eff.value * extend / plate_scale.value
                      )  # TODO: Needs unit check
    x_0 = image_size // 2
    y_0 = image_size // 2

    x, y = np.meshgrid(np.arange(image_size), np.arange(image_size))

    galaxy = GalaxyBase(x=x,
                        y=y,
                        x_0=x_0,
                        y_0=y_0,
                        r_eff=r_eff.value,
                        amplitude=1,
                        n=n,
                        ellip=ellip,
                        theta=theta)

    img = galaxy.intensity

    w, h = img.shape
    header = fits.Header({
        "NAXIS": 2,
        "NAXIS1": 2 * x_0 + 1,
        "NAXIS2": 2 * y_0 + 1,
        "CRPIX1": w // 2,
        "CRPIX2": h // 2,
        "CRVAL1": 0,
        "CRVAL2": 0,
        "CDELT1": -1 * plate_scale.to(u.deg).value,
        "CDELT2": plate_scale.to(u.deg).value,
        "CUNIT1": "DEG",
        "CUNIT2": "DEG",
        "CTYPE1": 'RA---TAN',
        "CTYPE2": 'DEC--TAN',
        "SPEC_REF": 0
    })

    hdu = fits.ImageHDU(data=img, header=header)
    # hdu.writeto("deleteme.fits", overwrite=True)
    src = Source()
    src.spectra = [scaled_sp]
    src.fields = [hdu]

    return src
示例#19
0
 def test_get_magnitude(self):
     sp = Spextrum("pickles/a0v")
     mag = sp.get_magnitude("elt/micado/Y", system_name="AB")
     assert isinstance(mag, u.Quantity)