def cross_match_CSAR(getsources_core_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', CSAR_catalog = '/mnt/scratch-lustre/jkeown/DS9_regions/L1157/CSAR/CEPl1157_CSAR.dat', high_res_coldens_image = '/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_255_mu.image.resamp.fits', CSAR_core_indices='L1157_matched_CSAR_cores.dat'): # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] ### Import the CSAR catalog ### ***MAKE SURE FIRST TWO COLUMNS OF "CSAR_catalog" FILE ARE X_POSITION AND Y_POSITION OF SOURCE IN DECIMAL DEGREES*** CSAR_array = numpy.loadtxt(CSAR_catalog,comments='#') #print CSAR_array CSAR_positions = numpy.column_stack((CSAR_array[:,0], CSAR_array[:,1])) #print CSAR_positions w = wcs.WCS(high_res_coldens_image) pos_pix = w.wcs_world2pix(CSAR_positions, 1) ### Loop through the potential matched cores identified in the step above. counter = 0 matched_cores = [] for line in cores_array: x_coor = str(line[3]) y_coor = str(line[4]) ### Create a DS9 region string for the core's getsources ellipse, ### from which a mask will be created. region = ('fk5;ellipse(' + x_coor + ', ' + y_coor + ', ' + str((line[50]/2.0)/3600.) + ', ' + str((line[51]/2.0)/3600.) + ', ' + str(line[52]+90.0)+')') r = pyregion.parse(region) f=fits.open(high_res_coldens_image) mymask = r.get_mask(hdu=f[0]) f.close() newmask=mymask ### Set all values outside the core's ellipse to zero, ### all values inside the ellipse are set to one. newmask=numpy.where(newmask==0,0,1) mask_shape = numpy.shape(newmask) ### Loop through the CSAR catalog ### If any CSAR cores fall within a getsources core's ellipse, ### store the getsources core's index match_counter=0 for i in pos_pix: ypos = int(round(i[1],0))-1 xpos = int(round(i[0],0))-1 if ypos<=mask_shape[0] and xpos<=mask_shape[1]: if newmask[ypos][xpos]==1 and match_counter==0: matched_cores.append(counter) # match_counter prevents counting indices twice # if two CSAR cores fall within getsources ellipse match_counter+=1 #print len(matched_cores) counter += 1 print 'CSAR_matched:total ratio =' + str(round(float(len(matched_cores)) / float(len(cores_array[:,0])),3)) ### Save the CSAR matched core indices to a file #numpy.savetxt(CSAR_core_indices, matched_cores, fmt='%i') return numpy.array(matched_cores)
def make_DS9_regions_good_cores(getsources_core_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', DS9_region_directory = '/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/', catalog_type=False, cross_matched_core_indices=False, candidate_prestellar_indices=False, robust_prestellar_indices=False): if catalog_type=='all_cores': # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] save_file_name = '_all_cores_good.reg' new_line = ' #color=green width=2\n' elif catalog_type=='proto': # Import the raw getsources protostar catalog protostar_array1 = numpy.loadtxt(YSO_catalog,comments='!', unpack=True) # Find the indices of the "good" protostars that pass HGBS selection criteria good_proto_indices = good_protostars_getsources.get_good_protostars(YSO_catalog) # Create new array of only the "good" protostars to be used for our analysis # Not sure why the transpose below is needed, but it seems the protostar_array1 # is imported transposed. This doesn't seem to be the case for the core_array1 cores_array = protostar_array1.T[numpy.array(good_proto_indices)] save_file_name = '_proto_good.reg' new_line = ' #color=red width=2\n' elif catalog_type=='proto_cores': cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] cores_array = cores_array[numpy.array(cross_matched_core_indices)] save_file_name = '_protostellar_cores.reg' new_line = ' #color=yellow width=2\n' elif catalog_type=='starless_cores': cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] indices = numpy.arange(len(cores_array[:,0])) for i in cross_matched_core_indices: indices_minus_protostellar_cores = filter(lambda a: a!=i,indices) indices = indices_minus_protostellar_cores cores_array = cores_array[numpy.array(indices)] save_file_name = '_starless_cores.reg' new_line = ' #color=magenta width=2\n' elif catalog_type=='prestellar_candidates': cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] cores_array = cores_array[numpy.array(candidate_prestellar_indices[0])] save_file_name = '_prestellar_candidates.reg' new_line = ' #color=brown width=2\n' elif catalog_type=='prestellar_robust': cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] cores_array = cores_array[numpy.array(robust_prestellar_indices[0])] save_file_name = '_prestellar_robust.reg' new_line = ' #color=blue width=2\n' header = 'Region file format: DS9 version 4.1 \nglobal color=green dashlist=8 3 width=2 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 \nfk5' ellipse = [] for i in cores_array[:,0]: ellipse.append('ellipse') number = [1, 2, 3, 4, 5, 6, 7] A = [cores_array[:,14], cores_array[:,23], cores_array[:,32], cores_array[:,41], cores_array[:,50], cores_array[:,59], cores_array[:,68]] B = [cores_array[:,15], cores_array[:,24], cores_array[:,33], cores_array[:,42], cores_array[:,51], cores_array[:,60], cores_array[:,69]] T = [cores_array[:,16], cores_array[:,25], cores_array[:,34], cores_array[:,43], cores_array[:,52], cores_array[:,61], cores_array[:,70]] f = 0 for wavelength in number: string = (numpy.array(A[f])/2.)/3600. #Divide by two because DS9 takes radius rather than FWHM (or diameter) &&& convert arcseconds to degrees string2 = [] for i in string: string2.append(str(i)) #string3 = [] #for i in string2: # string3.append(i+'"') AFWHM = string2 string = (numpy.array(B[f])/2.)/3600. string2 = [] for i in string: string2.append(str(i)) #string3 = [] #for i in string2: # string3.append(i+'"') BFWHM = string2 # theta is given as degrees E of N in getsources, but degrees ccw from the +ve x-axis in ds9. THEP_adjusted = numpy.array(T[f]) + 90.0 # Must divide FWHM by 2 because DS9 region files use a radius as input rather than diameter or "full width" data = numpy.column_stack((ellipse, cores_array[:,3], cores_array[:,4], AFWHM, BFWHM, THEP_adjusted)) wave = ['070', '160', '165', '250', '255', '350', '500'] numpy.savetxt(DS9_region_directory + wave[f]+save_file_name, data, delimiter=' ', fmt = '%s', header=header, newline=new_line) f = f + 1 # Write over the third line in the created files # If this is not added, the "fk5" string remains commented out in the header files = ['070' + save_file_name,'160' + save_file_name,'165' + save_file_name, '250' + save_file_name,'255' + save_file_name,'350' + save_file_name,'500' + save_file_name] for i in files: with open(DS9_region_directory + i, 'r') as file: data = file.readlines() data[2] = "fk5 \n" with open(DS9_region_directory + i, 'w') as file: file.writelines(data)
def make_DS9_regions_good_cores( getsources_core_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', DS9_region_directory='/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/', catalog_type=False, cross_matched_core_indices=False, candidate_prestellar_indices=False, robust_prestellar_indices=False): if catalog_type == 'all_cores': # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] save_file_name = '_all_cores_good.reg' new_line = ' #color=green width=2\n' elif catalog_type == 'proto': # Import the raw getsources protostar catalog protostar_array1 = numpy.loadtxt(YSO_catalog, comments='!', unpack=True) # Find the indices of the "good" protostars that pass HGBS selection criteria good_proto_indices = good_protostars_getsources.get_good_protostars( YSO_catalog) # Create new array of only the "good" protostars to be used for our analysis # Not sure why the transpose below is needed, but it seems the protostar_array1 # is imported transposed. This doesn't seem to be the case for the core_array1 cores_array = protostar_array1.T[numpy.array(good_proto_indices)] save_file_name = '_proto_good.reg' new_line = ' #color=red width=2\n' elif catalog_type == 'proto_cores': cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] cores_array = cores_array[numpy.array(cross_matched_core_indices)] save_file_name = '_protostellar_cores.reg' new_line = ' #color=yellow width=2\n' elif catalog_type == 'starless_cores': cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] indices = numpy.arange(len(cores_array[:, 0])) for i in cross_matched_core_indices: indices_minus_protostellar_cores = filter(lambda a: a != i, indices) indices = indices_minus_protostellar_cores cores_array = cores_array[numpy.array(indices)] save_file_name = '_starless_cores.reg' new_line = ' #color=magenta width=2\n' elif catalog_type == 'prestellar_candidates': cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] cores_array = cores_array[numpy.array(candidate_prestellar_indices[0])] save_file_name = '_prestellar_candidates.reg' new_line = ' #color=brown width=2\n' elif catalog_type == 'prestellar_robust': cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] cores_array = cores_array[numpy.array(robust_prestellar_indices[0])] save_file_name = '_prestellar_robust.reg' new_line = ' #color=blue width=2\n' header = 'Region file format: DS9 version 4.1 \nglobal color=green dashlist=8 3 width=2 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 \nfk5' ellipse = [] for i in cores_array[:, 0]: ellipse.append('ellipse') number = [1, 2, 3, 4, 5, 6, 7] A = [ cores_array[:, 14], cores_array[:, 23], cores_array[:, 32], cores_array[:, 41], cores_array[:, 50], cores_array[:, 59], cores_array[:, 68] ] B = [ cores_array[:, 15], cores_array[:, 24], cores_array[:, 33], cores_array[:, 42], cores_array[:, 51], cores_array[:, 60], cores_array[:, 69] ] T = [ cores_array[:, 16], cores_array[:, 25], cores_array[:, 34], cores_array[:, 43], cores_array[:, 52], cores_array[:, 61], cores_array[:, 70] ] f = 0 for wavelength in number: string = ( numpy.array(A[f]) / 2. ) / 3600. #Divide by two because DS9 takes radius rather than FWHM (or diameter) &&& convert arcseconds to degrees string2 = [] for i in string: string2.append(str(i)) #string3 = [] #for i in string2: # string3.append(i+'"') AFWHM = string2 string = (numpy.array(B[f]) / 2.) / 3600. string2 = [] for i in string: string2.append(str(i)) #string3 = [] #for i in string2: # string3.append(i+'"') BFWHM = string2 # theta is given as degrees E of N in getsources, but degrees ccw from the +ve x-axis in ds9. THEP_adjusted = numpy.array(T[f]) + 90.0 # Must divide FWHM by 2 because DS9 region files use a radius as input rather than diameter or "full width" data = numpy.column_stack( (ellipse, cores_array[:, 3], cores_array[:, 4], AFWHM, BFWHM, THEP_adjusted)) wave = ['070', '160', '165', '250', '255', '350', '500'] numpy.savetxt(DS9_region_directory + wave[f] + save_file_name, data, delimiter=' ', fmt='%s', header=header, newline=new_line) f = f + 1 # Write over the third line in the created files # If this is not added, the "fk5" string remains commented out in the header files = [ '070' + save_file_name, '160' + save_file_name, '165' + save_file_name, '250' + save_file_name, '255' + save_file_name, '350' + save_file_name, '500' + save_file_name ] for i in files: with open(DS9_region_directory + i, 'r') as file: data = file.readlines() data[2] = "fk5 \n" with open(DS9_region_directory + i, 'w') as file: file.writelines(data)
def auto_zoomed_cores(region='Aquila', distance=260.): print region getsources_core_catalog = '/mnt/scratch-lustre/jkeown/GS_Extractions/GS-Extractions/' + region + '/' + region + '.sw.final.reliable.ok.cat' core_figure_directory = '/mnt/scratch-lustre/jkeown/JCMT_GBS_Jybeam/JCMT_pipeline/Figures/' + region + '/core_figures/' JCMT_450um_image = '/mnt/scratch-lustre/jkeown/GS_Extractions/GS-Extractions/' + region + '/' + region + '_450_Jybeam.m.fits' JCMT_850um_image = '/mnt/scratch-lustre/jkeown/GS_Extractions/GS-Extractions/' + region + '/' + region + '_850_Jybeam.m.fits' # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores(region=region) cores_array = cores_array1[numpy.array(good_core_indices)] if region == 'PipeE1': cores_array = numpy.array(cores_array1) z = numpy.zeros(len(cores_array)) cores_array = numpy.stack((cores_array, z)) core_center_RA = cores_array[:, 3] core_center_Dec = cores_array[:, 4] core_index = 1 for line in cores_array: x_coor = str(line[3]) y_coor = str(line[4]) AFWHM_array = [line[14], line[23]] # 450, 850 BFWHM_array = [line[15], line[24]] Theta_array = [line[16], line[25]] SIG_array = [line[8], line[17]] images_array = [JCMT_450um_image, JCMT_850um_image] wavelengths = ['450', '850'] maximums = numpy.zeros(len(AFWHM_array)) minimums = numpy.zeros(len(AFWHM_array)) counter = 0 for i in wavelengths: ### Create a DS9 region string for the core's getsources ellipse, ### from which a mask will be created. region1 = ('fk5;ellipse(' + x_coor + ', ' + y_coor + ', ' + str(AFWHM_array[counter] / 3600.) + ', ' + str(BFWHM_array[counter] / 3600.) + ', ' + str(Theta_array[counter] + 90.) + ')') r = pyregion.parse(region1) f = fits.open(images_array[counter]) header_primary = fits.getheader(images_array[counter]) data = fits.getdata(images_array[counter]) mymask = r.get_mask(hdu=f[0]) newmask = numpy.where(mymask != 0) maximums[counter] = max(data[newmask]) minimums[counter] = min(data[newmask]) region2 = ('fk5;box(' + x_coor + ', ' + y_coor + ', ' + str(0.04) + ', ' + str(0.04) + ', ' + str(0.0) + ')') r = pyregion.parse(region2) mymask = r.get_mask(hdu=f[0]) newmask = numpy.where(mymask != 0) f.close() newmask2 = numpy.where(mymask == 0, 0, data) fits.writeto(region + '_' + i + '_contour_mask.fits', newmask2, header_primary, clobber=True) counter += 1 microns = ['mu_450', 'mu_850'] if maximums[0] < 0.: maximums[0] = 10.0 if minimums[0] < 0.: minimums[0] = -5.0 v_max = maximums v_min = minimums contour_levels = [(maximums[0] * 0.3, maximums[0] * 0.5, maximums[0] * 0.7, maximums[0] * 0.9), (maximums[1] * 0.3, maximums[1] * 0.5, maximums[1] * 0.7, maximums[1] * 0.9)] fig = plt.figure() #figsize=(8,5.5) f = 0 for i in wavelengths: microns[f] = aplpy.FITSFigure(region + '_' + i + '_contour_mask.fits', figure=fig, subplot=(2, 1, f + 1)) microns[f].recenter(line[3], line[4], 0.01) microns[f].show_contour(region + '_' + i + '_contour_mask.fits', colors=('white', 'white', 'white', 'grey'), levels=contour_levels[f], overlap=True) microns[f].show_colorscale(cmap='gist_stern', vmin=v_min[f], vmax=v_max[f]) #microns[f].show_regions('/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/L1157_core_SED/255_all_cores_good.reg') microns[f].add_colorbar() microns[f].colorbar.set_axis_label_text('Jy/beam') scale = str('{:.2f}'.format( 2 * (distance * numpy.tan(numpy.radians(0.5 * (1.0 / 60.)))))) if f == 0: microns[f].add_scalebar( (1. / 60.), path_effects=[ Patheffects.withStroke(linewidth=3, foreground='white') ]) microns[f].scalebar.show( 1. / 60.) # length in degrees (one arcminute) microns[f].scalebar.set_corner('top left') microns[f].scalebar.set_label('1' + "'" + ' = ' + scale + ' pc') if SIG_array[f] > 5.: line_type = 'solid' else: line_type = 'dashed' microns[f].show_ellipses(line[3], line[4], AFWHM_array[f] / 3600., BFWHM_array[f] / 3600., Theta_array[f] + 90., color='#00FF00', zorder=10, linewidth=1.0, linestyle=line_type) #microns[f].show_markers(line[3], line[4], c='#00FF00', marker='x', zorder=10, linewidths=1.5,s=20) #microns[f].show_markers(line[3], line[4], c='black', marker='x', zorder=9, linewidths=2.0,s=30) microns[f].tick_labels.hide() microns[f].axis_labels.hide() #microns[f].set_title('L' + name) microns[f].add_label(0.3, 0.1, i + ' $\mu$' + 'm', relative=True, path_effects=[ Patheffects.withStroke(linewidth=3, foreground='white') ]) f = f + 1 fig.subplots_adjust(hspace=0.05, wspace=0.35) fig.canvas.draw() fig.suptitle('Core Number ' + str(core_index) + ' - RA: ' + str(line[3]) + ' Dec: ' + str(line[4])) fig.savefig(core_figure_directory + 'core' + str(core_index) + '.pdf') print 'Core Number = ' + str(core_index) for i in range(2): microns[i].close() core_index = core_index + 1
def cross_match(getsources_core_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', high_res_coldens_image = '/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_255_mu.image.resamp.fits', proto_core_indices='L1157_matched_protostellar_cores.dat'): # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 = numpy.loadtxt(YSO_catalog,comments='!', unpack=True) good_proto_indices = good_protostars_getsources.get_good_protostars(YSO_catalog) #print len(good_proto_indices) ### Loop through entire core catalog to find cores that are close to YSOs. ### This step significantly reduces the time it would take to run through ### entire catalog. potential_matches = [] count = 0 for line in cores_array: match_counter=0 for i in good_proto_indices: distance = ((line[3]-WCS_ACOOR[i])**2 + (line[4]-WCS_DCOOR[i])**2)**0.5 if distance < 200.0/3600. and match_counter==0: # matched_counter prevents counting indices twice # if two YSO candidates fall within getsources ellipse potential_matches.append(count) match_counter+=1 count += 1 #print len(potential_matches) ### Loop through the potential matched cores identified in the step above. matched_cores = [] matched_cores_proto_index = [] for value in potential_matches: line = cores_array[value] x_coor = str(line[3]) y_coor = str(line[4]) ### Create a DS9 region string for the core's getsources ellipse, ### from which a mask will be created. region = ('fk5;ellipse(' + x_coor + ', ' + y_coor + ', ' + str((line[50]/2.0)/3600.) + ', ' + str((line[51]/2.0)/3600.) + ', ' + str(line[52]+90.0)+')') r = pyregion.parse(region) f=fits.open(high_res_coldens_image) mymask = r.get_mask(hdu=f[0]) f.close() newmask=mymask ### Set all values outside the core's ellipse to zero, ### all valus inside the ellipse are set to one. newmask=numpy.where(newmask==0,0,1) ### Loop through the 70 micron point sources ### If any fall within a core's ellipse, store that core's index match_counter=0 good_protostar_index = 0 for i in good_proto_indices: if newmask[int(round(YCO_P[i],0))-1][int(round(XCO_P[i],0))-1]!=0 and match_counter==0: matched_cores.append(value) matched_cores_proto_index.append(good_protostar_index) # matched_counter prevents counting indices twice # if two YSO candidates fall within getsources ellipse match_counter+=1 good_protostar_index+=1 else: good_protostar_index+=1 #print len(matched_cores) #print matched_cores #print matched_cores_proto_index ### Save the protostellar core indices to a file #numpy.savetxt(proto_core_indices, matched_cores, fmt='%i') # Return indices of matched cores and protostars from the "good" lists of each # i.e., The indices are the index from the "good" lists and not the unprocessed original, total getsources list return numpy.column_stack((numpy.array(matched_cores), numpy.array(matched_cores_proto_index)))
def auto_zoomed_cores(getsources_core_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', core_figure_directory = '/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/core_figures/', Herschel_70um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cepL1157_070_mu_emission.image.resamp.fits', Herschel_160um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cepL1157_160_mu_emission.image.resamp.fits', Herschel_250um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_250_mu.image.resamp.fits', Herschel_350um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_350_mu.image.resamp.fits', Herschel_500um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_500_mu.image.resamp.fits', Herschel_coldens_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_255_mu.image.resamp.fits', distance=325.): # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] core_center_RA = cores_array[:,3] core_center_Dec = cores_array[:,4] core_index = 1 for line in cores_array: x_coor = str(line[3]) y_coor = str(line[4]) AFWHM_array = [line[14], line[23], line[41], line[59], line[68], line[50]] # 70,160,250,350,500,coldens BFWHM_array = [line[15], line[24], line[42], line[60], line[69], line[51]] Theta_array = [line[16], line[25], line[43], line[61], line[70], line[52]] SIG_array = [line[8], line[17], line[35], line[53], line[62], line[44]] images_array = [Herschel_70um_image, Herschel_160um_image, Herschel_250um_image, Herschel_350um_image, Herschel_500um_image, Herschel_coldens_image] wavelengths = ['070', '160', '250', '350', '500', '255'] maximums = numpy.zeros(len(AFWHM_array)) minimums = numpy.zeros(len(AFWHM_array)) counter = 0 for i in wavelengths: ### Create a DS9 region string for the core's getsources ellipse, ### from which a mask will be created. region = ('fk5;box(' + x_coor + ', ' + y_coor + ', ' + str(0.05) + ', ' + str(0.05) + ', ' + str(0.0)+')') r = pyregion.parse(region) f = fits.open(images_array[counter]) header_primary = fits.getheader(images_array[counter]) data = fits.getdata(images_array[counter]) mymask = r.get_mask(hdu=f[0]) newmask=numpy.where(mymask!=0) maximums[counter] = max(data[newmask]) minimums[counter] = min(data[newmask]) f.close() newmask2=numpy.where(mymask==0, 0, data) fits.writeto(i + '_contour_mask.fits', newmask2, header_primary, clobber=True) counter+=1 microns = ['mu_070', 'mu_160', 'mu_250', 'mu_350', 'mu_500', 'mu_255'] v_max = maximums v_min = minimums contour_levels = [(maximums[0]*0.3,maximums[0]*0.5,maximums[0]*0.7,maximums[0]*0.9), (maximums[1]*0.3,maximums[1]*0.5,maximums[1]*0.7,maximums[1]*0.9), (maximums[2]*0.3,maximums[2]*0.5,maximums[2]*0.7,maximums[2]*0.9), (maximums[3]*0.3,maximums[3]*0.5,maximums[3]*0.7,maximums[3]*0.9), (maximums[4]*0.3,maximums[4]*0.5,maximums[4]*0.7,maximums[4]*0.9), (maximums[5]*0.3,maximums[5]*0.5,maximums[5]*0.7,maximums[5]*0.9)] fig = plt.figure(figsize=(8,5.5)) f=0 for i in wavelengths: microns[f]=aplpy.FITSFigure(i + '_contour_mask.fits', figure=fig, subplot=(2,3,f+1)) microns[f].recenter(line[3],line[4],0.025) microns[f].show_contour(i + '_contour_mask.fits', colors=('white', 'white', 'white','grey'), levels=contour_levels[f], overlap=True) microns[f].show_colorscale(cmap='gist_stern', vmin=v_min[f], vmax=v_max[f]) #microns[f].show_regions('/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/L1157_core_SED/255_all_cores_good.reg') microns[f].add_colorbar() if f==2 or f==5: microns[f].colorbar.set_axis_label_text('MJy/sr') scale = str('{:.2f}'.format(2*(distance*numpy.tan(numpy.radians(0.5*(1.0/60.)))))) if f==0: microns[f].add_scalebar((1./60.), path_effects=[Patheffects.withStroke(linewidth=3, foreground='white')]) microns[f].scalebar.show(1./60.) # length in degrees (one arcminute) microns[f].scalebar.set_corner('top left') microns[f].scalebar.set_label('1' + "'" + ' = ' + scale + ' pc') if SIG_array[f]>5.: line_type = 'solid' else: line_type = 'dashed' microns[f].show_ellipses(line[3], line[4], AFWHM_array[f]/3600., BFWHM_array[f]/3600., Theta_array[f]+90., color='#00FF00', zorder=10, linewidth=1.0, linestyle=line_type) #microns[f].show_markers(line[3], line[4], c='#00FF00', marker='x', zorder=10, linewidths=1.5,s=20) #microns[f].show_markers(line[3], line[4], c='black', marker='x', zorder=9, linewidths=2.0,s=30) microns[f].tick_labels.hide() microns[f].axis_labels.hide() #microns[f].set_title('L' + name) if i=='255': microns[f].add_label(0.3,0.1,'N$_{H2}$',relative=True, path_effects=[Patheffects.withStroke(linewidth=3, foreground='white')]) else: microns[f].add_label(0.3,0.1,i + ' $\mu$' + 'm',relative=True, path_effects=[Patheffects.withStroke(linewidth=3, foreground='white')]) f=f+1 fig.subplots_adjust(hspace=0.05, wspace=0.35) fig.canvas.draw() fig.suptitle('Core Number ' + str(core_index) + ' - RA: ' + str(line[3]) + ' Dec: ' + str(line[4])) fig.savefig(core_figure_directory + 'core' +str(core_index) + '.pdf') print 'Core Number = ' + str(core_index) for i in range(6): microns[i].close() core_index = core_index + 1
def core_mass_fits(region_name='Aquila', T_Dust=15.0, T_Dust_err=3.0, distance=260., Dunham_YSOs_file='Dunham_YSOs.dat'): getsources_core_catalog = '/mnt/scratch-lustre/jkeown/GS_Extractions/GS-Extractions/' + region_name + '/' + region_name + '.sw.final.reliable.ok.cat' SED_figure_directory = '/mnt/scratch-lustre/jkeown/JCMT_GBS_Jybeam/JCMT_pipeline/Figures/' + region_name + '/' # These are the values in each column of "cores_array" and "protostar_array" #NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02 # These are the values in each column of the "additional" "cores_array" and "protostar_array" # NO XCO_P YCO_P PEAK_SRC01 PEAK_BGF01 CONV_SRC01 CONV_BGF01 PEAK_SRC02 PEAK_BGF02 CONV_SRC02 CONV_BGF02 # Import the raw getsources core catalog (includes "bad" sources that don't pass HGBS selection criteria) cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') # Find the indices of the "good" cores that pass HGBS selection criteria good_core_indices = good_cores_getsources.get_good_cores(region_name) # Create new array of only the "good" cores to be used for our analysis cores_array = cores_array1[numpy.array(good_core_indices)] if region_name == 'PipeE1': cores_array = numpy.array(cores_array1) print cores_array z = numpy.zeros(len(cores_array)) cores_array = numpy.stack((cores_array, z)) print cores_array # Calculate the deconvolved core radii AFWH05 = cores_array[:, 23] BFWH05 = cores_array[:, 24] A = numpy.float64(((((AFWH05) / 60.) / 60.) * numpy.pi) / 180.) #radians A1 = numpy.float64(numpy.tan(A / 2.) * 2. * distance) #pc B = numpy.float64(((((BFWH05) / 60.) / 60.) * numpy.pi) / 180.) #radians B1 = numpy.float64(numpy.tan(B / 2.) * 2. * distance) #pc FWHM_mean = mstats.gmean([A1, B1]) HPBW = numpy.float64(((((14.1) / 60.) / 60.) * numpy.pi) / 180.) #radians HPBW1 = numpy.float64(numpy.tan(HPBW / 2.) * 2. * distance) #pc R_deconv = ((FWHM_mean**2.0) - (HPBW1**2.0))**0.5 #pc R_deconv = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0)) <= 0., FWHM_mean, R_deconv) resolved = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0)) <= 0., 0, 1) # Calculate the Bonnor-Ebert masses of each core based on their R_deconvolved c_s = 0.2 #km/s G = 4.302 * 10**-3 #pc/M_solar (km/s)^2 M_BE = (2.4 * R_deconv * (c_s**2.)) / G #M_solar #M_BE = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0))<0, 9999., M_BE) # Define a function that produces a Flux given wavelength, Temp, and Mass # We will input wavelength then find T and M using least squares minimization below def core_mass(wavelength, T, M): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = numpy.array(wavelength) * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = (0.12 * (numpy.exp(exponent) - 1.0))**-1.0 bbb = (0.1 * ((numpy.array(wavelength) / 300.)**-2.0)) / 0.01 ccc = (D / 100.)**-2 ddd = wavelength_mm**-3. return M * aaa * bbb * ccc * ddd # Define another function that calculates Mass directly from wavelength, Temp, and Flux # This will be used to find the Mass of cores that don't have reliable least-squares fits def core_mass_from_flux(wavelength, T, S_v): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = 0.12 * (numpy.exp(exponent) - 1.0) bbb = ((0.1 * ((wavelength / 300.)**-2.0)) / 0.01)**-1.0 ccc = (D / 100.)**2.0 ddd = wavelength_mm**3.0 return S_v * aaa * bbb * ccc * ddd # Define another function that calculates Mass uncertainty due to temp def core_mass_err_dT(wavelength, T, S_v, dT): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = 0.12 * (numpy.exp(exponent)) bbb = ((0.1 * ((wavelength / 300.)**-2.0)) / 0.01)**-1.0 ccc = (D / 100.)**2.0 ddd = wavelength_mm**3.0 eee = 1.439 * 10 * (wavelength_mm**-1) * (T**-2.) return S_v * aaa * bbb * ccc * ddd * dT * eee # Define another function that calculates Mass uncertainty due to flux def core_mass_err_dS_v(wavelength, T, S_v, dS_v): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = 0.12 * (numpy.exp(exponent) - 1.0) bbb = ((0.1 * ((wavelength / 300.)**-2.0)) / 0.01)**-1.0 ccc = (D / 100.)**2.0 ddd = wavelength_mm**3.0 return aaa * bbb * ccc * ddd * dS_v # Create some empty arrays to which we will append accepted values Masses = [] Temps = [] Masses_err = [] Temps_err = [] counter = 0 # Loop through all the "good" cores for NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02 in cores_array: #flux_err_run1 = [FXT_BEST01/SIG_MONO01, FXT_BEST02/SIG_MONO02] ## Should these be FXP_BEST? # Find the longest significant wavelength and corresponding flux wave = 850. flux_fit = FXT_BEST02 # Fluxes are in mJy, so multiple by 10^3 to get Jy flux_fit_err = FXT_ERRO02 # Fluxes are in mJy, so multiple by 10^3 to get Jy # Find the mass corresponding to that flux measurement # ***This uses the median of the best-fit Temps from the cores with # reliable SED fits (i.e., those that pass the test above) Mass_fit = core_mass_from_flux(wave, T_Dust, flux_fit) # Can add more uncertainties (e.g., calibration, etc.) below Mass_error = ( core_mass_err_dT(wave, T_Dust, flux_fit, T_Dust_err) + core_mass_err_dS_v(wave, T_Dust, flux_fit, flux_fit_err)**2.0)**0.5 # Store the Mass with uncertainties # Need to perform a more in-depth error analysis Masses.append(Mass_fit) Masses_err.append(Mass_error) Temps.append(T_Dust) Temps_err.append(T_Dust_err) #Replace nans if they exist in the M_BE array if len(cores_array) > 1: where_are_nans = numpy.isnan(M_BE) M_BE[where_are_nans] = 9999 # Calculate the alpha_BE ratio to determine prestellar cores alpha_BE = numpy.array(M_BE) / numpy.array(Masses) #alpha_BE = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0))<0, 9999., alpha_BE) # Create an array indicating a core as candidate(1)/robust(2) prestellar candidate_array = numpy.where(alpha_BE <= 5.0, 1, 0) #candidate_array = numpy.where(alpha_BE<=alpha_factor, 1, 0) robust_candidate_array = numpy.where(alpha_BE <= 2.0, 2, candidate_array) # Remove protostars from the alpha_BE array and find the indices of the remaining # candidate/robust prestellar cores robust_prestellar_indices = numpy.where(alpha_BE <= 2.0) candidate_prestellar_indices = numpy.where(alpha_BE <= 5.0) Masses2 = numpy.array(Masses) # Find the final list of prestellar candidate/robust Masses with protostars removed prestellar_candidates = Masses2[numpy.array( candidate_prestellar_indices[0])] prestellar_robust = Masses2[numpy.array(robust_prestellar_indices[0])] print 'prestellar candidates: ' + str(len(prestellar_candidates)) print 'robust prestellar candidates: ' + str(len(prestellar_robust)) # Plot Mass versus Radius and save the figure fig = plt.figure() plt.scatter(R_deconv, Masses, label='starless') if len(Masses) > 1: plt.scatter(R_deconv[numpy.array(candidate_prestellar_indices[0])], prestellar_candidates, color='red', label='candidate') plt.scatter(R_deconv[numpy.array(robust_prestellar_indices[0])], prestellar_robust, color='green', label='robust') plt.yscale('log') plt.xscale('log') #plt.legend() plt.title(region_name + ' Cores') plt.ylabel("Mass, M (M$_\odot$)") plt.xlabel("Deconvolved FWHM size, R (pc)") #plt.xlim([10**-3, 2*10**-1]) #plt.ylim([10**-3, 10**2]) fig.savefig(SED_figure_directory + 'mass_vs_radius_' + region_name + '_Feb2018.png') Cloud, Name, Av, alpha, T_bol, L_bol, alphaPrime, TbolPrime, LbolPrime, likelyAGB, Dunham_RA, Dunham_DEC, Class = numpy.loadtxt( Dunham_YSOs_file, delimiter=',', unpack=True, dtype=[('Cloud', 'S30'), ('Name', 'S40'), ('Av', float), ('alpha', float), ('T_bol', float), ('L_bol', float), ('alphaPrime', float), ('TbolPrime', float), ('LbolPrime', float), ('likelyAGB', 'S1'), ('Dunham_RA', float), ('Dunham_DEC', float), ('Class', 'S10')]) #Dunham_indices = numpy.where(Cloud==cloud_name) Spitzer_YSOs_RA = Dunham_RA Spitzer_YSOs_DEC = Dunham_DEC Spitzer_YSOs_Name = Name potential_matches = [] YSO_matches = [] count = 0 for line in cores_array: match_counter = 0 YSO_index = 0 for RA, DEC in zip(Spitzer_YSOs_RA, Spitzer_YSOs_DEC): distance = ((line[3] - RA)**2 + (line[4] - DEC)**2)**0.5 if distance < 6.0 / 3600. and match_counter == 0: # matched_counter prevents counting indices twice # if two YSO candidates fall within getsources ellipse potential_matches.append(count) match_counter += 1 YSO_matches.append(YSO_index) YSO_index += 1 count += 1 Spitzer_column = numpy.zeros(len(cores_array[:, 0]), dtype='S50') Spitzer_column[numpy.arange(0, len(cores_array[:, 0]))] = 'None' if len(potential_matches) > 0: Spitzer_column[numpy.array(potential_matches)] = Spitzer_YSOs_Name[ numpy.array(YSO_matches)] # Save a text file with RA and Dec of the "good" cores # This is needed for the SIMBAD cross-match numpy.savetxt(SED_figure_directory + region_name + '_SIMBAD_RA_DEC.dat', zip(cores_array[:, 3], cores_array[:, 4])) # Cross-match cores with SIMBAD catalog print "Cross-matching SIMBAD catalog:" RA, Dec = numpy.loadtxt(SED_figure_directory + region_name + '_SIMBAD_RA_DEC.dat', unpack=True) Simbad.ROW_LIMIT = 1 results = [] if len(cores_array) == 1: result_table = Simbad.query_region(astropy.coordinates.SkyCoord( ra=RA, dec=Dec, unit=(u.deg, u.deg)), radius=6. * u.arcsec) if result_table != None: results.append(result_table['MAIN_ID'][0].replace(" ", "_")) else: results.append('None') # Cross-match cores with NED catalog print "Cross-matching NED catalog:" Ned.ROW_LIMIT = 1 results2 = [] result_table_value = 'Yes' try: result_table = Ned.query_region(astropy.coordinates.SkyCoord( ra=RA, dec=Dec, unit=(u.deg, u.deg)), radius=6. * u.arcsec) except astroquery.exceptions.RemoteServiceError: result_table_value = None if result_table_value != None: results2.append(result_table['Object Name'][0].replace(" ", "_")) else: results2.append('None') else: for i, j in zip(RA, Dec): result_table = Simbad.query_region(astropy.coordinates.SkyCoord( ra=i, dec=j, unit=(u.deg, u.deg)), radius=6. * u.arcsec) if result_table != None: results.append(result_table['MAIN_ID'][0].replace(" ", "_")) else: results.append('None') # Cross-match cores with NED catalog print "Cross-matching NED catalog:" Ned.ROW_LIMIT = 1 results2 = [] for i, j in zip(RA, Dec): result_table_value = 'Yes' try: result_table = Ned.query_region(astropy.coordinates.SkyCoord( ra=i, dec=j, unit=(u.deg, u.deg)), radius=6. * u.arcsec) except astroquery.exceptions.RemoteServiceError: result_table_value = None if result_table_value != None: results2.append(result_table['Object Name'][0].replace( " ", "_")) else: results2.append('None') running_number = numpy.arange(len(cores_array[:, 0])) + 1 header1 = 'running_NO, getsources_NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, R_deconv, R_fwhm_mean, resolved, Mass, M_err, Temp, T_err, alpha_BE, SIMBAD_match, NED_match, Spitzer_match' # Append the Radius, Mass, Temperature, alpha_BE, etc. arrays as columns # onto the "good cores" array and save as a .dat file numpy.savetxt( SED_figure_directory + region_name + '_good_sources_Feb2018.dat', numpy.column_stack((running_number, cores_array, numpy.array(R_deconv), numpy.array(FWHM_mean), numpy.array(resolved), numpy.array(Masses), numpy.array(Masses_err), numpy.array(Temps), numpy.array(Temps_err), numpy.array(alpha_BE), numpy.array(results), numpy.array(results2), Spitzer_column)), fmt='%s', header=header1)
def core_mass_fits(region_name = 'L1157', cloud_name = 'Cepheus', distance = 325, getsources_core_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', getsources_additional_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.add.ok.cat', YSO_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_additional_catalog = '/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.add.ok.cat', high_res_coldens_image = '/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_255_mu.image.resamp.fits', SED_figure_directory = '/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/L1157_core_SED/', CSAR_catalog = '/mnt/scratch-lustre/jkeown/DS9_regions/L1157/CSAR/CEPl1157_CSAR.dat', Dunham_YSOs_file = 'Dunham_YSOs.dat'): # These are the values in each column of "cores_array" and "protostar_array" #NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 # These are the values in each column of the "additional" "cores_array" and "protostar_array" # NO XCO_P YCO_P PEAK_SRC01 PEAK_BGF01 CONV_SRC01 CONV_BGF01 PEAK_SRC02 PEAK_BGF02 CONV_SRC02 CONV_BGF02 PEAK_SRC03 PEAK_BGF03 CONV_SRC03 CONV_BGF03 PEAK_SRC04 PEAK_BGF04 CONV_SRC04 CONV_BGF04 PEAK_SRC05 PEAK_BGF05 CONV_SRC05 CONV_BGF05 PEAK_SRC06 PEAK_BGF06 CONV_SRC06 CONV_BGF06 PEAK_SRC07 PEAK_BGF07 CONV_SRC07 CONV_BGF07 # Import the raw getsources core catalog (includes "bad" sources that don't pass HGBS selection criteria) cores_array1 = numpy.loadtxt(getsources_core_catalog,comments='!') # Find the indices of the "good" cores that pass HGBS selection criteria good_core_indices = good_cores_getsources.get_good_cores(getsources_core_catalog) # Create new array of only the "good" cores to be used for our analysis cores_array = cores_array1[numpy.array(good_core_indices)] # Import the raw "additional" getsources catalog additional_cores_array1 = numpy.loadtxt(getsources_additional_catalog,comments='!') # Create another new array of only the "good" cores from the getsources "additional" catalog additional_cores_array = additional_cores_array1[numpy.array(good_core_indices)] # Import the raw getsources protostar catalog protostar_array1 = numpy.loadtxt(YSO_catalog,comments='!', unpack=True) # Find the indices of the "good" protostars that pass HGBS selection criteria good_proto_indices = good_protostars_getsources.get_good_protostars(YSO_catalog) # Create new array of only the "good" protostars to be used for our analysis # Not sure why the transpose below is needed, but it seems the protostar_array1 # is imported transposed. This doesn't seem to be the case for the core_array1 protostar_array = protostar_array1.T[numpy.array(good_proto_indices)] # Pull the 70micron flux and error columns to be used later flux_70um = protostar_array[:,12] flux_70um_err = protostar_array[:,13] # Import the raw getsources protostar catalog additional_protostar_array1 = numpy.loadtxt(YSO_additional_catalog,comments='!', unpack=True) # Create another new array of only the "good" YSOs from the getsources "additional" catalog additional_protostar_array = additional_protostar_array1.T[numpy.array(good_proto_indices)] # Cross-match the good cores and protostars arrays to find protostars that fall within a core's ellipse print "Cross-matching Core and Protostar Catalogs:" protostellar_core_indices = proto_core_cross_match.cross_match(getsources_core_catalog, YSO_catalog, high_res_coldens_image) # The first column of protostellar_core_indices is the core's index in cores_array cross_matched_core_indices = numpy.array(protostellar_core_indices[:,0]) # The second column of protostellar_core_indices is the protostar's index in protostar_array cross_matched_proto_indices = numpy.array(protostellar_core_indices[:,1]) # Replace the 70 micron flux measurements of protostellar cores with the protostar extraction measurements if len(cross_matched_core_indices)>0: for i,j in zip(cross_matched_core_indices, cross_matched_proto_indices): cores_array[i][10]=protostar_array[j][10] cores_array[i][11]=protostar_array[j][11] cores_array[i][12]=protostar_array[j][12] cores_array[i][13]=protostar_array[j][13] additional_cores_array[i][3]=additional_protostar_array[j][3] additional_cores_array[i][4]=additional_protostar_array[j][4] additional_cores_array[i][5]=additional_protostar_array[j][5] additional_cores_array[i][6]=additional_protostar_array[j][6] # Calculate the deconvolved core radii AFWH05 = cores_array[:,50] BFWH05 = cores_array[:,51] A = numpy.float64(((((AFWH05)/60.)/60.)*numpy.pi)/180.) #radians A1 = numpy.float64(numpy.tan(A/2.)*2.*distance) #pc B = numpy.float64(((((BFWH05)/60.)/60.)*numpy.pi)/180.) #radians B1 = numpy.float64(numpy.tan(B/2.)*2.*distance) #pc FWHM_mean = mstats.gmean([A1,B1]) HPBW = numpy.float64(((((18.2)/60.)/60.)*numpy.pi)/180.) #radians HPBW1 = numpy.float64(numpy.tan(HPBW/2.)*2.*distance) #pc R_deconv = ((FWHM_mean**2.0) - (HPBW1**2.0))**0.5 #pc R_deconv = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0))<=0., FWHM_mean, R_deconv) # Calculate the Bonnor-Ebert masses of each core based on their R_deconvolved c_s = 0.2 #km/s at 10K G = 4.302*10**-3 #pc/M_solar (km/s)^2 M_BE = (2.4*R_deconv*(c_s**2.))/G #M_solar M_BE = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0))<0, 9999., M_BE) # Define a function that produces a Flux given wavelength, Temp, and Mass # We will input wavelength then find T and M using least squares minimization below def core_mass(wavelength, T, M): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = numpy.array(wavelength)*10.**-3. exponent = 1.439*(wavelength_mm**-1)*((T/10.)**-1) aaa = (0.12*(numpy.exp(exponent)-1.0))**-1.0 bbb = (0.1*((numpy.array(wavelength)/300.)**-2.0))/0.01 ccc = (D/100.)**-2 ddd = wavelength_mm**-3. return M*aaa*bbb*ccc*ddd # Define another function that calculates Mass directly from wavelength, Temp, and Flux # This will be used to find the Mass of cores that don't have reliable least-squares fits def core_mass_from_flux(wavelength, T, S_v): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength*10.**-3. exponent = 1.439*(wavelength_mm**-1)*((T/10.)**-1) aaa = 0.12*(numpy.exp(exponent)-1.0) bbb = ((0.1*((wavelength/300.)**-2.0))/0.01)**-1.0 ccc = (D/100.)**2.0 ddd = wavelength_mm**3.0 return S_v*aaa*bbb*ccc*ddd # Define another function that calculates Mass uncertainty due to temp def core_mass_err_dT(wavelength, T, S_v, dT): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength*10.**-3. exponent = 1.439*(wavelength_mm**-1)*((T/10.)**-1) aaa = 0.12*(numpy.exp(exponent)) bbb = ((0.1*((wavelength/300.)**-2.0))/0.01)**-1.0 ccc = (D/100.)**2.0 ddd = wavelength_mm**3.0 eee = 1.439*10*(wavelength_mm**-1)*(T**-2.) return S_v*aaa*bbb*ccc*ddd*dT*eee # Define another function that calculates Mass uncertainty due to flux def core_mass_err_dS_v(wavelength, T, S_v, dS_v): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength*10.**-3. exponent = 1.439*(wavelength_mm**-1)*((T/10.)**-1) aaa = 0.12*(numpy.exp(exponent)-1.0) bbb = ((0.1*((wavelength/300.)**-2.0))/0.01)**-1.0 ccc = (D/100.)**2.0 ddd = wavelength_mm**3.0 return aaa*bbb*ccc*ddd*dS_v # Create some empty arrays to which we will append accepted values Temps = [] Masses = [] Temps_err = [] Masses_err = [] counter=0 not_accepted_counter = [] protostellar_core_counter = 0 mean_dust_Temp = 10.0 mean_dust_Temp_err = 4.0 # Designate the initial Temp and Mass guess for the least-squares fitting below guess = (20.0, 0.7) print "Begin SED-fitting:" # Loop through all the "good" cores for NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 in cores_array: not_accepted = False N_SED_counter = 0 fig = plt.figure() # Proceed with starless core SED-fitting procedure # Determine how many bands the core has significant flux measurements if SIG_MONO01 > 5.0: N_SED_counter+=1 if SIG_MONO02 > 5.0: N_SED_counter+=1 if SIG_MONO04 > 5.0: N_SED_counter+=1 if SIG_MONO06 > 5.0: N_SED_counter+=1 if SIG_MONO07 > 5.0: N_SED_counter+=1 # If the core has more than three bands in which it is significant, # and the 350um Flux is higher than the 500um flux, fit the SED # over the 70-500um bands if N_SED_counter>=3 and FXT_BEST06>FXT_BEST07: flux_run1 = [FXT_BEST01, FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err_run1 = [FXT_ERRO01, FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07] flux_run2 = [FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err_run2 = [FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07] wavelength_run1=[70., 160.,250.,350.,500.] wavelength_run2=[160.,250.,350.,500.] try: popt,pcov = curve_fit(core_mass, wavelength_run1, flux_run1, p0=guess, sigma=flux_err_run1) except RuntimeError: popt = [-9999., -9999.] # Perform a second round of least squares fitting (without 70um point) try: popt2, pcov2 = curve_fit(core_mass, wavelength_run2, flux_run2, p0=guess, sigma=flux_err_run2) except RuntimeError: popt2 = [-1., -1.] # If the best fit Mass from the two fits varies by more than a factor of 2, # calculate the mass from the flux of the longest wavelength with significant flux if (popt2[1]/popt[1]) > 2.0 or (popt2[1]/popt[1]) < 0.5: not_accepted = True not_accepted_counter.append("no_SED_fit") # Store fillers for Mass and T # Will re-calculate these values below using a median core dust temp # from the reliable SED fits Masses.append(9999) Temps.append(9999) Temps_err.append(9999) Masses_err.append(9999) else: not_accepted_counter.append(" ") # This means the SED fit is reliable # Store the best-fit T and M (from second run) to corresponding arrays Temps.append(popt2[0]) Masses.append(popt2[1]) # Find the uncertainty on T and M from the square root of the diagonal # terms in the covariance matrix and store in arrays Temps_err.append(pcov2[0][0]**0.5) Masses_err.append(pcov2[1][1]**0.5) else: # This means the SED is not reliable and we will instead get the Mass # directly from the longest significant wavelength's flux measurement not_accepted = True not_accepted_counter.append("no_SED_fit") # Store fillers for Mass and T # Will re-calculate these values below using a median core dust temp # from the reliable SED fits Masses.append(9999) Temps.append(9999) Temps_err.append(9999) Masses_err.append(9999) # Plot the fluxes of all Herschel bands regardless of significance wavelength3=[70., 160.,250.,350.,500.] flux3 = [FXT_BEST01, FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err3 = [FXT_ERRO01, FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07] plt.errorbar(wavelength3,flux3,yerr=flux_err3,ecolor='r',fmt='o') plt.yscale('log') plt.xscale('log') plt.xlabel("Wavelength ($\mu$m)") plt.ylabel("Flux density (Jy)") # If the SED fit is reliable, also plot the best fit line to the SED points wavelength2=[160.,250.,350.,500.] if not_accepted==False: plt.plot(np.linspace(wavelength2[0]-40,wavelength2[3]+100, 50),core_mass(np.linspace(wavelength2[0]-40,wavelength2[3]+100, 50), popt2[0], popt2[1]), color="green") plt.title('Core ' + str(counter+1) + ' \n' + 'T$_{dust}$ (K) = ' + str("{0:.2f}".format(round(popt2[0],2))) + ' $\pm$ ' + str("{0:.2f}".format(round(pcov2[0][0],3))) + ', Mass (M$_\odot$) = ' + str("{0:.2f}".format(round(popt2[1],2))) + ' $\pm$ ' + str("{0:.2f}".format(round(pcov2[1][1],3)))) # Save the plots as a PDF in specified SED_figure_directory # The core number (in terms of the "good" sources) is added to file name fig.savefig(SED_figure_directory + 'core' + str(counter+1) + '.pdf') plt.close(fig) # Keep track of the core's that have been fit counter=counter+1 print "Core Number " + str(counter) + " of " + str(len(cores_array)) redo_indices = numpy.where(numpy.array(Temps_err)==9999) print "Need to re-calculate Mass and Temp for " + str(len(redo_indices[0])) + " Cores" Temps = numpy.array(Temps) mean_dust_Temp = numpy.median(numpy.delete(Temps, redo_indices)) mean_dust_Temp_err = numpy.std(numpy.delete(Temps, redo_indices)) print "We will assume a core Temp of " + str(mean_dust_Temp) + " +/- " + str(mean_dust_Temp_err) + " for those cores" redo_indices = redo_indices[0] redo_counter = 0 for NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 in cores_array[redo_indices]: # Find the longest significant wavelength and corresponding flux if SIG_MONO07>5.0: wave = 500. flux_fit = FXT_BEST07 flux_fit_err = FXT_ERRO07 elif SIG_MONO06>5.0: wave = 350. flux_fit = FXT_BEST06 flux_fit_err = FXT_ERRO06 elif SIG_MONO04>5.0: wave = 250. flux_fit = FXT_BEST04 flux_fit_err = FXT_ERRO04 elif SIG_MONO02>5.0: wave = 160. flux_fit = FXT_BEST02 flux_fit_err = FXT_ERRO02 # Find the mass corresponding to that flux measurement # ***This uses the median of the best-fit Temps from the cores with # reliable SED fits (i.e., those that pass the test above) Mass_fit = core_mass_from_flux(wave, mean_dust_Temp, flux_fit) # Can add more uncertainties (e.g., calibration, etc.) below Mass_error = (core_mass_err_dT(wave, mean_dust_Temp, flux_fit, mean_dust_Temp_err) + core_mass_err_dS_v(wave, mean_dust_Temp, flux_fit, flux_fit_err)**2.0)**0.5 # Store the Mass and T with uncertainties # Need to perform a more in-depth error analysis Masses[redo_indices[redo_counter]] = Mass_fit Temps[redo_indices[redo_counter]] = mean_dust_Temp Temps_err[redo_indices[redo_counter]] = mean_dust_Temp_err Masses_err[redo_indices[redo_counter]] = Mass_error fig = plt.figure() wavelength3=[70., 160.,250.,350.,500.] flux3 = [FXT_BEST01, FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err3 = [FXT_ERRO01, FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07] plt.errorbar(wavelength3,flux3,yerr=flux_err3,ecolor='r',fmt='o') plt.yscale('log') plt.xscale('log') plt.xlabel("Wavelength ($\mu$m)") plt.ylabel("Flux density (Jy)") plt.title('Core ' + str(redo_indices[redo_counter]+1) + ' **Not Accepted** ' + ' \n' + 'T$_{dust}$ (K) = ' + str("{0:.2f}".format(round(mean_dust_Temp,2))) + "$\pm$" + str("{0:.2f}".format(round(mean_dust_Temp_err,2))) + ', Mass (M$_\odot$) = ' + str("{0:.2f}".format(round(Mass_fit,2))) + "$\pm$" + str("{0:.2f}".format(round(Mass_error,2)))) fig.savefig(SED_figure_directory + 'core' + str(redo_indices[redo_counter]+1) + '_NA.pdf') plt.close(fig) redo_counter+=1 print "Re-calculating Core " + str(redo_counter) + " of " + str(len(redo_indices)) unreliable = float(len(numpy.where(numpy.array(not_accepted_counter)=="no_SED_fit")[0])) print 'Fraction of Unreliable SED fits: ' + str(round((unreliable/float(len(cores_array))),3)) not_accepted_counter = numpy.where(numpy.array(not_accepted_counter) == "no_SED_fit", not_accepted_counter, "None") #Replace nans if they exist in the M_BE array where_are_nans = numpy.isnan(M_BE) M_BE[where_are_nans] = 9999 # Calculate the alpha_BE ratio to determine prestellar cores alpha_BE = numpy.array(M_BE)/numpy.array(Masses) alpha_BE = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0))<0, 9999., alpha_BE) # Create an array indicating a core as candidate(1)/robust(2) prestellar candidate_array = numpy.where(alpha_BE<=5.0, 1, 0) robust_candidate_array = numpy.where(alpha_BE<=2.0, 2, candidate_array) # Identify protostars in the array with the number (3) if len(cross_matched_core_indices)>0: robust_candidate_array[cross_matched_core_indices]=3 # Remove protostars from the alpha_BE array and find the indices of the remaining # candidate/robust prestellar cores robust_prestellar_indices = numpy.where(numpy.delete(alpha_BE,cross_matched_core_indices)<=2.0) candidate_prestellar_indices = numpy.where(numpy.delete(alpha_BE,cross_matched_core_indices)<=5.0) # Remove protostars from the Mass and Radius arrays # (we only want to plot starless cores in the Mass vs. Radius plot) R_deconv_minus_protos=numpy.delete(R_deconv, cross_matched_core_indices) Masses_minus_protos=numpy.delete(Masses, cross_matched_core_indices) # Find the final list of prestellar candidate/robust Masses with protostars removed prestellar_candidates = Masses_minus_protos[numpy.array(candidate_prestellar_indices[0])] prestellar_robust = Masses_minus_protos[numpy.array(robust_prestellar_indices[0])] print 'prestellar candidates: ' + str(len(prestellar_candidates)) print 'robust prestellar candidates: ' + str(len(prestellar_robust)) # Plot Mass versus Radius and save the figure fig = plt.figure() plt.scatter(R_deconv_minus_protos,Masses_minus_protos, label='starless') plt.scatter(R_deconv_minus_protos[numpy.array(candidate_prestellar_indices[0])],prestellar_candidates, color='red', label='candidate') plt.scatter(R_deconv_minus_protos[numpy.array(robust_prestellar_indices[0])],prestellar_robust, color='green', label='robust') plt.yscale('log') plt.xscale('log') #plt.legend() plt.title(region_name + ' Cores') plt.ylabel("Mass, M (M$_\odot$)") plt.xlabel("Deconvolved FWHM size, R (pc)") plt.xlim([10**-3, 2*10**-1]) plt.ylim([10**-3, 10**2]) fig.savefig(SED_figure_directory + 'mass_vs_radius_' + region_name + '.png') # Append the Radius, Mass, Temperature, alpha_BE, etc. arrays as columns # onto the "good cores" array and save as a .dat file numpy.savetxt(SED_figure_directory + region_name +'_good_sources.dat', numpy.column_stack((cores_array,numpy.array(R_deconv),numpy.array(FWHM_mean),numpy.array(Masses), numpy.array(Masses_err),numpy.array(Temps), numpy.array(Temps_err),numpy.array(alpha_BE),numpy.array(robust_candidate_array)))) # Save a text file with RA and Dec of the "good" cores # This is needed for the SIMBAD cross-match numpy.savetxt(SED_figure_directory + region_name +'_SIMBAD_RA_DEC.dat', zip(cores_array[:,3],cores_array[:,4])) # Create the catalog of good cores; includes flux measurments, positions, etc. make_catalog.make_catalog(region_name=region_name, cloud_name=cloud_name, distance=distance, additional_cores_array=additional_cores_array, good_cores_array = cores_array, cross_matched_core_indices=cross_matched_core_indices, cross_matched_proto_indices=cross_matched_proto_indices, alpha_BE=alpha_BE, getsources_core_catalog = getsources_core_catalog, R_deconv=R_deconv, FWHM_mean = FWHM_mean, Masses=Masses, Masses_err = Masses_err, Temps=Temps, Temps_err=Temps_err, not_accepted_counter = not_accepted_counter, CSAR_catalog = CSAR_catalog, high_res_coldens_image = high_res_coldens_image, SED_figure_directory=SED_figure_directory, Dunham_YSOs_file=Dunham_YSOs_file) make_CMF.CMF_plotter(region=region_name, Masses_minus_protos=Masses_minus_protos, prestellar_candidates=prestellar_candidates, prestellar_robust=prestellar_robust, SED_figure_directory=SED_figure_directory) # Create plot of column density PDF #make_plots.coldense_vs_cores(region_name=region_name, SED_figure_directory=SED_figure_directory, high_res_coldens_image=high_res_coldens_image) # Create histogram of background column densities for the prestellar cores make_plots.bg_coldense_plotter(region_name=region_name, SED_figure_directory=SED_figure_directory) # Create histogram of core dust temperatures from the cores with reliable SED fits make_plots.core_temp_plotter(region_name=region_name, SED_figure_directory=SED_figure_directory) # Create histogram of core radii for the starless core population make_plots.core_size_plotter(region_name=region_name, SED_figure_directory=SED_figure_directory) # Create DS9 region files for the good core and proto catalogs at all wavelengths make_DS9_region.make_DS9_regions_good_cores(getsources_core_catalog=getsources_core_catalog, YSO_catalog = YSO_catalog, DS9_region_directory = SED_figure_directory, catalog_type='all_cores', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores(getsources_core_catalog=getsources_core_catalog, YSO_catalog = YSO_catalog, DS9_region_directory = SED_figure_directory, catalog_type='proto', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores(getsources_core_catalog=getsources_core_catalog, YSO_catalog = YSO_catalog, DS9_region_directory = SED_figure_directory, catalog_type='prestellar_candidates', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores(getsources_core_catalog=getsources_core_catalog, YSO_catalog = YSO_catalog, DS9_region_directory = SED_figure_directory, catalog_type='prestellar_robust', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) if len(cross_matched_core_indices)>0: make_DS9_region.make_DS9_regions_good_cores(getsources_core_catalog=getsources_core_catalog, YSO_catalog = YSO_catalog, DS9_region_directory = SED_figure_directory, catalog_type='proto_cores', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores(getsources_core_catalog=getsources_core_catalog, YSO_catalog = YSO_catalog, DS9_region_directory = SED_figure_directory, catalog_type='starless_cores', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_CSAR(CSAR_catalog = CSAR_catalog, DS9_region_directory=SED_figure_directory)
def core_mass_fits( region_name='L1157', cloud_name='Cepheus', distance=325, getsources_core_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', getsources_additional_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.add.ok.cat', YSO_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_additional_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.add.ok.cat', high_res_coldens_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_255_mu.image.resamp.fits', SED_figure_directory='/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/L1157_core_SED/', CSAR_catalog='/mnt/scratch-lustre/jkeown/DS9_regions/L1157/CSAR/CEPl1157_CSAR.dat', Dunham_YSOs_file='Dunham_YSOs.dat'): # These are the values in each column of "cores_array" and "protostar_array" #NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 # These are the values in each column of the "additional" "cores_array" and "protostar_array" # NO XCO_P YCO_P PEAK_SRC01 PEAK_BGF01 CONV_SRC01 CONV_BGF01 PEAK_SRC02 PEAK_BGF02 CONV_SRC02 CONV_BGF02 PEAK_SRC03 PEAK_BGF03 CONV_SRC03 CONV_BGF03 PEAK_SRC04 PEAK_BGF04 CONV_SRC04 CONV_BGF04 PEAK_SRC05 PEAK_BGF05 CONV_SRC05 CONV_BGF05 PEAK_SRC06 PEAK_BGF06 CONV_SRC06 CONV_BGF06 PEAK_SRC07 PEAK_BGF07 CONV_SRC07 CONV_BGF07 # Import the raw getsources core catalog (includes "bad" sources that don't pass HGBS selection criteria) cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') # Find the indices of the "good" cores that pass HGBS selection criteria good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) # Create new array of only the "good" cores to be used for our analysis cores_array = cores_array1[numpy.array(good_core_indices)] # Import the raw "additional" getsources catalog additional_cores_array1 = numpy.loadtxt(getsources_additional_catalog, comments='!') # Create another new array of only the "good" cores from the getsources "additional" catalog additional_cores_array = additional_cores_array1[numpy.array( good_core_indices)] # Import the raw getsources protostar catalog protostar_array1 = numpy.loadtxt(YSO_catalog, comments='!', unpack=True) # Find the indices of the "good" protostars that pass HGBS selection criteria good_proto_indices = good_protostars_getsources.get_good_protostars( YSO_catalog) # Create new array of only the "good" protostars to be used for our analysis # Not sure why the transpose below is needed, but it seems the protostar_array1 # is imported transposed. This doesn't seem to be the case for the core_array1 protostar_array = protostar_array1.T[numpy.array(good_proto_indices)] # Pull the 70micron flux and error columns to be used later flux_70um = protostar_array[:, 12] flux_70um_err = protostar_array[:, 13] # Import the raw getsources protostar catalog additional_protostar_array1 = numpy.loadtxt(YSO_additional_catalog, comments='!', unpack=True) # Create another new array of only the "good" YSOs from the getsources "additional" catalog additional_protostar_array = additional_protostar_array1.T[numpy.array( good_proto_indices)] # Cross-match the good cores and protostars arrays to find protostars that fall within a core's ellipse print "Cross-matching Core and Protostar Catalogs:" protostellar_core_indices = proto_core_cross_match.cross_match( getsources_core_catalog, YSO_catalog, high_res_coldens_image) # The first column of protostellar_core_indices is the core's index in cores_array cross_matched_core_indices = numpy.array(protostellar_core_indices[:, 0]) # The second column of protostellar_core_indices is the protostar's index in protostar_array cross_matched_proto_indices = numpy.array(protostellar_core_indices[:, 1]) # Replace the 70 micron flux measurements of protostellar cores with the protostar extraction measurements if len(cross_matched_core_indices) > 0: for i, j in zip(cross_matched_core_indices, cross_matched_proto_indices): cores_array[i][10] = protostar_array[j][10] cores_array[i][11] = protostar_array[j][11] cores_array[i][12] = protostar_array[j][12] cores_array[i][13] = protostar_array[j][13] additional_cores_array[i][3] = additional_protostar_array[j][3] additional_cores_array[i][4] = additional_protostar_array[j][4] additional_cores_array[i][5] = additional_protostar_array[j][5] additional_cores_array[i][6] = additional_protostar_array[j][6] # Calculate the deconvolved core radii AFWH05 = cores_array[:, 50] BFWH05 = cores_array[:, 51] A = numpy.float64(((((AFWH05) / 60.) / 60.) * numpy.pi) / 180.) #radians A1 = numpy.float64(numpy.tan(A / 2.) * 2. * distance) #pc B = numpy.float64(((((BFWH05) / 60.) / 60.) * numpy.pi) / 180.) #radians B1 = numpy.float64(numpy.tan(B / 2.) * 2. * distance) #pc FWHM_mean = mstats.gmean([A1, B1]) HPBW = numpy.float64(((((18.2) / 60.) / 60.) * numpy.pi) / 180.) #radians HPBW1 = numpy.float64(numpy.tan(HPBW / 2.) * 2. * distance) #pc R_deconv = ((FWHM_mean**2.0) - (HPBW1**2.0))**0.5 #pc R_deconv = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0)) <= 0., FWHM_mean, R_deconv) # Calculate the Bonnor-Ebert masses of each core based on their R_deconvolved c_s = 0.2 #km/s at 10K G = 4.302 * 10**-3 #pc/M_solar (km/s)^2 M_BE = (2.4 * R_deconv * (c_s**2.)) / G #M_solar M_BE = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0)) < 0, 9999., M_BE) # Define a function that produces a Flux given wavelength, Temp, and Mass # We will input wavelength then find T and M using least squares minimization below def core_mass(wavelength, T, M): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = numpy.array(wavelength) * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = (0.12 * (numpy.exp(exponent) - 1.0))**-1.0 bbb = (0.1 * ((numpy.array(wavelength) / 300.)**-2.0)) / 0.01 ccc = (D / 100.)**-2 ddd = wavelength_mm**-3. return M * aaa * bbb * ccc * ddd # Define another function that calculates Mass directly from wavelength, Temp, and Flux # This will be used to find the Mass of cores that don't have reliable least-squares fits def core_mass_from_flux(wavelength, T, S_v): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = 0.12 * (numpy.exp(exponent) - 1.0) bbb = ((0.1 * ((wavelength / 300.)**-2.0)) / 0.01)**-1.0 ccc = (D / 100.)**2.0 ddd = wavelength_mm**3.0 return S_v * aaa * bbb * ccc * ddd # Define another function that calculates Mass uncertainty due to temp def core_mass_err_dT(wavelength, T, S_v, dT): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = 0.12 * (numpy.exp(exponent)) bbb = ((0.1 * ((wavelength / 300.)**-2.0)) / 0.01)**-1.0 ccc = (D / 100.)**2.0 ddd = wavelength_mm**3.0 eee = 1.439 * 10 * (wavelength_mm**-1) * (T**-2.) return S_v * aaa * bbb * ccc * ddd * dT * eee # Define another function that calculates Mass uncertainty due to flux def core_mass_err_dS_v(wavelength, T, S_v, dS_v): #wavelength input in microns, Temp in Kelvin, Mass in M_solar #returns S_v (i.e., Flux) in units of Jy D = distance #parsecs to cloud wavelength_mm = wavelength * 10.**-3. exponent = 1.439 * (wavelength_mm**-1) * ((T / 10.)**-1) aaa = 0.12 * (numpy.exp(exponent) - 1.0) bbb = ((0.1 * ((wavelength / 300.)**-2.0)) / 0.01)**-1.0 ccc = (D / 100.)**2.0 ddd = wavelength_mm**3.0 return aaa * bbb * ccc * ddd * dS_v # Create some empty arrays to which we will append accepted values Temps = [] Masses = [] Temps_err = [] Masses_err = [] counter = 0 not_accepted_counter = [] protostellar_core_counter = 0 mean_dust_Temp = 10.0 mean_dust_Temp_err = 4.0 # Designate the initial Temp and Mass guess for the least-squares fitting below guess = (20.0, 0.7) print "Begin SED-fitting:" # Loop through all the "good" cores for NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 in cores_array: not_accepted = False N_SED_counter = 0 fig = plt.figure() # Proceed with starless core SED-fitting procedure # Determine how many bands the core has significant flux measurements if SIG_MONO01 > 5.0: N_SED_counter += 1 if SIG_MONO02 > 5.0: N_SED_counter += 1 if SIG_MONO04 > 5.0: N_SED_counter += 1 if SIG_MONO06 > 5.0: N_SED_counter += 1 if SIG_MONO07 > 5.0: N_SED_counter += 1 # If the core has more than three bands in which it is significant, # and the 350um Flux is higher than the 500um flux, fit the SED # over the 70-500um bands if N_SED_counter >= 3 and FXT_BEST06 > FXT_BEST07: flux_run1 = [ FXT_BEST01, FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07 ] flux_err_run1 = [ FXT_ERRO01, FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07 ] flux_run2 = [FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err_run2 = [FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07] wavelength_run1 = [70., 160., 250., 350., 500.] wavelength_run2 = [160., 250., 350., 500.] try: popt, pcov = curve_fit(core_mass, wavelength_run1, flux_run1, p0=guess, sigma=flux_err_run1) except RuntimeError: popt = [-9999., -9999.] # Perform a second round of least squares fitting (without 70um point) try: popt2, pcov2 = curve_fit(core_mass, wavelength_run2, flux_run2, p0=guess, sigma=flux_err_run2) except RuntimeError: popt2 = [-1., -1.] # If the best fit Mass from the two fits varies by more than a factor of 2, # calculate the mass from the flux of the longest wavelength with significant flux if (popt2[1] / popt[1]) > 2.0 or (popt2[1] / popt[1]) < 0.5: not_accepted = True not_accepted_counter.append("no_SED_fit") # Store fillers for Mass and T # Will re-calculate these values below using a median core dust temp # from the reliable SED fits Masses.append(9999) Temps.append(9999) Temps_err.append(9999) Masses_err.append(9999) else: not_accepted_counter.append(" ") # This means the SED fit is reliable # Store the best-fit T and M (from second run) to corresponding arrays Temps.append(popt2[0]) Masses.append(popt2[1]) # Find the uncertainty on T and M from the square root of the diagonal # terms in the covariance matrix and store in arrays Temps_err.append(pcov2[0][0]**0.5) Masses_err.append(pcov2[1][1]**0.5) else: # This means the SED is not reliable and we will instead get the Mass # directly from the longest significant wavelength's flux measurement not_accepted = True not_accepted_counter.append("no_SED_fit") # Store fillers for Mass and T # Will re-calculate these values below using a median core dust temp # from the reliable SED fits Masses.append(9999) Temps.append(9999) Temps_err.append(9999) Masses_err.append(9999) # Plot the fluxes of all Herschel bands regardless of significance wavelength3 = [70., 160., 250., 350., 500.] flux3 = [FXT_BEST01, FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err3 = [ FXT_ERRO01, FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07 ] plt.errorbar(wavelength3, flux3, yerr=flux_err3, ecolor='r', fmt='o') plt.yscale('log') plt.xscale('log') plt.xlabel("Wavelength ($\mu$m)") plt.ylabel("Flux density (Jy)") # If the SED fit is reliable, also plot the best fit line to the SED points wavelength2 = [160., 250., 350., 500.] if not_accepted == False: plt.plot(np.linspace(wavelength2[0] - 40, wavelength2[3] + 100, 50), core_mass( np.linspace(wavelength2[0] - 40, wavelength2[3] + 100, 50), popt2[0], popt2[1]), color="green") plt.title('Core ' + str(counter + 1) + ' \n' + 'T$_{dust}$ (K) = ' + str("{0:.2f}".format(round(popt2[0], 2))) + ' $\pm$ ' + str("{0:.2f}".format(round(pcov2[0][0], 3))) + ', Mass (M$_\odot$) = ' + str("{0:.2f}".format(round(popt2[1], 2))) + ' $\pm$ ' + str("{0:.2f}".format(round(pcov2[1][1], 3)))) # Save the plots as a PDF in specified SED_figure_directory # The core number (in terms of the "good" sources) is added to file name fig.savefig(SED_figure_directory + 'core' + str(counter + 1) + '.pdf') plt.close(fig) # Keep track of the core's that have been fit counter = counter + 1 print "Core Number " + str(counter) + " of " + str(len(cores_array)) redo_indices = numpy.where(numpy.array(Temps_err) == 9999) print "Need to re-calculate Mass and Temp for " + str(len( redo_indices[0])) + " Cores" Temps = numpy.array(Temps) mean_dust_Temp = numpy.median(numpy.delete(Temps, redo_indices)) mean_dust_Temp_err = numpy.std(numpy.delete(Temps, redo_indices)) print "We will assume a core Temp of " + str( mean_dust_Temp) + " +/- " + str( mean_dust_Temp_err) + " for those cores" redo_indices = redo_indices[0] redo_counter = 0 for NO, XCO_P, YCO_P, WCS_ACOOR, WCS_DCOOR, SIG_GLOB, FG, GOOD, SIG_MONO01, FM01, FXP_BEST01, FXP_ERRO01, FXT_BEST01, FXT_ERRO01, AFWH01, BFWH01, THEP01, SIG_MONO02, FM02, FXP_BEST02, FXP_ERRO02, FXT_BEST02, FXT_ERRO02, AFWH02, BFWH02, THEP02, SIG_MONO03, FM03, FXP_BEST03, FXP_ERRO03, FXT_BEST03, FXT_ERRO03, AFWH03, BFWH03, THEP03, SIG_MONO04, FM04, FXP_BEST04, FXP_ERRO04, FXT_BEST04, FXT_ERRO04, AFWH04, BFWH04, THEP04, SIG_MONO05, FM05, FXP_BEST05, FXP_ERRO05, FXT_BEST05, FXT_ERRO05, AFWH05, BFWH05, THEP05, SIG_MONO06, FM06, FXP_BEST06, FXP_ERRO06, FXT_BEST06, FXT_ERRO06, AFWH06, BFWH06, THEP06, SIG_MONO07, FM07, FXP_BEST07, FXP_ERRO07, FXT_BEST07, FXT_ERRO07, AFWH07, BFWH07, THEP07 in cores_array[ redo_indices]: # Find the longest significant wavelength and corresponding flux if SIG_MONO07 > 5.0: wave = 500. flux_fit = FXT_BEST07 flux_fit_err = FXT_ERRO07 elif SIG_MONO06 > 5.0: wave = 350. flux_fit = FXT_BEST06 flux_fit_err = FXT_ERRO06 elif SIG_MONO04 > 5.0: wave = 250. flux_fit = FXT_BEST04 flux_fit_err = FXT_ERRO04 elif SIG_MONO02 > 5.0: wave = 160. flux_fit = FXT_BEST02 flux_fit_err = FXT_ERRO02 # Find the mass corresponding to that flux measurement # ***This uses the median of the best-fit Temps from the cores with # reliable SED fits (i.e., those that pass the test above) Mass_fit = core_mass_from_flux(wave, mean_dust_Temp, flux_fit) # Can add more uncertainties (e.g., calibration, etc.) below Mass_error = (core_mass_err_dT(wave, mean_dust_Temp, flux_fit, mean_dust_Temp_err) + core_mass_err_dS_v(wave, mean_dust_Temp, flux_fit, flux_fit_err)**2.0)**0.5 # Store the Mass and T with uncertainties # Need to perform a more in-depth error analysis Masses[redo_indices[redo_counter]] = Mass_fit Temps[redo_indices[redo_counter]] = mean_dust_Temp Temps_err[redo_indices[redo_counter]] = mean_dust_Temp_err Masses_err[redo_indices[redo_counter]] = Mass_error fig = plt.figure() wavelength3 = [70., 160., 250., 350., 500.] flux3 = [FXT_BEST01, FXT_BEST02, FXT_BEST04, FXT_BEST06, FXT_BEST07] flux_err3 = [ FXT_ERRO01, FXT_ERRO02, FXT_ERRO04, FXT_ERRO06, FXT_ERRO07 ] plt.errorbar(wavelength3, flux3, yerr=flux_err3, ecolor='r', fmt='o') plt.yscale('log') plt.xscale('log') plt.xlabel("Wavelength ($\mu$m)") plt.ylabel("Flux density (Jy)") plt.title('Core ' + str(redo_indices[redo_counter] + 1) + ' **Not Accepted** ' + ' \n' + 'T$_{dust}$ (K) = ' + str("{0:.2f}".format(round(mean_dust_Temp, 2))) + "$\pm$" + str("{0:.2f}".format(round(mean_dust_Temp_err, 2))) + ', Mass (M$_\odot$) = ' + str("{0:.2f}".format(round(Mass_fit, 2))) + "$\pm$" + str("{0:.2f}".format(round(Mass_error, 2)))) fig.savefig(SED_figure_directory + 'core' + str(redo_indices[redo_counter] + 1) + '_NA.pdf') plt.close(fig) redo_counter += 1 print "Re-calculating Core " + str(redo_counter) + " of " + str( len(redo_indices)) unreliable = float( len(numpy.where(numpy.array(not_accepted_counter) == "no_SED_fit")[0])) print 'Fraction of Unreliable SED fits: ' + str( round((unreliable / float(len(cores_array))), 3)) not_accepted_counter = numpy.where( numpy.array(not_accepted_counter) == "no_SED_fit", not_accepted_counter, "None") #Replace nans if they exist in the M_BE array where_are_nans = numpy.isnan(M_BE) M_BE[where_are_nans] = 9999 # Calculate the alpha_BE ratio to determine prestellar cores alpha_BE = numpy.array(M_BE) / numpy.array(Masses) alpha_BE = numpy.where(((FWHM_mean**2.0) - (HPBW1**2.0)) < 0, 9999., alpha_BE) # Create an array indicating a core as candidate(1)/robust(2) prestellar candidate_array = numpy.where(alpha_BE <= 5.0, 1, 0) robust_candidate_array = numpy.where(alpha_BE <= 2.0, 2, candidate_array) # Identify protostars in the array with the number (3) if len(cross_matched_core_indices) > 0: robust_candidate_array[cross_matched_core_indices] = 3 # Remove protostars from the alpha_BE array and find the indices of the remaining # candidate/robust prestellar cores robust_prestellar_indices = numpy.where( numpy.delete(alpha_BE, cross_matched_core_indices) <= 2.0) candidate_prestellar_indices = numpy.where( numpy.delete(alpha_BE, cross_matched_core_indices) <= 5.0) # Remove protostars from the Mass and Radius arrays # (we only want to plot starless cores in the Mass vs. Radius plot) R_deconv_minus_protos = numpy.delete(R_deconv, cross_matched_core_indices) Masses_minus_protos = numpy.delete(Masses, cross_matched_core_indices) # Find the final list of prestellar candidate/robust Masses with protostars removed prestellar_candidates = Masses_minus_protos[numpy.array( candidate_prestellar_indices[0])] prestellar_robust = Masses_minus_protos[numpy.array( robust_prestellar_indices[0])] print 'prestellar candidates: ' + str(len(prestellar_candidates)) print 'robust prestellar candidates: ' + str(len(prestellar_robust)) # Plot Mass versus Radius and save the figure fig = plt.figure() plt.scatter(R_deconv_minus_protos, Masses_minus_protos, label='starless') plt.scatter(R_deconv_minus_protos[numpy.array( candidate_prestellar_indices[0])], prestellar_candidates, color='red', label='candidate') plt.scatter(R_deconv_minus_protos[numpy.array( robust_prestellar_indices[0])], prestellar_robust, color='green', label='robust') plt.yscale('log') plt.xscale('log') #plt.legend() plt.title(region_name + ' Cores') plt.ylabel("Mass, M (M$_\odot$)") plt.xlabel("Deconvolved FWHM size, R (pc)") plt.xlim([10**-3, 2 * 10**-1]) plt.ylim([10**-3, 10**2]) fig.savefig(SED_figure_directory + 'mass_vs_radius_' + region_name + '.png') # Append the Radius, Mass, Temperature, alpha_BE, etc. arrays as columns # onto the "good cores" array and save as a .dat file numpy.savetxt( SED_figure_directory + region_name + '_good_sources.dat', numpy.column_stack( (cores_array, numpy.array(R_deconv), numpy.array(FWHM_mean), numpy.array(Masses), numpy.array(Masses_err), numpy.array(Temps), numpy.array(Temps_err), numpy.array(alpha_BE), numpy.array(robust_candidate_array)))) # Save a text file with RA and Dec of the "good" cores # This is needed for the SIMBAD cross-match numpy.savetxt(SED_figure_directory + region_name + '_SIMBAD_RA_DEC.dat', zip(cores_array[:, 3], cores_array[:, 4])) # Create the catalog of good cores; includes flux measurments, positions, etc. make_catalog.make_catalog( region_name=region_name, cloud_name=cloud_name, distance=distance, additional_cores_array=additional_cores_array, good_cores_array=cores_array, cross_matched_core_indices=cross_matched_core_indices, cross_matched_proto_indices=cross_matched_proto_indices, alpha_BE=alpha_BE, getsources_core_catalog=getsources_core_catalog, R_deconv=R_deconv, FWHM_mean=FWHM_mean, Masses=Masses, Masses_err=Masses_err, Temps=Temps, Temps_err=Temps_err, not_accepted_counter=not_accepted_counter, CSAR_catalog=CSAR_catalog, high_res_coldens_image=high_res_coldens_image, SED_figure_directory=SED_figure_directory, Dunham_YSOs_file=Dunham_YSOs_file) make_CMF.CMF_plotter(region=region_name, Masses_minus_protos=Masses_minus_protos, prestellar_candidates=prestellar_candidates, prestellar_robust=prestellar_robust, SED_figure_directory=SED_figure_directory) # Create plot of column density PDF #make_plots.coldense_vs_cores(region_name=region_name, SED_figure_directory=SED_figure_directory, high_res_coldens_image=high_res_coldens_image) # Create histogram of background column densities for the prestellar cores make_plots.bg_coldense_plotter(region_name=region_name, SED_figure_directory=SED_figure_directory) # Create histogram of core dust temperatures from the cores with reliable SED fits make_plots.core_temp_plotter(region_name=region_name, SED_figure_directory=SED_figure_directory) # Create histogram of core radii for the starless core population make_plots.core_size_plotter(region_name=region_name, SED_figure_directory=SED_figure_directory) # Create DS9 region files for the good core and proto catalogs at all wavelengths make_DS9_region.make_DS9_regions_good_cores( getsources_core_catalog=getsources_core_catalog, YSO_catalog=YSO_catalog, DS9_region_directory=SED_figure_directory, catalog_type='all_cores', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores( getsources_core_catalog=getsources_core_catalog, YSO_catalog=YSO_catalog, DS9_region_directory=SED_figure_directory, catalog_type='proto', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores( getsources_core_catalog=getsources_core_catalog, YSO_catalog=YSO_catalog, DS9_region_directory=SED_figure_directory, catalog_type='prestellar_candidates', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores( getsources_core_catalog=getsources_core_catalog, YSO_catalog=YSO_catalog, DS9_region_directory=SED_figure_directory, catalog_type='prestellar_robust', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) if len(cross_matched_core_indices) > 0: make_DS9_region.make_DS9_regions_good_cores( getsources_core_catalog=getsources_core_catalog, YSO_catalog=YSO_catalog, DS9_region_directory=SED_figure_directory, catalog_type='proto_cores', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_good_cores( getsources_core_catalog=getsources_core_catalog, YSO_catalog=YSO_catalog, DS9_region_directory=SED_figure_directory, catalog_type='starless_cores', cross_matched_core_indices=cross_matched_core_indices, candidate_prestellar_indices=candidate_prestellar_indices, robust_prestellar_indices=robust_prestellar_indices) make_DS9_region.make_DS9_regions_CSAR( CSAR_catalog=CSAR_catalog, DS9_region_directory=SED_figure_directory)
def auto_zoomed_cores( getsources_core_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo/+catalogs/L1157.sw.final.reliable.ok.cat', YSO_catalog='/mnt/scratch-lustre/jkeown/Getsources/Extract/cep1157/120115_flat/combo_proto/+catalogs/L1157.sw.final.reliable.ok.cat', core_figure_directory='/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/core_figures/', Herschel_70um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cepL1157_070_mu_emission.image.resamp.fits', Herschel_160um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cepL1157_160_mu_emission.image.resamp.fits', Herschel_250um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_250_mu.image.resamp.fits', Herschel_350um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_350_mu.image.resamp.fits', Herschel_500um_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_500_mu.image.resamp.fits', Herschel_coldens_image='/mnt/scratch-lustre/jkeown/Getsources/Prepare/Images/cep1157/080615/cep1157_255_mu.image.resamp.fits', distance=325.): # Import getsources "good core" data table cores_array1 = numpy.loadtxt(getsources_core_catalog, comments='!') good_core_indices = good_cores_getsources.get_good_cores( getsources_core_catalog) cores_array = cores_array1[numpy.array(good_core_indices)] core_center_RA = cores_array[:, 3] core_center_Dec = cores_array[:, 4] core_index = 1 for line in cores_array: x_coor = str(line[3]) y_coor = str(line[4]) AFWHM_array = [ line[14], line[23], line[41], line[59], line[68], line[50] ] # 70,160,250,350,500,coldens BFWHM_array = [ line[15], line[24], line[42], line[60], line[69], line[51] ] Theta_array = [ line[16], line[25], line[43], line[61], line[70], line[52] ] SIG_array = [line[8], line[17], line[35], line[53], line[62], line[44]] images_array = [ Herschel_70um_image, Herschel_160um_image, Herschel_250um_image, Herschel_350um_image, Herschel_500um_image, Herschel_coldens_image ] wavelengths = ['070', '160', '250', '350', '500', '255'] maximums = numpy.zeros(len(AFWHM_array)) minimums = numpy.zeros(len(AFWHM_array)) counter = 0 for i in wavelengths: ### Create a DS9 region string for the core's getsources ellipse, ### from which a mask will be created. region = ('fk5;box(' + x_coor + ', ' + y_coor + ', ' + str(0.05) + ', ' + str(0.05) + ', ' + str(0.0) + ')') r = pyregion.parse(region) f = fits.open(images_array[counter]) header_primary = fits.getheader(images_array[counter]) data = fits.getdata(images_array[counter]) mymask = r.get_mask(hdu=f[0]) newmask = numpy.where(mymask != 0) maximums[counter] = max(data[newmask]) minimums[counter] = min(data[newmask]) f.close() newmask2 = numpy.where(mymask == 0, 0, data) fits.writeto(i + '_contour_mask.fits', newmask2, header_primary, clobber=True) counter += 1 microns = ['mu_070', 'mu_160', 'mu_250', 'mu_350', 'mu_500', 'mu_255'] v_max = maximums v_min = minimums contour_levels = [(maximums[0] * 0.3, maximums[0] * 0.5, maximums[0] * 0.7, maximums[0] * 0.9), (maximums[1] * 0.3, maximums[1] * 0.5, maximums[1] * 0.7, maximums[1] * 0.9), (maximums[2] * 0.3, maximums[2] * 0.5, maximums[2] * 0.7, maximums[2] * 0.9), (maximums[3] * 0.3, maximums[3] * 0.5, maximums[3] * 0.7, maximums[3] * 0.9), (maximums[4] * 0.3, maximums[4] * 0.5, maximums[4] * 0.7, maximums[4] * 0.9), (maximums[5] * 0.3, maximums[5] * 0.5, maximums[5] * 0.7, maximums[5] * 0.9)] fig = plt.figure(figsize=(8, 5.5)) f = 0 for i in wavelengths: microns[f] = aplpy.FITSFigure(i + '_contour_mask.fits', figure=fig, subplot=(2, 3, f + 1)) microns[f].recenter(line[3], line[4], 0.025) microns[f].show_contour(i + '_contour_mask.fits', colors=('white', 'white', 'white', 'grey'), levels=contour_levels[f], overlap=True) microns[f].show_colorscale(cmap='gist_stern', vmin=v_min[f], vmax=v_max[f]) #microns[f].show_regions('/mnt/scratch-lustre/jkeown/DS9_regions/HGBS_pipeline/L1157/L1157_core_SED/255_all_cores_good.reg') microns[f].add_colorbar() if f == 2 or f == 5: microns[f].colorbar.set_axis_label_text('MJy/sr') scale = str('{:.2f}'.format( 2 * (distance * numpy.tan(numpy.radians(0.5 * (1.0 / 60.)))))) if f == 0: microns[f].add_scalebar( (1. / 60.), path_effects=[ Patheffects.withStroke(linewidth=3, foreground='white') ]) microns[f].scalebar.show( 1. / 60.) # length in degrees (one arcminute) microns[f].scalebar.set_corner('top left') microns[f].scalebar.set_label('1' + "'" + ' = ' + scale + ' pc') if SIG_array[f] > 5.: line_type = 'solid' else: line_type = 'dashed' microns[f].show_ellipses(line[3], line[4], AFWHM_array[f] / 3600., BFWHM_array[f] / 3600., Theta_array[f] + 90., color='#00FF00', zorder=10, linewidth=1.0, linestyle=line_type) #microns[f].show_markers(line[3], line[4], c='#00FF00', marker='x', zorder=10, linewidths=1.5,s=20) #microns[f].show_markers(line[3], line[4], c='black', marker='x', zorder=9, linewidths=2.0,s=30) microns[f].tick_labels.hide() microns[f].axis_labels.hide() #microns[f].set_title('L' + name) if i == '255': microns[f].add_label(0.3, 0.1, 'N$_{H2}$', relative=True, path_effects=[ Patheffects.withStroke( linewidth=3, foreground='white') ]) else: microns[f].add_label(0.3, 0.1, i + ' $\mu$' + 'm', relative=True, path_effects=[ Patheffects.withStroke( linewidth=3, foreground='white') ]) f = f + 1 fig.subplots_adjust(hspace=0.05, wspace=0.35) fig.canvas.draw() fig.suptitle('Core Number ' + str(core_index) + ' - RA: ' + str(line[3]) + ' Dec: ' + str(line[4])) fig.savefig(core_figure_directory + 'core' + str(core_index) + '.pdf') print 'Core Number = ' + str(core_index) for i in range(6): microns[i].close() core_index = core_index + 1