def map_kSZ_intensity(num_halo, redshift, simulation_type, nbins, rfov):
    # Import data
    path = extract.path_from_cluster_name(num_halo,
                                          simulation_type=simulation_type)
    file = extract.file_name_hdf5(
        subject='groups', redshift=extract.redshift_floatTostr(redshift))
    r200 = extract.group_r200(path, file)
    print(r200)
    group_CoP = extract.group_centre_of_potential(path, file)
    file = extract.file_name_hdf5(
        subject='particledata', redshift=extract.redshift_floatTostr(redshift))

    # Gas particles
    part_type = extract.particle_type('gas')
    mass = extract.particle_masses(path, file, part_type)
    coordinates = extract.particle_coordinates(path, file, part_type)
    velocities = extract.particle_velocity(path, file, part_type)
    temperatures = extract.particle_temperature(path, file, part_type)
    group_number = extract.group_number(path, file, part_type)
    subgroup_number = extract.subgroup_number(path, file, part_type)
    tot_rest_frame, _ = profile.total_mass_rest_frame(path, file)
    #gas_rest_frame, _ = profile.cluster_average_momentum(path, file, part_type)

    # Retrieve coordinates & velocities
    x = coordinates[:, 0] - group_CoP[0]
    y = coordinates[:, 1] - group_CoP[1]
    z = coordinates[:, 2] - group_CoP[2]
    vx = velocities[:, 0] - tot_rest_frame[0]
    vy = velocities[:, 1] - tot_rest_frame[1]
    vz = velocities[:, 2] - tot_rest_frame[2]

    h = extract.file_hubble_param(path, file)

    # Rescale to comoving coordinates
    x = profile.comoving_length(x, h, redshift)
    y = profile.comoving_length(y, h, redshift)
    z = profile.comoving_length(z, h, redshift)
    r200 = profile.comoving_length(r200, h, redshift)
    vx = profile.comoving_velocity(vx, h, redshift)
    vy = profile.comoving_velocity(vy, h, redshift)
    vz = profile.comoving_velocity(vz, h, redshift)

    vx = profile.velocity_units(vx, unit_system='astro')
    vy = profile.velocity_units(vy, unit_system='astro')
    vz = profile.velocity_units(vz, unit_system='astro')
    mass = profile.comoving_mass(mass, h, redshift)
    mass = profile.mass_units(mass, unit_system='astro')
    T = temperatures

    # Compute radial distance
    r = np.sqrt(x**2 + y**2 + z**2)

    # Particle selection
    index = np.where((r < 5 * r200) & (group_number > -1)
                     & (subgroup_number > -1) & (T > 10**5))[0]

    mass, T = mass[index], T[index]
    x, y, z = x[index], y[index], z[index]
    vx, vy, vz = vx[index], vy[index], vz[index]

    # Generate plot
    plotpar.set_defaults_plot()
    fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(20, 9))

    # Convert to angular distances
    #cosmo = {'omega_M_0' : 0.307, 'omega_lambda_0' : 0.693, 'h' : 0.6777}
    #cosmo = cosmolopy.set_omega_k_0(cosmo)
    redshift = extract.file_redshift(path, file)
    #angular_distance = cosmolopy.angular_diameter_distance(redshift, z0 = 0, **cosmo)

    cosmo = FlatLambdaCDM(H0=70, Om0=0.3)
    angular_distance = cosmo.luminosity_distance(redshift)
    print("angular_diameter_distance: ", angular_distance)
    Mpc_to_arcmin = np.power(
        np.pi, -1) * 180 * 60 / angular_distance * astropy.units.Mpc

    x = x * Mpc_to_arcmin
    y = y * Mpc_to_arcmin
    z = z * Mpc_to_arcmin
    r200 = r200 * Mpc_to_arcmin

    # Bin data
    cmap = [
        plt.get_cmap('seismic'),
        plt.get_cmap('seismic'),
        plt.get_cmap('seismic_r')
    ]
    #cmap = [mapgen.modified_spectral_cmap(Reversed = True), mapgen.modified_spectral_cmap(Reversed = True), mapgen.modified_spectral_cmap(Reversed = False)]
    xlabel = [
        r'$x\mathrm{/arcmin}$', r'$y\mathrm{/arcmin}$', r'$x\mathrm{/arcmin}$'
    ]
    ylabel = [
        r'$y\mathrm{/arcmin}$', r'$z\mathrm{/arcmin}$', r'$z\mathrm{/arcmin}$'
    ]
    thirdAX = [r'$\bigotimes z$', r'$\bigotimes x$', r'$\bigodot y$']
    cbarlabel = [
        r'$\sum_{i} m_i v_{z, i}\ [\mathrm{M_\odot\ km\ s^{-1}}]$',
        r'$\sum_{i} m_i v_{x, i}\ [\mathrm{M_\odot\ km\ s^{-1}}]$',
        r'$\sum_{i} m_i v_{y, i}\ [\mathrm{M_\odot\ km\ s^{-1}}]$'
    ]
    for i in [0, 1, 2]:
        # Handle data
        if i == 0:
            x_Data = x
            y_Data = y
            weight = vz
        elif i == 1:
            x_Data = y
            y_Data = z
            weight = vx
        elif i == 2:
            x_Data = x
            y_Data = z
            weight = vy

        x_bins = np.linspace(-rfov * r200, rfov * r200, nbins)
        y_bins = np.linspace(-rfov * r200, rfov * r200, nbins)
        Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
        # line of sight momentum weights
        count = mapgen.bins_evaluate(x_Data,
                                     y_Data,
                                     x_bins,
                                     y_bins,
                                     weights=mass * weight)

        # convolution
        kernel, _ = kernconv.nika2_kernel(x_bins, y_bins)
        kernel = np.array(kernel)
        kSZmap = convolve(count, kernel)

        norm = mapgen.MidpointNormalize(vmin=kSZmap.min(),
                                        vmax=kSZmap.max(),
                                        midpoint=0)

        img = axes[i].pcolor(Cx, Cy, kSZmap, cmap=cmap[i], norm=norm)

        # Render elements in plots
        axes[i].set_title(r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f$' %
                          (num_halo, redshift),
                          pad=94)
        axes[i].set_aspect('equal')
        axes[i].add_artist(
            Circle((0, 0),
                   radius=r200,
                   color='black',
                   fill=False,
                   linestyle='--',
                   label=r'$R_{200}$'))
        axes[i].add_artist(
            Circle((0, 0),
                   radius=5 * r200,
                   color='black',
                   fill=False,
                   linewidth=0.5,
                   linestyle='-',
                   label=r'$R_{200}$'))
        axes[i].set_xlim(-rfov * r200, rfov * r200)
        axes[i].set_ylim(-rfov * r200, rfov * r200)
        axes[i].set_xlabel(xlabel[i])
        axes[i].set_ylabel(ylabel[i])
        axes[i].annotate(thirdAX[i], (0.03, 0.03),
                         textcoords='axes fraction',
                         size=15)
        #if title:
        #    axes[i].set_title(r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f$' % (num_halo, redshift))
        # Colorbar adjustments
        ax2_divider = make_axes_locatable(axes[i])
        cax2 = ax2_divider.append_axes("top", size="5%", pad="2%")
        cbar = plt.colorbar(img, cax=cax2, orientation='horizontal')
        cbar.set_label(cbarlabel[i], labelpad=-70)
        #cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])
        cax2.xaxis.set_ticks_position("top")
        print("run completed:", i)

    #outfilename = 'parallel-out//I_kSZ_halo' + str(num_halo) +'_z016_' + str(nbins) + 'bins_' + str(rfov) + 'rfov.pdf'
    #plt.savefig(outfilename)
    plt.show()
