def make_cube(files=(file_nh311_dr1, file_nh322_dr1), rms_files=(file_rms_nh311_dr1, file_rms_nh322_dr1)): """ Opens the cube and calculates all the pre-fitting attributes of interest. """ # make sure we're working on arrays (why?) files = np.atleast_1d([f for f in files]) rms_files = np.atleast_1d([f for f in rms_files]) if files.size > 1: spc_dict = {f: pyspeckit.Cube(f) for f in files} rmsmaps = {f: fits.getdata(ef) for f, ef in zip(files, rms_files)} for f in files: spc_dict[f].errorcube = np.repeat([rmsmaps[f]], spc_dict[f].xarr.size, axis=0) # now the errorcubes should merge automatically spc = pyspeckit.CubeStack([spc_dict[f] for f in files]) spc.xarr.refX = spc.cubelist[0].xarr.refX spc.xarr.refX_unit = spc.cubelist[0].xarr.refX_unit else: spc = pyspeckit.Cube(files[0]) rms = fits.getdata(rms_files[0]) # easier to handle everything get_spectrum-related spc.errorcube = np.repeat([rms], spc.xarr.size, axis=0) # I don't see a reason why errorcube should be a masked array if type(spc.errorcube) == np.ma.MaskedArray: spc.errorcube = np.array(spc.errorcube) spc.xarr.velocity_convention = 'radio' spc.xarr.convert_to_unit('km/s') snr = (spc.cube / spc.errorcube).max(axis=0) # TODO: fix multinest-pipeline.py and run_multicube.py #spc.errmap = rms spc.snrmap = snr return spc
def get_subregion_pcube(cube303m, cube303, cube321, region): #scube = cube_merge_high.subcube_from_ds9region(pyregion.ShapeList([region])) scube303m = cube303m.subcube_from_ds9region(pyregion.ShapeList([region])) scube303 = cube303.subcube_from_ds9region(pyregion.ShapeList([region])) scube321 = cube321.subcube_from_ds9region(pyregion.ShapeList([region])) # TODO: get error map #pcube = pyspeckit.Cube(cube=scube) pcube303 = pyspeckit.Cube(cube=scube303) pcube303.xarr.refX = cube303.wcs.wcs.restfrq pcube303.xarr.refX_unit = 'Hz' pcube321 = pyspeckit.Cube(cube=scube321) pcube321.xarr.refX = cube321.wcs.wcs.restfrq pcube321.xarr.refX_unit = 'Hz' pcube = pyspeckit.CubeStack([ pcube303, pcube321, ]) pcube.specfit.Registry.add_fitter('h2co_simple', simple_fitter3, 4, multisingle='multi') pcube.xarr.refX = cube303m.wcs.wcs.restfrq pcube.xarr.refX_unit = 'Hz' return pcube, scube303m
# essentially the same, but you could use a different error map for each # frequency oneonemomentfn = '11_err_mosaic.fits' errmap11 = ( pyfits.getdata(oneonemomentfn).squeeze() * 13.6 * (300.0 / (pyspeckit.spectrum.models.ammonia.freq_dict['oneone'] / 1e9))**2 * 1. / cube11.header.get('BMAJ') / 3600. * 1. / cube11.header.get('BMIN') / 3600.) # Interpolate errors across NaN pixels errmap11[errmap11 != errmap11] = convolve_fft( errmap11, Gaussian2DKernel(3), nan_treatment='interpolate')[errmap11 != errmap11] # Stack the cubes into one big cube. The X-axis is no longer linear: there # will be jumps from 1-1 to 2-2 to 4-4. cubes = pyspeckit.CubeStack([cube11, cube22, cube44], maskmap=mask) cubes.unit = "K" # Make a "moment map" to contain the initial guesses # If you've already fit the cube, just re-load the saved version if os.path.exists('mosaic_momentcube.fits'): momentcubefile = pyfits.open('mosaic_momentcube.fits') momentcube = momentcubefile[0].data else: cube11.mapplot() # compute the moment at each pixel cube11.momenteach() momentcube = cube11.momentcube momentcubefile = pyfits.PrimaryHDU(data=momentcube, header=cube11.header) if astropy.version.major >= 2 or (astropy.version.major == 1 and astropy.version.minor >= 3):
def hmm1_cubefit(vmin=3.4, vmax=5.0, tk_ave=10., do_plot=False, snr_min=5.0, multicore=1, do_thin=False): """ Fit NH3(1,1) and (2,2) cubes for H-MM1. It fits all pixels with SNR larger than requested. Initial guess is based on moment maps and neighboring pixels. The fitting can be done in parallel mode using several cores, however, this is dangerous for large regions, where using a good initial guess is important. It stores the result in a FITS cube. TODO: -convert FITS cube into several FITS files -Improve initial guess Parameters ---------- vmin : numpy.float Minimum centroid velocity to plot, in km/s. vmax : numpy.float Maximum centroid velocity to plot, in km/s. tk_ave : numpy.float Mean kinetic temperature of the region, in K. do_plot : bool If True, then a map of the region to map is shown. snr_min : numpy.float Minimum signal to noise ratio of the spectrum to be fitted. multicore : int Numbers of cores to use for parallel processing. """ cube11sc = SpectralCube.read(OneOneFile) cube22sc = SpectralCube.read(TwoTwoFile) cube11_v = cube11sc.with_spectral_unit(u.km / u.s, velocity_convention='radio', rest_value=freq11) cube22_v = cube22sc.with_spectral_unit(u.km / u.s, velocity_convention='radio', rest_value=freq22) from pyspeckit.spectrum.units import SpectroscopicAxis spec11 = SpectroscopicAxis(cube11_v.spectral_axis, refX=freq11, velocity_convention='radio') spec22 = SpectroscopicAxis(cube22_v.spectral_axis, refX=freq22, velocity_convention='radio') errmap11 = fits.getdata(RMSFile_11) errmap22 = fits.getdata(RMSFile_22) errmap_K = errmap11 #[errmap11, errmap22] Tpeak11 = fits.getdata(OneOnePeak) moment1 = fits.getdata(OneOneMom1) moment2 = (fits.getdata(OneOneMom2))**0.5 snr = cube11sc.filled_data[:].value / errmap11 peaksnr = Tpeak11 / errmap11 planemask = (peaksnr > snr_min) # *(errmap11 < 0.15) planemask = remove_small_objects(planemask, min_size=40) planemask = opening(planemask, disk(1)) #planemask = (peaksnr>20) * (errmap11 < 0.2) mask = (snr > 3) * planemask maskcube = cube11sc.with_mask(mask.astype(bool)) maskcube = maskcube.with_spectral_unit(u.km / u.s, velocity_convention='radio') slab = maskcube.spectral_slab(vmax * u.km / u.s, vmin * u.km / u.s) w11 = slab.moment(order=0, axis=0).value peakloc = np.nanargmax(w11) ymax, xmax = np.unravel_index(peakloc, w11.shape) moment2[np.isnan(moment2)] = 0.2 moment2[moment2 < 0.2] = 0.2 ## Load FITS files cube11 = pyspeckit.Cube(OneOneFile, maskmap=planemask) cube22 = pyspeckit.Cube(TwoTwoFile, maskmap=planemask) # Stack files cubes = pyspeckit.CubeStack([cube11, cube22], maskmap=planemask) cubes.unit = "K" # Define initial guess guesses = np.zeros((6, ) + cubes.cube.shape[1:]) moment1[moment1 < vmin] = vmin + 0.2 moment1[moment1 > vmax] = vmax - 0.2 guesses[0, :, :] = tk_ave # Kinetic temperature guesses[1, :, :] = 7 # Excitation Temp guesses[2, :, :] = 14.5 # log(column) guesses[ 3, :, :] = moment2 # Line width / 5 (the NH3 moment overestimates linewidth) guesses[4, :, :] = moment1 # Line centroid guesses[5, :, :] = 0.5 # F(ortho) - ortho NH3 fraction (fixed) if do_plot: import matplotlib.pyplot as plt plt.imshow(w11 * planemask, origin='lower') plt.show() print('start fit') cubes.specfit.Registry.add_fitter('cold_ammonia', ammonia.cold_ammonia_model(), 6) if do_thin: file_out = "{0}H-MM1_cold_parameter_maps_snr{1}_thin_v1.fits".format( fit_dir, snr_min) else: file_out = "{0}H-MM1_cold_parameter_maps_snr{1}_thick_v1.fits".format( fit_dir, snr_min) cubes.fiteach(fittype='cold_ammonia', guesses=guesses, integral=False, verbose_level=3, fixed=[do_thin, False, False, False, False, True], signal_cut=2, limitedmax=[True, False, False, False, True, True], maxpars=[20, 15, 20, 0.4, vmax, 1], limitedmin=[True, True, True, True, True, True], minpars=[5, 2.8, 12.0, 0.05, vmin, 0], start_from_point=(xmax, ymax), use_neighbor_as_guess=True, position_order=1 / peaksnr, errmap=errmap_K, multicore=multicore) # Store fits into FITS cube fitcubefile = fits.PrimaryHDU(data=np.concatenate( [cubes.parcube, cubes.errcube]), header=cubes.header) fitcubefile.header.set('PLANE1', 'TKIN') fitcubefile.header.set('PLANE2', 'TEX') fitcubefile.header.set('PLANE3', 'COLUMN') fitcubefile.header.set('PLANE4', 'SIGMA') fitcubefile.header.set('PLANE5', 'VELOCITY') fitcubefile.header.set('PLANE6', 'FORTHO') fitcubefile.header.set('PLANE7', 'eTKIN') fitcubefile.header.set('PLANE8', 'eTEX') fitcubefile.header.set('PLANE9', 'eCOLUMN') fitcubefile.header.set('PLANE10', 'eSIGMA') fitcubefile.header.set('PLANE11', 'eVELOCITY') fitcubefile.header.set('PLANE12', 'eFORTHO') fitcubefile.header.set('CDELT3', 1) fitcubefile.header.set('CTYPE3', 'FITPAR') fitcubefile.header.set('CRVAL3', 0) fitcubefile.header.set('CRPIX3', 1) fitcubefile.writeto(file_out, overwrite=True)
def cubefit(region='NGC1333', blorder=1, vmin=5, vmax=15, do_plot=False, snr_min=5.0, multicore=1, file_extension=None, mask_function = None, gauss_fit=False): """ Fit NH3(1,1) and (2,2) cubes for the requested region. It fits all pixels with SNR larger than requested. Initial guess is based on moment maps and neighboring pixels. The fitting can be done in parallel mode using several cores, however, this is dangerous for large regions, where using a good initial guess is important. It stores the result in a FITS cube. TODO: -Improve initial guess Parameters ---------- region : str Name of region to reduce blorder : int order of baseline removed vmin : numpy.float Minimum centroid velocity to plot, in km/s. vmax : numpy.float Maximum centroid velocity to plot, in km/s. do_plot : bool If True, then a map of the region to map is shown. snr_min : numpy.float Minimum signal to noise ratio of the spectrum to be fitted. multicore : int Numbers of cores to use for parallel processing. file_extension : str File extension of the input maps. Default is 'base#' where # is the blorder parameter above. mask_function : fun function to create a custom made mask for analysis. Defaults to using `default_masking` """ if file_extension: root = file_extension else: # root = 'base{0}'.format(blorder) root = 'all' OneOneIntegrated = '{0}/{0}_NH3_11_{1}_mom0.fits'.format(region,root) OneOneFile = '{0}/{0}_NH3_11_{1}.fits'.format(region,root) RMSFile = '{0}/{0}_NH3_11_{1}_rms.fits'.format(region,root) TwoTwoFile = '{0}/{0}_NH3_22_{1}.fits'.format(region,root) ThreeThreeFile = '{0}/{0}_NH3_33_{1}.fits'.format(region,root) cube11sc = SpectralCube.read(OneOneFile) cube22sc = SpectralCube.read(TwoTwoFile) errmap11 = fits.getdata(RMSFile) rms = np.nanmedian(errmap11) snr = cube11sc.filled_data[:].value/errmap11 peaksnr = np.max(snr,axis=0) if mask_function is None: planemask = default_masking(peaksnr,snr_min = snr_min) else: planemask = mask_function(peaksnr,snr_min = snr_min) #planemask = (peaksnr>20) * (errmap11 < 0.2) mask = (snr>3)*planemask maskcube = cube11sc.with_mask(mask.astype(bool)) maskcube = maskcube.with_spectral_unit(u.km/u.s,velocity_convention='radio') slab = maskcube.spectral_slab( vmax*u.km/u.s, vmin*u.km/u.s) w11=slab.moment( order=0, axis=0).value peakloc = np.nanargmax(w11) ymax,xmax = np.unravel_index(peakloc,w11.shape) moment1 = slab.moment( order=1, axis=0).value moment2 = (slab.moment( order=2, axis=0).value)**0.5 moment2[np.isnan(moment2)]=0.2 moment2[moment2<0.2]=0.2 cube11 = pyspeckit.Cube(OneOneFile,maskmap=planemask) cube11.unit="K" cube22 = pyspeckit.Cube(TwoTwoFile,maskmap=planemask) cube22.unit="K" #cube33 = pyspeckit.Cube(ThreeThreeFile,maskmap=planemask) #cube33.unit="K" # removed as long as we're not modeling OPR cubes = pyspeckit.CubeStack([cube11,cube22],maskmap=planemask) cubes.unit="K" guesses = np.zeros((6,)+cubes.cube.shape[1:]) moment1[moment1<vmin] = vmin+0.2 moment1[moment1>vmax] = vmax-0.2 guesses[0,:,:] = 12 # Kinetic temperature guesses[1,:,:] = 3 # Excitation Temp guesses[2,:,:] = 14.5 # log(column) guesses[3,:,:] = moment2 # Line width / 5 (the NH3 moment overestimates linewidth) guesses[4,:,:] = moment1 # Line centroid guesses[5,:,:] = 0.0 # F(ortho) - ortho NH3 fraction (fixed) if do_plot: import matplotlib.pyplot as plt plt.imshow( w11, origin='lower',interpolation='nearest') plt.show() F=False T=True if not 'cold_ammonia' in cubes.specfit.Registry.multifitters: cubes.specfit.Registry.add_fitter('cold_ammonia',ammonia.cold_ammonia_model(),6) print('start fit') cubes.fiteach(fittype='cold_ammonia', guesses=guesses, integral=False, verbose_level=3, fixed=[F,F,F,F,F,T], signal_cut=2, limitedmax=[F,F,T,F,T,T], maxpars=[0,0,17.0,0,vmax,1], limitedmin=[T,T,T,T,T,T], minpars=[5,2.8,12.0,0.04,vmin,0], start_from_point=(xmax,ymax), use_neighbor_as_guess=True, position_order = 1/peaksnr, errmap=errmap11, multicore=multicore) fitcubefile = fits.PrimaryHDU(data=np.concatenate([cubes.parcube,cubes.errcube]), header=cubes.header) fitcubefile.header.set('PLANE1','TKIN') fitcubefile.header.set('PLANE2','TEX') fitcubefile.header.set('PLANE3','COLUMN') fitcubefile.header.set('PLANE4','SIGMA') fitcubefile.header.set('PLANE5','VELOCITY') fitcubefile.header.set('PLANE6','FORTHO') fitcubefile.header.set('PLANE7','eTKIN') fitcubefile.header.set('PLANE8','eTEX') fitcubefile.header.set('PLANE9','eCOLUMN') fitcubefile.header.set('PLANE10','eSIGMA') fitcubefile.header.set('PLANE11','eVELOCITY') fitcubefile.header.set('PLANE12','eFORTHO') fitcubefile.header.set('CDELT3',1) fitcubefile.header.set('CTYPE3','FITPAR') fitcubefile.header.set('CRVAL3',0) fitcubefile.header.set('CRPIX3',1) fitcubefile.writeto("{0}/{0}_parameter_maps_{1}.fits".format(region,root),clobber=True) if gauss_fit==True: molecules = ['C2S', 'HC7N_22_21', 'HC7N_21_20', 'HC5N'] for i in molecules: gauss_fitter(region=region, mol=i, vmin=vmin, vmax=vmax, snr_min=snr_min, multicore=multicore, file_extension=file_extension)
import pylab as pl # NH3 (1,1) cube region = 'L1688' file_extension = 'DR1_rebase3' line = 'NH3_11' OneOneFile = 'nh3_data/{0}_NH3_11_{1}_trim.fits'.format(region, file_extension) TwoTwoFile = 'nh3_data/{0}_NH3_22_{1}_trim.fits'.format(region, file_extension) FitFile = 'propertyMaps/{0}_parameter_maps_{1}_flag.fits'.format( region, file_extension) cube11 = pyspeckit.Cube(OneOneFile) cube11.unit = 'K' cube22 = pyspeckit.Cube(TwoTwoFile) cube22.unit = 'K' cubes = pyspeckit.CubeStack([cube11, cube22]) cubes.unit = 'K' if not 'cold_ammonia' in cubes.specfit.Registry.multifitters: cubes.specfit.Registry.add_fitter('cold_ammonia', ammonia.cold_ammonia_model(), 6) #cubes.load_model_fit(FitFile,6,npeaks=1,fittype='cold_ammonia') #cubes.specfit.parinfo[5]['fixed'] = True pix_coords = [54, 184] sp = cubes.get_spectrum(pix_coords[0], pix_coords[1]) F = False T = True sp.specfit(fittype='cold_ammonia',
pcube = pyspeckit.Cube(cube=mycube, xarr=myaxis, xunit='km/s', xarrkwargs=dict(refX=1 * u.GHz, velocity_convention='radio')) pcube.xarr.velocity_convention = 'radio' pcube.xarr.refX = 1 * u.GHz pcube.xarr.convert_to_unit('m/s') sp = pcube.get_spectrum(5, 5) print(pcube) print(pcube.__repr__()) stack = pyspeckit.CubeStack([pcube, pcube]) stack.xarr.convert_to_unit(u.km / u.s) x = stack.get_spectrum(0, 0) y = x.slice(10, 20) y.xarr.convert_to_unit('km/s') # Regression test for unit declaration... pcube = pyspeckit.Cube(cube=mycube, xarr=myaxis, xunit='km/s', xarrkwargs=dict(refX=1 * u.GHz, velocity_convention='radio')) pcube.xarr.velocity_convention = 'radio' pcube.xarr.refX = 1 pcube.xarr.refX_unit = u.GHz