Exemplo n.º 1
0
import os
from hf_only_model import hfonly_66_fixed_fitter, hfonly_fitter, sixsix_movinghf_fitter
from spectral_cube import SpectralCube
from astropy import units as u
import numpy as np
import pyspeckit

pyspeckit.fitters.default_Registry.add_fitter('hfonly', hfonly_fitter(), 7)
pyspeckit.fitters.default_Registry.add_fitter('hfonly66',
                                              hfonly_66_fixed_fitter(), 4)
pyspeckit.fitters.default_Registry.add_fitter('sixsix_movinghf',
                                              sixsix_movinghf_fitter(), 5)

cube = SpectralCube.read(
    '/Volumes/passport/W51-GODDI/W51e2_66_baselined-sc-pb.cube.image.fits')
scube = cube[:, 230:307, 205:270]
errmap = scube.spectral_slab(-20 * u.km / u.s, 10 * u.km / u.s).std(axis=0)
mn = scube.min(axis=0).value

guesses = np.empty((7, scube.shape[1], scube.shape[2]))
guesses[0, :, :] = 58
guesses[1, :, :] = 26.9
guesses[2, :, :] = 0.010
guesses[3, :, :] = 1.5
guesses[4, :, :] = 31.4
guesses[5, :, :] = 0.010
guesses[6, :, :] = 1.5