Exemplo n.º 2
0
def map_particles(num_halo, redshift, simulation_type = 'gas', output = 'show', title = True, save_name = 'Map_particles_gas', nbins = 400):
	# Import data
	path = 		extract.path_from_cluster_name(num_halo, simulation_type = simulation_type)
	file = 		extract.file_name_hdf5(subject = 'groups', redshift = extract.redshift_floatTostr(redshift))
	r200 = 		extract.group_r200(path, file)
	group_CoP = extract.group_centre_of_potential(path, file)
	file = 		extract.file_name_hdf5(subject = 'particledata', redshift = extract.redshift_floatTostr(redshift))
	#print(r200)
	h = extract.file_hubble_param(path, file)


	# Gas particles
	part_type = extract.particle_type('gas')
	mass = extract.particle_masses(path, file, part_type)
	coordinates = extract.particle_coordinates(path, file, part_type)
	velocities = extract.particle_velocity(path, file, part_type)
	group_number = extract.group_number(path, file, part_type)
	subgroup_number = extract.subgroup_number(path, file, part_type)
	tot_rest_frame, _ = profile.total_mass_rest_frame(path, file)
	#gas_rest_frame, _ = profile.cluster_average_momentum(path, file, part_type)


	# Retrieve coordinates & velocities
	x = coordinates[:,0] - group_CoP[0]
	y = coordinates[:,1] - group_CoP[1]
	z = coordinates[:,2] - group_CoP[2]
	vx = velocities[:,0] - tot_rest_frame[0]
	vy = velocities[:,1] - tot_rest_frame[1]
	vz = velocities[:,2] - tot_rest_frame[2]

	# Rescale to comoving coordinates
	x = profile.comoving_length(x, h, redshift)
	y = profile.comoving_length(y, h, redshift)
	z = profile.comoving_length(z, h, redshift)
	r200 = profile.comoving_length(r200, h, redshift)
	vx = profile.comoving_velocity(vx, h, redshift)
	vy = profile.comoving_velocity(vy, h, redshift)
	vz = profile.comoving_velocity(vz, h, redshift)
	vx = profile.velocity_units(vx, unit_system = 'astro')
	vy = profile.velocity_units(vy, unit_system = 'astro')
	vz = profile.velocity_units(vz, unit_system = 'astro')
	mass = profile.comoving_mass(mass, h, redshift)
	mass = profile.mass_units(mass, unit_system = 'astro')

	# Compute radial distance
	r = np.sqrt(x**2+y**2+z**2)

	# Select particles within 5*r200
	index = np.where((r < 5*r200) & (group_number > -1) & (subgroup_number > -1))[0]
	mass = mass[index]
	x, y, z = x[index], y[index], z[index]
	vx, vy, vz = vx[index], vy[index], vz[index]

	# Generate plot
	plotpar.set_defaults_plot()
	fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(20, 7))

	# Bin data
	#nbins = 250
	cmap = 'terrain_r'
	################################################################################################
	x_Data = x
	y_Data = y
	x_bins = np.linspace(np.min(x_Data), np.max(x_Data), nbins)
	y_bins = np.linspace(np.min(y_Data), np.max(y_Data), nbins)
	Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
	count = mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins, weights = None)
	img = axes[0].pcolor(Cx, Cy, np.log10(count), cmap=cmap)
	axes[0].set_xlabel(r'$x\mathrm{/Mpc}$')
	axes[0].set_ylabel(r'$y\mathrm{/Mpc}$')
	axes[0].annotate(r'$\bigotimes z$', (0.03, 0.03), textcoords='axes fraction', size = 15)
	# Colorbar adjustments
	ax2_divider = make_axes_locatable(axes[0])
	cax2 = ax2_divider.append_axes("right", size="3%", pad="2%")
	cbar = plt.colorbar(img, cax=cax2, orientation='vertical')
	#cbar.set_label(r'$\log_{10}(N_{particles})$', labelpad=17)
	#cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])	
	cax2.xaxis.set_ticks_position("top")

	
	x_Data = y
	y_Data = z
	x_bins = np.linspace(np.min(x_Data), np.max(x_Data), nbins)
	y_bins = np.linspace(np.min(y_Data), np.max(y_Data), nbins)
	Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
	count = mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins, weights = None)
	img = axes[1].pcolor(Cx, Cy, np.log10(count), cmap=cmap)
	axes[1].set_xlabel(r'$y\mathrm{/Mpc}$')
	axes[1].set_ylabel(r'$z\mathrm{/Mpc}$')
	axes[1].annotate(r'$\bigotimes x$', (0.03, 0.03), textcoords='axes fraction', size = 15)
	# Colorbar adjustments
	ax2_divider = make_axes_locatable(axes[1])
	cax2 = ax2_divider.append_axes("right", size="3%", pad="2%")
	cbar = plt.colorbar(img, cax=cax2, orientation='vertical')
	#cbar.set_label(r'$\log_{10}(N_{particles})$', labelpad=17)
	#cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])	
	cax2.xaxis.set_ticks_position("top")


	x_Data = x
	y_Data = z
	x_bins = np.linspace(np.min(x_Data), np.max(x_Data), nbins)
	y_bins = np.linspace(np.min(y_Data), np.max(y_Data), nbins)
	Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
	count = mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins, weights = None)
	img = axes[2].pcolor(Cx, Cy, np.log10(count), cmap=cmap)
	axes[2].set_xlabel(r'$x\mathrm{/Mpc}$')
	axes[2].set_ylabel(r'$z\mathrm{/Mpc}$')
	axes[2].annotate(r'$\bigodot y$', (0.03, 0.03), textcoords='axes fraction', size = 15)
	# Colorbar adjustments
	ax2_divider = make_axes_locatable(axes[2])
	cax2 = ax2_divider.append_axes("right", size="3%", pad="2%")
	cbar = plt.colorbar(img, cax=cax2, orientation='vertical')
	cbar.set_label(r'$\log_{10}(N_{particles})$', labelpad=17)
	#cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])	
	cax2.xaxis.set_ticks_position("top")
	################################################################################################

	# Plot r200 circle
	for i in [0,1,2]:
		axes[i].set_aspect('equal')
		axes[i].add_artist(Circle((0,0), radius=r200, color = 'red', fill = False, linestyle = '--', label = r'$R_{200}$'))
		axes[i].add_artist(Circle((0,0), radius=5*r200, color = 'black', fill = False, linewidth = 0.5,linestyle = '-', label = r'$R_{200}$'))
		axes[i].set_xlim(-5.1*r200, 5.1*r200)
		axes[i].set_ylim(-5.1*r200, 5.1*r200)
		if title: 
			axes[i].set_title(r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f$' % (num_halo, redshift))

	# Define output
	if output == 'show': 
		plt.show()
	elif output == 'save': 
		dir_name = 'Map particles'
		if not exists(dir_name): 
			makedirs(dir_name)
		plt.savefig(dir_name + '//'+save_name+'_partType'+part_type+'_halo'+str(num_halo)+'z'+str(redshift).replace(".", "")+'.pdf')
	else:
		print("[ERROR] The output type you are trying to select is not defined.")
		exit(1)
def map_weighted_velocity(num_halo,
                          redshift,
                          simulation_type='gas',
                          output='show',
                          title=True,
                          save_name='Map_particles_gas',
                          plot_groups='FoF',
                          nbins=400):
    # Import data
    path = extract.path_from_cluster_name(num_halo,
                                          simulation_type=simulation_type)
    file = extract.file_name_hdf5(
        subject='groups', redshift=extract.redshift_floatTostr(redshift))
    r200 = extract.group_r200(path, file)
    group_CoP = extract.group_centre_of_potential(path, file)
    file = extract.file_name_hdf5(
        subject='particledata', redshift=extract.redshift_floatTostr(redshift))

    # Gas particles
    part_type = extract.particle_type('gas')
    mass = extract.particle_masses(path, file, part_type)
    coordinates = extract.particle_coordinates(path, file, part_type)
    velocities = extract.particle_velocity(path, file, part_type)
    group_number = extract.group_number(path, file, part_type)
    subgroup_number = extract.subgroup_number(path, file, part_type)
    tot_rest_frame, _ = profile.total_mass_rest_frame(path, file)
    #gas_rest_frame, _ = profile.cluster_average_momentum(path, file, part_type)

    h = extract.file_hubble_param(path, file)

    # Retrieve coordinates & velocities
    x = coordinates[:, 0] - group_CoP[0]
    y = coordinates[:, 1] - group_CoP[1]
    z = coordinates[:, 2] - group_CoP[2]
    vx = velocities[:, 0] - tot_rest_frame[0]
    vy = velocities[:, 1] - tot_rest_frame[1]
    vz = velocities[:, 2] - tot_rest_frame[2]

    # Rescale to comoving coordinates
    x = profile.comoving_length(x, h, redshift)
    y = profile.comoving_length(y, h, redshift)
    z = profile.comoving_length(z, h, redshift)
    r200 = profile.comoving_length(r200, h, redshift)
    vx = profile.comoving_velocity(vx, h, redshift)
    vy = profile.comoving_velocity(vy, h, redshift)
    vz = profile.comoving_velocity(vz, h, redshift)
    vx = profile.velocity_units(vx, unit_system='astro')
    vy = profile.velocity_units(vy, unit_system='astro')
    vz = profile.velocity_units(vz, unit_system='astro')
    mass = profile.comoving_mass(mass, h, redshift)
    mass = profile.mass_units(mass, unit_system='astro')

    # Compute radial distance
    r = np.sqrt(x**2 + y**2 + z**2)

    # Select particles within 5*r200
    if plot_groups == 'FoF':
        index = np.where((r < 5 * r200) & (group_number > -1)
                         & (subgroup_number > -1))[0]
    elif plot_groups == 'subgroups':
        index = np.where((r < 5 * r200) & (group_number > -1)
                         & (subgroup_number > 0))[0]
    else:
        print(
            "[ERROR] The (sub)groups you are trying to plot are not defined.")
        exit(1)

    mass = mass[index]
    x, y, z = x[index], y[index], z[index]
    vx, vy, vz = vx[index], vy[index], vz[index]

    # Generate plot
    plotpar.set_defaults_plot()
    fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(20, 7))

    # Bin data
    #nbins = 800
    cmap = mapgen.modified_spectral_cmap(Reversed=True)
    xlabel = [r'$x\mathrm{/Mpc}$', r'$y\mathrm{/Mpc}$', r'$x\mathrm{/Mpc}$']
    ylabel = [r'$y\mathrm{/Mpc}$', r'$z\mathrm{/Mpc}$', r'$z\mathrm{/Mpc}$']
    thirdAX = [r'$\bigotimes z$', r'$\bigotimes x$', r'$\bigodot y$']
    cbarlabel = [
        r'$\sum_{i} m_i v_{z, i} / \sum_{i} m_i \ [\mathrm{km\ s^{-1}}]$',
        r'$\sum_{i} m_i v_{x, i} / \sum_{i} m_i \ [\mathrm{km\ s^{-1}}]$',
        r'$\sum_{i} m_i v_{y, i} / \sum_{i} m_i \ [\mathrm{km\ s^{-1}}]$'
    ]

    for i in [0, 1, 2]:
        # Handle data
        if i == 0:
            x_Data = x
            y_Data = y
            weight = vz
        elif i == 1:
            x_Data = y
            y_Data = z
            weight = vx
        elif i == 2:
            x_Data = x
            y_Data = z
            weight = vy
            cmap = mapgen.modified_spectral_cmap(Reversed=False)

        x_bins = np.linspace(np.min(x_Data), np.max(x_Data), nbins)
        y_bins = np.linspace(np.min(y_Data), np.max(y_Data), nbins)
        Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
        # line of sight momentum weights
        count_mv = mapgen.bins_evaluate(x_Data,
                                        y_Data,
                                        x_bins,
                                        y_bins,
                                        weights=mass * weight)
        # mass weights
        count_m = mapgen.bins_evaluate(x_Data,
                                       y_Data,
                                       x_bins,
                                       y_bins,
                                       weights=mass)
        # average mass weighted velocity
        count_m[count_m == 0] = 1
        count = np.divide(count_mv, count_m)

        norm = mapgen.MidpointNormalize(vmin=count.min(),
                                        vmax=count.max(),
                                        midpoint=0)
        img = axes[i].pcolor(Cx, Cy, count, cmap=cmap, norm=norm)

        # Render elements in plots
        axes[i].set_aspect('equal')
        axes[i].add_artist(
            Circle((0, 0),
                   radius=r200,
                   color='black',
                   fill=False,
                   linestyle='--',
                   label=r'$R_{200}$'))
        axes[i].add_artist(
            Circle((0, 0),
                   radius=5 * r200,
                   color='black',
                   fill=False,
                   linewidth=0.5,
                   linestyle='-',
                   label=r'$R_{200}$'))
        axes[i].set_xlim(-5.1 * r200, 5.1 * r200)
        axes[i].set_ylim(-5.1 * r200, 5.1 * r200)
        axes[i].set_xlabel(xlabel[i])
        axes[i].set_ylabel(ylabel[i])
        axes[i].annotate(thirdAX[i], (0.03, 0.03),
                         textcoords='axes fraction',
                         size=15)
        if title:
            axes[i].set_title(
                r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f$' %
                (num_halo, redshift))
        # Colorbar adjustments
        ax2_divider = make_axes_locatable(axes[i])
        cax2 = ax2_divider.append_axes("right", size="3%", pad="2%")
        cbar = plt.colorbar(img, cax=cax2, orientation='vertical')
        cbar.set_label(cbarlabel[i], labelpad=17)
        #cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])
        cax2.xaxis.set_ticks_position("top")

    # Define output
    if output == 'show':
        plt.show()
    elif output == 'save':
        dir_name = 'Map mass weighted velocity'
        if not exists(dir_name):
            makedirs(dir_name)
        plt.savefig(dir_name + '//' + save_name + '_partType' + part_type +
                    '_halo' + str(num_halo) + 'z' +
                    str(redshift).replace(".", "") + '.pdf')
    else:
        print(
            "[ERROR] The output type you are trying to select is not defined.")
        exit(1)
