Esempio n. 1
0
from sklearn.manifold import LocallyLinearEmbedding
from astroML.datasets import fetch_sdss_specgals
from astroML.datasets import fetch_sdss_spectrum

data = fetch_sdss_specgals()
print data.dtype.names
ngals = 326
nwavel = 3855
plates = data['plate'][:ngals]
mjds = data['mjd'][:ngals]
fiberIDs = data['fiberID'][:ngals]
h_alpha = data['h_alpha_flux'][:ngals]
bptclass = data['bptclass'][:ngals]
specdata = np.zeros((ngals, nwavel))

i = 0
for plate, mjd, fiberID in zip(plates, mjds, fiberIDs):
    tempdata = fetch_sdss_spectrum(plate, mjd, fiberID)
    specdata[i, :] = tempdata.spectrum/tempdata.spectrum.mean()
    i += 1

# Apply LLE
k = 7
for fignum, n in enumerate([2, 3]):
    lle = LocallyLinearEmbedding(k, n)
    lle.fit(specdata)
    proj = lle.transform(specdata)
    pl.subplot(2, 1, fignum+1)
    pl.scatter(proj[:,0], proj[:,1], c=bptclass, s=50)
pl.colorbar()
pl.show()
Esempio n. 2
0
the SDSS server for the given plate, fiber, and mjd, downloads the spectrum,
and plots the result.
"""
# Author: Jake VanderPlas <*****@*****.**>
# License: BSD
#   The figure is an example from astroML: see http://astroML.github.com
from matplotlib import pyplot as plt
from astroML.datasets import fetch_sdss_spectrum

#------------------------------------------------------------
# Fetch single spectrum
plate = 1615
mjd = 53166
fiber = 513

spec = fetch_sdss_spectrum(plate, mjd, fiber)

#------------------------------------------------------------
# Plot the resulting spectrum
ax = plt.axes()
ax.plot(spec.wavelength(), spec.spectrum, '-k', label='spectrum')
ax.plot(spec.wavelength(), spec.error, '-', color='gray', label='error')

ax.legend(loc=4)

ax.set_title('Plate = %(plate)i, MJD = %(mjd)i, Fiber = %(fiber)i' % locals())

ax.text(0.05, 0.95, 'z = %.2f' % spec.z, size=16,
        ha='left', va='top', transform=ax.transAxes)

ax.set_xlabel(r'$\lambda (\AA)$')
Esempio n. 3
0
def fetch_and_shift_spectra(n_spectra,
                            outfile,
                            primtarget=TARGET_GALAXY,
                            zlim=(0, 0.7),
                            loglam_start=3.5,
                            loglam_end=3.9,
                            Nlam=1000):
    """
    This function queries CAS for matching spectra, and then downloads
    them and shifts them to a common redshift binning
    """
    # First query for the list of spectra to download
    plate, mjd, fiber = query_plate_mjd_fiber(n_spectra, primtarget,
                                              zlim[0], zlim[1])

    # Set up arrays to hold information gathered from the spectra
    spec_cln = np.zeros(n_spectra, dtype=np.int32)
    lineindex_cln = np.zeros(n_spectra, dtype=np.int32)

    log_NII_Ha = np.zeros(n_spectra, dtype=np.float32)
    log_OIII_Hb = np.zeros(n_spectra, dtype=np.float32)

    z = np.zeros(n_spectra, dtype=np.float32)
    zerr = np.zeros(n_spectra, dtype=np.float32)
    spectra = np.zeros((n_spectra, Nlam), dtype=np.float32)
    mask = np.zeros((n_spectra, Nlam), dtype=np.bool)

    # Calculate new wavelength coefficients
    new_coeff0 = loglam_start
    new_coeff1 = (loglam_end - loglam_start) / Nlam

    # Now download all the needed spectra, and resample to a common
    #  wavelength bin.
    n_spectra = len(plate)
    num_skipped = 0
    i = 0

    while i < n_spectra:
        sys.stdout.write(' %i / %i spectra\r' % (i + 1, n_spectra))
        sys.stdout.flush()
        try:
            spec = fetch_sdss_spectrum(plate[i], mjd[i], fiber[i])
        except HTTPError:
            num_skipped += 1
            print("%i, %i, %i not found" % (plate[i], mjd[i], fiber[i]))
            i += 1
            continue

        spec_rebin = spec.restframe().rebin(new_coeff0, new_coeff1, Nlam)

        if np.all(spec_rebin.spectrum == 0):
            num_skipped += 1
            print("%i, %i, %i is all zero" % (plate[i], mjd[i], fiber[i]))
            continue

        spec_cln[i] = spec.spec_cln

        lineindex_cln[i], (log_NII_Ha[i], log_OIII_Hb[i])\
            = spec.lineratio_index()

        z[i] = spec.z
        zerr[i] = spec.zerr

        spectra[i] = spec_rebin.spectrum
        mask[i] = spec_rebin.compute_mask(0.5, 5)

        i += 1
    sys.stdout.write('\n')

    N = i
    print("   %i spectra skipped" % num_skipped)
    print("   %i spectra processed" % N)
    print("saving to %s" % outfile)

    np.savez(outfile,
             spectra=spectra[:N],
             mask=mask[:N],
             coeff0=new_coeff0,
             coeff1=new_coeff1,
             spec_cln=spec_cln[:N],
             lineindex_cln=lineindex_cln[:N],
             log_NII_Ha=log_NII_Ha[:N],
             log_OIII_Hb=log_OIII_Hb[:N],
             z=z[:N],
             zerr=zerr[:N])
Esempio n. 4
0
def plot_image_spec_sdss_galaxy(sdss_obj, save_figure=False):
    #plot image and spectrum of a specified SDSS galaxy
    # input sdss_obj = individual SDSS main galaxy data base entry
    # save_figure specifies whether PDF of the figure will be saved in fig/ subdirectory for the record
    #
    # define plot with 2 horizonthal panels of appropriate size
    fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(6, 2.))
    # set an appropriate font size for labels
    plt.rc('font',size=8)

    #get RA and DEC of the galaxy and form the filename to save SDSS image
    RA = sdss_obj['ra']; DEC = sdss_obj['dec']; scale=0.25
    outfile = image_home_dir()+str(sdss_obj['objID'])+'.jpg'
    fetch_sdss_image(outfile, RA, DEC, scale)
    img = Image.open(outfile)
    # do not plot pixel axis labels
    ax0.axis('off')
    ax0.imshow(img)

    # fetch SDSS spectrum using plate number, epoch, and fiber ID
    plate = sdss_obj['plate']; mjd = sdss_obj['mjd']; fiber = sdss_obj['fiberID']
    spec = fetch_sdss_spectrum(plate, mjd, fiber)

    # normalize spectrum for plotting
    spectrum = 0.5 * spec.spectrum  / spec.spectrum.max()
    lam = spec.wavelength()
    text_kwargs = dict(ha='center', va='center', alpha=0.5, fontsize=10)

    # set axis limits for spectrum plot
    ax1.set_xlim(3000, 10000)
    ax1.set_ylim(0, 0.6)

    color = np.zeros(5)
    for i, f, c, loc in zip([0,1,2,3,4],'ugriz', 'bgrmk', [3500, 4600, 6100, 7500, 8800]):
        data_home = setup.sdss_filter_dir()
        archive_file = os.path.join(data_home, '%s.dat' % f)
        if not os.path.exists(archive_file):
            raise ValueError("Error in plot_img_spec_sdss_galaxy: filter file '%s' does not exist!" % archive_file )
        F = open(archive_file)
        filt = np.loadtxt(F, unpack=True)
        ax1.fill(filt[0], filt[2], ec=c, fc=c, alpha=0.4)
        fsp = interp1d(filt[0],filt[2], bounds_error=False, fill_value=0.0)
        ax1.text(loc, 0.03, f, color=c, **text_kwargs)
        # compute magnitude in each band using simple Simpson integration of spectrum and filter using eq 1.2 in the notes
        fspn = lam*fsp(lam)/simps(fsp(lam)/lam,lam)
        lamf = fspn; #lamf = lamf.clip(0.0)
        specf = spec.spectrum * lamf
        color[i] = -2.5 * np.log10(simps(specf,lam)) 
        
    # print estimated g-r color for the object
    grcatcol = sdss_obj['modelMag_g']-sdss_obj['modelMag_r'] 
    print "computed g-r = ", color[1]-color[2]
    print "catalog g-r=", grcatcol

    ax1.plot(lam, spectrum, '-k', lw=0.5, label=r'$(g-r)=%.2f$'%grcatcol )
    ax1.set_xlabel(r'$\lambda {(\rm \AA)}$')
    ax1.set_ylabel(r'$\mathrm{norm.\ specific\ flux}\ \ \ f_{\lambda}$')
    #ax.set_title('Plate = %(plate)i, MJD = %(mjd)i, Fiber = %(fiber)i' % locals())
    #ax.set_title('%s' % objects[obj_]['name'])
    ax1.legend(frameon=False)

    if save_figure: 
        plt.savefig('fig/gal_img_spec'+'_'+str(sdss_obj['objID'])+'.pdf',bbox_inches='tight')

    plt.subplots_adjust(wspace = 0.2)
    plt.show()
    return
Esempio n. 5
0

primtarget=TARGET_GALAXY_RED
zlim=(0.2, 0.6)

plate, mjd, fiber = query_plate_mjd_fiber(100, primtarget, zlim[0], zlim[1])

agg = SpecMeanAggregator()
lam = agg.lam

zdist = []

for plate_n, mjd_n, fiber_n in zip(plate, mjd, fiber):
    sys.stdout.write("{0}.{1}.{2}         \r".format(plate_n, mjd_n, fiber_n))
    sys.stdout.flush()
    spec = fetch_sdss_spectrum(plate_n, mjd_n, fiber_n)
    zdist.append(spec.z)
    agg.add_spec(spec)

sys.stdout.write('\n')
    
spec, dspec = agg.reduce()

fig, ax = plt.subplots(2, 1, figsize=(8, 8))
ax[0].plot(lam, spec, '-k')
#ax[0].fill_between(lam, spec - dspec, spec + dspec,
#                   color='#AAAAAA', alpha=0.3)

ax[0].set_xlim(2500, 7500)
ax[0].set_ylim(0, 0.7)
ax[0].set_xlabel(r'$\lambda')
Esempio n. 6
0
#----------------------------------------------------------------------
# This function adjusts matplotlib settings for a uniform feel in the textbook.
# Note that with usetex=True, fonts are rendered with LaTeX.  This may
# result in an error if LaTeX is not installed on your system.  In that case,
# you can set usetex to False.
from astroML.plotting import setup_text_plots
setup_text_plots(fontsize=8, usetex=True)

#------------------------------------------------------------
# Fetch the spectrum from SDSS database & pre-process
plate = 659
mjd = 52199
fiber = 381

data = fetch_sdss_spectrum(plate, mjd, fiber)

lam = data.wavelength()
spec = data.spectrum

# wavelengths are logorithmically spaced: we'll work in log(lam)
loglam = np.log10(lam)

flag = (lam > 4000) & (lam < 5000)
lam = lam[flag]
loglam = loglam[flag]
spec = spec[flag]

lam = lam[:-1]
loglam = loglam[:-1]
spec = spec[:-1]
z_galaxies = d_galaxies['z']
modelMag_u_galaxies = d_galaxies['modelMag_u']
modelMag_i_galaxies = d_galaxies['modelMag_i']
modelMag_r_galaxies = d_galaxies['modelMag_r']
modelMag_g_galaxies = d_galaxies['modelMag_g']

properties = [h_alpha_flux_galaxies,extinction_r_galaxies,velDisp_galaxies,z_galaxies,\
        modelMag_u_galaxies-modelMag_g_galaxies,modelMag_u_galaxies-modelMag_i_galaxies]
nproperites = ["H_alpha","extinction_r","velocity Dispersion","redshift","u-g","u-i"]

#print mjd_galaxies

spectra = []

for mjd,plate,fiberID in zip(mjd_galaxies,plate_galaxies,fiberID_galaxies):
    spectra.append(fetch_sdss_spectrum(plate,mjd,fiberID))

#print spectra[0].wavelength()
#print spectra[1].wavelength()

#nwav = len(spectra[0].wavelength())

wavs0 = spectra[0].wavelength()
wavmin = wavs0.min()
wavmax = wavs0.max()

nwav = 5000

wavs = np.linspace(wavmin,wavmax,nwav)

data = np.zeros((Ngals,nwav))
Esempio n. 8
0
def fetch_and_shift_spectra(n_spectra,
                            outfile,
                            primtarget=TARGET_GALAXY,
                            zlim=(0, 0.7),
                            loglam_start=3.5,
                            loglam_end=3.9,
                            Nlam=1000):
    """
    This function queries CAS for matching spectra, and then downloads
    them and shifts them to a common redshift binning
    """
    # First query for the list of spectra to download
    plate, mjd, fiber = query_plate_mjd_fiber(n_spectra, primtarget,
                                              zlim[0], zlim[1])

    # Set up arrays to hold information gathered from the spectra
    spec_cln = np.zeros(n_spectra, dtype=np.int32)
    lineindex_cln = np.zeros(n_spectra, dtype=np.int32)

    log_NII_Ha = np.zeros(n_spectra, dtype=np.float32)
    log_OIII_Hb = np.zeros(n_spectra, dtype=np.float32)

    z = np.zeros(n_spectra, dtype=np.float32)
    zerr = np.zeros(n_spectra, dtype=np.float32)
    spectra = np.zeros((n_spectra, Nlam), dtype=np.float32)
    mask = np.zeros((n_spectra, Nlam), dtype=np.bool)
    specerr = np.zeros((n_spectra, Nlam), dtype=np.float32)

    # also save plate, mjd, fiber to allow reference to SDSS data
    plates = np.zeros(n_spectra, dtype=np.int32)
    mjds = np.zeros(n_spectra, dtype=np.int32)
    fibers = np.zeros(n_spectra, dtype=np.int32)

    # Calculate new wavelength coefficients
    new_coeff0 = loglam_start
    new_coeff1 = (loglam_end - loglam_start) / Nlam

    # Now download all the needed spectra, and resample to a common
    #  wavelength bin.
    n_spectra = len(plate)
    num_skipped = 0
    # changed counter and loop so that skipped spectra do not create gaps in arrays
    j = 0

    for i in range(n_spectra):
        sys.stdout.write(' %i / %i spectra\r' % (i + 1, n_spectra))
        sys.stdout.flush()
        try:
            spec = fetch_sdss_spectrum(plate[i], mjd[i], fiber[i], data_home='/epyc/users/sportill/specAE/cache')
        except HTTPError:
            num_skipped += 1
            print("%i, %i, %i not found" % (plate[i], mjd[i], fiber[i]))
            continue

        spec_rebin = spec.restframe().rebin(new_coeff0, new_coeff1, Nlam)

        if spec.z < zlim[0] or spec.z > zlim[1]:
            num_skipped += 1
            print("%i, %i, %i outside redshift range" % (plate[i], mjd[i], fiber[i]))
            continue

        if np.all(spec_rebin.spectrum == 0):
            num_skipped += 1
            print("%i, %i, %i is all zero" % (plate[i], mjd[i], fiber[i]))
            continue

        #if spec.spec_cln < 2 or spec.spec_cln > 3:
        #    num_skipped += 1
        #    print("%i, %i, %i is not a galaxy spectrum" % (plate[i], mjd[i], fiber[i]))
        #    continue

        spec_cln[j] = spec.spec_cln

        lineindex_cln[j], (log_NII_Ha[j], log_OIII_Hb[j])\
            = spec.lineratio_index()

        z[j] = spec.z
        zerr[j] = spec.zerr

        spectra[j] = spec_rebin.spectrum
        mask[j] = spec_rebin.compute_mask(0.5, 5)
        assert((mask[j] == 0).any())
        specerr[j] = spec_rebin.error

        plates[j] = plate[i]
        mjds[j] = mjd[i]
        fibers[j] = fiber[i]

        j += 1
    sys.stdout.write('\n')

    N = j
    print("   %i spectra skipped" % num_skipped)
    print("   %i spectra processed" % N)
    print("saving to %s" % outfile)

    np.savez(outfile,
             spectra=spectra[:N],
             mask=mask[:N],
             spec_err=specerr[:N],
             coeff0=new_coeff0,
             coeff1=new_coeff1,
             spec_cln=spec_cln[:N],
             lineindex_cln=lineindex_cln[:N],
             log_NII_Ha=log_NII_Ha[:N],
             log_OIII_Hb=log_OIII_Hb[:N],
             z=z[:N],
             zerr=zerr[:N],
             plate=plates[:N],
             mjd=mjds[:N],
             fiber=fibers[:N])
Esempio n. 9
0
def fetch_and_shift_spectra(n_spectra,
                            outfile,
                            primtarget=TARGET_GALAXY,
                            zlim=(0, 0.7),
                            loglam_start=3.5,
                            loglam_end=3.9,
                            Nlam=1000):
    """
    This function queries CAS for matching spectra, and then downloads
    them and shifts them to a common redshift binning
    """
    # First query for the list of spectra to download
    plate, mjd, fiber = query_plate_mjd_fiber(n_spectra, primtarget,
                                              zlim[0], zlim[1])
    print('plate:', plate,'mjd:', mjd, 'fiber:', fiber)                    # Print identifiers to check against other script


    # Set up arrays to hold information gathered from the spectra
    spec_cln = np.zeros(n_spectra, dtype=np.int32)
    lineindex_cln = np.zeros(n_spectra, dtype=np.int32)

    log_NII_Ha = np.zeros(n_spectra, dtype=np.float32)
    log_OIII_Hb = np.zeros(n_spectra, dtype=np.float32)

    z = np.zeros(n_spectra, dtype=np.float32)
    zerr = np.zeros(n_spectra, dtype=np.float32)
    spectra = np.zeros((n_spectra, Nlam), dtype=np.float32)
    spec_err = np.zeros((n_spectra, Nlam), dtype=np.float32)
    mask = np.zeros((n_spectra, Nlam), dtype=np.bool)

    # Calculate new wavelength coefficients
    new_coeff0 = loglam_start
    new_coeff1 = (loglam_end - loglam_start) / Nlam

    # Now download all the needed spectra, and resample to a common
    #  wavelength bin.
    n_spectra = len(plate)
    num_skipped = 0
    i = 0

    while i < n_spectra:
        sys.stdout.write(' %i / %i spectra\r' % (i + 1, n_spectra))
        sys.stdout.flush()
        try:
            spec = fetch_sdss_spectrum(plate[i], mjd[i], fiber[i])
            
        except HTTPError:
            num_skipped += 1
            print("%i, %i, %i not found" % (plate[i], mjd[i], fiber[i]))
            i += 1
            continue

        spec_rebin = spec.restframe().rebin(new_coeff0, new_coeff1, Nlam) # Redshift corrected

#        spec_rebin = spec.rebin(new_coeff0, new_coeff1, Nlam)   # Not redshift corrected


        if np.all(spec_rebin.spectrum == 0):
            num_skipped += 1
            print("%i, %i, %i is all zero" % (plate[i], mjd[i], fiber[i]))
            i += 1
            continue

        spec_cln[i] = spec.spec_cln
        
        lineindex_cln[i], (log_NII_Ha[i], log_OIII_Hb[i])\
            = spec.lineratio_index()

        z[i] = spec.z
        zerr[i] = spec.zerr

        spectra[i] = spec_rebin.spectrum
        spec_err[i] = spec_rebin.error
        mask[i] = spec_rebin.compute_mask(0.5, 5)

        i += 1
    sys.stdout.write('\n')

    N = i
    print("   %i spectra skipped" % num_skipped)
    print("   %i spectra processed" % N)
    print("saving to %s" % outfile)

    np.savez(outfile,
             spectra=spectra[:N],
             spec_err=spec_err[:N],
             mask=mask[:N],
             coeff0=new_coeff0,
             coeff1=new_coeff1,
             spec_cln=spec_cln[:N],
             lineindex_cln=lineindex_cln[:N],
             log_NII_Ha=log_NII_Ha[:N],
             log_OIII_Hb=log_OIII_Hb[:N],
             z=z[:N],
             zerr=zerr[:N])
Esempio n. 10
0
def plot_image_spec_sdss_galaxy(sdss_obj, save_figure=False):
    #plot image and spectrum of a specified SDSS galaxy
    # input sdss_obj = individual SDSS main galaxy data base entry
    # save_figure specifies whether PDF of the figure will be saved in fig/ subdirectory for the record
    #
    # define plot with 2 horizonthal panels of appropriate size
    fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(6, 2.))
    # set an appropriate font size for labels
    plt.rc('font', size=8)

    #get RA and DEC of the galaxy and form the filename to save SDSS image
    RA = sdss_obj['ra']
    DEC = sdss_obj['dec']
    scale = 0.25
    outfile = image_home_dir() + str(sdss_obj['objID']) + '.jpg'
    fetch_sdss_image(outfile, RA, DEC, scale)
    img = Image.open(outfile)
    # do not plot pixel axis labels
    ax0.axis('off')
    ax0.imshow(img)

    # fetch SDSS spectrum using plate number, epoch, and fiber ID
    plate = sdss_obj['plate']
    mjd = sdss_obj['mjd']
    fiber = sdss_obj['fiberID']
    spec = fetch_sdss_spectrum(plate, mjd, fiber)

    # normalize spectrum for plotting
    spectrum = 0.5 * spec.spectrum / spec.spectrum.max()
    lam = spec.wavelength()
    text_kwargs = dict(ha='center', va='center', alpha=0.5, fontsize=10)

    # set axis limits for spectrum plot
    ax1.set_xlim(3000, 10000)
    ax1.set_ylim(0, 0.6)

    color = np.zeros(5)
    for i, f, c, loc in zip([0, 1, 2, 3, 4], 'ugriz', 'bgrmk',
                            [3500, 4600, 6100, 7500, 8800]):
        data_home = setup.sdss_filter_dir()
        archive_file = os.path.join(data_home, '%s.dat' % f)
        if not os.path.exists(archive_file):
            raise ValueError(
                "Error in plot_img_spec_sdss_galaxy: filter file '%s' does not exist!"
                % archive_file)
        F = open(archive_file)
        filt = np.loadtxt(F, unpack=True)
        ax1.fill(filt[0], filt[2], ec=c, fc=c, alpha=0.4)
        fsp = interp1d(filt[0], filt[2], bounds_error=False, fill_value=0.0)
        ax1.text(loc, 0.03, f, color=c, **text_kwargs)
        # compute magnitude in each band using simple Simpson integration of spectrum and filter using eq 1.2 in the notes
        fspn = lam * fsp(lam) / simps(fsp(lam) / lam, lam)
        lamf = fspn
        #lamf = lamf.clip(0.0)
        specf = spec.spectrum * lamf
        color[i] = -2.5 * np.log10(simps(specf, lam))

    # print estimated g-r color for the object
    grcatcol = sdss_obj['modelMag_g'] - sdss_obj['modelMag_r']
    print("computed g-r = ", color[1] - color[2])
    print("catalog g-r=", grcatcol)

    ax1.plot(lam, spectrum, '-k', lw=0.5, label=r'$(g-r)=%.2f$' % grcatcol)
    ax1.set_xlabel(r'$\lambda {(\rm \AA)}$')
    ax1.set_ylabel(r'$\mathrm{norm.\ specific\ flux}\ \ \ f_{\lambda}$')
    #ax.set_title('Plate = %(plate)i, MJD = %(mjd)i, Fiber = %(fiber)i' % locals())
    #ax.set_title('%s' % objects[obj_]['name'])
    ax1.legend(frameon=False)

    if save_figure:
        plt.savefig('fig/gal_img_spec' + '_' + str(sdss_obj['objID']) + '.pdf',
                    bbox_inches='tight')

    plt.subplots_adjust(wspace=0.2)
    plt.show()
    return
Esempio n. 11
0
    def fitted_parameters(self, burnin=None, thin=1):
        if burnin is None:
            burnin = int(self.sampler.chain.shape[1] * 0.5)
            warn("no burnin given, using burnin of 50%")
        fitted = np.percentile(self.sampler.chain[:, burnin::thin].reshape(
            -1, self.sampler.chain.shape[-1]), (16, 50, 84),
                               axis=0)
        return pd.DataFrame(fitted.T,
                            columns=['lower', 'median', 'upper'],
                            index=self.parameter_names)


if __name__ == '__main__':
    from astroML.datasets import fetch_sdss_spectrum
    spec = fetch_sdss_spectrum(1975, 53734, 1).restframe()
    x, y, e = spec.wavelength(), spec.spectrum, spec.error

    norm_const = np.median(spec.spectrum[(x >= 5500) & (x <= 5600)])
    y /= norm_const
    e /= norm_const

    model = SpectrumModel()
    ha_group = model.add_region(6450, 6775, 'halpha')
    hb_group = model.add_region(4800, 5050, 'hbeta')

    NIIa = ha_group.add_emission_line('NIIa', 6549.86)
    NIIb = ha_group.add_emission_line('NIIb',
                                      6585.27,
                                      amplitude=NIIa.amplitude / 0.34,
                                      width=NIIa.width)