negmask = mn < -0.005
guesses[2, negmask] = -0.1
guesses[5, negmask] = -0.1
Exemplo n.º 2
0
def fit_highj_nh3_absorption(j=6, j2=6, object='w51e2-tot',
                             headerfile='../W51-25GHzcont.map.image.fits',
                             savepath='.',
                             fntemplate='spec-{object}-{j}{j2}-pb.txt',
                             background_tb=4.2e3):
    """
    Fit absorption lines of high-J NH3
    """

    linename = ammonia_constants.num_to_name[j] * 2
    
    sp, spK, mean_error, mean_error_k = load_spectrum(j=j, object=object, fntemplate=fntemplate)

    # create our ammonia fitter from the ammonia model that allows Tau as the
    # variable (instead of kinetic temperature)
    # the model comes in a few varieties: we've selected the one that assumes
    # there *is* a background, but we're fitting the continuum-subtracted
    # spectrum, so this one will accept the background as an input parameter
    amf = ammonia_hf.nh3_vtau[linename].background_contsub_fitter
    spK.specfit.Registry.add_fitter('ammonia_bg', amf, 5)

    sp.plotter()
    # Fit each component with a gaussian to determine the offsets between components
    sp.specfit(fittype='gaussian', guesses=[-0.15, 25, 3,
                                            -0.15, 32, 3,
                                            -0.30, 58, 6,
                                            -0.15, 84, 3,
                                            -0.15, 90, 3], quiet=True)
    # Store the fitted velocities and frequencies in convenient variables
    center = sp.specfit.parinfo[7].value
    voffs = u.Quantity([(((x-center)*u.km/u.s))
                        for x in sp.specfit.parinfo.values[1::3]])
    foffs = u.Quantity([((((x - center)*u.km/u.s) /
                          constants.c) * sp.xarr.refX).to(u.MHz)
                        for x in sp.specfit.parinfo.values[1::3]])
    print("Velocity Offsets: ",voffs)
    print("Frequency Offsets: ",foffs)
    models = (pyspeckit.spectrum.models.ammonia_constants.voff_lines_dict[linename][:3]
              +
              pyspeckit.spectrum.models.ammonia_constants.voff_lines_dict[linename][-2:])
    dfoffs = u.Quantity([(((x-center-m)*u.km/u.s))
                         for x,m in zip(sp.specfit.parinfo.values[1::3], models[::-1])])
    print("Difference between observed and modeled offsets: ",dfoffs)

    # plot the fits & residuals
    sp.specfit.plotresiduals(axis=sp.plotter.axis, clear=False,
                             yoffset=sp.data.min()*1.2, label=False)
    sp.plotter.axis.set_ylim(sp.data.min()*1.2 - 3*mean_error + sp.specfit.residuals.min(),
                             sp.data.max()*1.2 + 3*mean_error)

    sp.plotter.savefig(os.path.join(savepath,
                                    "{object}_nh3_{j}{j2}_eachcomponent.png".format(j=j,
                                                                                    j2=j2,
                                                                                    object=object)))

    T = True
    F = False
    #parnames=['Tbackground','Tex','tau','center','width'],
    # input guesses.  background_tb is fixed
    parinfo = amf.make_parinfo(params=[background_tb, 100, 2.5, 58, 0.5],
                               fixed=[T,F,F,F,F],)
    parinfo.TBACKGROUND0.limited = (False,False)
    parinfo.TEX0.mpmaxstep=1000
    print("DEBUG CHECK: Is parinfo set correctly? (should have background=fixed)\n",parinfo)

    # do the fits on the brightness temperature spectrum now (with ammonia model)
    # for the first fit, exclude the main line and fit only the hyperfines
    spK.plotter()
    spK.specfit.selectregion(exclude=[40,70], highlight=True)
    spK.specfit(fittype='ammonia_bg', parinfo=parinfo,
                #quiet=False, shh=False, verbose=True,
                veryverbose=False,
                reset_selection=False)

    spK.specfit.plot_fit()
    spK.specfit.plotresiduals(axis=spK.plotter.axis, clear=False,
                              yoffset=spK.data.min()*1.2, label=False)
    spK.plotter.axis.set_ylim(spK.data.min()*1.2 - 3*mean_error_k + spK.specfit.residuals.min(),
                              spK.data.max()*1.2 + 3*mean_error_k)
    spK.plotter.savefig("{object}_nh3_{j}{j2}_hyperfineonly.png".format(j=j,
                                                                        j2=j2,
                                                                        object=object))

    # second try: fit the main line and the hyperfines simultaneously
    spK.plotter()
    spK.specfit(fittype='ammonia_bg', parinfo=parinfo,
                #quiet=False, shh=False, verbose=True,
                veryverbose=False,
                reset_selection=True)
    spK.specfit.plotresiduals(axis=spK.plotter.axis, clear=False,
                              yoffset=spK.data.min()*1.2, label=False)
    spK.plotter.axis.set_ylim(spK.data.min()*1.2 - 3*mean_error_k + spK.specfit.residuals.min(),
                              spK.data.max()*1.2 + 3*mean_error_k)
    spK.plotter.savefig("{object}_nh3_{j}{j2}_fitwhole.png".format(j=j, j2=j2,
                                                                   object=object))

    # third try: all lines, but with two components
    parinfo = amf.make_parinfo(params=[background_tb, 200, 2.5, 58, 1.35,
                                       background_tb, 200, 2.5, 59,  0.5,],
                               fixed=[T,F,F,F,F,]*2,
                               npeaks=2)
    parinfo.TBACKGROUND0.limited = (False,False)
    parinfo.TBACKGROUND1.limited = (False,False)
    parinfo.TEX0.mpmaxstep=1000
    parinfo.TEX1.mpmaxstep=1000
    print("DEBUG CHECK: Is parinfo set correctly? (should have background=fixed and two sets of pars)\n",parinfo)
    spK.plotter()
    spK.specfit(fittype='ammonia_bg', parinfo=parinfo,
                #verbose=True, quiet=False, shh=False,
                veryverbose=False,
                reset_selection=True)
    spK.specfit.plotresiduals(axis=spK.plotter.axis, clear=False,
                              yoffset=spK.data.min()*1.2, label=False)
    spK.plotter.axis.set_ylim(spK.data.min()*1.2 - 3*mean_error_k + spK.specfit.residuals.min(),
                              spK.data.max()*1.2 + 3*mean_error_k)
    spK.plotter.axis.set_xlim(-30,200)
    spK.plotter.savefig("{object}_nh3_{j}{j2}_fitwhole_twocomp.png".format(j=j,
                                                                           j2=j2,
                                                                           object=object))

    pl.draw()
    pl.show()

    # TODO: refit with NH3 hyperfine model with velocity offsets and linewidths free
    # ??? optical depth reliable ???
    # examine Goddi 2015 on NGC 7538
    # -> column density (probably OK using simple LTE)
    # -> rotational temperature?

    spK.specfit.Registry.add_fitter('sixsix_movinghf', sixsix_movinghf_fitter(), 5)
    spK.specfit(fittype='sixsix_movinghf', guesses=[58, 30, 26.9, 31.2, 2])
    spK.specfit.plotresiduals(axis=spK.plotter.axis, clear=False,
                              yoffset=spK.data.min()*1.2, label=False)
    spK.plotter.axis.set_ylim(spK.data.min()*1.2 - 3*mean_error_k + spK.specfit.residuals.min(),
                              spK.data.max()*1.2 + 3*mean_error_k)
    spK.plotter.axis.set_xlim(-30,200)
    spK.plotter.savefig("{object}_nh3_{j}{j2}_fitwhole_movinghf.png".format(j=j,
                                                                            j2=j2,
                                                                            object=object))

    return sp, spK, (center, voffs, foffs, dfoffs)