Exemplo n.º 4
0
def render_tSZ(axes,
               num_halo,
               redshift,
               simulation_type,
               projection=0,
               nbins=100,
               rfov=5,
               cbar_color='inferno'):
    # Import data
    path = extract.path_from_cluster_name(num_halo,
                                          simulation_type=simulation_type)
    file = extract.file_name_hdf5(
        subject='groups', redshift=extract.redshift_floatTostr(redshift))
    r200 = extract.group_r200(path, file)
    group_CoP = extract.group_centre_of_potential(path, file)

    # Gas particles
    file = extract.file_name_hdf5(
        subject='particledata', redshift=extract.redshift_floatTostr(redshift))

    part_type = extract.particle_type('gas')
    mass = extract.particle_masses(path, file, part_type)
    coordinates = extract.particle_coordinates(path, file, part_type)
    velocities = extract.particle_velocity(path, file, part_type)
    temperatures = extract.particle_temperature(path, file, part_type)
    group_number = extract.group_number(path, file, part_type)
    subgroup_number = extract.subgroup_number(path, file, part_type)
    tot_rest_frame, _ = profile.total_mass_rest_frame(path, file)
    # gas_rest_frame, _ = profile.cluster_average_momentum(path, file, part_type)

    # Retrieve coordinates & velocities
    x = coordinates[:, 0] - group_CoP[0]
    y = coordinates[:, 1] - group_CoP[1]
    z = coordinates[:, 2] - group_CoP[2]
    vx = velocities[:, 0] - tot_rest_frame[0]
    vy = velocities[:, 1] - tot_rest_frame[1]
    vz = velocities[:, 2] - tot_rest_frame[2]

    # Rescale to comoving coordinates
    h = extract.file_hubble_param(path, file)
    redshift = extract.file_redshift(path, file)
    x = profile.comoving_length(x, h, redshift)
    y = profile.comoving_length(y, h, redshift)
    z = profile.comoving_length(z, h, redshift)
    r200 = profile.comoving_length(r200, h, redshift)
    vx = profile.comoving_velocity(vx, h, redshift)
    vy = profile.comoving_velocity(vy, h, redshift)
    vz = profile.comoving_velocity(vz, h, redshift)
    vx = profile.velocity_units(vx, unit_system='SI')
    vy = profile.velocity_units(vy, unit_system='SI')
    vz = profile.velocity_units(vz, unit_system='SI')
    mass = profile.comoving_mass(mass, h, redshift)
    mass = profile.mass_units(mass, unit_system='SI')
    T = temperatures

    # Compute radial distance
    r = np.sqrt(x**2 + y**2 + z**2)

    # Particle selection
    min_gn = 0
    min_sgn = 0
    min_T = 10**5
    max_r = 5

    index = np.where((r < max_r * r200) & (group_number >= min_gn)
                     & (subgroup_number >= min_sgn) & (T > min_T))[0]
    mass, T = mass[index], T[index]
    x, y, z = x[index], y[index], z[index]
    vx, vy, vz = vx[index], vy[index], vz[index]

    # Convert to angular distances
    angular_distance = cosmo.angular_diameter_D(redshift)
    Mpc_to_arcmin = np.power(np.pi, -1) * 180 * 60 / angular_distance
    x = x * Mpc_to_arcmin
    y = y * Mpc_to_arcmin
    z = z * Mpc_to_arcmin
    r200 = r200 * Mpc_to_arcmin

    cmap = [cbar_color, cbar_color, cbar_color]
    xlabel = [
        r'$x\mathrm{/arcmin}$', r'$y\mathrm{/arcmin}$', r'$x\mathrm{/arcmin}$'
    ]
    ylabel = [
        r'$y\mathrm{/arcmin}$', r'$z\mathrm{/arcmin}$', r'$z\mathrm{/arcmin}$'
    ]
    thirdAX = [r'$\bigotimes z$', r'$\bigotimes x$', r'$\bigodot y$']
    cbarlabel = [r'$y_{tSZ}$', r'$y_{tSZ}$', r'$y_{tSZ}$']

    # Compute angular bins
    x_bins = np.linspace(-rfov * r200, rfov * r200, nbins)
    y_bins = np.linspace(-rfov * r200, rfov * r200, nbins)

    m_H = 1.6737236 * 10**(-27)  # Hydrogen atom mass in kg
    A_pix = (x_bins[1] - x_bins[0]) * (y_bins[1] - y_bins[0]) * (
        3.0856776 * 10**22 / Mpc_to_arcmin)**2
    tSZconst = sigma_T.value * k_B.value / (m_e.value * c.value**2 * m_H *
                                            1.16)

    # Set up index permutations
    ijk = np.asarray([[0, 1, 2], [1, 2, 0], [0, 2, 1]])

    # Set up vectors
    pp_xyz = np.asarray([x, y, z])

    # Prepare Kernel
    kernel_Type = 'gauss'
    kernel, fwhm = kernconv.nika2_kernel(x_bins,
                                         y_bins,
                                         kernel_Type=kernel_Type)
    kernel = np.array(kernel)

    # mass
    mass = mass.astype(np.longdouble)

    # Histogram calculation
    Cx, Cy = mapgen.bins_meshify(pp_xyz[ijk[projection][0]],
                                 pp_xyz[ijk[projection][1]], x_bins, y_bins)

    weight = T.astype(np.longdouble)

    # Histogram calculation
    count_mT = mapgen.bins_evaluate(pp_xyz[ijk[projection][0]],
                                    pp_xyz[ijk[projection][1]],
                                    x_bins,
                                    y_bins,
                                    weights=mass * weight)

    # Compute tSZ
    tSZ = count_mT * tSZconst / A_pix

    # Convolution
    tSZmap = convolve(tSZ, kernel)
    tSZmap[tSZmap == 0] = 10**-10

    if axes is None:
        return tSZmap

    # Logarithmic normalization
    tSZnorm = colors.LogNorm(vmin=10**-10, vmax=10**-3)

    # Plot image
    img = axes.pcolor(Cx, Cy, tSZmap, cmap=cmap[projection], norm=tSZnorm)

    # Render elements in plots
    axes.set_aspect('equal')
    axes.add_artist(
        Circle((0, 0),
               radius=r200,
               color='black',
               fill=False,
               linestyle='--',
               label=r'$R_{200}$'))
    axes.add_artist(
        Circle((0, 0),
               radius=5 * r200,
               color='white',
               fill=False,
               linewidth=0.5,
               linestyle='-',
               label=r'$R_{200}$'))
    axes.set_xlim(-rfov * r200, rfov * r200)
    axes.set_ylim(-rfov * r200, rfov * r200)
    axes.set_xlabel(xlabel[projection])
    axes.set_ylabel(ylabel[projection])
    axes.annotate(thirdAX[projection], (0.03, 0.03),
                  textcoords='axes fraction',
                  size=15,
                  color='w')

    # Colorbar adjustments
    ax2_divider = make_axes_locatable(axes)
    cax2 = ax2_divider.append_axes("top", size="5%", pad="2%")
    cbar = plt.colorbar(img, cax=cax2, orientation='horizontal')
    cbar.set_label(cbarlabel[projection], labelpad=-70)
    cax2.xaxis.set_ticks_position("top")

    return tSZmap
