コード例 #1
0
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)
コード例 #2
0
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)
コード例 #3
0
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)
コード例 #4
0
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
コード例 #5
0
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)))
コード例 #6
0
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
コード例 #7
0
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)
コード例 #8
0
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)
コード例 #9
0
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)
コード例 #10
0
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