Exemplo n.º 3
0
mlpi6e2w = sp6e2w.specfit.parinfo
mlpi7e2w = sp7e2w.specfit.parinfo
mlpi9e2w = sp9e2w.specfit.parinfo
mlpi10e2w = sp9e2w.specfit.parinfo
mlpi13e2w = sp9e2w.specfit.parinfo
print >>outf, "gaussian 6-6 peak={0} +/- {1}, fwhm={2} +/- {3}, integral={4} +/- {5}, center={6} +/- {7}".format(*(tbl_vals_gaussian(sp6e2w.specfit.parinfo)))
print >>outf, "gaussian 7-7 peak={0} +/- {1}, fwhm={2} +/- {3}, integral={4} +/- {5}, center={6} +/- {7}".format(*(tbl_vals_gaussian(sp7e2w.specfit.parinfo)))
print >>outf, "gaussian 9-9 peak={0} +/- {1}, fwhm={2} +/- {3}, integral={4} +/- {5}, center={6} +/- {7}".format(*(tbl_vals_gaussian(sp9e2w.specfit.parinfo)))
print >>outf, "gaussian 10-10 peak={0} +/- {1}, fwhm={2} +/- {3}, integral={4} +/- {5}, center={6} +/- {7}".format(*(tbl_vals_gaussian(sp10e2w.specfit.parinfo)))
print >>outf, "gaussian 13-13 peak={0} +/- {1}, fwhm={2} +/- {3}, integral={4} +/- {5}, center={6} +/- {7}".format(*(tbl_vals_gaussian(sp13e2w.specfit.parinfo)))


# e2e aka e2east
sp6e2e,spK6e2e,_,_ = goddi_nh3_fits.load_spectrum(6, object='w51e2e', headerfile='/Users/adam/work/w51/goddi/W51-25GHzcont.map.image.fits')
sp6e2e.specfit.Registry.add_fitter('hfonly',hfonly_fitter(),7)
spK6e2e.specfit.Registry.add_fitter('sixsix',sixsix_movinghf_fitter(),7)
sp7e2e,spK7e2e,_,_ = goddi_nh3_fits.load_spectrum(7, object='w51e2e', headerfile='/Users/adam/work/w51/goddi/W51-25GHzcont.map.image.fits')
sp7e2e.specfit.Registry.add_fitter('hfonly',hfonly_fitter(),7)
sp9e2e,spK9e2e,_,_ = goddi_nh3_fits.load_spectrum(9, object='w51e2e', headerfile='/Users/adam/work/w51/goddi/W51-27GHzcont.map.image.fits')
sp9e2e.specfit.Registry.add_fitter('hfonly',hfonly_fitter(),7)
sp10e2e,spK10e2e,_,_ = goddi_nh3_fits.load_spectrum(10, object='w51e2e', headerfile='/Users/adam/work/w51/goddi/W51-27GHzcont.map.image.fits')
sp10e2e.specfit.Registry.add_fitter('hfonly',hfonly_fitter(),7)
sp13e2e,spK13e2e,_,_ = goddi_nh3_fits.load_spectrum(13, object='w51e2e', headerfile='/Users/adam/work/w51/goddi/W51-27GHzcont.map.image.fits')
sp13e2e.specfit.Registry.add_fitter('hfonly',hfonly_fitter(),7)