Exemplo n.º 5
0
def phase_diagram_master(redshift,
                         nbins=500,
                         output='save',
                         selection='all',
                         bg='w'):
    master_density = []
    master_temperature = []
    for num_halo in np.arange(390):
        print('Ímporting halo ' + str(num_halo))

        # Import data
        path = extract.path_from_cluster_name(num_halo, simulation_type='gas')
        file = extract.file_name_hdf5(
            subject='groups', redshift=extract.redshift_floatTostr(redshift))
        r200 = extract.group_r200(path, file)
        group_CoP = extract.group_centre_of_potential(path, file)

        file = extract.file_name_hdf5(
            subject='particledata',
            redshift=extract.redshift_floatTostr(redshift))

        # Gas particles
        part_type = extract.particle_type('gas')
        density = extract.particle_SPH_density(path, file, part_type)
        coordinates = extract.particle_coordinates(path, file, part_type)
        temperature = extract.particle_temperature(path, file, part_type)
        group_number = extract.group_number(path, file, part_type)
        subgroup_number = extract.subgroup_number(path, file, part_type)

        # Retrieve coordinates
        x = coordinates[:, 0] - group_CoP[0]
        y = coordinates[:, 1] - group_CoP[1]
        z = coordinates[:, 2] - group_CoP[2]

        # Rescale to comoving coordinates
        h = extract.file_hubble_param(path, file)
        x = profile.comoving_length(x, h, redshift)
        y = profile.comoving_length(y, h, redshift)
        z = profile.comoving_length(z, h, redshift)
        r200 = profile.comoving_length(r200, h, redshift)
        density = profile.comoving_density(density, h, redshift)
        density = profile.density_units(density, unit_system='nHcgs')

        # Compute radial distance
        r = np.sqrt(x**2 + y**2 + z**2)

        index = 0
        # Select particles within 5*r200
        if selection.lower() == 'all':
            index = np.where((r < 5 * r200) & (group_number == 1)
                             & (subgroup_number > -1))[0]
        if selection.lower() == 'sub':
            index = np.where((r < 5 * r200) & (group_number == 1)
                             & (subgroup_number > 0)
                             & (subgroup_number < 10000))[0]
        if selection.lower() == 'icm':
            index = np.where((r < 5 * r200) & (group_number == 1)
                             & (subgroup_number == 0))[0]

        density = density[index]
        temperature = temperature[index]

        master_density.append(density)
        master_temperature.append((temperature))

    # Bin data
    x_Data = np.concatenate(master_density)
    y_Data = np.concatenate(master_temperature)
    x_bins = np.logspace(np.min(np.log10(x_Data)), np.max(np.log10(x_Data)),
                         nbins)
    y_bins = np.logspace(np.min(np.log10(y_Data)), np.max(np.log10(y_Data)),
                         nbins)
    A_pix = (x_bins[1] - x_bins[0]) * (y_bins[1] - y_bins[0])
    Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
    count = mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins,
                                 weights=None) / A_pix

    # Generate plot
    plotpar.set_defaults_plot()
    fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(7, 7))

    # Logarithmic normalization
    norm = mpl.colors.LogNorm()  # (vmin=10 ** -2, vmax=10 ** 1)

    count2 = np.ma.masked_where(count == 0, count)
    cmap = plt.get_cmap('CMRmap')
    cmap.set_bad(color=bg, alpha=1)

    img = axes.pcolormesh(Cx, Cy, count2, cmap=cmap, norm=norm)
    axes.set_xscale('log')
    axes.set_yscale('log')
    axes.set_xlabel(r'$n_{\mathrm{H}}/\mathrm{cm}^{3}$')
    #axes.set_xlabel(r'$\rho/(M_\odot\ kpc^{-3})$')
    axes.set_ylabel(r'$T/\mathrm{K}$')

    # Colorbar adjustments
    ax2_divider = make_axes_locatable(axes)
    cax2 = ax2_divider.append_axes("top", size="3%", pad="2%")
    cbar = plt.colorbar(img, cax=cax2, orientation='horizontal')
    cbar.set_label(
        r'$N_{\mathrm{particles}} / (\mathrm{K}\ \mathrm{cm}^{-3})$',
        labelpad=-70)
    # cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])
    cax2.xaxis.set_ticks_position("top")

    # Define output
    if output == 'show':
        plt.show()

    elif output == 'save':
        save_name = 'phase-diagram_nHcgs_halo' + str(10) + '_z' + str(
            redshift).replace(
                ".", "") + '_nbins' + str(nbins) + '_' + selection + '.png'
        dir_name = 'phase_diagrams_T-Rho_master390'

        if not exists(dir_name): makedirs(dir_name)

        plt.savefig(dir_name + '//' + save_name)

    else:
        print(
            "[ERROR] The output type you are trying to select is not defined.")
        exit(1)
