return line(sp, HG) def line(sp, refX): sp = sp.copy() sp.xarr.units = 'angstroms' sp.xarr.refX = refX sp.xarr.refX_units = 'angstroms' sp.xarr.xtype = 'wavelength' sp.xarr.convert_to_unit('km/s') return sp sp2 = pyspeckit.Spectrum('UT121009_DIS.txt', skiplines=1, xarrkwargs={ 'xtype': 'wavelength', 'unit': 'angstroms' }) sp2.units = 'erg s$^{-1}$ cm$^{-2}$ $\\AA^{-1}$' sp2.specfit.register_fitter('mymodel', ModelClass, 18, multisingle='multi') sp2.specfit.register_fitter('pcygni', PCygni, 22, multisingle='multi') sp3 = pyspeckit.Spectrum('UT121002_DIS.txt', skiplines=1, xarrkwargs={ 'xtype': 'wavelength', 'unit': 'angstroms' }) sp3.units = 'erg s$^{-1}$ cm$^{-2}$ $\\AA^{-1}$' sp3.specfit.register_fitter('mymodel', ModelClass, 18, multisingle='multi') sp3.specfit.register_fitter('pcygni', PCygni, 22, multisingle='multi') sp4 = pyspeckit.Spectrum('UT120830_DIS.txt',
def fitnh3tkin(input_dict, dobaseline=True, baselinekwargs={}, crop=False, guessline='twotwo', tex=15,tkin=20,column=15.0,fortho=0.66, tau=None, thin=False, quiet=False, doplot=True, fignum=1, guessfignum=2, smooth=False, scale_keyword=None, rebase=False, npeaks=1, guesses=None, **kwargs): """ Given a dictionary of filenames and lines, fit them together e.g. {'oneone':'G000.000+00.000_nh3_11.fits'} """ spdict = dict([ (linename,pyspeckit.Spectrum(value, scale_keyword=scale_keyword)) if type(value) is str else (linename,value) for linename, value in input_dict.iteritems() ]) splist = spdict.values() for sp in splist: # required for plotting, cropping sp.xarr.convert_to_unit('km/s') if crop and len(crop) == 2: for sp in splist: sp.crop(*crop) if dobaseline: for sp in splist: sp.baseline(**baselinekwargs) if smooth and type(smooth) is int: for sp in splist: sp.smooth(smooth) spdict[guessline].specfit(fittype='gaussian', negamp=False, vheight=False, guesses='moments') ampguess,vguess,widthguess = spdict[guessline].specfit.modelpars if widthguess < 0: raise ValueError("Width guess was < 0. This is impossible.") print "RMS guess (errspec): ",spdict[guessline].specfit.errspec.mean() print "RMS guess (residuals): ",spdict[guessline].specfit.residuals.std() errguess = spdict[guessline].specfit.residuals.std() if rebase: # redo baseline subtraction excluding the centroid +/- about 20 km/s vlow = spdict[guessline].specfit.modelpars[1]-(19.8+spdict[guessline].specfit.modelpars[2]*2.35) vhigh = spdict[guessline].specfit.modelpars[1]+(19.8+spdict[guessline].specfit.modelpars[2]*2.35) for sp in splist: sp.baseline(exclude=[vlow,vhigh], **baselinekwargs) for sp in splist: sp.error[:] = errguess spdict[guessline].plotter(figure=guessfignum) spdict[guessline].specfit.plot_fit() spectra = pyspeckit.Spectra(splist) spectra.specfit.npeaks = npeaks if tau is not None: if guesses is None: guesses = [a for i in xrange(npeaks) for a in (tkin+random.random()*i, tex, tau+random.random()*i, widthguess+random.random()*i, vguess+random.random()*i, fortho)] spectra.specfit(fittype='ammonia_tau',quiet=quiet,multifit=None,guesses=guesses, thin=thin, **kwargs) else: if guesses is None: guesses = [a for i in xrange(npeaks) for a in (tkin+random.random()*i, tex, column+random.random()*i, widthguess+random.random()*i, vguess+random.random()*i, fortho)] spectra.specfit(fittype='ammonia',quiet=quiet,multifit=None,guesses=guesses, thin=thin, **kwargs) if doplot: plot_nh3(spdict,spectra,fignum=fignum) return spdict,spectra
c = 3E8 fnameT = './hist_figs/histogram_tkin.png' # creates an empty array, to store tkin values into for histogram htkin = [] for thisObject in objects: spect2 = {} if os.path.exists('./nh3/' + thisObject + '.n11.fits'): data1 = fits.getdata('./nh3/' + thisObject + '.n11.fits') A1 = np.arange(len(data1['DATA'].T)) nu1 = data1['CDELT1'] * (A1 - data1['CRPIX1'] + 1) + data1['CRVAL1'] v1 = c * (nu1 / data1['RESTFREQ'] - 1) spec11 = psk.Spectrum(data=(data1['DATA'].T).squeeze(), xarr=v1, xarrkwargs={ 'unit': 'm/s', 'refX': data1['RESTFREQ'] / 1E6, 'refX_units': 'MHz', 'xtype': 'VLSR-RAD' }) spect2['oneone'] = spec11 if os.path.exists('./nh3/' + thisObject + '.n22.fits'): data2 = fits.getdata('./nh3/' + thisObject + '.n22.fits') A2 = np.arange(len(data2['DATA'].T)) nu2 = data2['CDELT1'] * (A2 - data2['CRPIX1'] + 1) + data2['CRVAL1'] v2 = c * (nu2 / data2['RESTFREQ'] - 1) spec22 = psk.Spectrum(data=(data2['DATA'].T).squeeze(), xarr=v2, xarrkwargs={ 'unit': 'm/s', 'refX': data2['RESTFREQ'] / 1E6, 'refX_units': 'MHz',
flist = [fn] if 'fn' in locals() else glob.glob( paths.dpath('stacked_spectra/OrionSourceI_*robust0.5.fits')) for fn in flist: basefn = os.path.split(fn)[-1] if 'B7' in basefn and 'lb' not in basefn: continue print(fn) beam = (radio_beam.Beam(0.1 * u.arcsec, 0.08 * u.arcsec) if 'B3' in fn else radio_beam.Beam(0.043 * u.arcsec, 0.034 * u.arcsec) if 'B6' in fn else radio_beam.Beam(0.029 * u.arcsec, 0.022 * u.arcsec)) sp_st = pyspeckit.Spectrum(fn) jytok = beam.jtok(sp_st.xarr.mean()) sp_st.data *= jytok.value sp_st.unit = u.K pl.figure(0, figsize=(16, 6)).clf() sp_st.plotter(figure=pl.figure(0, figsize=(16, 6)), clear=True, ymin=-0.0025 * jytok.value, ymax=0.01 * jytok.value) for txt in sp_st.plotter.axis.texts: txt.set_backgroundcolor((1, 1, 1, 0.9)) catmaps = {
def measure_equivalent_width(filename, xmin, xmax, exclude_min, exclude_max, n): sp = p.Spectrum(filename) sp.xarr.units = 'micron' sp.xarr.xtype = 'wavelength' sp.plotter(xmin=xmin, xmax=xmax, ymin=0, errstyle='bars', color='grey') sp.baseline(xmin=xmin, xmax=xmax, exclude=[exclude_min, exclude_max], subtract=False, highlight_fitregion=False, selectregion=True, order=0) sp.specfit(plot=True, fittype='voigt', color='blue', guesses='moments', vheight=True) sp.specfit.EQW(plot=True, plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) sp2 = sp.copy() EQWs = [] for w in range(n): sp2.data = sp.data + np.random.randn(sp.data.size) * sp.error sp2.baseline(xmin=xmin, xmax=xmax, exclude=[exclude_min, exclude_max], subtract=False, highlight_fitregion=False, selectregion=True, order=0) sp2.specfit(fittype='voigt', guesses=sp.specfit.parinfo.values) dist = sp2.specfit.EQW(plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) EQWs.append(dist) EQWs = np.array(EQWs) EQWs = EQWs * 10000 sp.specfit.EQW(plot=True, plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) sp2 = sp.copy() EQWs = np.zeros(n) for w in range(n): sp2.data = sp.data + np.random.randn(sp.data.size) * sp.error sp2.baseline(xmin=xmin, xmax=xmax, exclude=[exclude_min, exclude_max], subtract=False, highlight_fitregion=False, selectregion=True, order=0) sp2.specfit(fittype='voigt', guesses=sp.specfit.parinfo.values) dist = sp2.specfit.EQW(plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) # Convert from microns to angstroms EQWs[w] = dist * 10000.0 plt.figure() mu, sigma = norm.fit(EQWs) print(mu, sigma) n, bins, patches = plt.hist(EQWs, 10, normed=True, facecolor='green', histtype='stepfilled') y = mlab.normpdf(bins, mu, sigma) plt.plot(bins, y, 'r--', linewidth=2) plt.grid(True) plt.ylabel('Probability') plt.xlabel('EQW') plt.show() num_bins = np.floor(np.log10(n)) * 10 # Light blue histogram for contrast and for R/G colorblind folks n, bins, patches = plt.hist(EQWs, num_bins, normed=True, facecolor='lightblue', histtype='stepfilled') y = mlab.normpdf(bins, mu, sigma) plt.plot(bins, y, 'r--', linewidth=2) # Plot the median and 68th percentile values for comparison perc = np.percentile(EQWs, [16, 50, 84]) ax = plt.gca() for p_value in perc: ax.axvline(p_value, linestyle=":", color="k", lw=1.5) plt.ylabel('Probability') plt.xlabel('EQW') plt.show()
import pyspeckit import pylab as pl # Load the spectrum & properly identify the units # The data is from http://adsabs.harvard.edu/abs/1999A%26A...348..600P sp = pyspeckit.Spectrum('02232+6138.txt') sp.xarr.units = 'km/s' sp.xarr.refX = 88.63184666e9 sp.xarr.xtype = 'velocity' sp.units = '$T_A^*$' # set the error array based on a signal-free part of the spectrum sp.error[:] = sp.stats((-35, -25))['std'] # Register the fitter # The HCN fitter is 'built-in' but is not registered by default; this example # shows how to register a fitting procedure # 'multi' indicates that it is possible to fit multiple components and a # background will not automatically be fit # 5 is the number of parameters in the model (line center, # line width, and amplitude for the 0-1, 2-1, and 1-1 lines) sp.Registry.add_fitter('hcn_varyhf', pyspeckit.models.hcn.hcn_varyhf_amp_fitter, 5, multisingle='multi') # This one is the same, but with fixed relative ampltidue hyperfine components sp.Registry.add_fitter('hcn_fixedhf', pyspeckit.models.hcn.hcn_amp, 3, multisingle='multi')
import latex_info dv = 15 * u.km / u.s v = 5.5 * u.km / u.s dv_linesearch = 2.5 * u.km / u.s fits = {} bad_fits = [ 'Unknown_8', # only half the line is detected ] for spw in (0, 1, 2, 3): sp = pyspeckit.Spectrum( paths.dpath( 'stacked_spectra/OrionSourceI_B6_spw{0}.fits'.format(spw)), ) for linename, freq in lines.disk_lines.items(): xmin = freq * (1 + (v - dv) / constants.c) xmax = freq * (1 + (v + dv) / constants.c) slc = sp.slice(xmin, xmax) if len(slc) == 0: continue guesses = [ slc.data.max(), (freq * (1 + v / constants.c)).to(u.GHz).value, (2 * u.km / u.s / constants.c * freq).to(u.GHz).value ]
import pyspeckit if not 'interactive' in globals(): interactive = False if not 'savedir' in globals(): savedir = '' # load a FITS-compliant spectrum spec = pyspeckit.Spectrum('10074-190_HCOp.fits') # The units are originally frequency (check this by printing spec.xarr.units). # I want to know the velocity. Convert! # Note that this only works because the reference frequency is set in the header # this is no longer necessary! #spec.xarr.frequency_to_velocity() # Default conversion is to m/s, but we traditionally work in km/s spec.xarr.convert_to_unit('km/s') # plot it up! spec.plotter() # compute statistics stats = spec.stats() # set the errors spec.error[:] = stats['std'] # Subtract a baseline (the data is only 'mostly' reduced) spec.baseline() # Fit a gaussian. We know it will be an emission line, so we force a positive guess # nsigcut_moments tells the moment analysis tool to only use high-significance # data points to estimate the width of the line (it's tricky) spec.specfit(negamp=False, nsigcut_moments=2) # Note that the errors on the fits are larger than the fitted parameters.
SIIb = 6732.68 # Offsets between SII lines in each complex SIIb_off = SIIb - SIIa OIIIb_off = OIIIb - OIIIa NIIa_off_Ha = NIIa - Halpha NIIb_off_Ha = NIIb - Halpha SIIa_off_Ha = SIIa - Halpha SIIb_off_Ha = SIIb - Halpha # Guesses narrow = 5. broad = 30. # Initialize spectrum object spec = pyspeckit.Spectrum('sample_sdss.txt') spec.unit = 'erg s^{-1} cm^{-2} \\AA^{-1}' spec.xarr.set_unit = u.dimensionless_unscaled # H-alpha spec.specfit.selectregion(xmin=Halpha - 5, xmax=Halpha + 5) ampHa = np.max(spec.data[spec.specfit.xmin:spec.specfit.xmax]) # SII spec.specfit.selectregion(xmin=SIIa - 20, xmax=SIIb + 20) smallamp = np.max(spec.data[spec.specfit.xmin:spec.specfit.xmax]) spec.specfit(guesses=[smallamp, SIIa, narrow, smallamp, SIIb, narrow], tied=['', '', 'p[-1]', '', 'p[1] + {0}'.format(SIIb_off), ''], negamp=False, quiet=True,
refX=freq_dict['twotwo']).as_unit(u.GHz) xarr33 = SpectroscopicAxis(np.linspace(-50, 50, 100) * u.km / u.s, velocity_convention='radio', refX=freq_dict['threethree']).as_unit(u.GHz) # Merge the three X-axes into a single axis xarr = SpectroscopicAxes([xarr11, xarr22, xarr33]) # Compute a synthetic model that is made of two temperature components with # identical velocities synthspec = ( ammonia.ammonia(xarr, tkin=20, ntot=15, fortho=0.5, xoff_v=0.0, width=1.0) + ammonia.ammonia(xarr, tkin=50, ntot=14, fortho=0.5, xoff_v=0.0, width=1.0)) # Create the Spectrum object spectrum = pyspeckit.Spectrum(xarr=xarr, data=synthspec) # Step 2. You have a spectrum. # plot it spectrum.plotter() # Use the multi-tex/multi-tau model generator to build up a model function # You can use any set of oneone, twotwo, ..., eighteight (no 9-9 or higher) # This sets the number of parameters to be fit: 2+2*(n_transitions) fitter = ammonia_hf.nh3_vtau_multimodel_generator( ['oneone', 'twotwo', 'threethree']) # Register the fitter - i.e., tell pyspeckit where it is and how to use it spectrum.specfit.Registry.add_fitter('nh3_vtau_123', fitter, fitter.npars) # These are the parameter names, approximately: # parnames=['center','width','Tex11','tau11','Tex22','tau22','Tex33','tau33'],
import pyspeckit # Load the spectrum sp = pyspeckit.Spectrum('n2hp_opha_example.fits') # Register the fitter # The N2H+ fitter is 'built-in' but is not registered by default; this example # shows how to register a fitting procedure # 'multi' indicates that it is possible to fit multiple components and a # background will not automatically be fit 4 is the number of parameters in the # model (excitation temperature, optical depth, line center, and line width) sp.Registry.add_fitter('n2hp_vtau', pyspeckit.models.n2hp.n2hp_vtau_fitter, 4) sp.xarr.velocity_convention = 'radio' # Run the fitter sp.specfit(fittype='n2hp_vtau', multifit=None, guesses=[15, 2, 4, 0.2]) # Plot the results sp.plotter() # Re-run the fitter (to get proper error bars) and show the individual fit components sp.specfit(fittype='n2hp_vtau', multifit=None, guesses=[15, 2, 4, 0.2], show_hyperfine_components=True) # Save the figure (this step is just so that an image can be included on the web page) sp.plotter.savefig('n2hp_ophA_fit.png')
def splat_1d(filename=None, vmin=None, vmax=None, button=None, dobaseline=False, exclude=None, smooth=None, order=1, savepre=None, vcrop=True, vconv=None, vpars=None, spec=None, xtora=None, ytodec=None, specname=None, quiet=True, specnum=0, errspecnum=None, wcstype='', offset=0.0, continuum=0.0, annotatebaseline=False, plotspectrum=True, smoothto=None, xunits=None, units=None, conversion_factor=None, smoothtype='gaussian', convmode='same', maskspecnum=None, fignum=1, axis=None, autorefresh=False, title=None, color=None, label=None, clear=False, negamp=None, plotscale=1.0, voff=0.0, **kwargs): sp = pyspeckit.Spectrum(filename, specnum=specnum, errspecnum=errspecnum, wcstype=wcstype, **kwargs) sp.plotter.xmin = vmin sp.plotter.xmax = vmax sp.plotter.offset = offset if type(continuum) is str: sp.plotter.offset += sp.header.get(continuum) else: sp.plotter.offset += continuum if vcrop and vmin and vmax: sp.crop(vmin, vmax) if button != None: print "button keyword doesn't do anything" if maskspecnum: print "maskspecnum doesn't do anything [not implemented]" if specname: sp.plotter.title = specname if title: sp.plotter.title = title if smoothto: smooth = abs(smoothto / sp.xarr.cdelt()) if smooth: sp.smooth(smooth, smoothtype=smoothtype, convmode=convmode) if xunits: sp.xarr.convert_to_unit(xunits) if units: sp.units = units if dobaseline: sp.baseline(order=order, exclude=exclude, annotate=annotatebaseline) if plotspectrum: if color is None: sp.plotter(figure=fignum, axis=axis, autorefresh=autorefresh, clear=clear, silent=quiet, reset_ylimits=True, title=title, plotscale=plotscale, xoffset=voff, label=label) else: sp.plotter(figure=fignum, axis=axis, autorefresh=autorefresh, color=color, clear=clear, silent=quiet, reset_ylimits=True, title=title, plotscale=plotscale, xoffset=voff, label=label) if savepre is not None: glon, glat = sp.header.get("GLON"), sp.header.get("GLAT") if glon is None or glat is None: raise ValueError( "Header doesn't contain glon/glat. Default savepre will not work." ) if glat < 0: pm = "" else: pm = "+" savename = savepre + "G%07.3f%0s%07.3f_" % ( glon, pm, glat) + sp.header.get('MOLECULE').replace( ' ', '') + sp.header.get('TRANSITI').replace(' ', '') sp.plotter.savefig(savename + '.png') sp.fitspec = sp.specfit sp.spectrum = sp.data sp.axis = sp.plotter.axis sp.dv = sp.xarr.cdelt() sp.vind = sp.xarr sp.cube = sp.data sp.save = sp.write return sp
import pyspeckit from DISfunctions import * tsp1 = pyspeckit.Spectrum('UT120831_TSpec.final.txt', skiplines=1) tsp1.specname = "UT120831" tsp1.xarr.units = 'angstroms' tsp1.xarr.xtype = 'wavelength' tsp1 = tsp1 * 10 tsp1.units = '$10^{-15}$ erg s$^{-1}$ cm$^{-2}$ $\\AA^{-1}$' tsp1.data.mask[tsp1.data > 0.1] = 0 tsp1.data.mask[(tsp1.xarr > 11100) * (tsp1.xarr < 11300)] = True tsp2 = pyspeckit.Spectrum('UT121002_TSpec.final.txt', skiplines=1) tsp2.specname = "UT121002" tsp2.xarr.units = 'angstroms' tsp2.xarr.xtype = 'wavelength' tsp2.data.mask = tsp2.data < 0 tsp2.units = '$10^{-14}$ erg s$^{-1}$ cm$^{-2}$ $\\AA^{-1}$' tsp2.data.mask[(tsp2.xarr > 11100) * (tsp2.xarr < 11300)] = True for sp in [tsp1, tsp2]: print sp.specname sp.plotter(xmin=12400, xmax=13300) sp.baseline(xmin=12400, xmax=13300, exclude=[12770, 12866], powerlaw=True, subtract=False, reset_selection=True) yoffset = sp.baseline.basespec[sp.xarr.x_to_pix(12821)] - 0.05 sp.plotter(xmin=12400, xmax=13300, ymin=yoffset - 0.05) sp.baseline.highlight_fitregion()
SIIb = 6732.68 # Offsets between SII lines in each complex SIIb_off = SIIb - SIIa OIIIb_off = OIIIb - OIIIa NIIa_off_Ha = NIIa - Halpha NIIb_off_Ha = NIIb - Halpha SIIa_off_Ha = SIIa - Halpha SIIb_off_Ha = SIIb - Halpha # Guesses narrow = 5. broad = 30. # Initialize spectrum object spec = pyspeckit.Spectrum('../tests/sample_sdss.txt') spec.units = 'erg s^{-1} cm^{-2} \\AA^{-1}' spec.xarr.units='angstroms' # H-alpha spec.specfit.selectregion(xmin = Halpha - 5, xmax = Halpha + 5) ampHa = np.max(spec.data[spec.specfit.xmin:spec.specfit.xmax]) # SII spec.specfit.selectregion(xmin = SIIa - 20, xmax = SIIb + 20) smallamp = np.max(spec.data[spec.specfit.xmin:spec.specfit.xmax]) spec.specfit(guesses = [smallamp, SIIa, narrow, smallamp, SIIb, narrow], tied=['', '', 'p[-1]', '', 'p[1] + {0}'.format(SIIb_off), ''], negamp=False, quiet=True, multifit=True, show_components=True)
import pyspeckit # Grab a .fits spectrum with a legitimate header sp = pyspeckit.Spectrum('G031.947+00.076_nh3_11_Tastar.fits') """ HEADER: SIMPLE = T / Written by IDL: Tue Aug 31 18:17:01 2010 BITPIX = -64 NAXIS = 1 / number of array dimensions NAXIS1 = 8192 /Number of positions along axis 1 CDELT1 = -0.077230503 CRPIX1 = 4096.0000 CRVAL1 = 68.365635 CTYPE1 = 'VRAD' CUNIT1 = 'km/s ' SPECSYS = 'LSRK' RESTFRQ = 2.3694500e+10 VELOSYS = -43755.930 CDELT1F = 6103.5156 CRPIX1F = 4096.0000 CRVAL1F = 2.3692555e+10 CTYPE1F = 'FREQ' CUNIT1F = 'Hz' SPECSYSF= 'LSRK' RESTFRQF= 2.3694500e+10 VELOSYSF= -43755.930 VDEF = 'RADI-LSR' SRCVEL = 70.000000 ZSOURCE = 0.00023349487 BUNIT = 'K ' OBJECT = 'G031.947+00.076' TELESCOP= 'GBT'
from __future__ import print_function import pyspeckit if not 'interactive' in globals(): interactive=False if not 'savedir' in globals(): savedir = '' filenames = {'oneone':'G032.751-00.071_nh3_11_Tastar.fits', 'twotwo':'G032.751-00.071_nh3_22_Tastar.fits', 'threethree':'G032.751-00.071_nh3_33_Tastar.fits',} sp1 = pyspeckit.Spectrum('G032.751-00.071_nh3_11_Tastar.fits') sp1.crop(0,80) sp1.smooth(4) sp1.plotter() sp1.baseline(exclude=[15,62]) sp1.plotter() sp1.plotter.savefig(savedir+'nh3_11_baselined.png') sp2 = pyspeckit.Spectrum('G032.751-00.071_nh3_22_Tastar.fits') sp2.crop(0,80) sp2.smooth(4) sp2.plotter() guesses = sp2.specfit.moments(fittype='gaussian')[1:] sp2.specfit(fittype='gaussian', guesses=guesses) sp2.baseline(exclude=[34,42]) sp2.plotter() sp2.plotter.savefig(savedir+'nh3_22_baselined.png') sp3 = pyspeckit.Spectrum('G032.751-00.071_nh3_33_Tastar.fits') sp3.crop(0,80) sp3.smooth(4)
import numpy as np import pylab as pl import pyspeckit import glob from astropy import log fig = pl.figure(figsize=(12, 16)) for fn in glob.glob("*_full_SgrB2_TETC7m_r0_spw0_lines.fits"): for spw in (0, 1, 2, 3): fn_ = fn.replace("spw0", "spw{0}".format(spw)) ax = pl.subplot(4, 1, spw + 1) sp = pyspeckit.Spectrum(fn_) sp.xarr.convert_to_unit('GHz') if not any(np.isfinite(sp.data)): log.warn("{0} is bad".format(fn_)) else: log.info("{0} is good".format(fn_)) sp.plotter(figure=fig, axis=ax, clear=True) if spw != 0: ax.set_title("") if spw == 3: sp.plotter.savefig('quicklooks/{0}.png'.format( fn.replace("_spw0", "")[:-5]))
fake_spec = ammonia.ammonia(xarr, tkin=tk, tex=tx, ntot=nt, width=sig, xoff_v=0, fortho=0.5) real_tau = ammonia.ammonia(xarr, tkin=tk, tex=tx, ntot=nt, width=sig, xoff_v=0, fortho=0.5, return_tau=True) if fake_spec.max()*3 < noise: noises.append(fake_spec.max()/3.) fake_spec += np.random.randn(fake_spec.size) * fake_spec.max()/3. signoise.append(3) else: noises.append(noise) signoise.append(fake_spec.max()/noise) fake_spec += np.random.randn(fake_spec.size) * noise sp = pyspeckit.Spectrum(xarr=xarr, data=fake_spec, err=err,units='K', header=pyfits.Header({'BUNIT':'K'})) # sp.plotter() sp.specfit(fittype='ammonia', multifit=True, guesses=[tk,tx,nt,sig,0,0.5], fixed=[F,F,F,F,F,T], limitedmax=[T,T,T,T,T,T], maxpars=[100,100,25,5,20,1], limitedmin=[T,T,T,T,T,T], minpars=[2.73,2.73,10,0,-20,0], use_lmfit=True, verbose=False) outs.append(sp.specfit.parinfo.values[:4]) errors.append(sp.specfit.parinfo.errors[:4]) print(" ".join(["%7s" % round(x,1) for x in ins[-1]]),"|",)
refX=freq_dict['twotwo']).as_unit(u.GHz) xarr33 = SpectroscopicAxis(np.linspace(-50, 50, 100) * u.km / u.s, velocity_convention='radio', refX=freq_dict['threethree']).as_unit(u.GHz) # Merge the three X-axes into a single axis xarr = SpectroscopicAxes([xarr11, xarr22, xarr33]) # Compute a synthetic model that is made of two temperature components with # identical velocities synthspec = ( ammonia.ammonia(xarr, trot=20, ntot=15, fortho=0.5, xoff_v=0.0, width=1.0) + ammonia.ammonia(xarr, trot=50, ntot=14, fortho=0.5, xoff_v=0.0, width=1.0)) # Create the Spectrum object spectrum = pyspeckit.Spectrum(xarr=xarr, data=synthspec, header={}) # Step 2. You have a spectrum. # plot it spectrum.plotter() # Use the multi-tex/multi-tau model generator to build up a model function # You can use any set of oneone, twotwo, ..., eighteight (no 9-9 or higher) # This sets the number of parameters to be fit: 2+2*(n_transitions) fitter = ammonia_hf.nh3_vtau_multimodel_generator( ['oneone', 'twotwo', 'threethree']) # Register the fitter - i.e., tell pyspeckit where it is and how to use it spectrum.specfit.Registry.add_fitter('nh3_vtau_123', fitter, fitter.npars) # These are the parameter names, approximately: # parnames=['center','width','Tex11','tau11','Tex22','tau22','Tex33','tau33'],
import pyspeckit import os from pyspeckit.spectrum.models import nh2d import numpy as np import astropy.units as u if not os.path.exists('p-nh2d_spec.fits'): import astropy.utils.data as aud from astropy.io import fits f = aud.download_file('https://github.com/pyspeckit/pyspeckit-example-files/raw/master/p-nh2d_spec.fits') with fits.open(f) as ff: ff.writeto('p-nh2d_spec.fits') # Load the spectrum spec = pyspeckit.Spectrum('p-nh2d_spec.fits') # Determine rms from line free section and load into cube rms = np.std(spec.data[10:340]) spec.error[:] = rms # setup spectral axis spec.xarr.refX = 110.153594*u.GHz spec.xarr.velocity_convention = 'radio' spec.xarr.convert_to_unit('km/s') # define useful shortcuts for True and False F=False T=True # Setup of matplotlib import matplotlib.pyplot as plt plt.ion() # Add NH2D fitter spec.Registry.add_fitter('nh2d_vtau', pyspeckit.models.nh2d.nh2d_vtau_fitter,4)
unit=str(cube.spectral_axis.unit), refX=cube.wcs.wcs.restfrq, refX_units='Hz') spectra = {} for region_number,reg in enumerate(regs): name = reg.attr[1]['text'] if name not in spectra: #sp = cube.get_apspec(reg.coord_list,coordsys='galactic',wunit='degree') shape = pyregion.ShapeList([reg]) #mask = shape.get_mask(header=noisehdr, shape=noise.shape) scube = cube.subcube_from_ds9region(shape) data = scube.apply_numpy_function(np.nanmean, axis=(1,2)) #error = ((noise[mask & noiseokmask]**2).sum()**0.5/np.count_nonzero(mask)) sp = pyspeckit.Spectrum(data=data, error=np.ones(data.size),#*error, xarr=xarr, header=cube.wcs.to_header()) sp.xarr.convert_to_unit('GHz') #sp.header['ERROR'] = error #sp.error[:] = sp.stats((218.5e9,218.65e9))['std'] sp.specname = reg.attr[1]['text'] # Error is already computed above; this is an old hack #sp.error[:] = sp.stats((218e9,218.1e9))['std'] spectra[name] = sp sp.unit = "$T_{A}$ [K]" else: sp = spectra[name] sp.plotter.figure = pl.figure(1) sp.plotter() #linesel = (lfreq > sp.xarr.as_unit('GHz').min()) & (lfreq < sp.xarr.as_unit('GHz').max())
import pyspeckit # Rest wavelengths of the lines we are fitting - use as initial guesses NIIa = 6549.86 NIIb = 6585.27 Halpha = 6564.614 SIIa = 6718.29 SIIb = 6732.68 # Initialize spectrum object and plot region surrounding Halpha-[NII] complex spec = pyspeckit.Spectrum('sample_sdss.txt', errorcol=2) spec.plotter(xmin=6450, xmax=6775, ymin=0, ymax=150) # We fit the [NII] and [SII] doublets, and allow two components for Halpha. # The widths of all narrow lines are tied to the widths of [SII]. guesses = [ 50, NIIa, 5, 100, Halpha, 5, 50, Halpha, 50, 50, NIIb, 5, 20, SIIa, 5, 20, SIIb, 5 ] tied = [ '', '', 'p[17]', '', '', 'p[17]', '', 'p[4]', '', '3 * p[0]', '', 'p[17]', '', '', 'p[17]', '', '', '' ] # Actually do the fit. spec.specfit(guesses=guesses, tied=tied, annotate=False) spec.plotter.refresh() # Let's use the measurements class to derive information about the emission # lines. The galaxy's redshift and the flux normalization of the spectrum # must be supplied to convert measured fluxes to line luminosities. If the
import pyspeckit import pylab as pl import astropy.units as u # Load the spectrum & properly identify the units # The data is from http://adsabs.harvard.edu/abs/1999A%26A...348..600P sp = pyspeckit.Spectrum('02232_plus_6138.txt') sp.xarr.set_unit(u.km / u.s) sp.xarr.refX = 88.63184666e9 * u.Hz sp.xarr.velocity_convention = 'radio' sp.xarr.xtype = 'velocity' sp.unit = '$T_A^*$' # set the error array based on a signal-free part of the spectrum sp.error[:] = sp.stats((-35, -25))['std'] # Register the fitter # The HCN fitter is 'built-in' but is not registered by default; this example # shows how to register a fitting procedure # 'multi' indicates that it is possible to fit multiple components and a # background will not automatically be fit # 5 is the number of parameters in the model (line center, # line width, and amplitude for the 0-1, 2-1, and 1-1 lines) sp.Registry.add_fitter('hcn_varyhf', pyspeckit.models.hcn.hcn_varyhf_amp_fitter, 5) # This one is the same, but with fixed relative ampltidue hyperfine components sp.Registry.add_fitter('hcn_fixedhf', pyspeckit.models.hcn.hcn_amp, 3) # Plot the results sp.plotter() # Run the fixed-ampltiude fitter and show the individual fit components
def line_ids(fn): results = [] Ulines = [] sp = pyspeckit.Spectrum(fn) # this is a bit hackier than I like # we'll do all our measurements in Kelvin! beams = Beams.from_fits_bintable(fits.open(fn)[1]) factors = jtok_factors(beams, sp.xarr.to(u.GHz)) sp.data = sp.data * factors sp.unit = u.K # want km/s - reference will be ~middle of SPW sp.xarr.convert_to_unit(u.km / u.s) med = np.nanmedian(sp.data) mad = stats.mad_std(sp.data - med) detections = (sp.data - med) > 5 * mad labels, ct = label(detections) for labelid in range(1, ct + 1): ssp = sp[labels == labelid] try: ssp.xarr.convert_to_unit(u.GHz) ssp.specfit() ssp.specfit.parinfo frq = ssp.specfit.parinfo['SHIFT0'].value * ssp.xarr.unit except Exception as ex: print(ex) frq = ssp.xarr.to(u.GHz).mean() sq = Splatalogue.query_lines( frq * (1 + 0 / 3e5), frq * (1 + 75 / 3e5), # 30/3e5 original lower bound only_astronomically_observed=True) if len(sq) > 0: tbl = utils.minimize_table(sq) try: total_intensity = ssp.data.sum() * np.abs( ssp.xarr.to(u.km / u.s).cdelt()) except ValueError: total_intensity = ssp.data.sum() * np.abs( sp.xarr.to(u.km / u.s).cdelt()) peak_intensity = ssp.data.max() tbl.add_column(Column(data=total_intensity, name='TotalIntensity')) tbl.add_column(Column(data=peak_intensity, name='PeakIntensity')) tbl.add_column(Column(data=mad, name='RMS')) tbl.add_column( Column(data=u.Quantity((-(frq.to(u.GHz).value - tbl['Freq']) / tbl['Freq'] * constants.c), u.km / u.s), name='Velocity')) # print(tbl.pprint(max_width=200)) results.append(tbl) else: log.warning(f"Frequency {frq.to(u.GHz)} had no hits") Ulines.append(frq) try: match_table = table.vstack(results) except ValueError: pass else: # match_table.remove_column('QNs') match_table = table.unique(match_table, keys='Species') match_table.sort('Freq') print(match_table.pprint(max_width=200)) print(match_table['Species', 'Freq', 'Velocity']) # match_table.write(f"line_fit_table_{suffix}.ipac", format='ascii.ipac', overwrite=True) return match_table
def measure_equivalent_width(filename, xmin, xmax, exclude_min, exclude_max, n): """ Calculate the equivalent width of an absorption or emission line for a given spectrum using PySpecKit. By: Munazza Alam ======= Args: ======= xmin,xmax - the specified interval of the spectrum to plot excludemin, excludemax - the specified interval (in wavelength space) of the absorption feature n - the number of Monte Carlo iterations ======= Returns: ======= - the mean and standard deviation of the equivalent width measured n times - the spectrum plotted with the Voigt profile line fit (blue), the pseudo-continuum (yellow), and the approximated rectangle (green) - a histogram of the EqW distribution """ sp = p.Spectrum(filename) sp.xarr.units = 'micron' sp.xarr.xtype = 'wavelength' sp.plotter(xmin=xmin, xmax=xmax, ymin=0, errstyle='bars', color='grey') sp.baseline(xmin=xmin, xmax=xmax, exclude=[exclude_min, exclude_max], subtract=False, highlight_fitregion=False, selectregion=True, order=0) sp.specfit(plot=True, fittype='voigt', color='blue', guesses='moments', vheight=True) sp.specfit.EQW(plot=True, plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) sp2 = sp.copy() EQWs = [] for w in range(n): sp2.data = sp.data + np.random.randn(sp.data.size) * sp.error sp2.baseline(xmin=xmin, xmax=xmax, exclude=[exclude_min, exclude_max], subtract=False, highlight_fitregion=False, selectregion=True, order=0) sp2.specfit(fittype='voigt', guesses=sp.specfit.parinfo.values) dist = sp2.specfit.EQW(plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) EQWs.append(dist) EQWs = np.array(EQWs) EQWs = EQWs * 10000 sp.specfit.EQW(plot=True, plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) sp2 = sp.copy() EQWs = np.zeros(n) for w in range(n): sp2.data = sp.data + np.random.randn(sp.data.size) * sp.error sp2.baseline(xmin=xmin, xmax=xmax, exclude=[exclude_min, exclude_max], subtract=False, highlight_fitregion=False, selectregion=True, order=0) sp2.specfit(fittype='voigt', guesses=sp.specfit.parinfo.values) dist = sp2.specfit.EQW(plotcolor='g', fitted=False, components=False, annotate=True, loc='lower left', xmin=None, xmax=None) # Convert from microns to angstroms EQWs[w] = dist * 10000.0 plt.figure() mu, sigma = norm.fit(EQWs) print mu, sigma n, bins, patches = plt.hist(EQWs, 10, normed=True, facecolor='green', histtype='stepfilled') y = mlab.normpdf(bins, mu, sigma) plt.plot(bins, y, 'r--', linewidth=2) plt.grid(True) plt.ylabel('Probability') plt.xlabel('EQW') plt.show() num_bins = np.floor(np.log10(n)) * 10 # Light blue histogram for contrast and for R/G colorblind folks n, bins, patches = plt.hist(EQWs, num_bins, normed=True, facecolor='lightblue', histtype='stepfilled') y = mlab.normpdf(bins, mu, sigma) plt.plot(bins, y, 'r--', linewidth=2) # Plot the median and 68th percentile values for comparison perc = np.percentile(EQWs, [16, 50, 84]) ax = plt.gca() for p_value in perc: ax.axvline(p_value, linestyle=":", color="k", lw=1.5) plt.ylabel('Probability') plt.xlabel('EQW') plt.show()
def fitrow(n): global guesses, sp Y = z[239 * n:239 * (n + 1)] X = x[239 * n:239 * (n + 1)] xarr = pyspeckit.spectrum.units.SpectroscopicAxis(X) yarr = pyspeckit.spectrum.units.SpectroscopicAxis(Y) sp = pyspeckit.Spectrum(xarr=xarr, data=yarr) sp.specfit.Registry.add_fitter('lorentzian', lorentzian_fitter(multisingle='multi'), 3, multisingle='multi', key='L') ## sp.Registry.add_fitter ('lorentzian',lorentzian_fitter(multisingle='multi'),3,multisingle='multi',key='L') sp.plotter() ## sp.smooth(2) guesses, tied = findpks(Y, X, 1e5) if len(guesses) == 0: return [0., 1., 1.] minp, maxp, lmin, lmax = limitparams(1, 0.02) sp.specfit(fittype='gaussian', multifit=True, negamp=False, annotate=False, limitedmin=lmin, limitedmax=lmax, minpars=minp, maxpars=maxp, guesses=guesses, tied=tied, quiet=True) guesses = sp.specfit.modelpars fixed = fixparams([True, True, False]) minp, maxp, lmin, lmax = limitparams(2, 3) ## minp, maxp, lmin, lmax = limitparams(2,0.05) sp.specfit(fittype='gaussian', multifit=True, negamp=False, annotate=False, limitedmin=lmin, limitedmax=lmax, minpars=minp, maxpars=maxp, guesses=guesses, fixed=fixed, quiet=True) guesses = sp.specfit.modelpars fixed = fixparams([False, True, True]) sp.specfit(fittype='lorentzian', multifit=True, negamp=False, annotate=False, guesses=guesses, fixed=fixed, quiet=True) guesses = sp.specfit.modelpars fixed = fixparams([True, True, False]) minp, maxp, lmin, lmax = limitparams(2, 0.2) sp.specfit(fittype='lorentzian', multifit=True, negamp=False, annotate=False, limitedmin=lmin, limitedmax=lmax, minpars=minp, maxpars=maxp, guesses=guesses, fixed=fixed, quiet=True) ## guesses=sp.specfit.modelpars ## sp.specfit(fittype='lorentzian',multifit=True,guesses=guesses,annotate=False) return sp.specfit.modelpars
import pyspeckit import numpy as np from pyspeckit.spectrum.models import voigtfitter # technically, the voigt fitter works as a singlefitter (i.e., you can fit the # background level and the peak simultaneously) # in practice, however, you need to fit the background independently except for # gaussians. I don't know why this is. xarr = pyspeckit.spectrum.units.SpectroscopicAxis(np.linspace(-100,100,500),unit='km/s',refX=1e9,refX_units='Hz') VF = voigtfitter.voigt_fitter() sp1 = pyspeckit.Spectrum(xarr=xarr, data=VF.voigt(xarr,1,0,2.5,2.5) + np.random.randn(xarr.shape[0])/20., error=np.ones(xarr.shape[0])/20.) sp1.plotter() sp1.specfit(fittype='gaussian',composite_fit_color='b',clear=False,annotate=False) sp1.specfit(fittype='lorentzian',composite_fit_color='g',clear=False,annotate=False) sp1.specfit(fittype='voigt',composite_fit_color='r',clear=False,annotate=True) sp1.baseline.annotate() sp2 = pyspeckit.Spectrum(xarr=xarr, data=VF.voigt(xarr,1,0,2.5,5.0) + np.random.randn(xarr.shape[0])/20., error=np.ones(xarr.shape[0])/20.) sp2.plotter() sp2.specfit(fittype='gaussian',composite_fit_color='b',clear=False,annotate=False) sp2.specfit(fittype='lorentzian',composite_fit_color='g',clear=False,annotate=False) sp2.specfit(fittype='voigt',composite_fit_color='r',clear=False,annotate=True) sp2.baseline.annotate() sp3 = pyspeckit.Spectrum(xarr=xarr, data=VF.voigt(xarr,1,0,2.5,5.0) + np.random.randn(xarr.shape[0])/50., error=np.ones(xarr.shape[0])/50.) sp3.plotter() sp3.specfit(fittype='gaussian',composite_fit_color='b',clear=False,annotate=False) sp3.specfit(fittype='lorentzian',composite_fit_color='g',clear=False,annotate=False) sp3.specfit(fittype='voigt',composite_fit_color='r',clear=False,annotate=True)
from __future__ import print_function """ Try to identify a pseudocontinuum zone """ import pyspeckit from astropy import units as u import numpy as np import scipy.ndimage import pylab as pl from astropy import log #log.setLevel(10) for spw in range(4): sp = pyspeckit.Spectrum('e8mm_spw{0}_mean.fits'.format(spw)) sp.plotter(figure=pl.figure(1)) sp.baseline.includemask &= (sp.data > 0.25) & (sp.data < 0.35) sp.baseline.highlight_fitregion() sp.baseline(order=1, subtract=False, reset=False, highlight_fitregion=False, reset_selection=False, selectregion=False) sp.baseline(order=1, subtract=True, reset=False, highlight_fitregion=False, reset_selection=False, selectregion=False)
trot=trot, tex=tex, width=sigma, xoff_v=center, ntot=ntot) # Add noise stddev = 0.1 noise = np.random.randn(xaxis.size) * stddev error = stddev * np.ones_like(synth_data) data = noise + synth_data # this will give a "blank header" warning, which is fine sp = pyspeckit.Spectrum(data=data, error=error, xarr=xaxis, xarrkwargs={'unit': 'km/s'}, unit=u.K) sp.plotter(figure=pl.figure(1), errstyle='fill') # fit with some vague initial guesses and a fixed ortho/para # fraction of 1 (it is unconstrained in our data) sp.specfit( fittype='ammonia', #guesses=[20, 15, 15.5, 3, 2, 1], guesses=[30, 25, 15.5, 3, 2, 0], fixed=[False, False, False, False, False, True]) # do it again to set the errors neatly sp.specfit(
unit=u.GHz) for fn in glob.glob("*merge.fits"): outf = 'avspec/avg_{0}'.format(fn) if not os.path.exists(outf): cube = SpectralCube.read(fn) cube.allow_huge_operations=True mad = cube.mad_std(axis=0) sum = (cube*mad).sum(axis=(1,2)) mean = sum/np.nansum(mad) mean.write('avspec/weighted_avg_{0}'.format(fn), overwrite=True) mn = cube.mean(axis=(1,2)) mn.write(outf, overwrite=True) for fn in glob.glob("*merge.fits"): spw = pyspeckit.Spectrum('avspec/weighted_avg_{0}'.format(fn)) sp = pyspeckit.Spectrum('avspec/avg_{0}'.format(fn)) sp.plotter() #spw.plotter(axis=sp.plotter.axis, clear=False, color='b') sp.plotter.savefig('avspec/avg_{0}'.format(fn.replace(".fits",".png"))) med = np.median(sp.data) sp.plotter.axis.set_ylim(med-0.1, med+0.2) sp.plotter.savefig('avspec/avg_yzoom_{0}'.format(fn.replace(".fits",".png"))) plot_kwargs = {'color':'r', 'linestyle':'--'} annotate_kwargs = {'color': 'r'} sp.plotter.line_ids(species_names, u.Quantity(frequencies), velocity_offset=velo, plot_kwargs=plot_kwargs, annotate_kwargs=annotate_kwargs)