sp6e2e.plotter()
spK6e2e.plotter()
sp7e2e.plotter()
sp9e2e.plotter()
# sp6e2e might be optically thick (in hyperfines, in emission!)
sp6e2e.specfit(fittype='hfonly', guesses=[58, 26.9, 0.02, 2.0, 31.4, 0.02, 2.0], fixed=[F,T,F,F,T,F,F], tied=tied)
Exemplo n.º 4
0
    return spectra,tbl

if __name__ == "__main__":
    spectra,tbl = fit_all()
    print(tbl)

    fig = pl.figure(13)
    fig.clf()
    T=True
    F=False
    sp = spectra['w51e2-core_66'][1]
    mean_error = sp.data[-20:-2].std()
    sp.plotter.figure = fig
    sp.plotter.axis = pl.subplot(2,1,1)
    sp.plotter()
    sp.specfit.Registry.add_fitter('sixsix_movinghf', sixsix_movinghf_fitter(), 7)
    sp.specfit(fittype='sixsix_movinghf', guesses=[58, 83, 26.9, 31.2, 2, 1800, 8200], fixed=[F,F,F,F,F,T,T], annotate=False)
    sp.plotter.axis.set_xticklabels([])
    sp.specfit.plotresiduals(axis=sp.plotter.axis, clear=False,
                             yoffset=sp.data.min()*1.3, label=False)
    sp.plotter.axis.set_ylim(sp.data.min()*1.3 - 3*mean_error + sp.specfit.residuals.min(),
                             sp.data.max()*1.3 + 3*mean_error)
    sp.plotter.axis.set_xlim(0, 120)
    sp1 = spectra['w51e2-core_77'][1]
    mean_error = sp1.data[-20:-2].std()
    sp1.plotter.figure = fig
    sp1.plotter.axis = pl.subplot(2,1,2)
    sp1.plotter()
    sp1.specfit.Registry.add_fitter('sevenseven_movinghf', sevenseven_movinghf_fitter(), 7)
    sp1.specfit(fittype='sevenseven_movinghf', guesses=[58, 83, 27.3, 31.2, 1.32, 1800, 8200], fixed=[F,F,F,F,F,T,T], annotate=False)
    sp1.specfit.plotresiduals(axis=sp1.plotter.axis, clear=False,
Exemplo n.º 5
0
import os
from hf_only_model import hfonly_66_fixed_fitter, hfonly_fitter, sixsix_movinghf_fitter
from spectral_cube import SpectralCube
from astropy import units as u
import numpy as np
import pyspeckit

pyspeckit.fitters.default_Registry.add_fitter('hfonly', hfonly_fitter(), 7)
pyspeckit.fitters.default_Registry.add_fitter('hfonly66', hfonly_66_fixed_fitter(), 4)
pyspeckit.fitters.default_Registry.add_fitter('sixsix_movinghf', sixsix_movinghf_fitter(), 5)

cube = SpectralCube.read('/Volumes/passport/W51-GODDI/W51e2_66_baselined-sc-pb.cube.image.fits')
scube = cube[:, 230:307, 205:270]
errmap = scube.spectral_slab(-20*u.km/u.s, 10*u.km/u.s).std(axis=0)
mn = scube.min(axis=0).value


guesses = np.empty((7, scube.shape[1], scube.shape[2]))
guesses[0,:,:] = 58
guesses[1,:,:] = 26.9
guesses[2,:,:] = 0.010
guesses[3,:,:] = 1.5
guesses[4,:,:] = 31.4
guesses[5,:,:] = 0.010
guesses[6,:,:] = 1.5

negmask = mn<-0.005
guesses[2, negmask] = -0.1
guesses[5, negmask] = -0.1