Exemplo n.º 6
0
def phase_diagram(num_halo,
                  redshift,
                  output='show',
                  title=True,
                  save_name='Central_group_all_part_halo_'):
    # Import data
    path = extract.path_from_cluster_name(num_halo,
                                          simulation_type=simulation_type)
    file = extract.file_name_hdf5(
        subject='groups', redshift=extract.redshift_floatTostr(redshift))
    r200 = extract.group_r200(path, file)
    group_CoP = extract.group_centre_of_potential(path, file)

    file = extract.file_name_hdf5(
        subject='particledata', redshift=extract.redshift_floatTostr(redshift))

    # Gas particles
    part_type = extract.particle_type('gas')
    density = extract.particle_SPH_density(path, file, part_type)
    coordinates = extract.particle_coordinates(path, file, part_type)
    temperature = extract.particle_temperature(path, file, part_type)
    group_number = extract.group_number(path, file, part_type)
    subgroup_number = extract.subgroup_number(path, file, part_type)

    # Retrieve coordinates
    x = coordinates[:, 0] - group_CoP[0]
    y = coordinates[:, 1] - group_CoP[1]
    z = coordinates[:, 2] - group_CoP[2]

    # Rescale to comoving coordinates
    x = profile.comoving_length(x, h, redshift)
    y = profile.comoving_length(y, h, redshift)
    z = profile.comoving_length(z, h, redshift)
    r200 = profile.comoving_length(r200, h, redshift)
    density = profile.comoving_density(density, h, redshift)
    density = profile.density_units(density, unit_system='astro')

    # Compute radial distance
    r = np.sqrt(x**2 + y**2 + z**2)

    # Select particles within 5*r200
    index = np.where((r < 5 * r200) & (group_number > -1)
                     & (subgroup_number > 0))[0]
    density = density[index]
    temperature = temperature[index]

    # Bin data
    nbins = 600
    x_Data = density
    y_Data = temperature
    x_bins = np.logspace(np.min(np.log10(x_Data)), np.max(np.log10(x_Data)),
                         nbins)
    y_bins = np.logspace(np.min(np.log10(y_Data)), np.max(np.log10(y_Data)),
                         nbins)
    Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
    count = mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins, weights=None)

    # Generate plot
    plotpar.set_defaults_plot()
    fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(7, 6))

    img = axes.pcolor(Cx, Cy, np.log10(count + 1), cmap='viridis')
    axes.set_xscale('log')
    axes.set_yscale('log')
    axes.set_xlabel(r'$\rho/(M_\odot\ pc^{-3})$')
    axes.set_ylabel(r'$T/K$')
    if title:
        axes.set_title(r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f$' %
                       (num_halo, redshift))

    # Colorbar adjustments
    ax2_divider = make_axes_locatable(axes)
    cax2 = ax2_divider.append_axes("right", size="3%", pad="2%")
    cbar = plt.colorbar(img, cax=cax2, orientation='vertical')
    cbar.set_label(r'$\log_{10}(N_{particles})$', labelpad=17)
    #cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])
    cax2.xaxis.set_ticks_position("top")

    # Define output
    if output == 'show':
        plt.show()
    elif output == 'save':
        dir_name = 'Temperature-Density phase diagrams'
        if not exists(dir_name):
            makedirs(dir_name)
        plt.savefig(dir_name + '//' + save_name + str(num_halo) + 'z' +
                    str(redshift).replace(".", "") + '.pdf')
    else:
        print(
            "[ERROR] The output type you are trying to select is not defined.")
        exit(1)
