def load_dendro(filename): """ Load a dendrogram saved by the astrodendro package :param file: Path to a dendrogram file :returns: A list of 2 glue Data objects: the original dataset, and dendrogram. """ label = data_label(filename) dg = Dendrogram.load_from(filename) structs = np.arange(len(dg)) parent = np.array([ dg[i].parent.idx if dg[i].parent is not None else -1 for i in structs ]) height = np.array([dg[i].height for i in structs]) pk = np.array([dg[i].get_peak(True)[1] for i in structs]) dendro = Data(parent=parent, height=height, peak=pk, label="{} [dendrogram]".format(label)) im = Data(intensity=dg.data, structure=dg.index_map, label="{} [data]".format(label)) im.join_on_key(dendro, 'structure', dendro.pixel_component_ids[0]) return [dendro, im]
def __init__(self, CO12FITS, dendroFITS, regionName): self.CO12FITS = CO12FITS self.dendroFITS = dendroFITS #read fits imediately hdu = fits.open(self.CO12FITS)[0] self.CO12Data = hdu.data self.CO12Head = hdu.header self.regionName = regionName self.catWithLevelTB = regionName + self.catWithLevelTB self.dendroCat = self.regionName + "_DendroCat.fit" self.maskPath = self.regionName + "Mask/" os.system("mkdir " + self.maskPath) self.pvPath = "./pvPath/" + self.regionName + "PVFITS/" os.system("mkdir " + self.pvPath) print "Loading dendrodata..." self.dendroData = Dendrogram.load_from(self.dendroFITS)
def explore_dendro(label='scimes', xaxis='radius', yaxis='v_rms'): d = Dendrogram.load_from(label + '_dendrogram.hdf5') cat = Table.read(label + '_full_catalog.txt', format='ascii.ecsv') dv = d.viewer() ds = Scatter(d, dv.hub, cat, xaxis, yaxis) ds.set_loglog() dv.show() return
def doScimes(self,dendroFITS,hd ): self.metadata["wcs"]= WCS(hd) d = Dendrogram.load_from( dendroFITS ) cat = ppv_catalog(d, self.metadata) res = SpectralCloudstering(d, cat, hd, criteria = ['volume' ], blind = True, rms = self.rms, s2nlim = 3, save_all = True, user_iter=1) res.clusters_asgn.writeto (self.regionName+'Cluster_asgn.fits', overwrite=True)
def get_dendrogram(self, max_pos): # if the dendrogram file doesn't exist if not os.path.isfile('dendrogram.fits'): dendro = Dendrogram.compute(self.vol_data, min_value=1.0, min_delta=1, min_npix=10, verbose=True) dendro.save_to('dendrogram.fits') dendro = Dendrogram.load_from('dendrogram.fits') substructure = dendro.structure_at(max_pos) # max_pos should be (z, y, x) dendro_mask = substructure.get_mask(shape=self.vol_data.shape) return dendro_mask
def get_dendrogram(self, max_pos): # if the dendrogram file doesn't exist if not os.path.isfile('dendrogram.fits'): dendro = Dendrogram.compute(self.vol_data, min_value=1.0, min_delta=1, min_npix=10, verbose=True) dendro.save_to('dendrogram.fits') dendro = Dendrogram.load_from('dendrogram.fits') substructure = dendro.structure_at( max_pos) # max_pos should be (z, y, x) dendro_mask = substructure.get_mask(shape=self.vol_data.shape) return dendro_mask
def get_catalog(cogal): from astrodendro import Dendrogram from astrodendro import ppv_catalog co = cogal[0] gal = cogal[1] # get data and info file = data[co][gal]['noise matched']['file'] cube = fits.open(file)[0] noise = data[co][gal]['noise matched']['rms'].to(u.K) bmin = cube.header['bmin'] * u.degree bmaj = cube.header['bmaj'] * u.degree beam_area = 1.13309 * bmin * bmaj pix1 = u.Quantity( str(np.abs(cube.header['cdelt1'])) + cube.header['cunit1']) pix2 = u.Quantity( str(np.abs(cube.header['cdelt2'])) + cube.header['cunit2']) pix3 = u.Quantity( str(np.abs(cube.header['cdelt3'])) + cube.header['cunit3']) pix_beam = (beam_area / pix1 / pix2) d = Dendrogram.load_from(join(compdir, gal + '.' + co + '.dendrogram.fits')) # time execution print("\nComputing catalog: " + co + " " + gal + "\n") start = time.time() # calculate catalog metadata = { 'data_unit': u.K, 'spatial_scale': parsec_to_angle(pix1, source=gal), 'velocity_scale': pix3, 'beam_major': bmaj, 'beam_minor': bmin, 'vaxis': 0, 'wavelength': lines[co]['restfreq'], 'wcs': WCS(cube.header) } catalog = ppv_catalog(d, metadata) fnpickle(catalog, join(compdir, gal + '.' + co + '.catalog.pickle')) # time execution stop = time.time() exec_time = np.round(stop - start, 1) print("\nFinished catalog: " + co + " " + gal + "\nExecution took " + str(datetime.timedelta(seconds=exec_time)) + "hours for " + str(len(catalog)) + " structures.\n")
def main(args): #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_dend + '.hdf5') print('') plot_image(args.file_map,args.file_velo,file_out=args.file_out,file_reg=args.file_reg,file_contour=args.file_contour,\ plot=args.plot,save=args.save,oformat=args.format,resize=args.resize,\ contour=args.contour,contour_color=args.contour_color,\ levels=args.levels,skycoor=args.skycoor,beam=args.beam,\ vmin=args.vmin,vmax=args.vmax,pmin=args.pmin,pmax=args.pmax,\ stretch=args.stretch,\ dendro=d,file_sour=args.file_sour) return 0
def test_save_dendrogram_catalog_output(): # 1. construct a silly dendrogram, catalog, header, and metadata data = np.zeros((3, 3, 3)) data[1, 1, 1] = 1 d = Dendrogram.compute(data, min_value=0) catalog = Table() catalog['test_column'] = np.zeros(10) header = Header.fromstring( "SIMPLE = T / conforms to FITS standard BITPIX = 64 / array data type NAXIS = 3 / number of array dimensions NAXIS1 = 6 NAXIS2 = 5 NAXIS3 = 4 CTYPE1 = 'VELO-LSR' CTYPE2 = 'GLON-CAR' CTYPE3 = 'GLAT-CAR' CRVAL1 = '' CRVAL2 = '' CRVAL3 = '' CDELT1 = '' CDELT2 = '' CDELT3 = '' CRPIX1 = '' CRPIX2 = '' CRPIX3 = '' END " ) metadata = {} metadata['data_unit'] = u.K # 2. run save_dendrogram_catalog_output on them - to some safe location kwargs = { 'data_filename': 'not_real_data_savetest.fits', 'min_value': 1, 'min_delta': 2, 'min_npix': 3, 'savepath': filepath } save_dendrogram_catalog_output(d, catalog, header, metadata, **kwargs) # 3. reload those things filename_base = filepath + "not_real_data_savetest.fits_1.000_2.000_3" d2 = Dendrogram.load_from(filename_base + "_d.hdf5") catalog2 = Table.read(filename_base + "_catalog.fits") header2 = getheader(filename_base + "_header.fits") metadata2 = pickle.load(open(filename_base + "_metadata.p", 'rb')) #4 and assert they equal the mock things. assert_equal(d2.index_map, d.index_map) assert_array_equal(catalog2, catalog) assert_equal(header2, header) assert_equal(metadata2, metadata) #5 then delete the saved objects. os.remove(filename_base + "_d.hdf5") os.remove(filename_base + "_catalog.fits") os.remove(filename_base + "_header.fits") os.remove(filename_base + "_metadata.p")
def colorcode(label='scimes', table='full_catalog', cubefile=None, mom0file=None, types=['v_cen', 'v_rms', 'tmax', 'imean'], outdir='plots', vmin=None, vmax=None, **kwargs): # Header info hdu3 = fits.open(cubefile)[0] hd3 = hdu3.header # Moment image hdu2 = fits.open(mom0file)[0] img = hdu2.data # Load the dendrogram d = Dendrogram.load_from(label + '_dendrogram.hdf5') print('\n') cat = Table.read(label + '_' + table + '.txt', format='ascii.ecsv') # Plot colored ellipses on maps for set in ['leaves', 'trunks', 'clusters']: idc = [] with open(label + '_' + set + '.txt', 'r') as f: reader = csv.reader(f, delimiter=' ') for row in reader: idc.append(int(row[0])) subcat = cat[idc] props_colmap(dendrogram=d, subcat=subcat, img=img, cubhd=hd3, props=types, prefix=outdir + '/' + label + '_' + set, vmin=vmin, vmax=vmax, **kwargs) # Plot colored dendrogram props_coltree(label=label, dendrogram=d, cat=cat, cubhd=hd3, props=types, prefix=outdir + '/' + label, vmin=vmin, vmax=vmax) return
def main(args): #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_d + '.hdf5') plot_image(args.file_map,args.file_out,file_reg=args.file_reg,file_contour=args.file_contour,\ plot=args.plot,oformat=args.format,resize=args.resize,\ contour=args.contour,contour_color=args.contour_color,\ levels=args.levels,skycoor=args.skycoor,beam=args.beam,beamcolor=args.beamcolor,\ vmin=args.vmin,vmax=args.vmax,pmin=args.pmin,pmax=args.pmax,smooth=args.smooth,\ stretch=args.stretch,cmap=args.cmap,colorbar=args.colorbar,\ dendro=d,file_catalog=args.file_catalog) return 0
def load_dendrogram(hdf5_file, min_deltas=None): ''' Load in a previously saved dendrogram. **Requires pyHDF5** Parameters ---------- hdf5_file : str Name of saved file. min_deltas : numpy.ndarray or list Minimum deltas of leaves in the dendrogram. ''' dendro = Dendrogram.load_from(hdf5_file) self = Dendrogram_Stats(dendro.data, min_deltas=min_deltas, dendro_params=dendro.params) return self
def main(args): if not os.path.isfile(args.file_fits): print("FITS File not found") return 0 if not os.path.isfile(args.file_dend): print("Dend File not found") return 0 #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') dendro = Dendrogram.load_from(args.file_dend) print('') #------------------------ # Load vlsr image #------------------------ f_base = os.path.splitext(args.file_fits)[0] f_mask = f_base + '_mask.fits' with fits.open(args.file_fits, mode='readonly') as hdul: hdr = hdul[0].header data = np.copy(np.squeeze(hdul[0].data)) count_branch = 0 for i, struc in enumerate(dendro.trunk): if struc.is_branch: # branch mask = struc.get_mask().mean(axis=0) d_ma = mask_data(mask, data, mode='outside') count_branch = count_branch + 1 subtree = struc.descendants for j, sub_struc in enumerate(subtree): if sub_struc.is_leaf: mask = sub_struc.get_mask().mean(axis=0) d_ma = mask_data(mask, d_ma, mode='inside') break fits.writeto(f_mask, d_ma, hdr, overwrite=True) return 0
def load_dendro(file): """ Load a dendrogram saved by the astrodendro package :param file: Path to a dendrogram file :returns: A list of 2 glue Data objects: the original dataset, and dendrogram. """ dg = Dendrogram.load_from(file) structs = np.arange(len(dg)) parent = np.array([dg[i].parent.idx if dg[i].parent is not None else -1 for i in structs]) height = np.array([dg[i].height for i in structs]) pk = np.array([dg[i].get_peak(True)[1] for i in structs]) dendro = Data(parent=parent, height=height, peak=pk, label='Dendrogram') im = Data(intensity=dg.data, structure=dg.index_map) im.join_on_key(dendro, 'structure', dendro.pixel_component_ids[0]) return [dendro, im]
""" import numpy as np import time import warnings from astropy import log from astrodendro import Dendrogram,ppv_catalog from astropy.table import Table, Column from paths import hpath,tpath from masked_cubes import cube303,cube303sm,cube321,cube321sm import flag_other_lines from astropy.utils.console import ProgressBar if 'dend' not in locals(): t0 = time.time() log.info("Loading dendrogram from file.") dend = Dendrogram.load_from(hpath("DendroMask_H2CO303202.hdf5")) log.info("Loaded dendrogram from file in {0:0.1f} seconds.".format(time.time()-t0)) dend.wcs = cube303.wcs if 'dendsm' not in locals(): t0 = time.time() log.info("Loading dendrogram from file.") dendsm = Dendrogram.load_from(hpath("DendroMask_H2CO303202_smooth.hdf5")) log.info("Loaded dendrogram from file in {0:0.1f} seconds.".format(time.time()-t0)) dendsm.wcs = cube303sm.wcs # Removed: the 321 signal extraction approach never worked nicely # if 'dend321' not in locals(): # t0 = time.time() # log.info("Loading dendrogram from file.") # dend321 = Dendrogram.load_from(hpath("DendroMask_H2CO321220.hdf5"))
from pruning import all_true, min_vchan, min_delta, min_area is_independent = all_true( (min_delta(3 * rms), min_area(3 * ppbeam), min_vchan(2))) d = Dendrogram.compute(data, min_value=0, is_independent=is_independent, verbose=1) d.save_to(path + 'DENDROGRAMS/' + files[f] + setup + '_dendrogram.fits') else: print("Loading dendrogram...") d = Dendrogram.load_from(path + 'DENDROGRAMS/' + files[f] + setup + '_dendrogram.fits') if os.path.isfile(path + 'CATALOGS/' + files[f] + setup + '_catalog.fits') == False: print("Making a simple catalog of dendrogram structures...") metadata = {} metadata[ 'data_unit'] = u.Jy #This must be Kelvin, but astrodendro gets only Jy, so fake Jy as unit cat = ppv_catalog(d, metadata) cat['luminosity'] = cat['flux'].data cat['volume'] = np.pi * cat['radius'].data**2 * cat['v_rms'].data os.system('rm -rf ' + path + 'CATALOGS/' + files[f] + setup + '_catalog.fits') cat.write(path + 'CATALOGS/' + files[f] + setup + '_catalog.fits')
def main(args): #------------------------ # Load DataCube #------------------------ print('Load DataCube') hdu = fits.open(args.fits_file)[0] hdr = hdu.header wcs = WCS(header=hdr).celestial data = hdu.data ny = data.shape[1] nx = data.shape[2] nchan = data.shape[0] velo = (np.arange(nchan) - hdr['CRPIX3'] + 1) * hdr['CDELT3'] + hdr['CRVAL3'] # ------------------------ # unit convert: Jy/beam -> mJy/pix # ------------------------ beam = 4.7 # arcmin pix = 1.0 # arcmin pix_over_beam = pix**2 / ((beam / 2)**2 * np.pi) data = data * 1000 * pix_over_beam # x Jy/beam = (x * pix/beam) Jy/pix #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_d + '.hdf5') print('') # ------------------------ # leaf label # ------------------------ list_idx = [] # raw index list_idv = [] # sorted index list_peak = [] # raw peaks for i, struc in enumerate(d.leaves): peak = struc.get_peak()[1] list_peak.append(peak) list_idx.append(struc.idx) peak_ind = np.argsort(np.array(list_peak))[::-1] leaves_idx_arr = np.array(list_idx)[peak_ind] # ------------------------ fig = plt.Figure(figsize=(8, 4)) for i, struc in enumerate(d.leaves): title, file_out = struc_info(struc, wcs, idx_arr=leaves_idx_arr, stype='leaf', method=args.method) print(title, struc.idx) if args.type == 'hydrogen': if struc.idx == 30: wbounds = [10, 30] else: wbounds = [5, 30] elif args.type == 'carbon': wbounds = [3, 8] spec, sp_fit, vlsr = struc_spec(struc, data, velo, args.chan_0, nchan, nx, ny, wbounds=wbounds, method=args.method) if args.type == 'carbon': vline = None vlim = [0, 300] else: vline = vlsr vlim = [-150, 150] plot_spec(fig, velo, spec, sp_fit, vlim=vlim, vline=vline, title=title, ftsize=25, method=args.method) fig.savefig(file_out, dpi=300, format='png', bbox_inches='tight') fig.clear(True) j = 0 for i, struc in enumerate(d.trunk): if struc.is_branch: # branch j = j + 1 title, file_out = struc_info(struc, wcs, stype='branch', label=j, method=args.method) spec, sp_fit, vlsr = struc_spec(struc, data, velo, args.chan_0, nchan, nx, ny, method=args.method) plot_spec(fig, velo, spec, sp_fit, vline=vlsr, title=title, method=args.method) fig.savefig(file_out, dpi=300, format='png', bbox_inches='tight') fig.clear(True) plt.close() return 0
""" import numpy as np import time import warnings from astropy import log from astrodendro import Dendrogram, ppv_catalog from astropy.table import Table, Column from paths import hpath, tpath from masked_cubes import cube303, cube303sm, cube321, cube321sm import flag_other_lines from astropy.utils.console import ProgressBar if 'dend' not in locals(): t0 = time.time() log.info("Loading dendrogram from file.") dend = Dendrogram.load_from(hpath("DendroMask_H2CO303202.hdf5")) log.info( "Loaded dendrogram from file in {0:0.1f} seconds.".format(time.time() - t0)) dend.wcs = cube303.wcs if 'dendsm' not in locals(): t0 = time.time() log.info("Loading dendrogram from file.") dendsm = Dendrogram.load_from(hpath("DendroMask_H2CO303202_smooth.hdf5")) log.info( "Loaded dendrogram from file in {0:0.1f} seconds.".format(time.time() - t0)) dendsm.wcs = cube303sm.wcs # Removed: the 321 signal extraction approach never worked nicely
def run_scimes(criteria=['volume'], label='scimes', cubefile=None, mom0file=None, bmajas=None, bminas=None, rfreq=None, redo='n', verbose=True, **kwargs): #%&%&%&%&%&%&%&%&%&%&%&% # Make dendrogram #%&%&%&%&%&%&%&%&%&%&%&% hdu3 = fits.open(cubefile)[0] hd3 = hdu3.header # Deal with oddities in 30 Dor cube if hd3['NAXIS'] == 3: for key in [ 'CTYPE4', 'CRVAL4', 'CDELT4', 'CRPIX4', 'CUNIT4', 'NAXIS4' ]: if key in hd3.keys(): hd3.remove(key) # Provide beam info if missing if bmajas is not None: hd3['bmaj'] = bmajas / 3600. if bminas is not None: hd3['bmin'] = bminas / 3600. # Get cube parameters sigma = stats.mad_std(hdu3.data[~np.isnan(hdu3.data)]) print('Robustly estimated RMS: {:.3f}'.format(sigma)) ppb = 1.133 * hd3['bmaj'] * hd3['bmin'] / (abs( hd3['cdelt1'] * hd3['cdelt2'])) print('Pixels per beam: {:.2f}'.format(ppb)) # Make the dendrogram if not present or redo=y if redo == 'n' and os.path.isfile(label + '_dendrogram.hdf5'): print('Loading pre-existing dendrogram') d = Dendrogram.load_from(label + '_dendrogram.hdf5') else: print('Make dendrogram from the full cube') d = Dendrogram.compute(hdu3.data, min_value=3 * sigma, min_delta=2.5 * sigma, min_npix=2 * ppb, verbose=verbose) d.save_to(label + '_dendrogram.hdf5') # checks/creates directory to place plots if os.path.isdir('plots') == 0: os.makedirs('plots') # Plot the tree fig = plt.figure(figsize=(14, 8)) ax = fig.add_subplot(111) ax.set_yscale('log') ax.set_xlabel('Structure') ax.set_ylabel('Intensity [' + hd3['BUNIT'] + ']') p = d.plotter() branch = [ s for s in d.all_structures if s not in d.leaves and s not in d.trunk ] tronly = [s for s in d.trunk if s not in d.leaves] for st in tronly: p.plot_tree(ax, structure=[st], color='brown', subtree=False) for st in branch: p.plot_tree(ax, structure=[st], color='black', subtree=False) for st in d.leaves: p.plot_tree(ax, structure=[st], color='green') plt.savefig('plots/' + label + '_dendrogram.pdf', bbox_inches='tight') #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Generate the catalog #%&%&%&%&%&%&%&%&%&%&%&%&%&% print('Generate a catalog of dendrogram structures') metadata = {} if hd3['BUNIT'].upper() == 'JY/BEAM': metadata['data_unit'] = u.Jy / u.beam elif hd3['BUNIT'].upper() == 'K': metadata['data_unit'] = u.K else: print('Warning: Unrecognized brightness unit') metadata['vaxis'] = 0 if rfreq is None: if 'RESTFREQ' in hd3.keys(): freq = hd3['RESTFREQ'] * u.Hz elif 'RESTFRQ' in hd3.keys(): freq = hd3['RESTFRQ'] * u.Hz else: freq = rfreq * u.GHz metadata['wavelength'] = freq.to(u.m, equivalencies=u.spectral()) metadata['spatial_scale'] = hd3['cdelt2'] * 3600. * u.arcsec metadata['velocity_scale'] = abs(hd3['cdelt3']) * u.meter / u.second bmaj = hd3['bmaj'] * 3600. * u.arcsec # FWHM bmin = hd3['bmin'] * 3600. * u.arcsec # FWHM metadata['beam_major'] = bmaj metadata['beam_minor'] = bmin cat = ppv_catalog(d, metadata, verbose=verbose) print(cat.info()) # Add additional properties: Average Peak Tb and Maximum Tb srclist = cat['_idx'].tolist() tmax = np.zeros(len(srclist), dtype=np.float64) tpkav = np.zeros(len(srclist), dtype=np.float64) for i, c in enumerate(srclist): peakim = np.nanmax(hdu3.data * d[c].get_mask(), axis=0) peakim[peakim == 0] = np.nan tmax[i] = np.nanmax(peakim) tpkav[i] = np.nanmean(peakim) if hd3['BUNIT'].upper() == 'JY/BEAM': omega_B = np.pi / (4 * np.log(2)) * bmaj * bmin convfac = (u.Jy).to(u.K, equivalencies=u.brightness_temperature( omega_B, freq)) tmax *= convfac tpkav *= convfac newcol = Column(tmax, name='tmax') newcol.unit = 'K' cat.add_column(newcol) newcol = Column(tpkav, name='tpkav') newcol.unit = 'K' cat.add_column(newcol) cat.write(label + '_full_catalog.txt', format='ascii.ecsv', overwrite=True) #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Running SCIMES #%&%&%&%&%&%&%&%&%&%&%&%&%&% print("Running SCIMES") dclust = SpectralCloudstering(d, cat, criteria=criteria, keepall=True) print(dclust.clusters) print("Visualize the clustered dendrogram") dclust.showdendro() plt.savefig('plots/' + label + '_clusters_tree.pdf') print("Produce the assignment cube") dclust.asgncube(hd3) try: os.remove(label + '_asgncube.fits.gz') except OSError: pass dclust.asgn.writeto(label + '_asgncube.fits.gz') #sys.exit("Stopping here") #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Image the trunks #%&%&%&%&%&%&%&%&%&%&%&%&%&% print("Image the trunks") hdu2 = fits.open(mom0file)[0] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) vmax = np.nanmax(hdu2.data) / 2. im = ax.matshow(hdu2.data, origin='lower', cmap=plt.cm.Blues, vmax=vmax) ax.axes.get_xaxis().set_ticks([]) ax.axes.get_yaxis().set_ticks([]) if 'xlims' in kwargs: ax.set_xlim(kwargs['xlims']) if 'ylims' in kwargs: ax.set_ylim(kwargs['ylims']) # Make a trunk list tronly = [s for s in d.trunk if s not in d.leaves] f = open(label + '_trunks.txt', 'w') for c in tronly: f.write('{:<4d} | '.format(c.idx)) # Plot the actual structure boundaries mask = d[c.idx].get_mask() mask_coll = np.amax(mask, axis=0) plt.contour(mask_coll, colors='red', linewidths=1, levels=[0]) # Plot the ellipse fits s = analysis.PPVStatistic(d[c.idx]) ellipse = s.to_mpl_ellipse(edgecolor='black', facecolor='none') ax.add_patch(ellipse) # Make sub-lists of descendants print('Finding descendants of trunk {}'.format(c.idx)) desclist = [] if len(d[c.idx].descendants) > 0: for s in d[c.idx].descendants: desclist.append(s.idx) desclist.sort() liststr = ','.join(map(str, desclist)) f.write(liststr) f.write("\n") f.close() fig.colorbar(im, ax=ax) plt.savefig('plots/' + label + '_trunks_map.pdf', bbox_inches='tight') plt.close() # Make a branch list branch = [ s for s in d.all_structures if s not in d.leaves and s not in d.trunk ] slist = [] for c in branch: slist.append(c.idx) slist.sort() with open(label + '_branches.txt', 'w') as output: writer = csv.writer(output) for val in slist: writer.writerow([val]) #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Image the leaves #%&%&%&%&%&%&%&%&%&%&%&%&%&% print("Image the leaves") fig = plt.figure() ax = fig.add_subplot(1, 1, 1) vmax = np.nanmax(hdu2.data) / 2. im = ax.matshow(hdu2.data, origin='lower', cmap=plt.cm.Blues, vmax=vmax) ax.axes.get_xaxis().set_ticks([]) ax.axes.get_yaxis().set_ticks([]) if 'xlims' in kwargs: ax.set_xlim(kwargs['xlims']) if 'ylims' in kwargs: ax.set_ylim(kwargs['ylims']) # Make a leaf list slist = [] for c in d.leaves: slist.append(c.idx) # Plot the actual structure boundaries mask = d[c.idx].get_mask() mask_coll = np.amax(mask, axis=0) plt.contour(mask_coll, colors='green', linewidths=1, levels=[0]) # Plot the ellipse fits s = analysis.PPVStatistic(d[c.idx]) ellipse = s.to_mpl_ellipse(edgecolor='black', facecolor='none') ax.add_patch(ellipse) slist.sort() with open(label + '_leaves.txt', "w") as output: writer = csv.writer(output) for val in slist: writer.writerow([val]) fig.colorbar(im, ax=ax) plt.savefig('plots/' + label + '_leaves_map.pdf', bbox_inches='tight') plt.close() #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Image the clusters #%&%&%&%&%&%&%&%&%&%&%&%&%&% print("Image the resulting clusters") clusts = np.array(dclust.clusters) colors = np.array(dclust.colors) inds = np.argsort(clusts) clusts = clusts[inds] colors = colors[inds] print(clusts) print(colors) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) vmax = np.nanmax(hdu2.data) / 2. im = ax.matshow(hdu2.data, origin='lower', cmap=plt.cm.Blues, vmax=vmax) ax.axes.get_xaxis().set_ticks([]) ax.axes.get_yaxis().set_ticks([]) if 'xlims' in kwargs: ax.set_xlim(kwargs['xlims']) if 'ylims' in kwargs: ax.set_ylim(kwargs['ylims']) # Make a cluster list f = open(label + '_clusters.txt', 'w') for i, c in enumerate(clusts): f.write('{:<4d} {:7} | '.format(c, colors[i])) # Plot the actual structure boundaries mask = d[c].get_mask() mask_coll = np.amax(mask, axis=0) plt.contour(mask_coll, colors=colors[i], linewidths=1, levels=[0]) # Plot the ellipse fits s = analysis.PPVStatistic(d[c]) ellipse = s.to_mpl_ellipse(edgecolor='black', facecolor='none') ax.add_patch(ellipse) # Make sub-lists of descendants print('Finding descendants of cluster {}'.format(c)) desclist = [] if len(d[c].descendants) > 0: for s in d[c].descendants: desclist.append(s.idx) desclist.sort() liststr = ','.join(map(str, desclist)) f.write(liststr) f.write("\n") f.close() fig.colorbar(im, ax=ax) plt.savefig('plots/' + label + '_clusters_map.pdf', bbox_inches='tight') plt.close() return
from astrodendro import Dendrogram, ppv_catalog, analysis try: x = len(d) except: x = 0 if x <= 0: import os if not os.path.exists(label + '_dendrogram.hdf5'): from run_dendro import run_dendro run_dendro(criteria=['volume'], label=label, cubefile=cubefile, mom0file=mom0file, nsigma=5.) d = Dendrogram.load_from(label + '_dendrogram.hdf5') cat = Table.read(label + '_full_catalog.txt', format='ascii.ecsv') if not os.path.exists(label + '_physprop.txt'): from calc_phys_props import * # calc_phys_props(label=label, cubefile=cubefile, boot_iter=400, efloor=0, # quick path: use 10 iterations for uncerts calc_phys_props(label=label, cubefile=cubefile, boot_iter=boot_iter, efloor=0, alphascale=1, distpc=4.8e4, copbcor=None, conoise=None,
if 0: #test dendro locate fo 30-60 km/s doCloud.doDendro( "/home/qzyan/WORK/myDownloads/MWISPcloud/G2650V3060/G2650V3060Sub.fits", minV=2, minPix=8, doSCIMES=False, minDelta=3, saveName="./G2650V3060/DendroTestV3060") sys.exit() if 0: #get cluster Assign #d = Dendrogram.load_from("minV2minP8_dendro.fits") #doCloud.getAssignByTB(d, "ClusterCat_2_8Ve20.fit", "ClusterAsgn_2_8Ve20_mannual.fits" ) d = Dendrogram.load_from("minV7minP8_dendro.fits") COFITS = "G2650Local30.fits" doCloud.getAssignByTB(d, COFITS, "ClusterCat_7_8Ve20.fit", "ClusterAsgn_7_8Ve20_mannual.fits") if 0: #reproduce trunk assign for sigmas in [7, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5]: for pixN in [8, 16]: COFITS = "G2650Local30.fits" dendroFITS = "minV{}minP{}_dendro.fits".format(sigmas, pixN) dendroCat = "minV{}minP{}_dendroCat.fit".format(sigmas, pixN) Table.read(dendroCat)
lat.set_ticks(spacing=0.2 * u.deg, color='black', exclude_overlapping=True, size=5, width=1.1) lon.set_ticklabel(size=fsize) lat.set_ticklabel(size=fsize) lon.display_minor_ticks(True) lat.display_minor_ticks(True) lon.set_minor_frequency(4) lat.set_minor_frequency(4) lon.set_major_formatter('d.d') lat.set_major_formatter('d.d') minval = np.nanmin(data) maxval = np.nanmax(data) im = ax.imshow(data, interpolation='nearest', cmap='Blues_r', origin='lower', norm=colors.PowerNorm(gamma=1./4.0)) d = Dendrogram.load_from(dendrofile) leaf_mask = np.zeros(data.shape) count=0 for leaf in d.leaves: foundleaf = (leaf.idx == catalog['index'].data) if np.any(foundleaf): arr = leaf.get_mask() leaf_mask[(arr==True)] = table['index'].data[count] count+=1 ax.contour(leaf_mask, transform=ax.get_transform(wcs), cmap='Reds', linewidths=0.25) plt.savefig(figure_name, dpi=800, bbox_inches='tight') plt.show()
def run_dendro( label='mycloud', cubefile=None, flatfile=None, redo='n', nsigma=3., min_delta=2.5, min_bms=2., position_dependent_noise=False, # will use rms map in dendro criteria=['volume'], # for SCIMES doplots=True, dendro_in=None, # use this instead of re-loading **kwargs): global cubedata, rmsmap, threshold_sigma #%&%&%&%&%&%&%&%&%&%&%&% # Make dendrogram #%&%&%&%&%&%&%&%&%&%&%&% hdu3 = fits.open(cubefile)[0] hd3 = hdu3.header cubedata = hdu3.data # Deal with oddities in 30 Dor cube if hd3['NAXIS'] == 3: for key in [ 'CTYPE4', 'CRVAL4', 'CDELT4', 'CRPIX4', 'CUNIT4', 'NAXIS4' ]: if key in hd3.keys(): hd3.remove(key) # Get cube parameters sigma = stats.mad_std(hdu3.data[~np.isnan(hdu3.data)]) print('Robustly estimated RMS: ', sigma) ppb = 1.133 * hd3['bmaj'] * hd3['bmin'] / (abs( hd3['cdelt1'] * hd3['cdelt2'])) print('Pixels per beam: ', ppb) # Make the dendrogram if not present or redo=y if position_dependent_noise: dendrofile = 'dendro_dendrogram_rmsmap.hdf5' else: dendrofile = 'dendro_dendrogram.hdf5' if dendro_in != None: d = dendro_in elif redo == 'n' and os.path.isfile(dendrofile): print('Loading pre-existing dendrogram') d = Dendrogram.load_from(dendrofile) else: print('Make dendrogram from the full cube') if position_dependent_noise: mask3d = cubedata < 3 * sigma rmsmap = np.nanstd(cubedata * mask3d, axis=0) # assumes spectral 1st threshold_sigma = min_delta # for custom_independent function d = Dendrogram.compute(hdu3.data, min_value=nsigma * sigma, min_delta=min_delta * sigma, min_npix=min_bms * ppb, verbose=1, is_independent=custom_independent) else: d = Dendrogram.compute(hdu3.data, min_value=nsigma * sigma, min_delta=min_delta * sigma, min_npix=min_bms * ppb, verbose=1) d.save_to(dendrofile) if doplots: # checks/creates directory to place plots if os.path.isdir('dendro_plots') == 0: os.makedirs('dendro_plots') # Plot the tree fig = plt.figure(figsize=(14, 8)) ax = fig.add_subplot(111) #ax.set_yscale('log') ax.set_xlabel('Structure') ax.set_ylabel('Intensity [' + hd3['BUNIT'] + ']') p = d.plotter() branch = [ s for s in d.all_structures if s not in d.leaves and s not in d.trunk ] tronly = [s for s in d.trunk if s not in d.leaves] for st in tronly: p.plot_tree(ax, structure=[st], color='brown', subtree=False) for st in branch: p.plot_tree(ax, structure=[st], color='black', subtree=False) for st in d.leaves: p.plot_tree(ax, structure=[st], color='green') #p.plot_tree(ax, color='black') plt.savefig('dendro_plots/' + label + '_dendrogram.pdf', bbox_inches='tight') #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Generate the catalog #%&%&%&%&%&%&%&%&%&%&%&%&%&% print("Generate a catalog of dendrogram structures") metadata = {} if hd3['BUNIT'].upper() == 'JY/BEAM': metadata['data_unit'] = u.Jy / u.beam elif hd3['BUNIT'].upper() == 'K': metadata['data_unit'] = u.K else: print("Warning: Unrecognized brightness unit") metadata['vaxis'] = 0 if 'RESTFREQ' in hd3.keys(): freq = hd3['RESTFREQ'] * u.Hz elif 'RESTFRQ' in hd3.keys(): freq = hd3['RESTFRQ'] * u.Hz metadata['wavelength'] = freq.to(u.m, equivalencies=u.spectral()) metadata['spatial_scale'] = hd3['cdelt2'] * 3600. * u.arcsec if hd3['ctype3'][0:3] == 'VEL' or hd3['ctype3'][0:4] == 'VRAD': dv = hd3['cdelt3'] / 1000. * u.km / u.s else: assert hd3['ctype3'][0:4] == 'FREQ' dv = 2.99792458e5 * np.absolute( hd3['cdelt3']) / freq.value * u.km / u.s metadata['velocity_scale'] = dv bmaj = hd3['bmaj'] * 3600. * u.arcsec # FWHM bmin = hd3['bmin'] * 3600. * u.arcsec # FWHM metadata['beam_major'] = bmaj metadata['beam_minor'] = bmin if not (redo == "n" and os.path.exists(label + '_full_catalog.txt')): print("generating catalog") cat = ppv_catalog(d, metadata) print(cat.info()) # Add additional properties: Average Peak Tb and Maximum Tb srclist = cat['_idx'].tolist() tmax = np.zeros(len(srclist), dtype=np.float64) tpkav = np.zeros(len(srclist), dtype=np.float64) for i, c in enumerate(srclist): peakim = np.nanmax(hdu3.data * d[c].get_mask(), axis=0) peakim[peakim == 0] = np.nan tmax[i] = np.nanmax(peakim) tpkav[i] = np.nanmean(peakim) if hd3['BUNIT'].upper() == 'JY/BEAM': omega_B = np.pi / (4 * np.log(2)) * bmaj * bmin convfac = (u.Jy).to(u.K, equivalencies=u.brightness_temperature( omega_B, freq)) tmax *= convfac tpkav *= convfac newcol = Column(tmax, name='tmax') newcol.unit = 'K' cat.add_column(newcol) newcol = Column(tpkav, name='tpkav') newcol.unit = 'K' cat.add_column(newcol) cat.write(label + '_full_catalog.txt', format='ascii.ecsv', overwrite=True) #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Generate the catalog with clipping #%&%&%&%&%&%&%&%&%&%&%&%&%&% if not (redo == "n" and os.path.exists(label + '_full_catalog_clipped.txt')): print("generating clipped catalog") ccat = ppv_catalog(d, metadata, clipping=True) print(ccat.info()) # Add additional properties: Average Peak Tb and Maximum Tb srclist = ccat['_idx'].tolist() tmax = np.zeros(len(srclist), dtype=np.float64) tpkav = np.zeros(len(srclist), dtype=np.float64) for i, c in enumerate(srclist): peakim = np.nanmax(hdu3.data * d[c].get_mask(), axis=0) peakim[peakim == 0] = np.nan clmin = np.nanmin(hdu3.data * d[c].get_mask()) tmax[i] = np.nanmax(peakim) - clmin tpkav[i] = np.nanmean(peakim) - clmin if hd3['BUNIT'].upper() == 'JY/BEAM': omega_B = np.pi / (4 * np.log(2)) * bmaj * bmin convfac = (u.Jy).to(u.K, equivalencies=u.brightness_temperature( omega_B, freq)) tmax *= convfac tpkav *= convfac newcol = Column(tmax, name='tmax-tmin') newcol.unit = 'K' ccat.add_column(newcol) newcol = Column(tpkav, name='tpkav-tmin') newcol.unit = 'K' ccat.add_column(newcol) ccat.write(label + '_full_catalog_clipped.txt', format='ascii.ecsv', overwrite=True) #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Running SCIMES #%&%&%&%&%&%&%&%&%&%&%&%&%&% # print("Running SCIMES") # dclust = SpectralCloudstering(d, cat, criteria = criteria, keepall=True) # print(dclust.clusters) # # print("Visualize the clustered dendrogram") # dclust.showdendro() # plt.savefig('dendro_plots/'+label+'_clusters_tree.pdf') # # print("Produce the assignment cube") # dclust.asgncube(hd3) # try: # os.remove(label+'_asgncube.fits.gz') # except OSError: # pass # dclust.asgn.writeto(label+'_asgncube.fits.gz') #sys.exit("Stopping here") #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Image the trunks #%&%&%&%&%&%&%&%&%&%&%&%&%&% if doplots: print("Image the trunks") hdu2 = fits.open(flatfile)[0] fig = plt.figure() ax = fig.add_subplot(1, 1, 1) vmax = np.nanmax(hdu2.data) / 2. im = ax.matshow(hdu2.data, origin='lower', cmap=plt.cm.Blues, vmax=vmax) ax.axes.get_xaxis().set_ticks([]) ax.axes.get_yaxis().set_ticks([]) if 'xlims' in kwargs: ax.set_xlim(kwargs['xlims']) if 'ylims' in kwargs: ax.set_ylim(kwargs['ylims']) # Make a trunk list tronly = [s for s in d.trunk if s not in d.leaves] f = open(label + '_trunks.txt', 'w') for c in tronly: f.write('{:<4d} | '.format(c.idx)) # Plot the actual structure boundaries mask = d[c.idx].get_mask() mask_coll = np.amax(mask, axis=0) plt.contour(mask_coll, colors='red', linewidths=1, levels=[0]) # Plot the ellipse fits s = analysis.PPVStatistic(d[c.idx]) ellipse = s.to_mpl_ellipse(edgecolor='black', facecolor='none') ax.add_patch(ellipse) # Make sub-lists of descendants print('Finding descendants of trunk ', c.idx) desclist = [] if len(d[c.idx].descendants) > 0: for s in d[c.idx].descendants: desclist.append(s.idx) desclist.sort() liststr = ','.join(map(str, desclist)) f.write(liststr) f.write("\n") f.close() fig.colorbar(im, ax=ax) plt.savefig('dendro_plots/' + label + '_trunks_map.pdf', bbox_inches='tight') plt.close() # Make a branch list branch = [ s for s in d.all_structures if s not in d.leaves and s not in d.trunk ] slist = [] for c in branch: slist.append(c.idx) slist.sort() with open(label + '_branches.txt', 'w') as output: writer = csv.writer(output) for val in slist: writer.writerow([val]) #%&%&%&%&%&%&%&%&%&%&%&%&%&% # Image the leaves #%&%&%&%&%&%&%&%&%&%&%&%&%&% print("Image the leaves") fig = plt.figure() ax = fig.add_subplot(1, 1, 1) vmax = np.nanmax(hdu2.data) / 2. im = ax.matshow(hdu2.data, origin='lower', cmap=plt.cm.Blues, vmax=vmax) ax.axes.get_xaxis().set_ticks([]) ax.axes.get_yaxis().set_ticks([]) if 'xlims' in kwargs: ax.set_xlim(kwargs['xlims']) if 'ylims' in kwargs: ax.set_ylim(kwargs['ylims']) # Make a leaf list slist = [] for c in d.leaves: slist.append(c.idx) # Plot the actual structure boundaries mask = d[c.idx].get_mask() mask_coll = np.amax(mask, axis=0) plt.contour(mask_coll, colors='green', linewidths=1, levels=[0]) # Plot the ellipse fits s = analysis.PPVStatistic(d[c.idx]) ellipse = s.to_mpl_ellipse(edgecolor='black', facecolor='none') ax.add_patch(ellipse) slist.sort() with open(label + '_leaves.txt', "w") as output: writer = csv.writer(output) for val in slist: writer.writerow([val]) fig.colorbar(im, ax=ax) plt.savefig('dendro_plots/' + label + '_leaves_map.pdf', bbox_inches='tight') plt.close()
default='nonLTE', help="Radiative transfer mode [LTE, nonLTE]") args = parser.parse_args() if args.folder[-1] != '/': args.folder += '/' folder_reg = './portions_moment0/' print('creating folder for output files:', folder_reg) os.system('mkdir %s' % folder_reg) print(args.incl, args.unit) #************************************************** #READING FILES and SETTING CONSTANTS #************************************************** tag_tuple = (args.unit, args.incl) d = Dendrogram.load_from(args.folder + 'img_moment0_dendrogram_%s_%s.fits' % tag_tuple) hdu = fits.open(args.folder + 'moment0_img_CO_J1-0_%s_%s_%s.fits' % (args.rtmode, args.unit, args.incl))[0] w = wcs.WCS(hdu.header) source_dist = float(np.loadtxt('../pars_size_rt.txt')[1]) pc2au = 206264.806247 #************************************************** #DENDROGRAM DEFAULT PROPERTIES #************************************************** hdu.data *= 1e-3 #m/s to km/s mean_val = np.mean(hdu.data[hdu.data > 1]) #************************************************** #CREATING MAIN MASK FOR LEAVES
d = Dendrogram.compute(data, min_value=2*rms, min_delta=2*rms, min_npix=10, verbose = 1) d.save_to(dendro_file+'.fits') d.viewer() # Load a premade dendrogram if do_load: data = fits.getdata(data_file) if size(shape(data))==4: data = data[0,:,:,:] print 'Load dendrogram file: '+load_file d = Dendrogram.load_from(load_file) #d.viewer() # Introduction to the spectral clustering: # make the necessary matrices and some # experimental ones. if do_matrix: #Calculate the adjacency matrix s = d.trunk[-1] #Preparing the matrices
#minPixels=500 #doScimes.doDendroAndScimes( maskFITS,reDo=True, saveAll=False , minPix=minPixels,vScale=vscale, useLuminosity=True, useVolume=False,useVelociy=True, subRegion="LuVeSingleTestPureCluster" ) saveAll=True dendroMark="dendroSave{}".format(minPixels) #dendroINPUT,catName=doScimes.doDendroAndScimes( maskFITS,reDo=True, saveAll=saveAll , minPix=minPixels, saveDendro=True,saveDenroMark=dendroMark, useLuminosity=False, useVolume=True,useVelociy=False, calDendro=True ) catName="./{}/dendroSave{}.fit".format(regionName,minPixels) dendroName="./{}/dendroSave{}.fits".format(regionName,minPixels) print dendroName dendroINPUT= Dendrogram.load_from(dendroName) #for vscale in [16,18,20,22,24,26,28,30]: #single criteria does not work well #doScimes.doDendroAndScimes( maskFITS,reDo=True, saveAll=saveAll ,vScale=vscale, minPix=minPixels, useLuminosity=True, useVolume=True,useVelociy=True, calDendro=False, inputDendro=dendroINPUT,iinputDenroCatFile=catName) #doScimes.doDendroAndScimes( maskFITS,reDo=True, saveAll=saveAll ,vScale=vscale, minPix=minPixels, useLuminosity=False, useVolume=False,useVelociy=True, calDendro=False,inputDendro=dendroINPUT,iinputDenroCatFile=catName) #doScimes.doDendroAndScimes( maskFITS,reDo=True, saveAll=saveAll ,vScale=vscale, minPix=minPixels, useLuminosity=True, useVolume=False,useVelociy=False, calDendro=False,inputDendro=dendroINPUT,iinputDenroCatFile=catName) #doScimes.doDendroAndScimes( maskFITS,reDo=True, saveAll=saveAll ,vScale=vscale, minPix=minPixels, useLuminosity=False, useVolume=True,useVelociy=False, calDendro=False,inputDendro=dendroINPUT,iinputDenroCatFile=catName)
def add_ltemass(label='pcc_12', n13cub=None, i12cub=None, i13cub=None, n13cub_uc=None, distpc=4.8e4, co13toh2=5.0e6): # Make the uncertainty input a list if not isinstance(n13cub_uc, list): n13cub_uc = [n13cub_uc] # Adopted parameters dist = distpc * u.pc # Get basic info from header hd = getheader(n13cub) deltav = np.abs(hd['cdelt3'] / 1000.) pixdeg = np.abs(hd['cdelt2']) pix2cm = (np.radians(pixdeg) * dist).to(u.cm) ppbeam = np.abs((hd['bmaj'] * hd['bmin']) / (hd['cdelt1'] * hd['cdelt2']) * 2 * np.pi / (8 * np.log(2))) osamp = np.sqrt(ppbeam) # Total the LTE masses (and optionally, 12CO and 13CO fluxes) d = Dendrogram.load_from(label + '_dendrogram.hdf5') cat = Table.read(label + '_physprop.txt', format='ascii.ecsv') srclist = cat['_idx'].tolist() for col in [ 'flux12', 'flux13', 'mlte', 'e_mlte', 'siglte', 'e_siglte', 'e_mlte_alt' ]: newcol = Column(name=col, data=np.zeros(np.size(srclist))) if col == 'flux12': if i12cub is not None: data, ihd = getdata(i12cub, header=True) if 'RESTFREQ' in ihd.keys(): rfreq = ihd['RESTFREQ'] * u.Hz elif 'RESTFRQ' in ihd.keys(): rfreq = ihd['RESTFRQ'] * u.Hz newcol.description = '12CO flux within the structure' else: continue elif col == 'flux13': if i13cub is not None: data, ihd = getdata(i13cub, header=True) if 'RESTFREQ' in ihd.keys(): rfreq = ihd['RESTFREQ'] * u.Hz elif 'RESTFRQ' in ihd.keys(): rfreq = ihd['RESTFRQ'] * u.Hz newcol.description = '13CO flux within the structure' else: continue elif col == 'mlte': data = getdata(n13cub) newcol.description = 'LTE mass using H2/13CO=' + str(co13toh2) elif col == 'e_mlte': data = getdata(n13cub_uc[0]) newcol.description = 'fractional unc in mlte' elif col == 'siglte': data = getdata(n13cub) newcol.description = 'LTE mass divided by area in pc2' elif col == 'e_siglte': data = getdata(n13cub_uc[0]) newcol.description = 'fractional unc in siglte [same as e_lte]' elif col == 'e_mlte_alt': if len(n13cub_uc) > 1: data = getdata(n13cub_uc[1]) newcol.description = 'fractional unc in mlte from alt approach' else: continue for i, c in enumerate(srclist): mask = d[c].get_mask() if not col.startswith('e_'): newcol[i] = np.nansum(data[np.where(mask)]) # nansum returns zero if all are NaN, want NaN chknan = np.asarray(np.isnan(data[np.where(mask)])) if chknan.all(): newcol[i] = np.nan else: newcol[i] = np.sqrt(np.nansum(data[np.where(mask)]**2)) * osamp if col in ['flux12', 'flux13']: # Convert from K*pix*ch to Jy*km/s convfac = (1 * u.K).to( u.Jy / u.deg**2, equivalencies=u.brightness_temperature(rfreq)) newcol *= deltav * convfac.value * (pixdeg)**2 newcol.unit = 'Jy km / s' else: # Multiply by channel width in km/s and area in cm^2 to get molecule number newcol *= deltav * pix2cm.value**2 # Convert from molecule number to solar masses including He newcol *= co13toh2 * 2 * 1.36 * const.m_p.value / const.M_sun.value if col == 'mlte': newcol.unit = 'solMass' elif col == 'siglte': newcol /= cat['area_pc2'] newcol.unit = 'solMass/pc2' else: newcol /= cat['mlte'] newcol.unit = '' cat.add_column(newcol) #cat.pprint(show_unit=True) cat.write(label + '_physprop_add.txt', format='ascii.ecsv', overwrite=True) return
def main(args): #------------------------ # Load DataCube #------------------------ print('Load DataCube') hdu = fits.open(args.fits_file)[0] hdr = hdu.header wcs = WCS(header=hdr).celestial data = hdu.data nchan = data.shape[0] velo = (np.arange(nchan) - hdr['CRPIX3'] + 1) * hdr['CDELT3'] + hdr['CRVAL3'] ny = data.shape[1] nx = data.shape[2] #------------------------ # unit convert: Jy/beam -> mJy/pix #------------------------ beam = 4.7 # arcmin pix = 1.0 # arcmin pix_over_beam = pix**2/((beam/2)**2*np.pi) data = data * 1000 * pix_over_beam # x Jy/beam = (x * pix/beam) Jy/pix #------------------------ # Load contour data #------------------------ if args.file_contour is not None: hdu1 = fits.open(args.file_contour)[0] hdr1= hdu1.header wcs1 = WCS(header=hdr).celestial contour_data = hdu1.data #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_d+'.hdf5') print('') #------------------------ # Plot all leaves and branches on full frame of Moment0 map. #------------------------ fig = plt.figure(figsize=(8,8)) for i, struc in enumerate(d.leaves): mask = struc.get_mask().mean(axis=0) peak = struc.get_peak()[0] x_p = peak[2] y_p = peak[1] v_p = args.chan_0+peak[0] imag = data[v_p-10:v_p+10,:,:].sum(axis=0) * hdr['CDELT3']; coor = SkyCoord.from_pixel(x_p,y_p,wcs) gc = coor.transform_to('galactic') gname = 'G{:5.2f}{:+5.2f}'.format(gc.l.value,gc.b.value) file_out = '{}_{}.png'.format(gname,args.cmap) ax = plot_imag(fig,imag,mask,wcs,coor=(x_p,y_p),cmap=args.cmap,size=args.size,beam=args.beam,ftsize=20) if args.file_contour is not None: ax.contour(contour_data,linewidths=1.5,levels=args.levels,colors=args.contour_color) fig.savefig(file_out,dpi=300,format='png',bbox_inches='tight') fig.clear(True) return 0
def main(args): #------------------------ # Load DataCube #------------------------ print('Load DataCube') hdu = fits.open(args.fits_file)[0] hdr = hdu.header wcs = WCS(header=hdr).celestial data = hdu.data ny = data.shape[1] nx = data.shape[2] nchan = data.shape[0] velo = (np.arange(nchan) - hdr['CRPIX3'] + 1) * hdr['CDELT3'] + hdr['CRVAL3'] # ------------------------ # unit convert: Jy/beam -> mJy/pix # ------------------------ beam = 4.7 # arcmin pix = 1.0 # arcmin pix_over_beam = pix**2 / ((beam / 2)**2 * np.pi) data = data * 1000 * pix_over_beam # x Jy/beam = (x * pix/beam) Jy/pix #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_d) print('') # ------------------------ # leaf label # ------------------------ list_idx = [] # raw index list_idv = [] # sorted index list_peak = [] # raw peaks for i, struc in enumerate(d.leaves): peak = struc.get_peak()[1] list_peak.append(peak) list_idx.append(struc.idx) peak_ind = np.argsort(np.array(list_peak))[::-1] leaves_idx_arr = np.array(list_idx)[peak_ind] # ------------------------ fig = plt.Figure(figsize=(6, 4.5)) spec_arr = [] rms_arr = [] for i, struc in enumerate(d.leaves): title, file_out = struc_info(struc, wcs, idx_arr=leaves_idx_arr, stype='leaf', method=args.method) print(title, struc.idx) if args.type == 'hydrogen': if struc.idx == 30: wbounds = [10, 30] else: wbounds = [5, 30] elif args.type == 'carbon': wbounds = [3, 8] spec = struc_spec(struc, data, velo, args.chan_0, nchan, nx, ny, wbounds=wbounds, method=args.method) rms = np.nanstd(spec[-100:-1]) spec_arr.append(spec) rms_arr.append(rms) for i, spec in enumerate(spec_arr): #weight = 1. #weight = 1./rms_arr[i] weight = 1. / (rms_arr[i]**2) spec_i = spec * weight if i == 0: spec_ave = spec_i else: spec_ave = spec_ave + spec_i velo = np.arange(0, len(spec_ave)) * 0.5 - 200 print(spec_ave.shape) print('rms', np.std(spec_ave[0:300])) print('max', np.max(spec_ave)) plot_spec(fig, velo, spec_ave, vline=0, ftsize=12, method=args.method) fig.savefig('clump_spec_aver_w1.png', dpi=300, format='png', bbox_inches='tight') plt.close() return 0
def main(args): # #------------------------ # # Load DataCube # #------------------------ # print('Load DataCube') # hdu = fits.open(args.file_cube)[0] # hdr = hdu.header # wcs = WCS(header=hdr).celestial # data = hdu.data # nchan = data.shape[0] # velo = (np.arange(nchan) - hdr['CRPIX3'] + 1) * hdr['CDELT3'] + hdr['CRVAL3'] # ny = data.shape[1] # nx = data.shape[2] # # # unit convert: Jy/beam -> mJy/pix # beam = 4.7 # arcmin # pix = 1.0 # arcmin # pix_over_beam = pix**2/((beam/2)**2*np.pi) # data = data * 1000 * pix_over_beam # x Jy/beam = (x * pix/beam) Jy/pix # imag0 = data[args.chan_0:args.chan_1,:,:].mean(axis=0) # print(imag0.shape) #------------------------ # Load Moment 0 map #------------------------ hdu = fits.open(args.file_map)[0] hdr = hdu.header wcs = WCS(header=hdr).celestial imag0 = hdu.data print(imag0.shape) #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_d + '.hdf5') #------------------------ # Plot all leaves and branches on full frame of Moment0 map. #------------------------ norm = simple_norm(imag0, stretch='asinh', asinh_a=0.18, min_percent=5, max_percent=100) fig0 = plt.figure(figsize=(8, 8)) ax0 = fig0.add_subplot(1, 1, 1, projection=wcs) im0 = ax0.imshow(imag0,origin='lower',interpolation='nearest',cmap=colormap(args.cmap),\ aspect='equal')#,norm=norm) # coordinates if args.proj == 'equ': ra0 = ax0.coords['ra'] de0 = ax0.coords['dec'] ra0.set_axislabel('R.A. (J2000)', minpad=0.5, size="xx-large") de0.set_axislabel('Dec. (J2000)', minpad=0.5, size="xx-large") ra0.set_separator(('$\mathrm{^h}$', '$\mathrm{^m}$')) ra0.set_ticklabel(size="xx-large") de0.set_ticklabel(size="xx-large") elif args.proj == 'gal': l0 = ax0.coords['glon'] b0 = ax0.coords['glat'] l0.set_axislabel('l deg', minpad=0.5, size="xx-large") b0.set_axislabel('b deg', minpad=0.5, size="xx-large") l0.set_ticklabel(size="xx-large") b0.set_ticklabel(size="xx-large") # beam if args.beam is not None: beam = patches.Circle((5, 5), radius=args.beam / 2, edgecolor='k', facecolor='w', alpha=0.5) # pixel coordinates ax0.add_patch(beam) # ------------------------ # add sources in catalog if args.file_c is not None: add_source(ax0, args.file_c, wcs) # ------------------------ # leaf label list_idx = [] # raw index list_idv = [] # sorted index list_peak = [] # raw peaks for i, struc in enumerate(d.leaves): peak = struc.get_peak()[1] list_peak.append(peak) list_idx.append(struc.idx) peak_ind = np.argsort(np.array(list_peak))[::-1] leaves_idx_arr = np.array(list_idx)[peak_ind] # ------------------------ colors = ['blue', 'red', 'green'] c = 1 for i, struc in enumerate(d.trunk): if struc.is_leaf: leaf_label = add_leaf_label(ax0, leaves_idx_arr, struc) file_out = 'leaf_{:d}_{}.png'.format(leaf_label, args.cmap) color = colors[0] subtree = [] line = 'solid' elif struc.is_branch: # branch file_out = 'branch_{:d}_{}.png'.format(struc.idx, args.cmap) color = colors[c] c = c + 1 subtree = struc.descendants line = 'dashed' mask = struc.get_mask().mean(axis=0) ax0.contour(mask, linewidths=1.5, levels=[0.001], alpha=0.8, colors=[color], linestyles=line) for j, sub_struc in enumerate(subtree): if sub_struc.is_leaf: leaf_label = add_leaf_label(ax0, leaves_idx_arr, sub_struc) file_out = 'leaf_{:d}_{}.png'.format(leaf_label, args.cmap) mask = sub_struc.get_mask().mean(axis=0) print(mask.shape) ax0.contour(mask, linewidths=1.5, levels=[0.001], alpha=0.8, colors=[color]) fig0.savefig('m0-clumps_{}.png'.format(args.cmap), dpi=300, format='png', bbox_inches='tight') return 0
def calc_phys_props(label='pcc_12', cubefile=None, dendrofile=None, boot_iter=400, efloor=0, alphascale=1, distpc=4.8e4, copbcor=None, conoise=None, ancfile=None, anclabel=None, verbose=False, clipping=False, co13toh2=1e6, n13cube=None, n13errcube=None, dendro_in=None): if clipping: clipstr = "_clipped" else: clipstr = "" rmstorad = 1.91 alphaco = 4.3 * u.solMass * u.s / (u.K * u.km * u.pc**2) # Bolatto+ 13 dist = distpc * u.pc as2 = 1 * u.arcsec**2 asarea = (as2 * dist**2).to(u.pc**2, equivalencies=u.dimensionless_angles()) # ---- load the dendrogram and catalog if dendrofile == None: dendrofile = label + '_dendrogram.hdf5' if dendro_in != None: d = dendro_in elif os.path.isfile(dendrofile): print('Loading pre-existing dendrogram') d = Dendrogram.load_from(dendrofile) cat = Table.read(label + '_full_catalog' + clipstr + '.txt', format='ascii.ecsv') srclist = cat['_idx'].tolist() # ---- load the cube and extract the metadata cube, hd3 = getdata(cubefile, header=True) metadata = {} if hd3['BUNIT'].upper() == 'JY/BEAM': metadata['data_unit'] = u.Jy / u.beam elif hd3['BUNIT'].upper() == 'K': metadata['data_unit'] = u.K else: print("\nWarning: Unrecognized brightness unit") metadata['vaxis'] = 0 if 'RESTFREQ' in hd3.keys(): freq = hd3['RESTFREQ'] * u.Hz elif 'RESTFRQ' in hd3.keys(): freq = hd3['RESTFRQ'] * u.Hz cdelt1 = abs(hd3['cdelt1']) * 3600. * u.arcsec cdelt2 = abs(hd3['cdelt2']) * 3600. * u.arcsec # this assumes vel cube! if hd3['ctype3'][0:4] == "FREQ": nu0 = hd3['restfrq'] dnu = hd3['cdelt3'] deltav = 2.99792458e5 * np.absolute(dnu) / nu0 * u.km / u.s else: deltav = abs(hd3['cdelt3']) / 1000. * u.km / u.s metadata['wavelength'] = freq.to(u.m, equivalencies=u.spectral()) metadata['spatial_scale'] = cdelt2 metadata['velocity_scale'] = deltav bmaj = hd3['bmaj'] * 3600. * u.arcsec # FWHM bmin = hd3['bmin'] * 3600. * u.arcsec # FWHM metadata['beam_major'] = bmaj metadata['beam_minor'] = bmin ppbeam = np.abs( (bmaj * bmin) / (cdelt1 * cdelt2) * 2 * np.pi / (8 * np.log(2))) print("\nPixels per beam: {:.2f}".format(ppbeam)) # Assume every 2 channels have correlated noise indfac = np.sqrt(ppbeam * 2) # ---- read in ancillary files if copbcor is not None and conoise is not None: cube12, hd12 = getdata(copbcor, header=True) ecube12, ehd12 = getdata(conoise, header=True) if 'RESTFREQ' in hd12.keys(): freq12 = hd12['RESTFREQ'] * u.Hz elif 'RESTFRQ' in hd12.keys(): freq12 = hd12['RESTFRQ'] * u.Hz else: print('Rest frequency missing from file ' + copbcor) raise if hd12['BUNIT'].upper() != 'K': print('Non-Kelvin units not yet supported for copbcor') raise if ehd12['NAXIS'] == 2: tmpcube = np.broadcast_to(ecube12, np.shape(cube12)) ecube12 = tmpcube if ancfile is not None: ancdata, anchd = getdata(ancfile, header=True) # elliptical function def w_ell(ratio): return np.log(np.sqrt(ratio**2 - 1) + ratio) / np.sqrt(ratio**2 - 1) # ---- call the bootstrapping routine emaj, emin, epa, evrms, errms, eaxra, eflux, emvir, eemvir, ealpha, tb12, ancmean, ancrms = [ np.zeros(len(srclist)) for _ in range(13) ] print("Calculating property errors... with %i iterations" % boot_iter) print("....................\r", end='') nsrc = len(srclist) nsrcd = nsrc // 20 for j, clust in enumerate(srclist): if j % nsrcd == 0 and j > 0: print("+" * (j // nsrcd) + "." * ((nsrc - j) // nsrcd) + "\r", end='') if verbose: print(" cl", j, "/", len(srclist)) asgn = np.zeros(cube.shape) asgn[d[clust].get_mask(shape=asgn.shape)] = 1 sindices = np.where(asgn == 1) svalues = cube[sindices] emmajs, emmins, emomvs, emom0s, pa = clustbootstrap(sindices, svalues, metadata, boot_iter, verbose=False) # bin_list=np.linspace(np.floor(min(emmajs)),np.ceil(max(emmajs)),50) # fig, axes = plt.subplots() # axes.hist(emmajs, bin_list, normed=0, histtype='bar') # plt.savefig('emmajs_histo.pdf', bbox_inches='tight') bootmaj = np.asarray(emmajs) * u.arcsec bootmajpc = (bootmaj * dist).to(u.pc, equivalencies=u.dimensionless_angles()) bootmin = np.asarray(emmins) * u.arcsec bootpa = np.asarray(pa) * u.deg bootvrms = (np.asarray(emomvs) * u.m / u.s).to(u.km / u.s) bootrrms = (np.sqrt(np.asarray(emmajs) * np.asarray(emmins)) * u.arcsec * dist).to(u.pc, equivalencies=u.dimensionless_angles()) bootaxrat = bootmin / bootmaj bootflux = np.asarray(emom0s) * u.Jy # RI: cube assumed to be Jy bootmvir = (5 * rmstorad * bootvrms**2 * bootrrms / const.G).to( u.solMass) # elliptical mvir: bootemvir = (5 * rmstorad * bootvrms**2 * bootmajpc / w_ell(1. / bootaxrat) / const.G).to(u.solMass) bootmlum = alphaco * alphascale * deltav * asarea * (bootflux).to( u.K, equivalencies=u.brightness_temperature(as2, freq)) bootalpha = bootmvir / bootmlum emaj[j] = indfac * mad_std(bootmaj) / np.median(bootmaj) emin[j] = indfac * mad_std(bootmin) / np.median(bootmin) epa[j] = indfac * mad_std(bootpa) / np.median(bootpa) evrms[j] = indfac * mad_std(bootvrms) / np.median(bootvrms) errms[j] = indfac * mad_std(bootrrms) / np.median(bootrrms) eaxra[j] = indfac * mad_std(bootaxrat) / np.median(bootaxrat) emvir[j] = indfac * mad_std(bootmvir) / np.median(bootmvir) eemvir[j] = indfac * mad_std(bootemvir) / np.median(bootemvir) ealpha[j] = indfac * mad_std(bootalpha) / np.median(bootalpha) if copbcor is not None and conoise is not None: tb12[j] = np.nansum(asgn * cube12) eflux[j] = indfac * np.sqrt(np.nansum(asgn * ecube12**2)) / tb12[j] #print(j, len(svalues), tb12[j], etb12[j]) else: eflux[j] = indfac * mad_std(bootflux) / np.median(bootflux) if ancfile is not None: if anchd['NAXIS'] == 2: collapsedmask = np.amax(asgn, axis=0) collapsedmask[collapsedmask == 0] = np.nan ancmean[j] = np.nanmean(ancdata * collapsedmask) ancrms[j] = np.sqrt( np.nanmean((ancdata * collapsedmask)**2) - ancmean[j]**2) else: ancmean[j] = np.nanmean(ancdata * asgn) ancrms[j] = np.sqrt( np.nanmean((ancdata * asgn)**2) - ancmean[j]**2) print() # ---- report the median uncertainties print("The median fractional error in rad_pc is {:2.4f}".format( np.nanmedian(errms))) print("The median fractional error in vrms_k is {:2.4f}".format( np.nanmedian(evrms))) print("The median fractional error in mlumco is {:2.4f}".format( np.nanmedian(eflux))) # ---- apply a floor if requested if efloor > 0: print("Applying a minimum fractional error of {:2.3f}".format(efloor)) errms[errms < efloor] = efloor evrms[evrms < efloor] = efloor eflux[eflux < efloor] = efloor # ---- calculate the physical properties rms_pc = (cat['radius'] * dist).to(u.pc, equivalencies=u.dimensionless_angles()) maj_pc = (cat['major_sigma'] * dist).to( u.pc, equivalencies=u.dimensionless_angles()) rad_pc = rmstorad * rms_pc v_rms = cat['v_rms'].to(u.km / u.s) axrat = cat['minor_sigma'] / cat['major_sigma'] axrat.unit = "" ellarea = (cat['area_ellipse'] * dist**2).to( u.pc**2, equivalencies=u.dimensionless_angles()) xctarea = (cat['area_exact'] * dist**2).to( u.pc**2, equivalencies=u.dimensionless_angles()) if copbcor is not None and conoise is not None: # Convert from K*pix*ch to Jy*km/s #convfac = (1*u.K).to(u.Jy/u.arcsec**2, equivalencies=u.brightness_temperature(freq12)) #flux12 = tb12 * deltav.value * convfac.value * cdelt2.value**2 mlumco = alphaco * alphascale * tb12 * u.K * deltav * asarea * cdelt2.value**2 else: # lumco = Luminosity in K km/s pc^2 lumco = deltav * asarea * (cat['flux']).to( u.K, equivalencies=u.brightness_temperature(as2, freq)) mlumco = alphaco * alphascale * lumco siglum = mlumco / xctarea mvir = (5 * rmstorad * v_rms**2 * rms_pc / const.G).to( u.solMass) # Rosolowsky+ 08 emvir = (5 * rmstorad * v_rms**2 * maj_pc / w_ell(1. / axrat) / const.G).to(u.solMass) # Rosolowsky+ 08 sigvir = mvir / xctarea sigevir = emvir / xctarea alpha = mvir / mlumco # ---- make the physical properties table ptab = Table() ptab['_idx'] = Column(srclist) ptab['area_pc2'] = Column(xctarea, description='projected area of structure') ptab['rad_pc'] = Column(rad_pc, description='equivalent radius in pc') ptab['e_rad_pc'] = Column(errms, description='frac error in radius') ptab['vrms_k'] = Column(v_rms, description='rms linewidth in km/s') ptab['e_vrms_k'] = Column(evrms, description='frac error in linewidth') ptab['axratio'] = Column(axrat, unit='', description='minor to major axis ratio') ptab['e_axratio'] = Column(eaxra, description='frac error in axis ratio') if copbcor is not None and conoise is not None: #ptab['flux12'] = Column(flux12, unit='Jy km / s', description='CO flux in structure') #ptab['e_flux12'] = Column(eflux, description='frac error in CO flux') ptab['mlumco'] = Column(mlumco, description='CO-based mass with alphascale=' + str(alphascale) + ' from ' + os.path.basename(copbcor)) else: ptab['mlumco'] = Column( mlumco, description='Mass from scaling luminosity with alphascale=' + str(alphascale)) ptab['e_mlumco'] = Column(eflux, description='frac error in luminous mass') ptab['siglum'] = Column(siglum, description='average surface density from mlumco') ptab['e_siglum'] = Column(eflux, description='same as e_mlumco') ptab['mvir'] = Column(mvir, description='virial mass') ptab['e_mvir'] = Column(emvir, description='frac error in virial mass') ptab['emvir'] = Column(emvir, description='elliptical virial mass') ptab['e_emvir'] = Column( eemvir, description='frac error in elliptical virial mass') ptab['sigvir'] = Column(sigvir, description='virial surface density') ptab['e_sigvir'] = Column(emvir, description='same as e_mvir') ptab['sigevir'] = Column(sigevir, description='ell. virial surface density') ptab['e_sigevir'] = Column(emvir, description='same as e_mvir') ptab['alpha'] = Column(alpha, unit='', description='virial parameter') ptab['e_alpha'] = Column(ealpha, description='frac error in virial parameter') if ancfile is not None: if anclabel is None: anclabel = ancimg.replace('.', '_').split('_')[1] ptab[anclabel] = Column(ancmean, unit=anchd['BUNIT']) ancferr = indfac * ancrms / ancmean ptab['e_' + anclabel] = Column(ancferr) from ellfit import ellfit # add ellipse at half-max like in cprops halfmax_ell_maj = np.zeros(len(srclist), dtype=np.float64) halfmax_ell_min = np.zeros(len(srclist), dtype=np.float64) halfmax_ell_pa = np.zeros(len(srclist), dtype=np.float64) if clipping: tmax = cat['tmax-tmin'] else: tmax = cat['tmax'] for i, c in enumerate(srclist): if tmax[i] > 0: ind = d[c].indices() half_ind_z = np.where(cube[ind] > 0.5 * cube[ind].max())[0] z, y, x = ind # unique set of 2-d indices for the 3-d clump twod_id = x[half_ind_z] + y[half_ind_z] * (x[half_ind_z].max() + 1) # half_twod_ind = np.unique(twod_id[half_ind],return_index=True)[1] half_twod_ind = np.unique(twod_id, return_index=True)[1] half_twod_x = x[half_twod_ind] half_twod_y = y[half_twod_ind] halfmax_ell_maj[i], halfmax_ell_min[i], halfmax_ell_pa[i] = ellfit( half_twod_x, half_twod_y) ptab['halfmax_ell_maj'] = Column(halfmax_ell_maj, name='halfmax_ell_maj', unit='pix') ptab['halfmax_ell_min'] = Column(halfmax_ell_min, name='halfmax_ell_min', unit='pix') ptab['halfmax_ell_pa'] = Column(halfmax_ell_min, name='halfmax_ell_pa', unit='rad') # go ahead and add lte mass here to have all this in one place if n13cube != None: if os.path.exists(n13cube): print("adding MLTE from " + n13cube) srclist = ptab['_idx'].tolist() newcol = Column(name="mlte", data=np.zeros(np.size(srclist))) data = fits.getdata(n13cube) cubehdr = fits.getheader(n13cube) dx = cubehdr['cdelt2'] * 3600 / 206265 * dist.value # pc nu0 = cubehdr['restfrq'] if cubehdr['ctype3'] == 'VRAD' or cubehdr['ctype3'][0:3] == 'VEL': dv = cubehdr['cdelt3'] / 1000 else: dnu = cubehdr['cdelt3'] dv = 2.99792458e5 * np.absolute(dnu) / nu0 newcol.description = 'LTE mass using H2/13CO=' + str(co13toh2) if os.path.exists(n13errcube): e_newcol = Column(name="e_mlte", data=np.zeros(np.size(srclist))) uncert2 = fits.getdata(n13errcube)**2 e_newcol.description = 'LTE mass uncert.' for i, c in enumerate(srclist): mask = d[c].get_mask() if clipping: cmin = np.nanmin(data[np.where(mask)]) newcol[i] = np.nansum(data[np.where(mask)] - cmin) else: newcol[i] = np.nansum(data[np.where(mask)]) # nansum returns zero if all are NaN, want NaN chknan = np.asarray(np.isnan(data[np.where(mask)])) if chknan.all(): newcol[i] = np.nan if os.path.exists(n13errcube): e_newcol[i] = np.nansum(uncert2[np.where(mask)]) # nansum returns zero if all are NaN, want NaN chknan = np.asarray(np.isnan(uncert2[np.where(mask)])) if chknan.all(): e_newcol[i] = np.nan # Multiply by channel width in km/s and area in cm^2 to get molecule number newcol *= dv * (dx * 3.09e18)**2 # Convert from molecule number to solar masses including He newcol *= co13toh2 * 2 * 1.36 * 1.66e-24 / 1.99e33 newcol.unit = 'solMass' ptab['mlte'] = newcol if os.path.exists(n13errcube): e_newcol = np.sqrt(e_newcol) e_newcol *= dv * (dx * 3.09e18)**2 # Convert from molecule number to solar masses including He e_newcol *= co13toh2 * 2 * 1.36 * 1.66e-24 / 1.99e33 e_newcol.unit = 'solMass' ptab['e_mlte'] = e_newcol ptab.write(label + '_physprop' + clipstr + '.txt', format='ascii.ecsv', overwrite=True)
def main(args): # ------------------------------------------- # Load DataCube # ------------------------------------------- print('Load DataCube') hdu = fits.open(args.fits_file)[0] hdr = hdu.header wcs = WCS(header=hdr).celestial data = hdu.data nchan = data.shape[0] velo = (np.arange(nchan) - hdr['CRPIX3'] + 1) * hdr['CDELT3'] + hdr['CRVAL3'] ny = data.shape[1] nx = data.shape[2] # ------------------------ # unit convert: Jy/beam -> mJy/pix # ------------------------ beam = 4.7 # arcmin pix = 1.0 # arcmin pix_over_beam = pix**2/((beam/2)**2*np.pi) data = data * 1000 * pix_over_beam # x Jy/beam = (x * pix/beam) Jy/pix #------------------------ # Load dendrogram #------------------------ print('Load Dendrogram') d = Dendrogram.load_from(args.file_d+'.hdf5') print('') # ------------------------ # leaf label # ------------------------ list_idx = [] # raw index list_idv = [] # sorted index list_peak= [] # raw peaks for i, struc in enumerate(d.leaves): peak = struc.get_peak()[1] list_peak.append(peak) list_idx.append(struc.idx) peak_ind = np.argsort(np.array(list_peak))[::-1] leaves_idx_arr = np.array(list_idx)[peak_ind] # ------------------------ # init CSV # ------------------------ if args.file_csv is not None: import csv fcsv = open(args.file_csv,'w') fieldnames = ['Index', 'GName', 'GLon', 'GLat', 'Coordinate', \ 'Peak', 'Peak_err', 'VLSR', 'VLSR_err', 'FWHM', 'FWHM_err',\ 'Flux_int', 'Area', 'D_far', 'D_near','He2H'] writer = csv.DictWriter(fcsv,fieldnames=fieldnames,quoting=csv.QUOTE_NONE) writer.writeheader() # ------------------------ for i in range(len(d.leaves)): ind = peak_ind[i] struc = d.leaves[ind] leaf_label = np.argwhere(leaves_idx_arr == struc.idx)[0][0]+1 peak = struc.get_peak()[0] v_p = args.chan_0+peak[0] x_p = peak[2] y_p = peak[1] coor = SkyCoord.from_pixel(x_p,y_p,wcs) equ_str = coor.to_string(style='hmsdms',precision=0) gc = coor.transform_to('galactic') gal_str = 'G{:5.2f}{:+5.2f}'.format(gc.l.value,gc.b.value) if struc.idx == 30: wbounds = [10,30] else: wbounds = [5,30] spec, peak,vlsr,fwhm,err1,err2,err3,size = struc_spec(struc,data,velo,args.chan_0,nchan,nx,ny,wbounds=wbounds,method=args.method) r_he2h = calc_he2h_rms(velo,spec, peak, vlsr,fwhm,v_res=0.5) d_far,d_near = vlsr_distance(gc.l.value,vlsr) print("{index:02d} {Gname} {Coor} {peak:5.2f}$\pm${perr:4.2f} {vlsr:4.1f}$\pm${verr:3.1f} {fwhm:4.1f}$\pm${werr:3.1f} {integ:8.2f} {area:3d} {d1:4.1f} {d2:4.1f} {he2h:4.2f}".format(index=leaf_label,Gname=gal_str,Coor=equ_str,peak=peak,perr=err1,vlsr=vlsr,verr=err2,fwhm=fwhm,werr=err3,integ=peak*fwhm,area=size,d1=d_far,d2=d_near,he2h=r_he2h)) if args.file_csv is not None: row = {'Index':leaf_label, 'GName':gal_str,\ 'GLon':gc.l.value, 'GLat':gc.b.value,'Coordinate':equ_str,\ 'Peak':peak, 'Peak_err':err1,'VLSR':vlsr, 'VLSR_err':err2,\ 'FWHM':fwhm, 'FWHM_err':err3, 'Flux_int':peak*fwhm,\ 'Area':size, 'D_far':d_far, 'D_near':d_near,'He2H':r_he2h} writer.writerow(row) if args.file_csv is not None: fcsv.close() return 0
def get_dendrogram(self, field, axis): self.get_dendrogram_name(field, axis) return Dendrogram.load_from(self.dendrogram_name)
def doSCIMES(self, CO12FITS, dendroFITS, catName, saveMarker, criteriaUsed=None, scales=None, saveAll=True, inputD=None): #since reading dendrogram if inputD == None: d = Dendrogram.load_from(dendroFITS) else: d = inputD cat = Table.read(catName) hdu = fits.open(CO12FITS)[0] dataCO = hdu.data headCO = hdu.header print "" print len(cat), "<-- total number of structures?" treeFile = "tmpTree{}.txt".format(saveMarker) self.writeTreeStructure(d, treeFile) newVo, newVe, newRatio, newFlux, lostFlux = self.getTrueVolumeAndVrms( treeFile, catName) cat[self.myVolume] = newVo cat[self.myVrms] = newVe cat[self.myRatio] = newRatio cat[self.myFlux] = newFlux cat[self.lostFluxRatio] = lostFlux print "Processing clustering..." if criteriaUsed != None and scales != None: res = SpectralCloudstering(d, cat, headCO, criteria=criteriaUsed, user_scalpars=scales, blind=True, rms=self.rms, s2nlim=3, save_all=saveAll, user_iter=1) else: res = SpectralCloudstering(d, cat, headCO, criteria=["volume", "luminosity"], blind=True, rms=self.rms, s2nlim=3, save_all=saveAll, user_iter=1) print "Done..." res.clusters_asgn.writeto('ClusterAsgn_{}.fits'.format(saveMarker), overwrite=True) clusterCat = cat[res.clusters] clusterCat.write("ClusterCat_{}.fit".format(saveMarker), overwrite=True) cat.write( "DendroCatExtended_{}.fit".format(saveMarker), overwrite=True ) #same as the catlog of dendrogram, but with several extended columns. used to see how good the criterin