Source code for idstools.view.edge_profiles

import logging

import numpy as np

from idstools.compute.edge_profiles import EdgeProfilesCompute

logger = logging.getLogger("module")


[docs]class EdgeProfilesView: def __init__(self, edge_profile_ids=None): self.edge_profiles_compute = EdgeProfilesCompute(edge_profile_ids)
[docs] @staticmethod def view_plasma_composition_with_species_concentration(ids_object, slice_index=0, print_data=False): """ Nice display of plasma composition with species concentrations """ composition_data = EdgeProfilesCompute.get_plasma_composition_with_species_concentration( ids_object, slice_index ) if composition_data != 0 and composition_data != -1: edge_profiles_view = EdgeProfilesView() edge_profiles_view._print_plasma_composition(composition_data) edge_profiles_view._print_specis_concentration(composition_data) if print_data is True: import json print(json.dumps(composition_data, sort_keys=True, indent=4)) return composition_data
def _print_plasma_composition(self, composition_data): disp_species = f"{'species:': <15}" disp_a = f"{'a:': <15}" disp_z = f"{'z:': <15}" disp_nspec_over_ntot = f"{'n_over_ntot:': <15}" disp_nspec_over_ne = f"{'n_over_ne:': <15}" disp_nspec_over_nmaj = f"{'n_over_n_maj:': <15}" main_species = "" for species_key, species_data in composition_data.items(): if species_data["nspec_over_ntot"] > 0.45: if len(main_species) == 0: main_species = main_species + species_data["species"] else: main_species = main_species + "-" + species_data["species"] if species_data["nspec_over_ne"] > 0.0: species_name = f"{species_data['species']}({species_data['label']})" species_name = species_name[:11] disp_species = f"{disp_species} {species_name : >12}" a = f"{species_data['a'].value :.1f}" disp_a = f"{disp_a} {a : >12}" z = f"{species_data['z'] :.1f}" disp_z = f"{disp_z} {z : >12}" if species_data["nspec_over_ntot"] < 1.0e-2: nspec_over_ntot = f"{species_data['nspec_over_ntot'] :.2e}" disp_nspec_over_ntot = f"{disp_nspec_over_ntot} {nspec_over_ntot : >12}" else: nspec_over_ntot = f"{species_data['nspec_over_ntot'] :.3f}" disp_nspec_over_ntot = f"{disp_nspec_over_ntot} {nspec_over_ntot : >12}" if species_data["nspec_over_ne"] < 1.0e-2: nspec_over_ne = f"{species_data['nspec_over_ne'] :.2e}" disp_nspec_over_ne = f"{disp_nspec_over_ne} {nspec_over_ne : >12}" else: nspec_over_ne = f"{species_data['nspec_over_ne'] :.3f}" disp_nspec_over_ne = f"{disp_nspec_over_ne} {nspec_over_ne : >12}" if species_data["nspec_over_nmaj"] < 1.0e-2: nspec_over_nmaj = f"{species_data['nspec_over_nmaj'] :.2e}" disp_nspec_over_nmaj = f"{disp_nspec_over_nmaj} {nspec_over_nmaj : >12}" else: nspec_over_nmaj = f"{species_data['nspec_over_nmaj'] :.3f}" disp_nspec_over_nmaj = f"{disp_nspec_over_nmaj} {nspec_over_nmaj : >12}" print(disp_species) print(disp_a) print(disp_z) print(disp_nspec_over_ntot) print(disp_nspec_over_ne) print(disp_nspec_over_nmaj) print(" ------------") def _print_specis_concentration(self, composition_data): for species_key, species_data in composition_data.items(): states = species_data["states"] nstates = len(states) if nstates > 1: comm = "s" else: comm = "" if nstates != 0: print( species_data["species"], " has ", nstates, " state" + comm, ) istate = 0 for state_key, state_data in states.items(): n_ni = f"{state_data['n_ni']:.6f}" label_space = 0 if state_data["label"].strip() != "": label_space = 7 print( f"\t {'state' + str(istate + 1) : <8}{state_data['label'].value: <{label_space}} z : " f"{state_data['z_average']:.6f} n/ni, % :{n_ni : >12}" ) istate += 1
[docs] def view_electrons_density(self, ax, time_slice, show_separatrix=False): """ The function `view_electrons_density` plots the electron density on a rectangular grid and adds a separatrix line. Args: ax: The parameter "ax" is an instance of the matplotlib Axes class. It represents the axes on which the electron density plot will be drawn. time_slice: The `time_slice` parameter represents the time slice at which the neutral density will be plotted. It is an optional parameter with a default value of 0. Defaults to 0 Returns: the pcolormesh object 'c'. """ x, y = self.edge_profiles_compute.get_rectangular_grid(500) ne_edge = self.edge_profiles_compute.get_electron_density(time_slice, x, y) if ne_edge is not None: ax.grid(False) c = ax.pcolormesh(x, y, ne_edge, vmin=0, vmax=5e19, shading="auto") core_boundry = self.edge_profiles_compute.get_core_boundry(time_slice) ax.fill(core_boundry[:, 0], core_boundry[:, 1], facecolor="w", edgecolor="r", linewidth=0) if show_separatrix: separatrix = self.edge_profiles_compute.get_separatrix(time_slice) if separatrix is not None: ax.scatter(separatrix[:, 0], separatrix[:, 1], color="#FF1493", marker="x") ax.set_aspect("equal", adjustable="box") ax.set_xlabel("R,m") ax.set_ylabel("Z,m") ax.set_title("Electron density") return c else: xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() ax.text( (xmax + xmin) / 2, (ymax + ymin) / 2, "No data", horizontalalignment="left", verticalalignment="center", ) return None
[docs] def view_ion_density(self, ax, time_slice, show_separatrix=False): """ The function `view_ion_density` plots the ion density on a rectangular grid and adds a separatrix line. Args: ax: The parameter "ax" is an instance of the matplotlib Axes class. It represents the axes on which the ion density plot will be drawn. time_slice: The `time_slice` parameter represents the time slice at which the neutral density will be plotted. It is an optional parameter with a default value of 0. Defaults to 0 Returns: the pcolormesh object 'c'. """ x, y = self.edge_profiles_compute.get_rectangular_grid(500) ni_edge = self.edge_profiles_compute.get_ion_density(time_slice, x, y) if ni_edge is not None: ax.grid(False) c = ax.pcolormesh(x, y, ni_edge, vmin=0, vmax=5e19, shading="auto") core_boundry = self.edge_profiles_compute.get_core_boundry(time_slice) ax.fill(core_boundry[:, 0], core_boundry[:, 1], facecolor="w", edgecolor="r", linewidth=0) if show_separatrix: separatrix = self.edge_profiles_compute.get_separatrix(time_slice) if separatrix is not None: ax.scatter(separatrix[:, 0], separatrix[:, 1], color="#FF1493", marker="x") ax.set_aspect("equal", adjustable="box") ax.set_xlabel("R,m") ax.set_ylabel("Z,m") ax.set_title("Ion density") return c else: xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() ax.text( (xmax + xmin) / 2, (ymax + ymin) / 2, "No data", horizontalalignment="left", verticalalignment="center", ) return None
[docs] def view_neutral_density(self, ax, time_slice, show_separatrix=False): """ The function `view_neutral_density` plots the neutral density on a rectangular grid and adds a separatrix line. Args: ax: The parameter "ax" is an instance of the matplotlib Axes class. It represents the axes on which the plot will be drawn. time_slice: The `time_slice` parameter represents the time slice at which the neutral density will be plotted. It is an optional parameter with a default value of 0. Defaults to 0 Returns: the pcolormesh object 'c'. """ x, y = self.edge_profiles_compute.get_rectangular_grid(500) n_neutral_edge = self.edge_profiles_compute.get_neutral_density(time_slice, x, y) if n_neutral_edge is not None: ax.grid(False) c = ax.pcolormesh(x, y, n_neutral_edge, vmin=0, vmax=5e19, shading="auto") core_boundry = self.edge_profiles_compute.get_core_boundry(time_slice) ax.fill(core_boundry[:, 0], core_boundry[:, 1], facecolor="w", edgecolor="r", linewidth=0) if show_separatrix: separatrix = self.edge_profiles_compute.get_separatrix(time_slice) if separatrix is not None: ax.scatter(separatrix[:, 0], separatrix[:, 1], color="#FF1493", marker="x") ax.set_aspect("equal", adjustable="box") ax.set_xlabel("R,m") ax.set_ylabel("Z,m") ax.set_title("Neutral density") return c else: xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() ax.text( (xmax + xmin) / 2, (ymax + ymin) / 2, "No data", horizontalalignment="left", verticalalignment="center", ) return None
[docs] def view_equatorial_plane_and_diverter_density(self, ax, time_slice, logscale=False): x, y = self.edge_profiles_compute.get_rectangular_grid(500) ne_edge = self.edge_profiles_compute.get_electron_density(time_slice, x, y) if ne_edge is not None: # choose Z position for a radial profile: z0 = 0.0 ind = np.argmin(abs(y[:, 0] - z0)) ax.plot(x[ind, :], ne_edge[ind, :], label="Equatorial plane") z0 = -4.0 ind = np.argmin(abs(y[:, 0] - z0)) ax.plot(x[ind, :], ne_edge[ind, :], label="Divertor") if logscale: ax.set_yscale("log") ax.set_title("Electron density") ax.set_xlabel("R,m") # ax.set_ylim([0, 1.5e21]) ax.legend() else: xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() ax.text( (xmax + xmin) / 2, (ymax + ymin) / 2, "No data", horizontalalignment="left", verticalalignment="center", ) return None
[docs] def show_info_on_plot(self, ax, info: str = ""): xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() left, width = xmin, xmax - xmin bottom, height = ymin, ymax - ymin right = left + width top = bottom + height ax.text( right, top, info, horizontalalignment="right", verticalalignment="bottom", fontsize=5, )