def render_figure(halo_number, redshift, projection, output="Show"):
    plotpar.set_defaults_plot()
    nullfmt = NullFormatter()
    fig = plt.figure(1, figsize=(10, 13))

    # Now, create the gridspec structure, as required
    gs = gridspec.GridSpec(ncols=3,
                           nrows=7,
                           height_ratios=[0.05, 1, 0.5, 0.7, 0.05, 1, 0.5],
                           width_ratios=[1, 1, 0.5])

    # 3 rows, 4 columns, each with the required size ratios.
    # Also make sure the margins and spacing are apropriate

    gs.update(left=0.05,
              right=0.95,
              bottom=0.08,
              top=0.93,
              wspace=0.08,
              hspace=0.08)

    # Note: I set the margins to make it look good on my screen ...
    # BUT: this is irrelevant for the saved image, if using bbox_inches='tight'in savefig !

    # Note: Here, I use a little trick. I only have three vertical layers of plots :
    # a scatter plot, a histogram, and a line plot. So, in principle, I could use a 3x3 structure.
    # However, I want to have the histogram 'closer' from the scatter plot than the line plot.
    # So, I insert a 4th layer between the histogram and line plot,
    # keep it empty, and use its thickness (the 0.2 above) to adjust the space as required.

    selection_color = 'coral'
    # selection_color = 'lime'
    colormap = 'YlGnBu_r'
    alpha_select = 0.1

    # LABELS
    label_n = r'$n_{sub}$'
    label_M = r'$M/M_\odot$'
    label_R = r'$R/R_{200}$'
    label_f = r'$f_{g}$'
    label_v = r'$v_{z}/\mathrm{(km\ s^{-1})}$'

    # GRIDS & NBINS
    grid_on = False

    # loop over plots
    for j in [0, 4]:
        for i in [0, 1]:

            print('Block started')

            if i == 0 and j == 0:
                x = data_dict['R']
                y = data_dict['Fg']
                SELECT_x_min, SELECT_x_max = selec_dict[
                    'SELECT_R_MIN'], selec_dict['SELECT_R_MAX']
                SELECT_y_min, SELECT_y_max = selec_dict[
                    'SELECT_Fg_MIN'], selec_dict['SELECT_Fg_MAX']
            if i == 1 and j == 0:
                x = data_dict['M']
                y = data_dict['Fg']
                SELECT_x_min, SELECT_x_max = selec_dict[
                    'SELECT_M_MIN'], selec_dict['SELECT_M_MAX']
                SELECT_y_min, SELECT_y_max = selec_dict[
                    'SELECT_Fg_MIN'], selec_dict['SELECT_Fg_MAX']
            if i == 0 and j == 4:
                x = data_dict['R']
                y = data_dict['Vr']
                SELECT_x_min, SELECT_x_max = selec_dict[
                    'SELECT_R_MIN'], selec_dict['SELECT_R_MAX']
                SELECT_y_min, SELECT_y_max = selec_dict[
                    'SELECT_Vr_MIN'], selec_dict['SELECT_Vr_MAX']
            if i == 1 and j == 4:
                x = data_dict['M']
                y = data_dict['Vr']
                SELECT_x_min, SELECT_x_max = selec_dict[
                    'SELECT_M_MIN'], selec_dict['SELECT_M_MAX']
                SELECT_y_min, SELECT_y_max = selec_dict[
                    'SELECT_Vr_MIN'], selec_dict['SELECT_Vr_MAX']

            x_min_LIN, x_max_LIN = np.min(x), np.max(x)
            x_min_LOG, x_max_LOG = np.log10(x_min_LIN), np.log10(x_max_LIN)
            y_min_LIN, y_max_LIN = np.min(y), np.max(y)
            if j == 0: y_min_LIN, y_max_LIN = 0, 0.3

            # First, the scatter plot
            ax1 = fig.add_subplot(gs[j + 1, i])
            print('\tComputing 2dhist \t\t (%1i, %1i)' % (j + 1, i))
            # # Get the optimal number of bins based on knuth_bin_width
            # N_xbins = int((np.max(x)-np.min(x))/knuth_bin_width(x)) + 1
            # N_ybins = int((np.max(y)-np.min(y))/knuth_bin_width(y)) + 1
            N_xbins = 50
            N_ybins = N_xbins
            bins_LOG = np.logspace(x_min_LOG, x_max_LOG, num=N_xbins)
            bins_LIN = np.linspace(y_min_LIN, y_max_LIN, num=N_ybins)
            Cx, Cy = mapgen.bins_meshify(x, y, bins_LOG, bins_LIN)
            count = mapgen.bins_evaluate(x,
                                         y,
                                         bins_LOG,
                                         bins_LIN,
                                         weights=None)
            norm = colors.LogNorm()
            plt1 = ax1.pcolor(Cx, Cy, count, cmap=colormap, norm=norm)
            ax1.grid(grid_on)
            ax1.set_xlim([x_min_LIN, x_max_LIN])
            ax1.set_ylim([y_min_LIN, y_max_LIN])
            ax1.set_xscale('log')
            ax1.set_yscale('linear')
            ax1.set_xlabel(r' ')  # Force this empty !
            ax1.xaxis.set_major_formatter(nullfmt)
            ax1.set_ylabel(label_f)
            if j == 4:
                ax1.axhspan(-SELECT_y_max,
                            -SELECT_y_min,
                            alpha=alpha_select,
                            color=selection_color)
                rect2 = patches.Rectangle((SELECT_x_min, -SELECT_y_max),
                                          SELECT_x_max - SELECT_x_min,
                                          -SELECT_y_min + SELECT_y_max,
                                          linewidth=1.5,
                                          edgecolor='r',
                                          facecolor='none')
                ax1.add_patch(rect2)

            ax1.axvspan(SELECT_x_min,
                        SELECT_x_max,
                        alpha=alpha_select,
                        color=selection_color)
            ax1.axhspan(SELECT_y_min,
                        SELECT_y_max,
                        alpha=alpha_select,
                        color=selection_color)
            rect = patches.Rectangle((SELECT_x_min, SELECT_y_min),
                                     SELECT_x_max - SELECT_x_min,
                                     SELECT_y_max - SELECT_y_min,
                                     linewidth=1.5,
                                     edgecolor='r',
                                     facecolor='none')
            ax1.add_patch(rect)
            if j == 0:
                ax1.set_ylabel(label_f)
            elif j == 4:
                ax1.set_ylabel(label_v)

            # Colorbar
            cbax = fig.add_subplot(gs[j, i])
            print('\tComputing colorbar \t\t (%1i, %1i)' % (j, i))
            cb = Colorbar(ax=cbax,
                          mappable=plt1,
                          orientation='horizontal',
                          ticklocation='top')
            cb.set_label(label_n, labelpad=10)
            trig_vertical_hist = 0
            # VERTICAL HISTOGRAM
            if i != 0:
                ax1v = fig.add_subplot(gs[j + 1, i + 1])
                print('\tComputing vert hist \t (%1i, %1i)' % (j + 1, i + 1))
                ax1v.hist(y,
                          bins=bins_LIN,
                          orientation='horizontal',
                          color='k',
                          histtype='step')
                ax1v.hist(y,
                          bins=bins_LIN,
                          orientation='horizontal',
                          color='red',
                          histtype='step',
                          cumulative=-1)
                ax1v.set_yticks(ax1.get_yticks(
                ))  # Ensures we have the same ticks as the scatter plot !
                ax1v.set_xlabel(label_n)
                ax1v.tick_params(labelleft=False)
                ax1v.set_ylim(ax1.get_ylim())
                ax1v.set_xscale('log')
                ax1v.set_yscale('linear')
                ax1v.grid(grid_on)
                ax1v.axhspan(SELECT_y_min,
                             SELECT_y_max,
                             alpha=alpha_select,
                             color=selection_color)
                if j == 4:
                    ax1v.axhspan(-SELECT_y_max,
                                 -SELECT_y_min,
                                 alpha=alpha_select,
                                 color=selection_color)

                ax1.yaxis.set_major_formatter(nullfmt)
                ax1.set_ylabel('')
                trig_vertical_hist = 1

            # Percentiles
            percents = [15.9, 50, 84.1]
            percent_str = [r'$16\%$', r'$50\%$', r'$84\%$']
            clr = ['orange', 'blue', 'green']
            percent_ticks = np.percentile(y, percents)
            if trig_vertical_hist:
                percent_str = np.flipud(percent_str)
                clr = np.flipud(clr)
                ax1v_TWIN = ax1v.twinx()
                ax1v_TWIN.set_ylim(ax1.get_ylim())
                ax1v_TWIN.tick_params(axis='y',
                                      which='both',
                                      labelleft='off',
                                      labelright='on')
                ax1v_TWIN.set_yticks(percent_ticks)
                ax1v_TWIN.set_yticklabels(percent_str)
                for percent_tick, c, tick in zip(
                        percent_ticks, clr, ax1v_TWIN.yaxis.get_major_ticks()):
                    tick.label1.set_color(c)
                    ax1v_TWIN.axhline(y=percent_tick, color=c, linestyle='--')
                percent_str = np.flipud(percent_str)
                clr = np.flipud(clr)

            # HORIZONTAL HISTOGRAM
            ax1h = fig.add_subplot(gs[j + 2, i])
            print('\tComputing horiz hist \t (%1i, %1i)' % (j + 2, i))
            ax1h.hist(x,
                      bins=bins_LOG,
                      orientation='vertical',
                      color='k',
                      histtype='step')
            ax1h.hist(x,
                      bins=bins_LOG,
                      orientation='vertical',
                      color='red',
                      histtype='step',
                      cumulative=True)
            ax1h.set_xticks(ax1.get_xticks(
            ))  # Ensures we have the same ticks as the scatter plot !
            ax1h.set_xlim(ax1.get_xlim())
            if i == 0:
                ax1h.set_xlabel(label_R)
                ax1h.set_ylabel(label_n)
            elif i == 1:
                ax1h.set_xlabel(label_M)
                ax1h.tick_params(labelleft=False)
                ax1h.set_ylabel('')
            ax1h.set_xscale('log')
            ax1h.set_yscale('log')
            ax1h.grid(grid_on)
            ax1h.axvspan(SELECT_x_min,
                         SELECT_x_max,
                         alpha=alpha_select,
                         color=selection_color)
            percent_ticks = np.percentile(x, percents)
            for i in range(len(percents)):
                ax1h.axvline(x=percent_ticks[i], color=clr[i], linestyle='--')

            print('Block completed\n')

    if output.lower() == 'show':
        fig.show()

    elif output.lower() == 'save':
        dir_name = 'Subfind-Selection'
        if not exists(dir_name): makedirs(dir_name)
        save_name = 'selection-phase-space_halo' + str(
            halo_number) + '_z' + str(redshift).replace(
                ".", "") + '_proj' + str(projection) + '.pdf'
        fig.savefig(dir_name + '//' + save_name,
                    dpi=None,
                    facecolor='w',
                    edgecolor='w',
                    orientation='portrait',
                    papertype=None,
                    format=None,
                    transparent=False,
                    bbox_inches='tight',
                    pad_inches=0.1,
                    frameon=None)

    elif output.lower() == 'none':
        pass

    else:
        print("Error: Invalid request")
