u.sr) peak_line_freq = u.Quantity([dendro_merge['peak{0}freq'.format(pid)][ii] if pid >= 0 else 1.0 for ii,pid in enumerate(peak_line_id)], u.GHz) peak_line_cont = u.Quantity([dendro_merge['continuum20pct{0}'.format(pid)][ii] if pid >= 0 else 0.0 for ii,pid in enumerate(peak_line_id)], u.Jy) tbequiv = u.brightness_temperature(peak_line_beam_area, peak_line_freq) peak_line_brightness = (peak_line_flux*u.Jy).to(u.K, tbequiv) dendro_merge.add_column(Column(peak_line_brightness, name='PeakLineBrightness')) continuum20pct_K = (peak_line_cont.to(u.K, tbequiv)) dendro_merge.add_column(Column(continuum20pct_K, name='PeakLineContinuumBG')) tcm = Column([(masscalc.mass_conversion_factor(20).to(u.M_sun).value if np.isnan(row['PeakLineBrightness']) else masscalc.mass_conversion_factor(TK=row['PeakLineBrightness']).to(u.M_sun).value) * row['peak_cont_flux'] for row in dendro_merge], name='T_corrected_mass', unit=u.M_sun) temperature_corrected_mass = tcm dendro_merge.add_column(temperature_corrected_mass) columns = ['SourceID', 'peak_cont_mass', 'T_corrected_mass', 'PeakLineBrightness', 'PeakLineFlux', 'PeakLineSpecies', 'peak_cont_col', 'mean_velo',
'mean_cont_flux', 'peak_cont_mass', 'peak_cont_col', 'beam_area'] radii = (0.2,0.4,0.6,0.8,1.0,1.5)*u.arcsec columns = {k:[] for k in (keys)} log.info("Doing photometry") for ii, row in enumerate(ProgressBar(ppcat)): structure = dend[row['_idx']] assert structure.idx == row['_idx'] == ii dend_inds = structure.indices() columns['noise'].append(noise[dend_inds].mean()) columns['is_leaf'].append(structure.is_leaf) peakflux = data[dend_inds].max() columns['peak_cont_flux'].append(peakflux) columns['min_cont_flux'].append(data[dend_inds].min()) columns['mean_cont_flux'].append(data[dend_inds].mean()) columns['peak_cont_mass'].append((masscalc.mass_conversion_factor()*peakflux).to(u.M_sun).value) columns['peak_cont_col'].append((masscalc.col_conversion_factor(beamomega=beam.sr.value)*peakflux).to(u.cm**-2).value) columns['beam_area'].append(beam.sr.value) for k in columns: if k not in ppcat.keys(): ppcat.add_column(Column(name=k, data=columns[k])) cat_mask = (ppcat['is_leaf'] & (ppcat['peak_cont_flux']>8*ppcat['noise']) & (ppcat['mean_cont_flux']>5*ppcat['noise']) & (ppcat['min_cont_flux']>1*ppcat['noise'])) pruned_ppcat = ppcat[cat_mask] mask = dend.index_map.copy() log.info("Pruning mask image") for ii in ProgressBar(list(range(len(ppcat)))): if ii not in pruned_ppcat['_idx']:
print(rpath) reg = pyregion.open(paths.rpath(rpath)) mask = reg.get_mask(fh[0]) cutout = fh[0].data*mask limits = [0.005, 0.015] total_flux_perbeam = cutout[(cutout > limits[0]) & (cutout < limits[1])].sum() total_flux = total_flux_perbeam / ppbeam.value print("Total flux: {0}".format(total_flux)) rad = reg[0].coord_list[-1]*u.deg rad_pc = (rad*masscalc.distance).to(u.pc, u.dimensionless_angles()) print("Total mass(20K): {0}".format(total_flux*masscalc.mass_conversion_factor(TK=20))) print("Total mass(50K): {0}".format(total_flux*masscalc.mass_conversion_factor(TK=50))) print("Assumed radius: {0}".format(rad_pc)) print("Total density(50K): {0}".format((total_flux*masscalc.mass_conversion_factor(TK=50)/(4/3*np.pi*rad_pc**3) / (2.8*u.Da)).to(u.cm**-3))) Qlyc = 1e49 * 1/u.s alpha_b = 3e-13*u.cm**3*u.s**-1 n_h = 5e5*u.cm**-3 rstrom = (3 * Qlyc /(4*np.pi*alpha_b*n_h**2))**(1/3.) print("Stromgren radius: {0}".format(rstrom)) # sound speed at 8500K cii = 7.1*u.km/u.s def r_of_t(Rs, t, cii=cii, ): return Rs * (1+7/4. * cii/Rs * t)**(4/7.)
'mean_cont_flux', 'peak_cont_mass', 'peak_cont_col', 'beam_area'] radii = (0.2,0.4,0.6,0.8,1.0,1.5)*u.arcsec columns = {k:[] for k in (keys)} log.info("Doing photometry") for ii, row in enumerate(ProgressBar(ppcat)): structure = dend[row['_idx']] assert structure.idx == row['_idx'] == ii dend_inds = structure.indices() columns['noise'].append(noise[dend_inds].mean()) columns['is_leaf'].append(structure.is_leaf) peakflux = data[dend_inds].max() columns['peak_cont_flux'].append(peakflux) columns['min_cont_flux'].append(data[dend_inds].min()) columns['mean_cont_flux'].append(data[dend_inds].mean()) columns['peak_cont_mass'].append((masscalc.mass_conversion_factor()*peakflux).to(u.M_sun).value) columns['peak_cont_col'].append((masscalc.col_conversion_factor(beamomega=beam.sr.value)*peakflux).to(u.cm**-2).value) columns['beam_area'].append(beam.sr.value) for k in columns: if k not in ppcat.keys(): ppcat.add_column(Column(name=k, data=columns[k])) cat_mask = (ppcat['is_leaf'] & (ppcat['peak_cont_flux']>6.5*ppcat['noise']) & (ppcat['mean_cont_flux']>3*ppcat['noise']) & (ppcat['min_cont_flux']>1*ppcat['noise'])) log.info("Keeping {0} of {1} core candidates ({2}%)".format(cat_mask.sum(), len(cat_mask), cat_mask.sum()/len(cat_mask)*100)) pruned_ppcat = ppcat[cat_mask] mask = dend.index_map.copy() log.info("Pruning mask image") for ii in ProgressBar(list(range(len(ppcat)))):
def make_rprof(regions, ploteach=False): names = [r.attr[1]['text'] for r in regions] center_positions = coordinates.SkyCoord([r.coord_list for r in regions], unit=(u.deg, u.deg), frame='fk5') size = u.Quantity([1.25, 1.25], u.arcsec) if ploteach: nplots = len(names) for ii in range(nplots): pl.figure(ii).clf() pl.figure(nplots + ii).clf() pl.figure(nplots * 2 + ii).clf() linestyles = { name: itertools.cycle(['-'] + ['--'] + [':'] + ['-.']) for name in names } for fn in ffiles: fh = fits.open(paths.dpath("12m/continuum/" + fn)) mywcs = wcs.WCS(fh[0].header) if 'BMAJ' not in fh[0].header: #print("File {0} does not have BMAJ".format(fn)) continue try: beam = radio_beam.Beam.from_fits_header(fh[0].header) except KeyError: #print("File {0} doesn't have beam info in the header".format(fn)) continue pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr / (pixscale**2 * u.deg**2)).decompose().value / u.beam print("fn {0} ppbeam={1:0.2f}".format(fn, ppbeam)) for ii, (name, position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = image_tools.radialprofile.azimuthalAverage( cutout.data, binsize=1.0, return_nr=True) linestyle = next(linestyles[name]) pl.figure(ii) pl.title(name) pl.plot(bins * pixscale * 3600., rprof / ppbeam, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius (arcsec)") cumul_rprof = np.nan_to_num(rprof * nr / ppbeam).cumsum() pl.figure(nplots + ii) pl.title(name) pl.plot(bins * pixscale * 3600., cumul_rprof, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius (arcsec)") if ii == 0: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.pc, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = [0.005, 0.01, 0.015, 0.02, 0.025 ] * u.pc new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius (pc)") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0, 6000, 1000) yticks_Jy = yticks_mass / masscalc.mass_conversion_factor( ).value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.figure(nplots * 2 + ii) pl.title(name) pl.plot(((bins * pixscale * u.deg) * masscalc.distance).to( u.pc, u.dimensionless_angles()), cumul_rprof * masscalc.mass_conversion_factor(), label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.xlabel("Radius (pc)") for ii in range(nplots): for xtra in (0, nplots * 2): ax = pl.figure(ii + xtra).gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) else: nplots = 0 pl.matplotlib.rc_file('pubfiguresrc') pl.figure(nplots * 3 + 1).clf() pl.figure(nplots * 3 + 2).clf() pl.figure(nplots * 3 + 3).clf() fn = "selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits" fh = fits.open(paths.dpath("12m/continuum/" + fn)) mywcs = wcs.WCS(fh[0].header) beam = radio_beam.Beam.from_fits_header(fh[0].header) pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr / (pixscale**2 * u.deg**2)).decompose().value / u.beam for ii, (name, position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = image_tools.radialprofile.azimuthalAverage( cutout.data, binsize=1.0, return_nr=True) pl.figure(nplots * 3 + 1) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins * pixscale * 3600., rprof / ppbeam, label=name) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius (arcsec)") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) cumul_rprof = np.nan_to_num(rprof * nr / ppbeam).cumsum() pl.figure(nplots * 3 + 2) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins * pixscale * 3600., cumul_rprof, label=name) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius (arcsec)") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius (au)") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0, 6000, 1000) yticks_Jy = yticks_mass / masscalc.mass_conversion_factor( TK=40).value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.figure(nplots * 3 + 3) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(((bins * pixscale * u.deg) * masscalc.distance).to( u.pc, u.dimensionless_angles()), cumul_rprof * masscalc.mass_conversion_factor(TK=40), label=name) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
def jeans_maps(regions, size=u.Quantity([2.25, 2.25], u.arcsec), smooth=0): names = [r.attr[1]['text'] for r in regions] center_positions = coordinates.SkyCoord([r.coord_list for r in regions], unit=(u.deg, u.deg), frame='fk5') fn = "W51_te_continuum_best.fits" fh = fits.open(paths.dpath(fn)) mywcs = wcs.WCS(fh[0].header) bm = radio_beam.Beam.from_fits_header(fh[0].header) pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg pixscale_cm = (pixscale * masscalc.distance).to(u.cm, u.dimensionless_angles()) ppbeam = (bm.sr / (pixscale**2)).decompose().value / u.beam mass_maps = {} for ii, (name, position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) source = 'e2' if name == 'e2e' else name temperature_map_fn = paths.dpath( '12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source)) temperature_map_fh = fits.open(temperature_map_fn) # this whole section is copied from overlay_contours_on_ch3oh #ch3ohN_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_columnmap.fits'.format(source))) #ch3ohT_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source))) #bigwcs = wcs.WCS(ch3ohT_hdul[0].header) #bigpixscale = (bigwcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg #ch3ohN = ch3ohN_hdul[0].data #ch3ohT = ch3ohT_hdul[0].data #dust_brightness,wts = reproject.reproject_interp(fits.open(paths.dpath('W51_te_continuum_best.fits')), # ch3ohN_hdul[0].header) temwcs = wcs.WCS(temperature_map_fh[0].header) temcutout = Cutout2D(temperature_map_fh[0].data, position, size, wcs=temwcs) #maskcutout = Cutout2D(mask.astype('float'), position, size, wcs=bigwcs) tem_pixscale = (temwcs.pixel_scale_matrix.diagonal()** 2).sum()**0.5 * u.deg ppbeam_tem = ppbeam * (pixscale / tem_pixscale)**2 print("ppbeam, ppbeam_tem: ", ppbeam, ppbeam_tem) # geometric average FWHM bm_cm_fwhm = ((bm.major * bm.minor)**0.5 * masscalc.distance).to( u.cm, u.dimensionless_angles()) bm_cm = bm_cm_fwhm / (8 * np.log(2))**0.5 if smooth != 0: stddev_pix = ((smooth**2 / (8 * np.log(2)) - bm_cm**2)**0.5 / pixscale_cm).decompose() print('stddev_pix: {0}'.format(stddev_pix.decompose())) kernel = Gaussian2DKernel(stddev_pix) kernel.normalize('peak') #smdata = convolve(cutout.data / ppbeam, kernel) mass_map = (cutout.data * masscalc.mass_conversion_factor(TK=temcutout.data)).to( u.M_sun) # mass_map is the sum over a gaussian 'aperture', but it has to account for the # beam to avoid double-counting # (this is better than using smooth temperature, since that leads to a huge overestimate) new_ppbeam = (2 * np.pi * smooth**2 / (8 * np.log(2)) / pixscale_cm**2).decompose() / u.beam print('new_ppbeam: {0}, ppbeam: {1}, old_ppbeam: {2}'.format( new_ppbeam, ppbeam_tem, 2 * np.pi * (bm_cm / pixscale_cm).decompose()**2)) mass_map = convolve(mass_map, kernel) * u.M_sun * ( ppbeam / new_ppbeam).decompose() # temperature should be the average temperature kernel.normalize('integral') temmap = convolve(temcutout.data, kernel) #mass_map = (smdata * masscalc.mass_conversion_factor(TK=temcutout.data)).to(u.M_sun) bm_cm = smooth / (8 * np.log(2))**0.5 else: mass_map = (cutout.data * masscalc.mass_conversion_factor(TK=temcutout.data)).to( u.M_sun) temmap = temcutout.data # volume of a gaussian: sqrt(2 pi)^N r^N volume = (2 * np.pi)**(1.5) * bm_cm**3 density_map = (mass_map / volume / (2.8 * u.Da)).to(u.cm**-3) print("Scale: {0}".format(bm_cm.to(u.au))) c_s_map = ((constants.k_B * temmap * u.K / (2.4 * u.Da))**0.5).to( u.km / u.s) MJ_map_ = (np.pi / 6. * c_s_map**3 / (constants.G**1.5 * (2.8 * u.Da * density_map)**0.5)).to( u.M_sun) LJ_map = (c_s_map / (constants.G**0.5 * (2.8 * u.Da * density_map)**0.5)).to(u.au) MJ_map = (4 / 3. * np.pi * (LJ_map / 2.)**3 * (2.8 * u.Da * density_map)).to(u.M_sun) np.testing.assert_almost_equal(MJ_map.value, MJ_map_.value) fig = pl.figure(ii) fig.clf() ax1 = pl.subplot(2, 3, 1) im1 = ax1.imshow(mass_map.value, cmap='gray', vmin=0, vmax=10) ax1.set_title("Measured mass") fig.colorbar(im1) ax2 = pl.subplot(2, 3, 2) im2 = ax2.imshow(MJ_map.value, cmap='gray', vmin=0, vmax=10) ax2.set_title("Jeans mass") fig.colorbar(im2) ax3 = pl.subplot(2, 3, 3) ax3.set_title("Black: unstable") # 1 -> white # 0 -> black # mass > M_J = unstable # M_J > mass = stable = 1 = white ax3.imshow(MJ_map > mass_map, cmap='gray', vmin=0, vmax=1) ax4 = pl.subplot(2, 3, 4) ax4.set_title("log Density") im4 = ax4.imshow(np.log10(density_map.value), cmap='gray', vmin=7, vmax=9.5) fig.colorbar(im4) ax5 = pl.subplot(2, 3, 5) ax5.set_title("Temperature") im5 = ax5.imshow(temmap, cmap='gray', vmin=0, vmax=700) fig.colorbar(im5) ax6 = pl.subplot(2, 3, 6) im6 = ax6.imshow(LJ_map.value, cmap='gray', vmin=0, vmax=1e4) ax6.contourf(LJ_map.value, levels=[ 0, 2 * (bm_cm_fwhm.to(u.au)).value * gaussian_fwhm_to_sphere_r ], colors=['r', 'r']) ax6.set_title("Jeans Length (AU)") fig.colorbar(im6) for jj in range(1, 7): pl.subplot(2, 3, jj).xaxis.set_major_formatter(pl.NullFormatter()) pl.subplot(2, 3, jj).yaxis.set_major_formatter(pl.NullFormatter()) if smooth == 0: fig.savefig(paths.fpath("jeans_maps_{0}.png".format(name))) else: fig.savefig( paths.fpath("jeans_maps_{0}_smooth{1}.png".format( name, smooth))) mass_maps[name] = (mass_map, MJ_map) return mass_maps
def jeans_maps(regions, size=u.Quantity([2.25,2.25], u.arcsec), smooth=0): names = [r.attr[1]['text'] for r in regions] center_positions = coordinates.SkyCoord([r.coord_list for r in regions], unit=(u.deg, u.deg), frame='fk5') fn = "W51_te_continuum_best.fits" fh = fits.open(paths.dpath(fn)) mywcs = wcs.WCS(fh[0].header) bm = radio_beam.Beam.from_fits_header(fh[0].header) pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg pixscale_cm = (pixscale * masscalc.distance).to(u.cm, u.dimensionless_angles()) ppbeam = (bm.sr/(pixscale**2)).decompose().value / u.beam mass_maps = {} for ii,(name,position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) source = 'e2' if name == 'e2e' else name temperature_map_fn = paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source)) temperature_map_fh = fits.open(temperature_map_fn) # this whole section is copied from overlay_contours_on_ch3oh #ch3ohN_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_columnmap.fits'.format(source))) #ch3ohT_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source))) #bigwcs = wcs.WCS(ch3ohT_hdul[0].header) #bigpixscale = (bigwcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg #ch3ohN = ch3ohN_hdul[0].data #ch3ohT = ch3ohT_hdul[0].data #dust_brightness,wts = reproject.reproject_interp(fits.open(paths.dpath('W51_te_continuum_best.fits')), # ch3ohN_hdul[0].header) temwcs = wcs.WCS(temperature_map_fh[0].header) temcutout = Cutout2D(temperature_map_fh[0].data, position, size, wcs=temwcs) #maskcutout = Cutout2D(mask.astype('float'), position, size, wcs=bigwcs) tem_pixscale = (temwcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg ppbeam_tem = ppbeam * (pixscale/tem_pixscale)**2 print("ppbeam, ppbeam_tem: ",ppbeam,ppbeam_tem) # geometric average FWHM bm_cm_fwhm = ((bm.major * bm.minor)**0.5 * masscalc.distance).to(u.cm, u.dimensionless_angles()) bm_cm = bm_cm_fwhm / (8*np.log(2))**0.5 if smooth != 0: stddev_pix = ((smooth**2/(8*np.log(2)) - bm_cm**2)**0.5 / pixscale_cm).decompose() print('stddev_pix: {0}'.format(stddev_pix.decompose())) kernel = Gaussian2DKernel(stddev_pix) kernel.normalize('peak') #smdata = convolve(cutout.data / ppbeam, kernel) mass_map = (cutout.data * masscalc.mass_conversion_factor(TK=temcutout.data)).to(u.M_sun) # mass_map is the sum over a gaussian 'aperture', but it has to account for the # beam to avoid double-counting # (this is better than using smooth temperature, since that leads to a huge overestimate) new_ppbeam = (2*np.pi*smooth**2/(8*np.log(2)) / pixscale_cm**2).decompose() / u.beam print('new_ppbeam: {0}, ppbeam: {1}, old_ppbeam: {2}'.format(new_ppbeam, ppbeam_tem, 2*np.pi*(bm_cm/pixscale_cm).decompose()**2)) mass_map = convolve(mass_map, kernel)*u.M_sun * (ppbeam/new_ppbeam).decompose() # temperature should be the average temperature kernel.normalize('integral') temmap = convolve(temcutout.data, kernel) #mass_map = (smdata * masscalc.mass_conversion_factor(TK=temcutout.data)).to(u.M_sun) bm_cm = smooth/(8*np.log(2))**0.5 else: mass_map = (cutout.data * masscalc.mass_conversion_factor(TK=temcutout.data)).to(u.M_sun) temmap = temcutout.data # volume of a gaussian: sqrt(2 pi)^N r^N volume = (2*np.pi)**(1.5) * bm_cm**3 density_map = (mass_map / volume / (2.8*u.Da)).to(u.cm**-3) print("Scale: {0}".format(bm_cm.to(u.au))) c_s_map = ((constants.k_B * temmap*u.K / (2.4*u.Da))**0.5).to(u.km/u.s) MJ_map_ = (np.pi/6. * c_s_map**3 / (constants.G**1.5 * (2.8*u.Da*density_map)**0.5)).to(u.M_sun) LJ_map = (c_s_map / (constants.G**0.5 * (2.8*u.Da*density_map)**0.5)).to(u.au) MJ_map = (4/3. * np.pi * (LJ_map/2.)**3 * (2.8*u.Da*density_map)).to(u.M_sun) np.testing.assert_almost_equal(MJ_map.value, MJ_map_.value) fig = pl.figure(ii) fig.clf() ax1=pl.subplot(2,3,1) im1 = ax1.imshow(mass_map.value, cmap='gray', vmin=0, vmax=10) ax1.set_title("Measured mass") fig.colorbar(im1) ax2=pl.subplot(2,3,2) im2 = ax2.imshow(MJ_map.value, cmap='gray', vmin=0, vmax=10) ax2.set_title("Jeans mass") fig.colorbar(im2) ax3=pl.subplot(2,3,3) ax3.set_title("Black: unstable") # 1 -> white # 0 -> black # mass > M_J = unstable # M_J > mass = stable = 1 = white ax3.imshow(MJ_map > mass_map, cmap='gray', vmin=0, vmax=1) ax4=pl.subplot(2,3,4) ax4.set_title("log Density") im4 = ax4.imshow(np.log10(density_map.value), cmap='gray', vmin=7, vmax=9.5) fig.colorbar(im4) ax5=pl.subplot(2,3,5) ax5.set_title("Temperature") im5 = ax5.imshow(temmap, cmap='gray', vmin=0, vmax=700) fig.colorbar(im5) ax6=pl.subplot(2,3,6) im6 = ax6.imshow(LJ_map.value, cmap='gray', vmin=0, vmax=1e4) ax6.contourf(LJ_map.value, levels=[0, 2*(bm_cm_fwhm.to(u.au)).value * gaussian_fwhm_to_sphere_r], colors=['r', 'r']) ax6.set_title("Jeans Length (AU)") fig.colorbar(im6) for jj in range(1,7): pl.subplot(2,3,jj).xaxis.set_major_formatter(pl.NullFormatter()) pl.subplot(2,3,jj).yaxis.set_major_formatter(pl.NullFormatter()) if smooth == 0: fig.savefig(paths.fpath("jeans_maps_{0}.png".format(name))) else: fig.savefig(paths.fpath("jeans_maps_{0}_smooth{1}.png".format(name, smooth))) mass_maps[name] = (mass_map, MJ_map) return mass_maps
pixel_scale = np.abs(mywcs.pixel_scale_matrix.diagonal().prod())**0.5 * u.deg pixel_scale_as = pixel_scale.to(u.arcsec).value ppbeam = (beam.sr / (pixel_scale**2)).decompose().value / u.beam #pl.hist(data[np.isfinite(data)], bins=np.linspace(1e-4,0.1,100)) # over what threshold are we including flux when measuring total masses? threshold = 10 * u.mJy / u.beam threshold_column = (threshold * u.beam / u.Jy * masscalc.col_conversion_factor(beam)).to(u.cm**-2) threshold_column = masscalc.dust.colofsnu(nu=masscalc.centerfreq, snu=threshold * u.beam, beamomega=beam.sr).to( u.cm**-2, u.dimensionless_angles()) threshold_density = (masscalc.mass_conversion_factor(20) * (threshold * u.beam).to(u.mJy).value / (4 / 3. * np.pi) / (beam.sr.value * masscalc.distance**2)**(1.5) / (2.8 * constants.m_p)).to(1 / u.cm**3) definitely_signal = data > threshold total_signal = data[definitely_signal].sum() / ppbeam print("Total flux: {0}".format(total_signal)) print("Total mass(20K): {0}".format( total_signal * masscalc.mass_conversion_factor() * u.M_sun / u.Jy)) print("Threshold column (20K): {0:e}".format(threshold_column)) print("Threshold density (20K): {0:e}".format(threshold_density)) flux_of_filament = 132 * u.Jy / u.beam / ppbeam print("Total *filament* mass(20K): {0}".format( flux_of_filament * masscalc.mass_conversion_factor() * u.M_sun / u.Jy)) print("Total *filament* mass(100K): {0}".format( flux_of_filament * masscalc.mass_conversion_factor(TK=100) * u.M_sun /
cores_merge.add_column(Column(brightest_noncld_lines, 'BrightestFittedLine')) cores_merge.add_column(Column(brightest_noncld_qns, 'BrightestFittedQNs')) cores_merge.add_column(Column(brightest_noncld_fluxes, 'BrightestFittedPeakPixFlux', unit=u.Jy)) cores_merge.add_column(Column(brightest_fitted_brightness, 'BrightestFittedPeakPixBrightness', unit=u.K)) # need to add back in continuum because we're concerned with the *absolute* # brightness # moved to other merge jtok_eq = u.brightness_temperature(cores_merge['beam_area'], 225*u.GHz) # moved to other merge cont_brightness = (u.beam * cores_merge['sum']/cores_merge['npix']).to(u.K, jtok_eq) cont_brightness = cores_merge['MeanContinuumBrightness'] contincluded_line_brightness = cores_merge['BrightestFittedPeakPixBrightness'] + cont_brightness cores_merge.add_column(Column(contincluded_line_brightness, 'BrightestFittedPeakPixBrightnessWithcont', unit=u.K)) temperature_corrected_aperturemass = Column([(masscalc.mass_conversion_factor(20).value if np.isnan(row['BrightestFittedPeakPixBrightnessWithcont']) or (row['BrightestFittedPeakPixBrightnessWithcont'] < 20) else masscalc.mass_conversion_factor(row['BrightestFittedPeakPixBrightnessWithcont']).value) * row['sum']/ppbeam for row in cores_merge], name='T_corrected_aperturemass', unit=u.M_sun) cores_merge.add_column(temperature_corrected_aperturemass) apertures = ('0p2', '0p4', '0p6', '0p8', '1p0', '1p5') for ap in apertures: tcm = Column([(masscalc.mass_conversion_factor(20).value if np.isnan(row['BrightestFittedPeakPixBrightnessWithcont']) or row['BrightestFittedPeakPixBrightnessWithcont'] < 20 else masscalc.mass_conversion_factor(row['BrightestFittedPeakPixBrightnessWithcont']).value)
Column(peak_line_flux, name='PeakLineFlux', unit=cores_merge['peak0'].unit)) cores_merge.add_column(Column(brightest_line_name, name='PeakLineSpecies')) peak_line_brightness = (peak_line_flux * u.Jy).to( u.K, u.brightness_temperature(cores_merge['beam_area'], 220 * u.GHz)) cores_merge.add_column(Column(peak_line_brightness, name='PeakLineBrightness')) jtok_eq = u.brightness_temperature(cores_merge['beam_area'], 225 * u.GHz) cont_brightness = Column( (u.beam * cores_merge['sum'] / cores_merge['npix']).to(u.K, jtok_eq), name='MeanContinuumBrightness') cores_merge.add_column(cont_brightness) aperturemass20k = cores_merge[ 'sum'] / ppbeam * masscalc.mass_conversion_factor(20) cores_merge.add_column( Column(aperturemass20k.value, name='ApertureMass20K', unit=u.M_sun)) temperature_corrected_mass = Column( [(masscalc.mass_conversion_factor(20).value if np.isnan( row['PeakLineBrightness']) else masscalc.mass_conversion_factor( row['PeakLineBrightness'])).value * row['peak'] for row in cores_merge], name='T_corrected_peakmass', unit=u.M_sun) cores_merge.add_column(temperature_corrected_mass) cores_merge = cores_merge['SourceID', 'peak_mass', 'ApertureMass20K', 'T_corrected_peakmass', 'PeakLineBrightness', 'PeakLineFlux', 'PeakLineSpecies', 'peak_col',
radii = (0.2, 0.4, 0.6, 0.8, 1.0, 1.5) * u.arcsec columns = {k: [] for k in (keys)} log.info("Doing photometry") for ii, row in enumerate(ProgressBar(ppcat)): structure = dend[row['_idx']] assert structure.idx == row['_idx'] == ii dend_inds = structure.indices() columns['noise'].append(noise[dend_inds].mean()) columns['is_leaf'].append(structure.is_leaf) peakflux = data[dend_inds].max() columns['peak_cont_flux'].append(peakflux) columns['min_cont_flux'].append(data[dend_inds].min()) columns['mean_cont_flux'].append(data[dend_inds].mean()) columns['peak_cont_mass'].append( (masscalc.mass_conversion_factor() * peakflux).to(u.M_sun).value) columns['peak_cont_col'].append( (masscalc.col_conversion_factor(beamomega=beam.sr.value) * peakflux).to(u.cm**-2).value) columns['beam_area'].append(beam.sr.value) for k in columns: if k not in ppcat.keys(): ppcat.add_column(Column(name=k, data=columns[k])) cat_mask = (ppcat['is_leaf'] & (ppcat['peak_cont_flux'] > 8 * ppcat['noise']) & (ppcat['mean_cont_flux'] > 5 * ppcat['noise']) & (ppcat['min_cont_flux'] > 1 * ppcat['noise'])) pruned_ppcat = ppcat[cat_mask] mask = dend.index_map.copy() log.info("Pruning mask image") for ii in ProgressBar(list(range(len(ppcat)))):
ax1.vlines(3, 0, 25, linestyle='-', color='k', label='3') ax1.vlines(5, 0, 25, linestyle='--', color='r', label='5') ax1.vlines(7, 0, 25, linestyle=':', color='b', label='7') ax1.set_xscale('log') #ax1.set_xlim(l[:-1][h>0].min()/1.1, l[1:][h>0].max()*1.1) ax1.set_ylim(0, 25) ax1.set_xlabel("S/N") ax1.set_ylabel("$N(cores)$") fig1.savefig(paths.fpath('core_SN_histogram.pdf'), bbox_inches='tight') fig1 = pl.figure(1) fig1.clf() ax1 = fig1.gca() shift = np.log10(masscalc.mass_conversion_factor().value) h, l, p = ax1.hist(core_phot_tbl['peak'] * masscalc.mass_conversion_factor(TK=40, beta=1.75), log=False, bins=np.logspace(-4 + shift, -1 + shift, 50)) ax1.set_xscale('log') ax1.set_xlim(l[:-1][h > 0].min() / 1.1, l[1:][h > 0].max() * 1.1) #ax1.set_ylim(0.6, 15) ax1.set_xlabel("$M(T=40$ K, $\\beta=1.75$) [$M_\odot$]") ax1.set_ylabel("$N(cores)$") fig1.savefig(paths.fpath('core_mass_histogram_40K.pdf'), bbox_inches='tight') fig2 = pl.figure(2) fig2.clf() ax2 = fig2.gca()
def make_rprof(regions, ploteach=False): names = [r.attr[1]['text'] for r in regions] center_positions = coordinates.SkyCoord([r.coord_list for r in regions], unit=(u.deg, u.deg), frame='fk5') size = u.Quantity([1.25,1.25], u.arcsec) if ploteach: nplots = len(names) for ii in range(nplots): pl.figure(ii).clf() pl.figure(nplots+ii).clf() pl.figure(nplots*2+ii).clf() linestyles = {name: itertools.cycle(['-'] + ['--'] + [':'] + ['-.']) for name in names} for fn in ffiles: fh = fits.open(paths.dpath("12m/continuum/"+fn)) mywcs = wcs.WCS(fh[0].header) if 'BMAJ' not in fh[0].header: #print("File {0} does not have BMAJ".format(fn)) continue try: beam = radio_beam.Beam.from_fits_header(fh[0].header) except KeyError: #print("File {0} doesn't have beam info in the header".format(fn)) continue pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr/(pixscale**2*u.deg**2)).decompose().value / u.beam #print("fn {0} ppbeam={1:0.2f}".format(fn, ppbeam)) for ii,(name,position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = azimuthalAverage(cutout.data, binsize=1.0, return_nr=True) linestyle = next(linestyles[name]) pl.figure(ii) pl.title(name) pl.plot(bins*pixscale*3600., rprof/ppbeam, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius [arcsec]") cumul_rprof = np.nan_to_num(rprof*nr/ppbeam).cumsum() pl.figure(nplots+ii) pl.title(name) pl.plot(bins*pixscale*3600., cumul_rprof, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius [arcsec]") if ii == 0: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.pc, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = [0.005,0.01,0.015,0.02,0.025]*u.pc new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius (pc)") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0,6000,1000) yticks_Jy = yticks_mass/masscalc.mass_conversion_factor().value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.figure(nplots*2+ii) pl.title(name) pl.plot(((bins*pixscale*u.deg)*masscalc.distance).to(u.pc, u.dimensionless_angles()), cumul_rprof * masscalc.mass_conversion_factor(), label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.xlabel("Radius (pc)") for ii in range(nplots): for xtra in (0,nplots*2): ax = pl.figure(ii+xtra).gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) else: nplots = 0 pl.matplotlib.rc_file('pubfiguresrc') for jj in range(nplots*3+1, nplots*3+15+1): pl.figure(jj).clf() # $ find ~/work/w51/alma/FITS/ -samefile ~/work/w51/alma/FITS/W51_te_continuum_best.fits # /Users/adam/work/w51/alma/FITS//12m/continuum/selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits # /Users/adam/work/w51/alma/FITS//W51_te_continuum_best.fits fn = "selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits" fh = fits.open(paths.dpath("12m/continuum/"+fn)) mywcs = wcs.WCS(fh[0].header) beam = radio_beam.Beam.from_fits_header(fh[0].header) pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr/(pixscale**2*u.deg**2)).decompose().value / u.beam for ii,(name,position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = azimuthalAverage(cutout.data, binsize=1.0, return_nr=True) pl.figure(nplots*3+1) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., rprof/ppbeam, label=name) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) cumul_rprof = np.nan_to_num(rprof*nr/ppbeam).cumsum() pl.figure(nplots*3+2) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., cumul_rprof, label=name) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0,6000,1000) yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") radii = ((bins*pixscale*u.deg)*masscalc.distance).to(u.pc, u.dimensionless_angles()) mass_40k_profile = (cumul_rprof * masscalc.mass_conversion_factor(TK=40) / u.beam).to(u.M_sun) pl.figure(nplots*3+3) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(radii, mass_40k_profile, label=name) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) density_40k_profile = (mass_40k_profile / (4/3.*np.pi*radii**3) / (2.8*u.Da)).to(u.cm**-3) #print(density_40k_profile) #print(radii) pl.figure(nplots*3+4) #pl.title(fn.replace(".image.pbcor.fits","")) pl.semilogy(radii, density_40k_profile, label=name) pl.ylabel("Cumulative Density [n(H$_2$), $T=40$ K]") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) angular_radii = bins*pixscale*3600. azimuthal_average_flux = rprof/ppbeam azimuthal_average_mass_40K = azimuthal_average_flux * masscalc.mass_conversion_factor(TK=40) / u.beam bindiff_as = np.diff(bins).mean() * pixscale * 3600. bindiff_cm = bindiff_as * masscalc.distance / 206265. bins_cm = (angular_radii * masscalc.distance / 206265.).to(u.cm) sqdiffbins_cm = u.Quantity([bins_cm[0].to(u.cm).value**2] + (bins_cm.to(u.cm)[1:]**2 - bins_cm.to(u.cm)[:-1]**2).value.tolist(), u.cm**2) cudiffbins_cm = u.Quantity([bins_cm[0].to(u.cm).value**3] + (bins_cm.to(u.cm)[1:]**3 - bins_cm.to(u.cm)[:-1]**3).value.tolist(), u.cm**3) sqdiffbins_pix = [bins[0]**2] + (bins[1:]**2 - bins[:-1]**2).tolist() azimuthal_average_density_40K = (azimuthal_average_mass_40K * sqdiffbins_pix / (2.8*u.Da) / (4/3.*np.pi*(cudiffbins_cm))).to(u.cm**-3) pl.figure(nplots*3+5) pl.semilogy(angular_radii, azimuthal_average_density_40K, label=name) pl.ylabel("Azimuthally Averaged Density\nat T=40K [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") c_s_40k = ((constants.k_B * 40*u.K / (2.4*u.Da))**0.5).to(u.km/u.s) azimuthal_average_MJ_40k = (np.pi/6. * c_s_40k**3 / (constants.G**1.5 * (2.8*u.Da*azimuthal_average_density_40K)**0.5)).to(u.M_sun) pl.figure(nplots*3+6) pl.semilogy(angular_radii, azimuthal_average_MJ_40k, label=name) pl.ylabel("Azimuthally Averaged $M_J$\nat $T=40$K") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") source = 'e2' if name == 'e2e' else name temperature_map_fn = paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source)) temperature_map_fh = fits.open(temperature_map_fn) # this whole section is copied from overlay_contours_on_ch3oh ch3ohN_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_columnmap.fits'.format(source))) ch3ohT_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source))) bigwcs = wcs.WCS(ch3ohT_hdul[0].header) bigpixscale = (bigwcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg ch3ohN = ch3ohN_hdul[0].data ch3ohT = ch3ohT_hdul[0].data dust_brightness,wts = reproject.reproject_interp(fits.open(paths.dpath('W51_te_continuum_best.fits')), ch3ohN_hdul[0].header) bm = radio_beam.Beam.from_fits_header(paths.dpath("W51_te_continuum_best.fits")) yy,xx = np.indices(ch3ohN.shape) if source == 'north': center = [84.,38.] else: center = [ch3ohN.shape[0]/2., ch3ohN.shape[1]/2.] yyc = (yy-center[0]) xxc = (xx-center[1]) rr = (yyc**2 + xxc**2)**0.5 rr_as = (rr*bigpixscale).to(u.arcsec) theta = np.arctan2(yyc,xxc)*u.rad dust_column = dust_emissivity.dust.colofsnu(225*u.GHz, dust_brightness*u.Jy, beamomega=bm, temperature=ch3ohT*u.K) ch3oh_abundance = ch3ohN / dust_column.value mask = (ch3oh_abundance > 1e-10) & (ch3oh_abundance < 1e-5) if source == 'e2': mask = mask & (((theta > 15*u.deg) & (theta < 345*u.deg)) | (theta < -15*u.deg)) mask = mask & np.isfinite(ch3oh_abundance) # exclude high-abundance, low-column regions: likely to be div-by-zero zones mask = mask & (~((ch3ohN < 1e18) & (ch3oh_abundance > 5e-6))) mask = mask & (~((dust_brightness<1e-2) & (ch3ohT > 500) & (ch3oh_abundance > 1e-6))) #mask = mask & (~((ch3ohT > 250) & # (ch3ohN < 1e18) & # (rr_as>1.5*u.arcsec)) # )# these are low-column, temwcs = wcs.WCS(temperature_map_fh[0].header) temcutout = Cutout2D(temperature_map_fh[0].data, position, size, wcs=temwcs) maskcutout = Cutout2D(mask.astype('float'), position, size, wcs=bigwcs) tem_nr, tem_bins, tem_rprof = azimuthalAverage(temcutout.data, weights=(maskcutout.data>0).astype('float'), binsize=1.0, return_nr=True, interpnan=True, ) azimuthal_average_temperature = tem_rprof mass_map = (cutout.data * masscalc.mass_conversion_factor(TK=temcutout.data) ).to(u.M_sun) yy,xx = np.indices(cutout.data.shape) rr_map = ((xx-cutout.data.shape[1]/2.)**2 + (yy-cutout.data.shape[0]/2.)**2) mass_profile = (cumul_rprof * masscalc.mass_conversion_factor(TK=tem_rprof) / u.beam).to(u.M_sun) density_profile = (mass_profile / (4/3.*np.pi*radii**3) / (2.8*u.Da)).to(u.cm**-3) azimuthal_average_mass = (azimuthal_average_flux * masscalc.mass_conversion_factor(TK=tem_rprof) / u.beam) # how accurate is this? We are measuring mass in cylindrical annuli, # but we are assuming the underlying source structure is spherical # See Cores.ipynb (in notes/, not in this repo) for a detailed # analysis... azimuthal_average_density = (azimuthal_average_mass * sqdiffbins_pix / (2.8*u.Da) / (4/3.*np.pi*(cudiffbins_cm))).to(u.cm**-3) # this is not a good approximation for the spherial density profile... # see cores.ipynb. # Really should be this number +1 (so see the +1 below) # Also, negatived... density_alpha_ = 1-((np.log(density_profile[1:].value) - np.log(density_profile[:-1].value)) / (np.log(angular_radii[1:]) - np.log(angular_radii[:-1])) ) # from cores.ipynb, this actually gets (close to) the right answer density_alpha = -((np.log(azimuthal_average_density[1:].value) - np.log(azimuthal_average_density[:-1].value)) / (np.log(angular_radii[1:]) - np.log(angular_radii[:-1])) ) c_s = ((constants.k_B * tem_rprof*u.K / (2.4*u.Da))**0.5).to(u.km/u.s) azimuthal_average_MJ = (np.pi/6. * c_s**3 / (constants.G**1.5 * (2.8*u.Da*azimuthal_average_density)**0.5) ).to(u.M_sun) cumulative_mass_weighted_temperature = ((azimuthal_average_mass * azimuthal_average_temperature).cumsum() / mass_profile) cumulative_c_s = ((constants.k_B * cumulative_mass_weighted_temperature*u.K / (2.4*u.Da))**0.5).to(u.km/u.s) cumulative_profile_MJ = (np.pi/6. * cumulative_c_s**3 / (constants.G**1.5 * (2.8*u.Da*density_profile)**0.5) ).to(u.M_sun) pl.figure(nplots*3+7) line, = pl.plot(angular_radii, azimuthal_average_MJ, label=name) # WRONG pl.plot(angular_radii, azimuthal_average_mass, linestyle='--', # WRONG alpha=0.75, color=line.get_color()) #pl.plot(rr_map*pixscale*3600., mass_map, 'k.', alpha=0.25) pl.axis([0,1.2,0.0,5.0]) pl.ylabel("Azimuthally Averaged $M_J$\nat $T(\\mathrm{CH}_3\\mathrm{OH})$ [$M_\\odot$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots*3+8) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., mass_profile, label=name) pl.ylabel("Cumulative Mass at T(CH$_3$OH)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='upper left') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots*3+9) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., tem_rprof, label=name) pl.legend(loc='best') pl.ylabel("CH$_3$OH temperature") pl.xlabel("Radius [as]") # Jeans length (radius = length/2) azimuthal_average_RJ = (c_s**1 / (constants.G**0.5 * (2.8*u.Da*azimuthal_average_density)**0.5) ).to(u.au) / 2. pl.figure(nplots*3+10) pl.plot(angular_radii, azimuthal_average_RJ, label=name) pl.plot([0,(7000*u.au/masscalc.distance).to(u.arcsec, u.dimensionless_angles()).value], [0,7000], 'k--', alpha=0.5) pl.ylabel("Azimuthally Averaged $R_J$\nat $T(\\mathrm{CH}_3\\mathrm{OH})$ [au]") pl.xlabel("Radius [arcsec]") pl.ylim(0,8000) if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots*3+11) line, = pl.plot((angular_radii[1:]+angular_radii[:-1])/2., density_alpha) pl.plot((angular_radii[1:]+angular_radii[:-1])/2., density_alpha_, '--', color=line.get_color(), alpha=0.5) pl.xlabel("Radius [as]") pl.ylabel("Density Profile Exponent $\\kappa_\\rho$") pl.figure(nplots*3+12) pl.semilogy(angular_radii, azimuthal_average_density, label=name) pl.ylabel("Azimuthally Averaged Density\nat T=T(CH$_3$OH) [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(1e6, 2e9) ax.set_xlim(0,1.2) ax2 = ax.twiny() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,7000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") ax3 = ax.twinx() def tick_function(old_x): newx = ((constants.G * 2.8*u.Da * (old_x*u.cm**-3))**-0.5).to(u.kyr).value return ["%.1f" % z for z in newx] new_tick_locations = [1.3,1.5,2,3,5]*u.kyr new_tick_locs_dens = ((new_tick_locations**2 * constants.G * 2.8*u.Da)**-1).to(u.cm**-3) ax3.set_ylim(ax.get_ylim()) ax3.set_yticks(new_tick_locs_dens.value) ax3.set_yticklabels(tick_function(new_tick_locs_dens.value)) ax3.set_ylabel(r"$t_{ff}$ [kyr]") # start from 0.05 arcsec xlim = u.Quantity([0.05, ax.get_xlim()[1]], u.arcsec) xax_as = np.linspace(xlim[0], xlim[1], 100) xax_m = (xax_as * masscalc.distance).to(u.m, u.dimensionless_angles()) yax_s = ((ax.get_ylim() * u.cm**-3 * 2.8 * u.Da * constants.G)**-0.5).to(u.s) # plot 1 km/s line line_1 = (((xax_m / (7.5*u.km/u.s))**2 * constants.G * 2.8*u.Da)**-1).to(u.cm**-3) line_2 = (((xax_m / (5*u.km/u.s))**2 * constants.G * 2.8*u.Da)**-1).to(u.cm**-3) line_3 = (((xax_m / (10*u.km/u.s))**2 * constants.G * 2.8*u.Da)**-1).to(u.cm**-3) line, = pl.plot(xax_as.value, line_1.value, 'k:', label='7.5 km s$^{-1}$', zorder=-10) labelLine(line, 0.45, "7.5 km s$^{-1}$") line, = pl.plot(xax_as.value, line_2.value, 'k:', label='5 km s$^{-1}$', zorder=-10) labelLine(line, 0.6, "5 km s$^{-1}$") line, = pl.plot(xax_as.value, line_3.value, 'k-.', label='10 km s$^{-1}$', zorder=-10) labelLine(line, 0.7, "10 km s$^{-1}$") #ax.set_xlim(0,1.2) #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.figure(nplots*3+13) pl.plot(angular_radii, cumulative_profile_MJ, label=name) pl.ylabel("$M_J(r<R)$ at T=T(CH$_3$OH) [$M_\odot$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(0, 2) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.figure(nplots*3+14) line, = pl.plot(angular_radii, azimuthal_average_MJ, label=name) pl.plot(angular_radii, azimuthal_average_mass, linestyle='--', color=line.get_color()) pl.ylabel("Mass at T=T(CH$_3$OH) [$M_\odot$]") pl.xlabel("Radius [arcsec]") handles, labels = ax.get_legend_handles_labels() if '$\\bar{M}$' not in labels: handles.append(pl.matplotlib.lines.Line2D([],[], color='k', linestyle='--')) labels.append('$\\bar{M}$') if '$M_J$' not in labels: handles.append(pl.matplotlib.lines.Line2D([],[], color='k', linestyle='-')) labels.append('$M_J$') if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(0, 5) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.8, box.height]) ax2.set_position([box.x0, box.y0, box.width * 0.8, box.height]) # Put a legend to the right of the current axis ax.legend(handles, labels, loc='center left', bbox_to_anchor=(1, 0.5)) pl.figure(nplots*3+15) pl.subplot(2,2,1) pl.semilogy(angular_radii, azimuthal_average_density, label=name) pl.ylabel("Azimuthally Averaged Density\nat T=T(CH$_3$OH) [cm$^{-3}$]") pl.subplot(2,2,3) pl.semilogy(angular_radii, density_profile, label=name) pl.ylabel("Cumulative Average Density\nat T=T(CH$_3$OH) [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") pl.subplot(2,2,2) pl.plot(azimuthal_average_density, density_profile, label=name) pl.plot(sorted(azimuthal_average_density.value), sorted(azimuthal_average_density.value), 'k--') pl.xlabel("Azimuthally Averaged Density\nat T=T(CH$_3$OH) [cm$^{-3}$]", fontsize=12) pl.ylabel("Cumulative Average Density\nat T=T(CH$_3$OH) [cm$^{-3}$]", fontsize=12) pl.subplot(2,2,4) pl.ylabel("Azimuthal / Cumulative", fontsize=12) pl.plot(angular_radii, azimuthal_average_density / density_profile, label=name) #pl.plot(angular_radii, [1.0] * len(angular_radii), 'k--') pl.xlabel("Radius [arcsec]") return locals()
unit=u.K)) # need to add back in continuum because we're concerned with the *absolute* # brightness # moved to other merge jtok_eq = u.brightness_temperature(cores_merge['beam_area'], 225*u.GHz) # moved to other merge cont_brightness = (u.beam * cores_merge['sum']/cores_merge['npix']).to(u.K, jtok_eq) cont_brightness = cores_merge['MeanContinuumBrightness'] contincluded_line_brightness = cores_merge[ 'BrightestFittedPeakPixBrightness'] + cont_brightness cores_merge.add_column( Column(contincluded_line_brightness, 'BrightestFittedPeakPixBrightnessWithcont', unit=u.K)) temperature_corrected_aperturemass = Column( [(masscalc.mass_conversion_factor(20).value if np.isnan(row['BrightestFittedPeakPixBrightnessWithcont']) or (row['BrightestFittedPeakPixBrightnessWithcont'] < 20) else masscalc.mass_conversion_factor( row['BrightestFittedPeakPixBrightnessWithcont']).value) * row['sum'] / ppbeam for row in cores_merge], name='T_corrected_aperturemass', unit=u.M_sun) cores_merge.add_column(temperature_corrected_aperturemass) apertures = ('0p2', '0p4', '0p6', '0p8', '1p0', '1p5') for ap in apertures: tcm = Column( [ (masscalc.mass_conversion_factor(20).value if np.isnan(row['BrightestFittedPeakPixBrightnessWithcont'])
h,l,p = ax1.hist(peak_brightness, log=False, bins=np.logspace(-0.6, 3.0,30)) ax1.set_xscale('log') ax1.set_xlim(l[:-1][h>0].min()/1.1, l[1:][h>0].max()*1.1) #ax1.set_ylim(0.6, 15) ax1.set_xlabel("$T_{B,3 mm}$ [K]") ax1.set_ylabel("$N(cores)$") fig1.savefig(paths.fpath('core_peak_brightness_histogram.png')) fig1 = pl.figure(1) fig1.clf() ax1 = fig1.gca() shift = np.log10(masscalc.mass_conversion_factor().value) h,l,p = ax1.hist(core_phot_tbl['peak']*masscalc.mass_conversion_factor(40, beta=1.75), log=False, bins=np.logspace(-4+shift,-1+shift,50)) ax1.set_xscale('log') ax1.set_xlim(l[:-1][h>0].min()/1.1, l[1:][h>0].max()*1.1) #ax1.set_ylim(0.6, 15) ax1.set_xlabel("$M(T=40$ K, $\\beta=1.75$) [$M_\odot$]") ax1.set_ylabel("$N(cores)$") fig1.savefig(paths.fpath('core_mass_histogram_40K.png')) fig2 = pl.figure(2) fig2.clf() ax2 = fig2.gca()
mask = reg.get_mask(fh[0]) cutout = fh[0].data * mask limits = [0.005, 0.015] total_flux_perbeam = cutout[(cutout > limits[0]) & (cutout < limits[1])].sum() total_flux = total_flux_perbeam / ppbeam.value print("Total flux: {0}".format(total_flux)) rad = reg[0].coord_list[-1] * u.deg rad_pc = (rad * masscalc.distance).to(u.pc, u.dimensionless_angles()) print("Total mass(20K): {0}".format( total_flux * masscalc.mass_conversion_factor(TK=20))) print("Total mass(50K): {0}".format( total_flux * masscalc.mass_conversion_factor(TK=50))) print("Assumed radius: {0}".format(rad_pc)) print("Total density(50K): {0}".format( (total_flux * masscalc.mass_conversion_factor(TK=50) / (4 / 3 * np.pi * rad_pc**3) / (2.8 * u.Da)).to(u.cm**-3))) Qlyc = 1e49 * 1 / u.s alpha_b = 3e-13 * u.cm**3 * u.s**-1 n_h = 5e5 * u.cm**-3 rstrom = (3 * Qlyc / (4 * np.pi * alpha_b * n_h**2))**(1 / 3.) print("Stromgren radius: {0}".format(rstrom)) # sound speed at 8500K cii = 7.1 * u.km / u.s
def make_rprof(regions, ploteach=False): names = [r.attr[1]['text'] for r in regions] center_positions = coordinates.SkyCoord([r.coord_list for r in regions], unit=(u.deg, u.deg), frame='fk5') size = u.Quantity([1.25, 1.25], u.arcsec) if ploteach: nplots = len(names) for ii in range(nplots): pl.figure(ii, figsize=figsize).clf() pl.figure(nplots + ii, figsize=figsize).clf() pl.figure(nplots * 2 + ii, figsize=figsize).clf() linestyles = { name: itertools.cycle(['-'] + ['--'] + [':'] + ['-.']) for name in names } for fn in ffiles: fh = fits.open(paths.dpath("12m/continuum/" + fn)) mywcs = wcs.WCS(fh[0].header) if 'BMAJ' not in fh[0].header: #print("File {0} does not have BMAJ".format(fn)) continue try: beam = radio_beam.Beam.from_fits_header(fh[0].header) except KeyError: #print("File {0} doesn't have beam info in the header".format(fn)) continue pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr / (pixscale**2 * u.deg**2)).decompose().value / u.beam #print("fn {0} ppbeam={1:0.2f}".format(fn, ppbeam)) for jj, (name, position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = azimuthalAverage(cutout.data, binsize=1.0, return_nr=True) linestyle = next(linestyles[name]) pl.figure(jj, figsize=figsize) pl.title(name) pl.plot(bins * pixscale * 3600., rprof / ppbeam, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius [arcsec]") cumul_rprof = np.nan_to_num(rprof * nr / ppbeam).cumsum() pl.figure(nplots + jj, figsize=figsize) pl.title(name) pl.plot(bins * pixscale * 3600., cumul_rprof, label=fn.split(".")[0], linestyle=linestyle) if jj == 0: pl.fill_between([0, beam.major.to(u.arcsec).value], [100, 100], [0, 0], zorder=-5, alpha=0.1, color='k') pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius [arcsec]") if jj == 0: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.pc, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = [0.005, 0.01, 0.015, 0.02, 0.025 ] * u.pc new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius (pc)") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0, 6000, 1000) yticks_Jy = yticks_mass / masscalc.mass_conversion_factor( ).value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.figure(nplots * 2 + jj, figsize=figsize) pl.title(name) pl.plot(((bins * pixscale * u.deg) * masscalc.distance).to( u.pc, u.dimensionless_angles()), cumul_rprof * masscalc.mass_conversion_factor(), label=fn.split(".")[0], linestyle=linestyle) if jj == 0: pl.fill_between([0, beam.major.to(u.arcsec).value], [100, 100], [0, 0], zorder=-5, alpha=0.1, color='k') pl.ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.xlabel("Radius (pc)") for ii in range(nplots): for xtra in (0, nplots * 2): ax = pl.figure(ii + xtra, figsize=figsize).gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) else: nplots = 0 for jj in range(nplots * 3 + 1, nplots * 3 + 15 + 1): pl.figure(jj, figsize=figsize).clf() # $ find ~/work/w51/alma/FITS/ -samefile ~/work/w51/alma/FITS/W51_te_continuum_best.fits # /Users/adam/work/w51/alma/FITS//12m/continuum/selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits # /Users/adam/work/w51/alma/FITS//W51_te_continuum_best.fits fn = "selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits" fh = fits.open(paths.dpath("12m/continuum/" + fn)) mywcs = wcs.WCS(fh[0].header) beam = radio_beam.Beam.from_fits_header(fh[0].header) pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr / (pixscale**2 * u.deg**2)).decompose().value / u.beam for ii, (name, position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = azimuthalAverage(cutout.data, binsize=1.0, return_nr=True) pl.figure(nplots * 3 + 1, figsize=figsize) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins * pixscale * 3600., rprof / ppbeam, label=name) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) cumul_rprof = np.nan_to_num(rprof * nr / ppbeam).cumsum() pl.figure(nplots * 3 + 2, figsize=figsize) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins * pixscale * 3600., cumul_rprof, label=name) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0, 6000, 1000) yticks_Jy = yticks_mass / masscalc.mass_conversion_factor( TK=40).value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") radii = ((bins * pixscale * u.deg) * masscalc.distance).to( u.pc, u.dimensionless_angles()) mass_40k_profile = (cumul_rprof * masscalc.mass_conversion_factor(TK=40) / u.beam).to(u.M_sun) pl.figure(nplots * 3 + 3, figsize=figsize) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(radii, mass_40k_profile, label=name) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) density_40k_profile = (mass_40k_profile / (4 / 3. * np.pi * radii**3) / (2.8 * u.Da)).to(u.cm**-3) #print(density_40k_profile) #print(radii) pl.figure(nplots * 3 + 4, figsize=figsize) #pl.title(fn.replace(".image.pbcor.fits","")) pl.semilogy(radii, density_40k_profile, label=name) pl.ylabel("Cumulative Density [n(H$_2$), $T=40$ K]") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) angular_radii = bins * pixscale * 3600. azimuthal_average_flux = rprof / ppbeam azimuthal_average_mass_40K = azimuthal_average_flux * masscalc.mass_conversion_factor( TK=40) / u.beam bindiff_as = np.diff(bins).mean() * pixscale * 3600. bindiff_cm = bindiff_as * masscalc.distance / 206265. bins_cm = (angular_radii * masscalc.distance / 206265.).to(u.cm) sqdiffbins_cm = u.Quantity([bins_cm[0].to(u.cm).value**2] + (bins_cm.to(u.cm)[1:]**2 - bins_cm.to(u.cm)[:-1]**2).value.tolist(), u.cm**2) cudiffbins_cm = u.Quantity([bins_cm[0].to(u.cm).value**3] + (bins_cm.to(u.cm)[1:]**3 - bins_cm.to(u.cm)[:-1]**3).value.tolist(), u.cm**3) sqdiffbins_pix = [bins[0]**2] + (bins[1:]**2 - bins[:-1]**2).tolist() azimuthal_average_density_40K = (azimuthal_average_mass_40K * sqdiffbins_pix / (2.8 * u.Da) / (4 / 3. * np.pi * (cudiffbins_cm))).to(u.cm**-3) pl.figure(nplots * 3 + 5, figsize=figsize) pl.semilogy(angular_radii, azimuthal_average_density_40K, label=name) pl.ylabel("Azimuthally Averaged Density\nat 40K [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") c_s_40k = ((constants.k_B * 40 * u.K / (2.4 * u.Da))**0.5).to(u.km / u.s) azimuthal_average_MJ_40k = ( np.pi / 6. * c_s_40k**3 / (constants.G**1.5 * (2.8 * u.Da * azimuthal_average_density_40K)**0.5)).to(u.M_sun) pl.figure(nplots * 3 + 6, figsize=figsize) pl.semilogy(angular_radii, azimuthal_average_MJ_40k, label=name) pl.ylabel("Azimuthally Averaged $M_J$\nat $T=40$K") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") source = 'e2' if name == 'e2e' else name temperature_map_fn = paths.dpath( '12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source)) temperature_map_fh = fits.open(temperature_map_fn) # this whole section is copied from overlay_contours_on_ch3oh ch3ohN_hdul = fits.open( paths.dpath( '12m/moments/CH3OH_{0}_cutout_columnmap.fits'.format(source))) ch3ohT_hdul = fits.open( paths.dpath( '12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format( source))) bigwcs = wcs.WCS(ch3ohT_hdul[0].header) bigpixscale = (bigwcs.pixel_scale_matrix.diagonal()** 2).sum()**0.5 * u.deg ch3ohN = ch3ohN_hdul[0].data ch3ohT = ch3ohT_hdul[0].data dust_brightness, wts = reproject.reproject_interp( fits.open(paths.dpath('W51_te_continuum_best.fits')), ch3ohN_hdul[0].header) contbm = radio_beam.Beam.from_fits_header( paths.dpath("W51_te_continuum_best.fits")) yy, xx = np.indices(ch3ohN.shape) if source == 'north': center = [84., 38.] else: center = [ch3ohN.shape[0] / 2., ch3ohN.shape[1] / 2.] yyc = (yy - center[0]) xxc = (xx - center[1]) rr = (yyc**2 + xxc**2)**0.5 rr_as = (rr * bigpixscale).to(u.arcsec) theta = np.arctan2(yyc, xxc) * u.rad dust_column = dust_emissivity.dust.colofsnu( 225 * u.GHz, dust_brightness * u.Jy / contbm, #beamomega=contbm, temperature=ch3ohT * u.K) ch3oh_abundance = ch3ohN / dust_column.value mask = (ch3oh_abundance > 1e-10) & (ch3oh_abundance < 1e-5) if source == 'e2': mask = mask & (((theta > 15 * u.deg) & (theta < 345 * u.deg)) | (theta < -15 * u.deg)) mask = mask & np.isfinite(ch3oh_abundance) # exclude high-abundance, low-column regions: likely to be div-by-zero zones mask = mask & (~((ch3ohN < 1e18) & (ch3oh_abundance > 5e-6))) mask = mask & (~((dust_brightness < 1e-2) & (ch3ohT > 500) & (ch3oh_abundance > 1e-6))) #mask = mask & (~((ch3ohT > 250) & # (ch3ohN < 1e18) & # (rr_as>1.5*u.arcsec)) # )# these are low-column, temwcs = wcs.WCS(temperature_map_fh[0].header) temcutout = Cutout2D(temperature_map_fh[0].data, position, size, wcs=temwcs) maskcutout = Cutout2D(mask.astype('float'), position, size, wcs=bigwcs) tem_nr, tem_bins, tem_rprof = azimuthalAverage( temcutout.data, weights=(maskcutout.data > 0).astype('float'), binsize=1.0, return_nr=True, interpnan=True, ) azimuthal_average_temperature = tem_rprof mass_map = (cutout.data * masscalc.mass_conversion_factor(TK=temcutout.data)).to( u.M_sun) yy, xx = np.indices(cutout.data.shape) rr_map = ((xx - cutout.data.shape[1] / 2.)**2 + (yy - cutout.data.shape[0] / 2.)**2) mass_profile = (cumul_rprof * masscalc.mass_conversion_factor(TK=tem_rprof) / u.beam).to(u.M_sun) density_profile = (mass_profile / (4 / 3. * np.pi * radii**3) / (2.8 * u.Da)).to(u.cm**-3) azimuthal_average_mass = ( azimuthal_average_flux * masscalc.mass_conversion_factor(TK=tem_rprof) / u.beam) # how accurate is this? We are measuring mass in cylindrical annuli, # but we are assuming the underlying source structure is spherical # See Cores.ipynb (in notes/, not in this repo) for a detailed # analysis... azimuthal_average_density = (azimuthal_average_mass * sqdiffbins_pix / (2.8 * u.Da) / (4 / 3. * np.pi * (cudiffbins_cm))).to( u.cm**-3) # this is not a good approximation for the spherial density profile... # see cores.ipynb. # Really should be this number +1 (so see the +1 below) # Also, negatived... density_alpha_ = 1 - ( (np.log(density_profile[1:].value) - np.log(density_profile[:-1].value)) / (np.log(angular_radii[1:]) - np.log(angular_radii[:-1]))) # from cores.ipynb, this actually gets (close to) the right answer density_alpha = -( (np.log(azimuthal_average_density[1:].value) - np.log(azimuthal_average_density[:-1].value)) / (np.log(angular_radii[1:]) - np.log(angular_radii[:-1]))) c_s = ((constants.k_B * tem_rprof * u.K / (2.4 * u.Da))**0.5).to(u.km / u.s) azimuthal_average_MJ = ( np.pi / 6. * c_s**3 / (constants.G**1.5 * (2.8 * u.Da * azimuthal_average_density)**0.5)).to(u.M_sun) cumulative_mass_weighted_temperature = ( (azimuthal_average_mass * azimuthal_average_temperature).cumsum() / mass_profile) cumulative_c_s = ((constants.k_B * cumulative_mass_weighted_temperature * u.K / (2.4 * u.Da))**0.5).to(u.km / u.s) cumulative_profile_MJ = (np.pi / 6. * cumulative_c_s**3 / (constants.G**1.5 * (2.8 * u.Da * density_profile)**0.5)).to( u.M_sun) pl.figure(nplots * 3 + 7, figsize=figsize) line, = pl.plot(angular_radii, azimuthal_average_MJ, label=name) # WRONG pl.plot(angular_radii, azimuthal_average_mass, linestyle='--', # WRONG alpha=0.75, color=line.get_color()) #pl.plot(rr_map*pixscale*3600., mass_map, 'k.', alpha=0.25) pl.axis([0, 1.2, 0.0, 5.0]) pl.ylabel( "Azimuthally Averaged $M_J$\nat $T(\\mathrm{CH}_3\\mathrm{OH})$ [$M_\\odot$]" ) pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots * 3 + 8, figsize=figsize) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins * pixscale * 3600., mass_profile, label=name) if ii == 0: pl.fill_between([0, beam.major.to(u.arcsec).value], [100, 100], [0, 0], zorder=-5, alpha=0.1, color='k') pl.ylabel("Cumulative Mass at T(CH$_3$OH) [M$_\\odot$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='upper left') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots * 3 + 9, figsize=figsize) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins * pixscale * 3600., tem_rprof, label=name) pl.legend(loc='best') pl.ylabel("CH$_3$OH temperature") pl.xlabel("Radius [as]") # Jeans length (radius = length/2) azimuthal_average_RJ = ( c_s**1 / (constants.G**0.5 * (2.8 * u.Da * azimuthal_average_density)**0.5)).to(u.au) / 2. pl.figure(nplots * 3 + 10, figsize=figsize) pl.plot(angular_radii, azimuthal_average_RJ, label=name) pl.plot([ 0, (7000 * u.au / masscalc.distance).to( u.arcsec, u.dimensionless_angles()).value ], [0, 7000], 'k--', alpha=0.5) pl.plot([ beam.major.to(u.arcsec).value, (7000 * u.au / masscalc.distance).to( u.arcsec, u.dimensionless_angles()).value ], [1000, 1000], 'k:', alpha=0.5) if ii == 0: pl.fill_between([0, beam.major.to(u.arcsec).value], [8000, 8000], zorder=-5, alpha=0.1, color='k') pl.ylabel( "Azimuthally Averaged $R_\\mathrm{J}$\nat $T(\\mathrm{CH}_3\\mathrm{OH})$ [au]" ) pl.xlabel("Radius [arcsec]") pl.ylim(0, 8000) if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots * 3 + 11, figsize=figsize) line, = pl.plot((angular_radii[1:] + angular_radii[:-1]) / 2., density_alpha) pl.plot((angular_radii[1:] + angular_radii[:-1]) / 2., density_alpha_, '--', color=line.get_color(), alpha=0.5) pl.xlabel("Radius [as]") pl.ylabel("Density Profile Exponent $\\kappa_\\rho$") pl.figure(nplots * 3 + 12, figsize=figsize) pl.semilogy(angular_radii, azimuthal_average_density, label=name) pl.ylabel("Azimuthally Averaged Density\nat T(CH$_3$OH) [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(1e6, 2e9) ax.set_xlim(0, 1.2) ax2 = ax.twiny() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 7000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") ax3 = ax.twinx() def tick_function(old_x): newx = ((constants.G * 2.8 * u.Da * (old_x * u.cm**-3))**-0.5).to(u.kyr).value return ["%.1f" % z for z in newx] new_tick_locations = [1.3, 1.5, 2, 3, 5] * u.kyr new_tick_locs_dens = ((new_tick_locations**2 * constants.G * 2.8 * u.Da)**-1).to(u.cm**-3) ax3.set_ylim(ax.get_ylim()) ax3.set_yticks(new_tick_locs_dens.value) ax3.set_yticklabels(tick_function(new_tick_locs_dens.value)) ax3.set_ylabel(r"$t_{ff}$ [kyr]") # start from 0.05 arcsec xlim = u.Quantity([0.05, ax.get_xlim()[1]], u.arcsec) xax_as = np.linspace(xlim[0], xlim[1], 100) xax_m = (xax_as * masscalc.distance).to(u.m, u.dimensionless_angles()) yax_s = ((ax.get_ylim() * u.cm**-3 * 2.8 * u.Da * constants.G)**-0.5).to(u.s) # plot 1 km/s line line_1 = (((xax_m / (7.5 * u.km / u.s))**2 * constants.G * 2.8 * u.Da)**-1).to(u.cm**-3) line_2 = (((xax_m / (5 * u.km / u.s))**2 * constants.G * 2.8 * u.Da)**-1).to(u.cm**-3) line_3 = (((xax_m / (10 * u.km / u.s))**2 * constants.G * 2.8 * u.Da)**-1).to(u.cm**-3) line, = pl.plot(xax_as.value, line_1.value, 'k:', label='7.5 km s$^{-1}$', zorder=-10) labelLine(line, 0.45, "7.5 km s$^{-1}$") line, = pl.plot(xax_as.value, line_2.value, 'k:', label='5 km s$^{-1}$', zorder=-10) labelLine(line, 0.6, "5 km s$^{-1}$") line, = pl.plot(xax_as.value, line_3.value, 'k-.', label='10 km s$^{-1}$', zorder=-10) labelLine(line, 0.7, "10 km s$^{-1}$") #ax.set_xlim(0,1.2) #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.figure(nplots * 3 + 13, figsize=figsize) pl.plot(angular_radii, cumulative_profile_MJ, label=name) pl.ylabel("$M_J(r<R)$ at T(CH$_3$OH) [$M_\odot$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii == len(names) - 1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(0, 2) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.figure(nplots * 3 + 14) line, = pl.plot(angular_radii, azimuthal_average_MJ, label=name) pl.plot(angular_radii, azimuthal_average_mass, linestyle='--', color=line.get_color()) if ii == 0: pl.fill_between([0, beam.major.to(u.arcsec).value], [100, 100], [0, 0], zorder=-5, alpha=0.1, color='k') pl.ylabel("Mass at T(CH$_3$OH) [$M_\odot$]") pl.xlabel("Radius [arcsec]") handles, labels = ax.get_legend_handles_labels() if '$\\bar{M}$' not in labels: handles.append( pl.matplotlib.lines.Line2D([], [], color='k', linestyle='--')) labels.append('$\\bar{M}$') if '$M_J$' not in labels: handles.append( pl.matplotlib.lines.Line2D([], [], color='k', linestyle='-')) labels.append('$M_J$') if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(0, 5) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x * u.arcsec * masscalc.distance).to( u.au, u.dimensionless_angles()).value return ["%i" % z for z in newx] new_tick_locations = np.arange(0, 8000, 1000) * u.au new_tick_locs_as = (new_tick_locations / masscalc.distance).to( u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 1.0, box.height]) ax2.set_position([box.x0, box.y0, box.width * 1.0, box.height]) # Put a legend to the right of the current axis ax.legend(handles, labels, loc='center left', bbox_to_anchor=(1, 0.5)) pl.figure(nplots * 3 + 15, figsize=figsize) pl.subplot(2, 2, 1) pl.semilogy(angular_radii, azimuthal_average_density, label=name) pl.ylabel("Azimuthally Averaged Density\nat T(CH$_3$OH) [cm$^{-3}$]") pl.subplot(2, 2, 3) pl.semilogy(angular_radii, density_profile, label=name) pl.ylabel("Cumulative Average Density\nat T(CH$_3$OH) [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") pl.subplot(2, 2, 2) pl.plot(azimuthal_average_density, density_profile, label=name) pl.plot(sorted(azimuthal_average_density.value), sorted(azimuthal_average_density.value), 'k--') pl.xlabel("Azimuthally Averaged Density\nat T(CH$_3$OH) [cm$^{-3}$]") pl.ylabel("Cumulative Average Density\nat T(CH$_3$OH) [cm$^{-3}$]") pl.subplot(2, 2, 4) pl.ylabel("Azimuthal / Cumulative") pl.plot(angular_radii, azimuthal_average_density / density_profile, label=name) #pl.plot(angular_radii, [1.0] * len(angular_radii), 'k--') pl.xlabel("Radius [arcsec]") return locals()
def make_rprof(regions, ploteach=False): names = [r.attr[1]['text'] for r in regions] center_positions = coordinates.SkyCoord([r.coord_list for r in regions], unit=(u.deg, u.deg), frame='fk5') size = u.Quantity([1.25,1.25], u.arcsec) if ploteach: nplots = len(names) for ii in range(nplots): pl.figure(ii).clf() pl.figure(nplots+ii).clf() pl.figure(nplots*2+ii).clf() linestyles = {name: itertools.cycle(['-'] + ['--'] + [':'] + ['-.']) for name in names} for fn in ffiles: fh = fits.open(paths.dpath("12m/continuum/"+fn)) mywcs = wcs.WCS(fh[0].header) if 'BMAJ' not in fh[0].header: #print("File {0} does not have BMAJ".format(fn)) continue try: beam = radio_beam.Beam.from_fits_header(fh[0].header) except KeyError: #print("File {0} doesn't have beam info in the header".format(fn)) continue pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr/(pixscale**2*u.deg**2)).decompose().value / u.beam #print("fn {0} ppbeam={1:0.2f}".format(fn, ppbeam)) for ii,(name,position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = azimuthalAverage(cutout.data, binsize=1.0, return_nr=True) linestyle = next(linestyles[name]) pl.figure(ii) pl.title(name) pl.plot(bins*pixscale*3600., rprof/ppbeam, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius [arcsec]") cumul_rprof = np.nan_to_num(rprof*nr/ppbeam).cumsum() pl.figure(nplots+ii) pl.title(name) pl.plot(bins*pixscale*3600., cumul_rprof, label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius [arcsec]") if ii == 0: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.pc, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = [0.005,0.01,0.015,0.02,0.025]*u.pc new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius (pc)") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0,6000,1000) yticks_Jy = yticks_mass/masscalc.mass_conversion_factor().value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.figure(nplots*2+ii) pl.title(name) pl.plot(((bins*pixscale*u.deg)*masscalc.distance).to(u.pc, u.dimensionless_angles()), cumul_rprof * masscalc.mass_conversion_factor(), label=fn.split(".")[0], linestyle=linestyle) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=20$ K)") pl.xlabel("Radius (pc)") for ii in range(nplots): for xtra in (0,nplots*2): ax = pl.figure(ii+xtra).gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) else: nplots = 0 pl.matplotlib.rc_file('pubfiguresrc') for jj in range(nplots*3+1, nplots*3+11): pl.figure(jj).clf() # $ find ~/work/w51/alma/FITS/ -samefile ~/work/w51/alma/FITS/W51_te_continuum_best.fits # /Users/adam/work/w51/alma/FITS//12m/continuum/selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits # /Users/adam/work/w51/alma/FITS//W51_te_continuum_best.fits fn = "selfcal_allspw_selfcal_3_mfs_deeper.image.pbcor.fits" fh = fits.open(paths.dpath("12m/continuum/"+fn)) mywcs = wcs.WCS(fh[0].header) beam = radio_beam.Beam.from_fits_header(fh[0].header) pixscale = (mywcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 ppbeam = (beam.sr/(pixscale**2*u.deg**2)).decompose().value / u.beam for ii,(name,position) in enumerate(zip(names, center_positions)): cutout = Cutout2D(fh[0].data, position, size, wcs=mywcs) nr, bins, rprof = azimuthalAverage(cutout.data, binsize=1.0, return_nr=True) pl.figure(nplots*3+1) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., rprof/ppbeam, label=name) pl.ylabel("Azimuthally Averaged Flux (Jy)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) cumul_rprof = np.nan_to_num(rprof*nr/ppbeam).cumsum() pl.figure(nplots*3+2) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., cumul_rprof, label=name) pl.ylabel("Cumulative Flux (Jy)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") ax3.set_ylim(ax.get_ylim()) yticks_mass = np.arange(0,6000,1000) yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value ax3.set_yticks(yticks_Jy) ax3.set_yticklabels(yticks_mass) ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") radii = ((bins*pixscale*u.deg)*masscalc.distance).to(u.pc, u.dimensionless_angles()) mass_40k_profile = (cumul_rprof * masscalc.mass_conversion_factor(TK=40) / u.beam).to(u.M_sun) pl.figure(nplots*3+3) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(radii, mass_40k_profile, label=name) pl.ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) density_40k_profile = (mass_40k_profile / (4/3.*np.pi*radii**3) / (2.8*u.Da)).to(u.cm**-3) #print(density_40k_profile) #print(radii) pl.figure(nplots*3+4) #pl.title(fn.replace(".image.pbcor.fits","")) pl.semilogy(radii, density_40k_profile, label=name) pl.ylabel("Cumulative Density [n(H$_2$), $T=40$ K]") pl.xlabel("Radius (pc)") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) angular_radii = bins*pixscale*3600. azimuthal_average_flux = rprof/ppbeam azimuthal_average_mass = azimuthal_average_flux * masscalc.mass_conversion_factor(TK=40) / u.beam bindiff_as = np.diff(bins).mean() * pixscale * 3600. bindiff_cm = bindiff_as * masscalc.distance / 206265. bins_cm = (angular_radii * masscalc.distance / 206265.).to(u.cm) sqdiffbins_cm = u.Quantity([bins_cm[0].to(u.cm).value**2] + (bins_cm.to(u.cm)[1:]**2 - bins_cm.to(u.cm)[:-1]**2).value.tolist(), u.cm**2) cudiffbins_cm = u.Quantity([bins_cm[0].to(u.cm).value**3] + (bins_cm.to(u.cm)[1:]**3 - bins_cm.to(u.cm)[:-1]**3).value.tolist(), u.cm**3) sqdiffbins_pix = [bins[0]**2] + (bins[1:]**2 - bins[:-1]**2).tolist() azimuthal_average_density = (azimuthal_average_mass * sqdiffbins_pix / (2.8*u.Da) / (4/3.*np.pi*(cudiffbins_cm))).to(u.cm**-3) pl.figure(nplots*3+5) pl.semilogy(angular_radii, azimuthal_average_density, label=name) pl.ylabel("Azimuthally Averaged Density [cm$^{-3}$]") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") #ax3.set_ylim(ax.get_ylim()) #yticks_mass = np.arange(0,6000,1000) #yticks_Jy = yticks_mass/masscalc.mass_conversion_factor(TK=40).value #ax3.set_yticks(yticks_Jy) #ax3.set_yticklabels(yticks_mass) #ax3.set_ylabel("Cumulative Mass (M$_\\odot$, $T=40$ K)") c_s_40k = ((constants.k_B * 40*u.K / (2.4*u.Da))**0.5).to(u.km/u.s) azimuthal_average_MJ_40k = (np.pi/6. * c_s_40k**3 / (constants.G**1.5 * (2.8*u.Da*azimuthal_average_density)**0.5)).to(u.M_sun) pl.figure(nplots*3+6) pl.semilogy(angular_radii, azimuthal_average_MJ_40k, label=name) pl.ylabel("Azimuthally Averaged $M_J$ at $T=40$K") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") source = 'e2' if name == 'e2e' else name temperature_map_fn = paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source)) temperature_map_fh = fits.open(temperature_map_fn) # this whole section is copied from overlay_contours_on_ch3oh ch3ohN_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_columnmap.fits'.format(source))) ch3ohT_hdul = fits.open(paths.dpath('12m/moments/CH3OH_{0}_cutout_temperaturemap.fits'.format(source))) bigwcs = wcs.WCS(ch3ohT_hdul[0].header) bigpixscale = (bigwcs.pixel_scale_matrix.diagonal()**2).sum()**0.5 * u.deg ch3ohN = ch3ohN_hdul[0].data ch3ohT = ch3ohT_hdul[0].data dust_brightness,wts = reproject.reproject_interp(fits.open(paths.dpath('W51_te_continuum_best.fits')), ch3ohN_hdul[0].header) bm = radio_beam.Beam.from_fits_header(paths.dpath("W51_te_continuum_best.fits")) yy,xx = np.indices(ch3ohN.shape) if source == 'north': center = [84.,38.] else: center = [ch3ohN.shape[0]/2., ch3ohN.shape[1]/2.] yyc = (yy-center[0]) xxc = (xx-center[1]) rr = (yyc**2 + xxc**2)**0.5 rr_as = (rr*bigpixscale).to(u.arcsec) theta = np.arctan2(yyc,xxc)*u.rad dust_column = dust_emissivity.dust.colofsnu(225*u.GHz, dust_brightness*u.Jy, beamomega=bm, temperature=ch3ohT*u.K) ch3oh_abundance = ch3ohN / dust_column.value mask = (ch3oh_abundance > 1e-10) & (ch3oh_abundance < 1e-5) if source == 'e2': mask = mask & (((theta > 15*u.deg) & (theta < 345*u.deg)) | (theta < -15*u.deg)) mask = mask & np.isfinite(ch3oh_abundance) # exclude high-abundance, low-column regions: likely to be div-by-zero zones mask = mask & (~((ch3ohN < 1e18) & (ch3oh_abundance > 5e-6))) mask = mask & (~((dust_brightness<1e-2) & (ch3ohT > 500) & (ch3oh_abundance > 1e-6))) #mask = mask & (~((ch3ohT > 250) & # (ch3ohN < 1e18) & # (rr_as>1.5*u.arcsec)) # )# these are low-column, temwcs = wcs.WCS(temperature_map_fh[0].header) temcutout = Cutout2D(temperature_map_fh[0].data, position, size, wcs=temwcs) maskcutout = Cutout2D(mask.astype('float'), position, size, wcs=bigwcs) tem_nr, tem_bins, tem_rprof = azimuthalAverage(temcutout.data, weights=(maskcutout.data>0).astype('float'), binsize=1.0, return_nr=True, interpnan=True, ) mass_profile = (cumul_rprof * masscalc.mass_conversion_factor(TK=tem_rprof) / u.beam).to(u.M_sun) density_profile = (mass_profile / (4/3.*np.pi*radii**3) / (2.8*u.Da)).to(u.cm**-3) density_alpha = ((np.log(density_profile[1:].value) - np.log(density_profile[:-1].value)) / (np.log(angular_radii[1:]) - np.log(angular_radii[:-1])) ) c_s = ((constants.k_B * tem_rprof*u.K / (2.4*u.Da))**0.5).to(u.km/u.s) azimuthal_average_MJ = (np.pi/6. * c_s**3 / (constants.G**1.5 * (2.8*u.Da*azimuthal_average_density)**0.5) ).to(u.M_sun) pl.figure(nplots*3+7) pl.plot(angular_radii, azimuthal_average_MJ, label=name) pl.ylabel("Azimuthally Averaged $M_J$ at $T(\\mathrm{CH}_3\\mathrm{OH})$") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots*3+8) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., mass_profile, label=name) pl.ylabel("Cumulative Mass at T(CH$_3$OH)") pl.xlabel("Radius [arcsec]") if len(names) < 5: pl.legend(loc='upper left') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() ax2 = ax.twiny() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots*3+9) #pl.title(fn.replace(".image.pbcor.fits","")) pl.plot(bins*pixscale*3600., tem_rprof, label=name) pl.legend(loc='best') pl.ylabel("CH$_3$OH temperature") pl.xlabel("Radius [as]") azimuthal_average_RJ = (c_s**1 / (constants.G**0.5 * (2.8*u.Da*azimuthal_average_density)**0.5) ).to(u.au) pl.figure(nplots*3+10) pl.plot(angular_radii, azimuthal_average_RJ, label=name) pl.plot([0,(7000*u.au/masscalc.distance).to(u.arcsec, u.dimensionless_angles()).value], [0,7000], 'k--', alpha=0.5) pl.ylabel("Azimuthally Averaged $R_J$ at $T(\\mathrm{CH}_3\\mathrm{OH})$ [au]") pl.xlabel("Radius [arcsec]") pl.ylim(0,3000) if len(names) < 5: pl.legend(loc='best') elif ii==len(names)-1: ax = pl.gca() box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.6, box.height]) # Put a legend to the right of the current axis ax.legend(loc='center left', bbox_to_anchor=(1, 0.5)) if ii == len(names) - 1: ax = pl.gca() #ax.set_ylim(1e7, 5e10) ax2 = ax.twiny() #ax3 = ax.twinx() def tick_function(old_x): newx = (old_x*u.arcsec*masscalc.distance).to(u.au, u.dimensionless_angles()).value return ["%.1f" % z for z in newx] new_tick_locations = np.arange(0,8000,1000)*u.au new_tick_locs_as = (new_tick_locations/masscalc.distance).to(u.arcsec, u.dimensionless_angles()) ax2.set_xlim(ax.get_xlim()) ax2.set_xticks(new_tick_locs_as.value) ax2.set_xticklabels(tick_function(new_tick_locs_as.value)) ax2.set_xlabel(r"Radius [au]") pl.figure(nplots*3+11) pl.plot((angular_radii[1:]+angular_radii[:-1])/2., density_alpha) pl.xlabel("Radius [as]") pl.ylabel("Density Profile Exponent $\\kappa_\\rho$")
shreg = pyregion.ShapeList([reg]) name = reg.attr[1]['text'] log.info(name) mask = shreg.get_mask(hdu=contfile[0]) data = contfile[0].data results[name] = {'peak': data[mask].max(), 'sum': data[mask].sum(), 'npix': mask.sum(), 'beam_area': beam.sr, 'RA': reg.coord_list[0], 'Dec': reg.coord_list[1], } results[name]['peak_mass'] = masscalc.mass_conversion_factor()*results[name]['peak'] results[name]['peak_col'] = masscalc.col_conversion_factor(beamomega=beam.sr.value)*results[name]['peak'] for image, imname in ((contfile,''), (radio_image,'KUband')): data = image[0].data.squeeze() mywcs = wcs.WCS(image[0].header).celestial beam = radio_beam.Beam.from_fits_header(image[0].header) pixel_scale = np.abs(mywcs.pixel_scale_matrix.diagonal().prod())**0.5 * u.deg pixel_scale_as = pixel_scale.to(u.arcsec).value ppbeam = (beam.sr/(pixel_scale**2)).decompose().value keys = ['{1}cont_flux{0}arcsec'.format(rr.value, imname) for rr in radii] for k in keys: results[name][k] = []
'Dec': u.deg, } results = photometry(data, mywcs, regs, beam) fn_90GHz = paths.tmpath('SgrB2_nocal_TE_continuum_90GHz.image.pbcor.fits') results_90GHz = photometry(fits.getdata(fn_90GHz), wcs.WCS(fits.getheader(fn_90GHz)), regs, radio_beam.Beam.from_fits_header(fits.getheader(fn_90GHz))) fn_100GHz = paths.tmpath('SgrB2_nocal_TE_continuum_100GHz.image.pbcor.fits') results_100GHz = photometry(fits.getdata(fn_100GHz), wcs.WCS(fits.getheader(fn_100GHz)), regs, radio_beam.Beam.from_fits_header(fits.getheader(fn_100GHz))) for name in results: results[name]['peak_mass_20K'] = masscalc.mass_conversion_factor()*results[name]['peak'] results[name]['peak_col_20K'] = masscalc.col_conversion_factor(results[name]['peak']*u.Jy, beam.sr) results[name]['peak_90GHz'] = results_90GHz[name]['peak'] results[name]['peak_100GHz'] = results_100GHz[name]['peak'] results[name]['sum_90GHz'] = results_90GHz[name]['sum'] results[name]['sum_100GHz'] = results_100GHz[name]['sum'] results[name]['bgmad_90GHz'] = results_90GHz[name]['bgmad'] results[name]['bgmad_100GHz'] = results_100GHz[name]['bgmad'] # invert the table to make it parseable by astropy... # (this shouldn't be necessary....) results_inv = {'name':{}} columns = {'name':[]} for k,v in results.items(): results_inv['name'][k] = k columns['name'].append(k)
brightest_line_flux = np.array([cores_merge[y].data for y in ('peak0','peak1','peak2','peak3')]) peak_line_flux = np.nanmax(brightest_line_flux, axis=0) peak_line_id = np.nanargmax(brightest_line_flux, axis=0) brightest_line_name = np.array([cores_merge[('peak0species','peak1species','peak2species','peak3species')[y]][ii] for ii,y in enumerate(peak_line_id)]) cores_merge.add_column(Column(peak_line_flux, name='PeakLineFlux', unit=cores_merge['peak0'].unit)) cores_merge.add_column(Column(brightest_line_name, name='PeakLineSpecies')) peak_line_brightness = (peak_line_flux*u.Jy).to(u.K, u.brightness_temperature(cores_merge['beam_area'], 220*u.GHz)) cores_merge.add_column(Column(peak_line_brightness, name='PeakLineBrightness')) jtok_eq = u.brightness_temperature(cores_merge['beam_area'], 225*u.GHz) cont_brightness = Column((u.beam * cores_merge['sum']/cores_merge['npix']).to(u.K, jtok_eq), name='MeanContinuumBrightness') cores_merge.add_column(cont_brightness) aperturemass20k = cores_merge['sum'] / ppbeam * masscalc.mass_conversion_factor(20) cores_merge.add_column(Column(aperturemass20k.value, name='ApertureMass20K', unit=u.M_sun)) temperature_corrected_mass = Column([(masscalc.mass_conversion_factor(20).value if np.isnan(row['PeakLineBrightness']) else masscalc.mass_conversion_factor(row['PeakLineBrightness'])).value * row['peak'] for row in cores_merge], name='T_corrected_peakmass', unit=u.M_sun) cores_merge.add_column(temperature_corrected_mass) cores_merge = cores_merge['SourceID', 'peak_mass', 'ApertureMass20K', 'T_corrected_peakmass', 'PeakLineBrightness',
cores_merge.add_column( Column(brightest_fitted_brightness, 'BrightestFittedApMeanBrightness', unit=u.K)) # need to add back in continuum because we're concerned with the *absolute* # brightness # moved to other merge jtok_eq = u.brightness_temperature(cores_merge['beam_area'], 225*u.GHz) # moved to other merge cont_brightness = (u.beam * cores_merge['sum']/cores_merge['npix']).to(u.K, jtok_eq) cont_brightness = cores_merge['MeanContinuumBrightness'] contincluded_line_brightness = cores_merge[ 'BrightestFittedApMeanBrightness'] + cont_brightness cores_merge.add_column( Column(contincluded_line_brightness, 'BrightestFittedApMeanBrightnessWithcont', unit=u.K)) temperature_corrected_aperturemass = Column( [(masscalc.mass_conversion_factor(20).value if np.isnan(row['BrightestFittedApMeanBrightnessWithcont']) else masscalc.mass_conversion_factor( row['BrightestFittedApMeanBrightnessWithcont']).value) * row['sum'] / ppbeam for row in cores_merge], name='T_corrected_aperturemass', unit=u.M_sun) cores_merge.add_column(temperature_corrected_aperturemass) cores_merge.write(paths.tpath('core_continuum_and_line.ipac'), format='ascii.ipac', overwrite=True)
dendro_merge['peak{0}freq'.format(pid)][ii] if pid >= 0 else 1.0 for ii, pid in enumerate(peak_line_id) ], u.GHz) peak_line_cont = u.Quantity([ dendro_merge['continuum20pct{0}'.format(pid)][ii] if pid >= 0 else 0.0 for ii, pid in enumerate(peak_line_id) ], u.Jy) tbequiv = u.brightness_temperature(peak_line_beam_area, peak_line_freq) peak_line_brightness = (peak_line_flux * u.Jy).to(u.K, tbequiv) dendro_merge.add_column(Column(peak_line_brightness, name='PeakLineBrightness')) continuum20pct_K = (peak_line_cont.to(u.K, tbequiv)) dendro_merge.add_column(Column(continuum20pct_K, name='PeakLineContinuumBG')) tcm = Column( [(masscalc.mass_conversion_factor(20).to(u.M_sun).value if np.isnan( row['PeakLineBrightness']) else masscalc.mass_conversion_factor( TK=row['PeakLineBrightness']).to(u.M_sun).value) * row['peak_cont_flux'] for row in dendro_merge], name='T_corrected_mass', unit=u.M_sun) temperature_corrected_mass = tcm dendro_merge.add_column(temperature_corrected_mass) columns = [ 'SourceID', 'peak_cont_mass', 'T_corrected_mass', 'PeakLineBrightness', 'PeakLineFlux', 'PeakLineSpecies',
fits.getdata(fn_90GHz), wcs.WCS(fits.getheader(fn_90GHz)), regs, radio_beam.Beam.from_fits_header(fits.getheader(fn_90GHz))) #fn_100GHz = paths.tmpath('SgrB2_nocal_TE_continuum_100GHz.image.pbcor.fits') fn_100GHz = paths.mergepath( 'continuum/SgrB2_selfcal_full_TETC7m_selfcal5_ampphase_continuum_100GHz.image.pbcor.fits' ) results_100GHz = photometry( fits.getdata(fn_100GHz), wcs.WCS(fits.getheader(fn_100GHz)), regs, radio_beam.Beam.from_fits_header(fits.getheader(fn_100GHz))) for name in results: results[name]['peak_col_20K'] = masscalc.col_conversion_factor( results[name]['peak'] * u.Jy, beam.sr) results[name]['peak_mass_20K'] = np.nan * u.g if np.isnan( results[name]['peak_col_20K'] ) else masscalc.mass_conversion_factor() * results[name]['peak'] results[name]['peak_col_40K'] = masscalc.col_conversion_factor( results[name]['peak'] * u.Jy, beam.sr, TK=40 * u.K) results[name]['peak_mass_40K'] = ( np.nan * u.g if np.isnan(results[name]['peak_col_40K']) else masscalc.mass_conversion_factor(TK=40 * u.K) * results[name]['peak']) results[name]['peak_90GHz'] = results_90GHz[name]['peak'] results[name]['peak_100GHz'] = results_100GHz[name]['peak'] results[name]['sum_90GHz'] = results_90GHz[name]['sum'] results[name]['sum_100GHz'] = results_100GHz[name]['sum'] results[name]['bgmad_90GHz'] = results_90GHz[name]['bgmad'] results[name]['bgmad_100GHz'] = results_100GHz[name]['bgmad'] # invert the table to make it parseable by astropy... # (this shouldn't be necessary....)
pixel_scale = np.abs(mywcs.pixel_scale_matrix.diagonal().prod())**0.5 * u.deg pixel_scale_as = pixel_scale.to(u.arcsec).value ppbeam = (beam.sr/(pixel_scale**2)).decompose().value / u.beam #pl.hist(data[np.isfinite(data)], bins=np.linspace(1e-4,0.1,100)) # over what threshold are we including flux when measuring total masses? threshold = 10*u.mJy/u.beam # threshold above which 20 K is very thick thick_threshold = (20*u.K).to(u.mJy, u.brightness_temperature(beam, masscalc.centerfreq)) / u.beam threshold_column = (threshold * u.beam/u.Jy * masscalc.col_conversion_factor(beam)).to(u.cm**-2) threshold_column = masscalc.dust.colofsnu(nu=masscalc.centerfreq, snu=threshold*u.beam, beamomega=beam.sr).to(u.cm**-2, u.dimensionless_angles()) threshold_density = (masscalc.mass_conversion_factor(20) * (threshold*u.beam).to(u.mJy).value / (4/3.*np.pi) / (beam.sr.value*masscalc.distance**2)**(1.5) / (2.8*constants.m_p)).to(1/u.cm**3) definitely_signal = data > threshold definitely_thick_if_20K = data > thick_threshold total_signal = data[definitely_signal].sum() / ppbeam print("Total pixels > 10mJy/beam: {0} = {1}; r_eff = {2}" .format(definitely_signal.sum(), definitely_signal.sum()/ppbeam, ((definitely_signal.sum()*(pixel_scale*masscalc.distance)**2)**0.5).to(u.pc, u.dimensionless_angles()))) print("Total pixels > {3}: {0} = {1}; r_eff = {2}, fraction={4}, fraction of signal: {5}" .format(definitely_thick_if_20K.sum(), definitely_thick_if_20K.sum()/ppbeam, ((definitely_thick_if_20K.sum() * (pixel_scale*masscalc.distance)**2)**0.5).to(u.pc, u.dimensionless_angles()),
integ_north_lores = (cutout_north_lores[cutout_north_lores > 3 * u.mJy / u.beam]).sum() * u.beam / ppbeam_lores print( "Integrated intensity of e2: {0:0.2f} / {1:0.2f} -> {2:0.1f}% recovered" .format(integ_e2, integ_e2_lores, integ_e2 / integ_e2_lores * 100)) print( "Integrated intensity of e8: {0:0.2f} / {1:0.2f} -> {2:0.1f}% recovered" .format(integ_e8, integ_e8_lores, integ_e8 / integ_e8_lores * 100)) print( "Integrated intensity of north: {0:0.2f} / {1:0.2f} -> {2:0.1f}% recovered" .format(integ_north, integ_north_lores, integ_north / integ_north_lores * 100)) print() integmass_e2 = integ_e2 * masscalc.mass_conversion_factor(e2etbpeak) / u.Jy integmass_e8 = integ_e8 * masscalc.mass_conversion_factor(e8tbpeak) / u.Jy integmass_north = integ_north * masscalc.mass_conversion_factor( northtbpeak) / u.Jy print("Integrated mass of e2: {0}".format(integmass_e2)) print("Integrated mass of e8: {0}".format(integmass_e8)) print("Integrated mass of north: {0}".format(integmass_north)) print() integmass_e2 = integ_e2 * masscalc.mass_conversion_factor(200 * u.K) / u.Jy integmass_e8 = integ_e8 * masscalc.mass_conversion_factor(200 * u.K) / u.Jy integmass_north = integ_north * masscalc.mass_conversion_factor( 200 * u.K) / u.Jy print("Integrated mass of e2 at T=200K: {0}".format(integmass_e2))