def map_tSZ_intensity(num_halo,
                      redshift,
                      simulation_type,
                      nbins=100,
                      rfov=2,
                      output='show',
                      title=True,
                      plot_groups='FoF'):
    # Import data
    path = extract.path_from_cluster_name(num_halo,
                                          simulation_type=simulation_type)
    file = extract.file_name_hdf5(
        subject='groups', redshift=extract.redshift_floatTostr(redshift))
    r200 = extract.group_r200(path, file)
    group_CoP = extract.group_centre_of_potential(path, file)
    file = extract.file_name_hdf5(
        subject='particledata', redshift=extract.redshift_floatTostr(redshift))
    redshift_short = redshift

    # Gas particles
    part_type = extract.particle_type('gas')
    mass = extract.particle_masses(path, file, part_type)
    coordinates = extract.particle_coordinates(path, file, part_type)
    velocities = extract.particle_velocity(path, file, part_type)
    temperatures = extract.particle_temperature(path, file, part_type)
    group_number = extract.group_number(path, file, part_type)
    subgroup_number = extract.subgroup_number(path, file, part_type)
    tot_rest_frame, _ = profile.total_mass_rest_frame(path, file)
    #gas_rest_frame, _ = profile.cluster_average_momentum(path, file, part_type)

    # Retrieve coordinates & velocities
    x = coordinates[:, 0] - group_CoP[0]
    y = coordinates[:, 1] - group_CoP[1]
    z = coordinates[:, 2] - group_CoP[2]
    vx = velocities[:, 0] - tot_rest_frame[0]
    vy = velocities[:, 1] - tot_rest_frame[1]
    vz = velocities[:, 2] - tot_rest_frame[2]

    # Rescale to comoving coordinates
    h = extract.file_hubble_param(path, file)
    redshift = extract.file_redshift(path, file)
    x = profile.comoving_length(x, h, redshift)
    y = profile.comoving_length(y, h, redshift)
    z = profile.comoving_length(z, h, redshift)
    r200 = profile.comoving_length(r200, h, redshift)
    vx = profile.comoving_velocity(vx, h, redshift)
    vy = profile.comoving_velocity(vy, h, redshift)
    vz = profile.comoving_velocity(vz, h, redshift)
    vx = profile.velocity_units(vx, unit_system='SI')
    vy = profile.velocity_units(vy, unit_system='SI')
    vz = profile.velocity_units(vz, unit_system='SI')
    mass = profile.comoving_mass(mass, h, redshift)
    mass = profile.mass_units(mass, unit_system='SI')
    T = temperatures

    # Compute radial distance
    r = np.sqrt(x**2 + y**2 + z**2)

    # Particle selection
    min_gn = 0
    min_T = 10**5
    max_r = 5
    if plot_groups == 'FoF': min_sgn = 0
    elif plot_groups == 'subgroups': min_sgn = 1
    else:
        print(
            "[ERROR] The (sub)groups you are trying to plot are not defined.")
        exit(1)

    index = np.where((r < max_r * r200) & (group_number >= min_gn)
                     & (subgroup_number >= min_sgn) & (T > min_T))[0]
    mass, T = mass[index], T[index]
    x, y, z = x[index], y[index], z[index]
    vx, vy, vz = vx[index], vy[index], vz[index]

    # Generate plot frame
    plotpar.set_defaults_plot()
    fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(20, 9))

    # Convert to angular distances
    angular_distance = cosmo.angular_diameter_D(redshift)
    Mpc_to_arcmin = np.power(np.pi, -1) * 180 * 60 / angular_distance
    x = x * Mpc_to_arcmin
    y = y * Mpc_to_arcmin
    z = z * Mpc_to_arcmin
    r200 = r200 * Mpc_to_arcmin

    # Bin data
    cmap = ['Blues', 'Blues', 'Blues']
    # cmap = [mapgen.modified_spectral_cmap(Reversed = True), mapgen.modified_spectral_cmap(Reversed = True), mapgen.modified_spectral_cmap(Reversed = False)]
    xlabel = [
        r'$x\mathrm{/arcmin}$', r'$y\mathrm{/arcmin}$', r'$x\mathrm{/arcmin}$'
    ]
    ylabel = [
        r'$y\mathrm{/arcmin}$', r'$z\mathrm{/arcmin}$', r'$z\mathrm{/arcmin}$'
    ]
    thirdAX = [r'$\bigotimes z$', r'$\bigotimes x$', r'$\bigodot y$']
    cbarlabel = [r'$y_{tSZ}$', r'$y_{tSZ}$', r'$y_{tSZ}$']
    weight_function = r'$y_{tSZ} = - \frac{\sigma_T}{A_{pix} \mu_e m_H c} \sum_{i=0}^{N_{l.o.s.} m^{g}_i T^{g}_i}$'
    for i in [0, 1, 2]:
        # Handle data
        if i == 0:
            x_Data = x
            y_Data = y
            weight = T
        elif i == 1:
            x_Data = y
            y_Data = z
            weight = T
        elif i == 2:
            x_Data = x
            y_Data = z
            weight = T

        # Compute angular bins
        x_bins = np.linspace(-rfov * r200, rfov * r200, nbins)
        y_bins = np.linspace(-rfov * r200, rfov * r200, nbins)
        Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)

        from astropy.constants import c, sigma_T, k_B, m_e
        m_H = 1.6737236 * 10**(-27)  # Hydrogen atom mass in kg
        A_pix = (x_bins[1] - x_bins[0]) * (y_bins[1] - y_bins[0]) * (
            3.0856776 * 10**22 / Mpc_to_arcmin)**2
        const = sigma_T.value * k_B.value / (m_e.value * c.value**2 * m_H *
                                             1.16)
        # line of sight momentum weights
        mass = mass.astype(np.longdouble)
        weight = weight.astype(np.longdouble)
        count_mT = mapgen.bins_evaluate(x_Data,
                                        y_Data,
                                        x_bins,
                                        y_bins,
                                        weights=mass * weight)
        # Compute tSZ
        tSZ = count_mT * const / (A_pix)

        # convolution
        kernel_Type = 'gauss'
        #kernel = Gaussian2DKernel(stddev=2)
        kernel, fwhm = kernconv.nika2_kernel(x_bins,
                                             y_bins,
                                             kernel_Type=kernel_Type)
        kernel = np.array(kernel)
        tSZmap = convolve(tSZ, kernel)

        # norm = mapgen.MidpointNormalize(vmin=tSZmap.min(), vmax=tSZmap.max(), midpoint=0)
        c
        # norm = colors.PowerNorm(gamma=0.2)
        img = axes[i].pcolor(Cx, Cy, tSZmap, cmap=cmap[i], norm=norm)

        # Render elements in plots
        axes[i].set_aspect('equal')
        axes[i].add_artist(
            Circle((0, 0),
                   radius=r200,
                   color='black',
                   fill=False,
                   linestyle='--',
                   label=r'$R_{200}$'))
        axes[i].add_artist(
            Circle((0, 0),
                   radius=5 * r200,
                   color='black',
                   fill=False,
                   linewidth=0.5,
                   linestyle='-',
                   label=r'$R_{200}$'))
        axes[i].set_xlim(-rfov * r200, rfov * r200)
        axes[i].set_ylim(-rfov * r200, rfov * r200)
        axes[i].set_xlabel(xlabel[i])
        axes[i].set_ylabel(ylabel[i])
        axes[i].annotate(thirdAX[i], (0.03, 0.03),
                         textcoords='axes fraction',
                         size=15)
        if title and plot_groups == 'FoF':
            axes[i].set_title(
                r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f \qquad \mathrm{ICM + subhalos}$'
                % (num_halo, redshift),
                pad=94)
        if title and plot_groups == 'subgroups':
            axes[i].set_title(
                r'$\mathrm{MACSIS\ halo\ } %3d \qquad z = %8.3f \qquad \mathrm{subhalos}$'
                % (num_halo, redshift),
                pad=94)

        # Colorbar adjustments
        ax2_divider = make_axes_locatable(axes[i])
        cax2 = ax2_divider.append_axes("top", size="5%", pad="2%")
        cbar = plt.colorbar(img, cax=cax2, orientation='horizontal')
        cbar.set_label(cbarlabel[i], labelpad=-70)
        #cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])
        cax2.xaxis.set_ticks_position("top")
        print("Plot run completed:\t", i)

    # Define output
    if output == 'show':
        plt.show()

    elif output == 'save':
        dir_name = 'tSZ maps'
        if not exists(dir_name):
            makedirs(dir_name)
        save_name = 'tSZmap_' + plot_groups + '_halo' + str(
            num_halo) + '_z' + str(redshift_short).replace(
                ".", "") + '_rfov' + str(rfov) + '_nbins' + str(nbins)
        plt.savefig(dir_name + '//' + save_name + '.pdf')

        # Generate metadata.txt
        args = (num_halo, simulation_type, redshift, angular_distance, min_gn,
                min_sgn, min_T, max_r, weight_function, nbins, rfov,
                kernel_Type, fwhm, r200, r200 / Mpc_to_arcmin)
        meta.metadata_file(args, dir_name + '//' + save_name)

    else:
        print(
            "[ERROR] The output type you are trying to select is not defined.")
        exit(1)
def phase_diagram_master(axes, redshift, nbins = 400, max_halo=10, selection = 'all', bg='w'):
    master_density = []
    master_temperature = []
    for num_halo in np.arange(max_halo):
        print('Ímporting halo ' + str(num_halo))

        # Import data
        path = extract.path_from_cluster_name(num_halo, simulation_type='gas')
        file = extract.file_name_hdf5(subject='groups', redshift=extract.redshift_floatTostr(redshift))
        r200 = extract.group_r200(path, file)
        group_CoP = extract.group_centre_of_potential(path, file)

        file = extract.file_name_hdf5(subject='particledata', redshift=extract.redshift_floatTostr(redshift))

        # Gas particles
        part_type = extract.particle_type('gas')
        density = extract.particle_SPH_density(path, file, part_type)/1.16 # Account for the fact that there are H/He atoms
        coordinates = extract.particle_coordinates(path, file, part_type)
        temperature = extract.particle_temperature(path, file, part_type)
        group_number = extract.group_number(path, file, part_type)
        subgroup_number = extract.subgroup_number(path, file, part_type)

        # Retrieve coordinates
        x = coordinates[:, 0] - group_CoP[0]
        y = coordinates[:, 1] - group_CoP[1]
        z = coordinates[:, 2] - group_CoP[2]

        # Rescale to comoving coordinates
        h = extract.file_hubble_param(path, file)
        x = profile.comoving_length(x, h, redshift)
        y = profile.comoving_length(y, h, redshift)
        z = profile.comoving_length(z, h, redshift)
        r200 = profile.comoving_length(r200, h, redshift)
        density = profile.comoving_density(density, h, redshift)
        density = profile.density_units(density, unit_system='nHcgs')

        # Compute radial distance
        r = np.sqrt(x ** 2 + y ** 2 + z ** 2)

        index = 0
        # Select particles within 5*r200
        if selection.lower() == 'all':
            index = np.where((r < 5 * r200) & (group_number == 1) & (subgroup_number > -1))[0]
        if selection.lower() == 'sub':
            index = np.where((r < 5 * r200) & (group_number == 1) & (subgroup_number > 0) & (subgroup_number < 10000))[0]
        if selection.lower() == 'icm':
            index = np.where((r < 5 * r200) & (group_number == 1) & (subgroup_number == 0))[0]

        density = density[index]
        temperature = temperature[index]

        master_density.append(density)
        master_temperature.append((temperature))


    # Bin data
    x_Data = np.concatenate(master_density)
    y_Data = np.concatenate(master_temperature)
    x_bins = np.logspace(np.min(np.log10(x_Data)), np.max(np.log10(x_Data)), nbins)
    y_bins = np.logspace(np.min(np.log10(y_Data)), np.max(np.log10(y_Data)), nbins)
    #A_pix = (x_bins[1:] - x_bins[:-1]) * (y_bins[1] - y_bins[0])
    #Ex, Ey = np.meshgrid(x_bins, y_bins)
    #A_pix = np.asarray([np.multiply((Ex[i][1:]-Ex[i][:-1]),(Ey[i+1][0]-Ey[i][0])) for i in range(np.shape(Ex)[0]-1)])
    Cx, Cy = mapgen.bins_meshify(x_Data, y_Data, x_bins, y_bins)
    #count = np.divide(mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins, weights=None), A_pix)
    count = mapgen.bins_evaluate(x_Data, y_Data, x_bins, y_bins, weights=None)

    # Logarithmic normalization
    norm = mpl.colors.LogNorm()  # (vmin=10 ** -2, vmax=10 ** 1)

    count2 = np.ma.masked_where(count == 0, count)
    cmap = plt.get_cmap('CMRmap')
    cmap.set_bad(color=bg, alpha=1)

    img = axes.pcolormesh(Cx, Cy, count2, cmap=cmap, norm=norm)
    axes.set_facecolor('k')
    axes.set_xscale('log')
    axes.set_yscale('log')
    #axes.axvline(x=0.1, linewidth=1, color='w', linestyle='dotted')
    axes.axhline(y=1e5, linewidth=1, color='w', linestyle='dashed')
    #__M__ axes.axhline(y=1e5, linewidth=1, color='darkgrey', linestyle='dashed')
    axes.set_xlabel(r'$n_{\mathrm{H}}/\mathrm{cm}^{3}$')
    axes.set_xlim(2e-6, 1e3)
    #axes.set_xlabel(r'$\rho/(M_\odot\ kpc^{-3})$')
    if selection=='all':
        axes.set_ylabel(r'$T/\mathrm{K}$')
        t = axes.text(.15, 10 ** 9, r'$\mathrm{ICM\ +\ SUBHALOS}$', color='w', fontsize = 15)
        #__M__t = axes.text(1, 10 ** 9, r'$\mathrm{ALL\ GAS}$', color='w', fontsize=15)

    else:
        axes.set_ylabel(r' ')
        t = axes.text(.2, 10 ** 9, r'$\mathrm{SUBHALOS\ ONLY}$', color='w', fontsize = 15)
        #__M__t = axes.text(.07, 10 ** 9, r'$\mathrm{SUBHALO\ GAS\ ONLY}$', color='w', fontsize=15)
    t.set_bbox(dict(facecolor='k', alpha=0.9, edgecolor='grey'))
    #__M__t.set_bbox(dict(facecolor='w', alpha=0.15, edgecolor='darkgrey'))
    # Colorbar adjustments
    ax2_divider = make_axes_locatable(axes)
    cax2 = ax2_divider.append_axes("top", size="3%", pad="2%")
    cbar = plt.colorbar(img, cax=cax2, orientation='horizontal')
    #cbar.set_label(r'$N_{\mathrm{particles}} / (\mathrm{K}\ \mathrm{cm}^{-3})$', labelpad=-60)
    cbar.set_label(r'$N_{\mathrm{particles}}$', labelpad=-60)
    # cax2.xaxis.set_tick_labels(['0',' ','0.5',' ','1',' ', '1.5',' ','2'])
    cax2.xaxis.set_ticks_position("top")