Example #1
0
def interpgridnodes(Pk=5.0, kappa=np.inf, struct="pp", sampling=1):

    # 1: Extract the "spectra from the grid nodes
    grid_name = "[NII]/[SII]+;[OIII]/[SII]+"

    grid = pyqz.get_grid(
        grid_name, Pk=Pk, struct=struct, kappa=kappa, coeffs=pyqz.diagnostics[grid_name]["coeffs"], sampling=sampling
    )

    grid_nodes = grid[0][
        :, [grid[1].index("LogQ"), grid[1].index("Tot[O]+12"), grid[1].index("Mix_x"), grid[1].index("Mix_y")]
    ]

    # 2: Now, interpolate and checks the output
    interp_qs = pyqz.interp_qz(
        "LogQ",
        [grid_nodes[:, -2], grid_nodes[:, -1]],
        grid_name,
        coeffs=pyqz.diagnostics[grid_name]["coeffs"],
        Pk=Pk,
        kappa=kappa,
        struct=struct,
        sampling=sampling,
    )
    interp_zs = pyqz.interp_qz(
        "Tot[O]+12",
        [grid_nodes[:, -2], grid_nodes[:, -1]],
        grid_name,
        coeffs=pyqz.diagnostics[grid_name]["coeffs"],
        Pk=Pk,
        kappa=kappa,
        struct=struct,
        sampling=sampling,
    )

    return np.all(np.round(interp_qs, 2) == grid_nodes[:, 0]) and np.all(np.round(interp_zs, 3) == grid_nodes[:, 1])
Example #2
0
def plot_grid(ratios,
              coeffs=[[1, 0], [0, 1]],
              Pk=5.0,
              kappa=np.inf,
              struct='pp',
              sampling=1,
              color_mode='Tot[O]+12',
              figname=None,
              show_plot=True,
              data=None,
              interp_data=None):
    '''
    Creates the diagram of a given line ratio grid for rapid inspection, including wraps
    (fold-over regions), and of certain line ratios, if "data" is specified.
        
    :Args:
        ratios: string 
                The line ratios defining the grid, e.g. '[NII]/[SII]+;[OIII]/Hb'
        coeffs: list of list [default: [[1,0],[0,1]] ]
                The different coefficients with which to mix the line ratios. 
                The size of each sub-list must be equal to the number of line ratios 
                involved. Used for projected 3D diagnostic grids.
        Pk: float [default: 5.0] 
            MAPPINGS model pressure. This value must match an existing grid file.
        kappa: float [default: np.inf 
               The kappa value. This value must match an existing grid file.
        struct: string [default: 'pp']
                spherical ('sph') or plane-parallel ('pp') HII regions. This value 
                must match an existing reference grid file.
        sampling: int [default: 1]
                  Use a resampled grid ?
        color_mode: string [default: 'Tot[O]+12']
                    Color the grid according to 'Tot[O]+12', 'gas[O]+12' or 'LogQ'.    
        figname: string [default: None]
                  'path+name+format' to save the Figure to.
        show_plot: bool [default: True]
                  Do you want to display the Figure ?
        data: list of numpy array [default: None]
              List of Arrays of the line ratio values. One array per line ratio.
        interp_data: numpy array [default: 'linear']
                     interpolated line ratios (via pyqz.interp_qz)
   '''

    # 0) Let's get the data in question
    [grid, grid_cols, metadata] = pyqz.get_grid(ratios,
                                                coeffs=coeffs,
                                                Pk=Pk,
                                                kappa=kappa,
                                                struct=struct,
                                                sampling=sampling)

    # 1) What are the bad segments in this grid ?
    bad_segs = pyqz.check_grid(ratios,
                               coeffs=coeffs,
                               Pk=Pk,
                               kappa=kappa,
                               struct=struct,
                               sampling=sampling)

    # 2) Start the plotting
    fig = plt.figure(figsize=(10, 8))

    gs = gridspec.GridSpec(1, 2, height_ratios=[1], width_ratios=[1, 0.05])
    gs.update(left=0.14,
              right=0.88,
              bottom=0.14,
              top=0.92,
              wspace=0.1,
              hspace=0.1)
    ax1 = fig.add_subplot(gs[0, 0])

    if not (color_mode in grid_cols):
        raise Exception('color_mode unknown: %s' % color_mode)

    # 2) Plot the grid points
    # Let's make the distinction between the 'TRUE' MAPPINGS point,
    # and those that were interpolated in a finer grid using Akima splines
    pts = ax1.scatter(grid[:, grid_cols.index('Mix_x')],
                      grid[:, grid_cols.index('Mix_y')],
                      marker='o',
                      c=grid[:, grid_cols.index(color_mode)],
                      s=30,
                      cmap=pyqzm.pyqz_cmap_0,
                      edgecolor='none',
                      vmin=np.min(grid[:, grid_cols.index(color_mode)]),
                      vmax=np.max(grid[:, grid_cols.index(color_mode)]),
                      zorder=3)

    # Now mark the "original" points with a black outline. First, which are they ?
    if sampling > 1:
        origin_cond = [
            n for n in range(len(grid))
            if (grid[n, metadata['columns'].index('LogQ')] in
                metadata['resampled']['LogQ']) and (
                    grid[n, metadata['columns'].index('Tot[O]+12')] in
                    metadata['resampled']['Tot[O]+12'])
        ]
    else:
        origin_cond = [n for n in range(len(grid))]

    # Now plot the black outlines.
    original_pts = ax1.scatter(grid[origin_cond,
                                    grid_cols.index('Mix_x')],
                               grid[origin_cond,
                                    grid_cols.index('Mix_y')],
                               marker='o',
                               c=grid[origin_cond,
                                      grid_cols.index(color_mode)],
                               s=60,
                               cmap=pyqzm.pyqz_cmap_0,
                               edgecolor='k',
                               facecolor='white',
                               vmin=np.min(grid[:,
                                                grid_cols.index(color_mode)]),
                               vmax=np.max(grid[:,
                                                grid_cols.index(color_mode)]),
                               zorder=5)

    # 2-1) Draw the grid lines
    # Check as a function of LogQ and Tot[O]+12. Where are these ?
    u = grid_cols.index('LogQ')
    v = grid_cols.index('Tot[O]+12')

    for i in [u, v]:
        # Here, 'var' plays the role of 'q' or 'z' depending on 'i'.
        for var in np.unique(grid[:, i]):
            # Plot the grid line
            ax1.plot(grid[grid[:, i] == var][:, grid_cols.index('Mix_x')],
                     grid[grid[:, i] == var][:, grid_cols.index('Mix_y')],
                     'k-',
                     lw=1,
                     zorder=1)

    # Plot the bad segments
    for bad_seg in bad_segs:
        ax1.plot([bad_seg[0][0], bad_seg[1][0]],
                 [bad_seg[0][1], bad_seg[1][1]],
                 'r-',
                 linewidth=4,
                 zorder=0)

    # Now, also plot the data, if anything was provided !
    if not (interp_data is None):

        # Compute the combined "observed" ratios
        data_comb = [np.zeros_like(data[0]), np.zeros_like(data[1])]
        for k in range(len(ratios.split(';'))):
            data_comb[0] += coeffs[0][k] * data[k]
            data_comb[1] += coeffs[1][k] * data[k]

        ax1.scatter(data_comb[0][interp_data == interp_data],
                    data_comb[1][interp_data == interp_data],
                    marker='s',
                    c=interp_data[interp_data == interp_data],
                    s=15,
                    cmap=pyqzm.pyqz_cmap_0,
                    edgecolor='k',
                    vmin=np.min(grid[:, grid_cols.index(color_mode)]),
                    vmax=np.max(grid[:, grid_cols.index(color_mode)]),
                    zorder=2,
                    alpha=0.35)

        # Plot also the points outside the grid ?
        # Which are they ? Need to check if they have a valid input first !
        # mind the "~" to invert the bools ! isn't this cool ?
        my_out_pts = ~np.isnan(data_comb[0]) * ~np.isnan(data_comb[1]) * \
            np.isnan(interp_data)

        # Don't do this if this is a test with fullgrid_x ...
        ax1.scatter(data_comb[0][my_out_pts],
                    data_comb[1][my_out_pts],
                    marker='^',
                    facecolor='none',
                    edgecolor='k',
                    s=60)

    # 3) Plot the colorbar
    cb_ax = plt.subplot(gs[0, 1])
    cb = Colorbar(ax=cb_ax, mappable=pts, orientation='vertical')

    # Colorbar legend
    cb.set_label(color_mode, labelpad=10)

    # 4) Axis names, kappa value, etc ...
    rats = ratios.split(';')
    # Make sure the labels look pretty in ALL cases ...
    labelx, labely = get_plot_labels(rats, coeffs)

    ax1.set_xlabel(labelx, labelpad=10)
    ax1.set_ylabel(labely, labelpad=10)

    if not (kappa in [np.inf, 'inf']):
        kappa_str = r'$\kappa$ = ' + str(kappa)
    else:
        kappa_str = r'$\kappa$ = $\infty$'

    ax1.text(0.85,
             0.9,
             kappa_str,
             horizontalalignment='left',
             verticalalignment='bottom',
             transform=ax1.transAxes)
    ax1.grid(True)

    if figname:
        fig.savefig(figname, bbox_inches='tight')
    if show_plot:
        plt.show()
    else:
        plt.close()
Example #3
0
def plot_grid(ratios, coeffs = [[1,0],[0,1]],
              Pk = 5.0, kappa=np.inf, struct = 'pp', sampling = 1,
              color_mode = 'Tot[O]+12', figname = None, show_plot = True,
              data = None, interp_data = None):
    '''
    Creates the diagram of a given line ratio grid for rapid inspection, including wraps
    (fold-over regions), and of certain line ratios, if "data" is specified.
        
    :Args:
        ratios: string 
                The line ratios defining the grid, e.g. '[NII]/[SII]+;[OIII]/Hb'
        coeffs: list of list [default: [[1,0],[0,1]] ]
                The different coefficients with which to mix the line ratios. 
                The size of each sub-list must be equal to the number of line ratios 
                involved. Used for projected 3D diagnostic grids.
        Pk: float [default: 5.0] 
            MAPPINGS model pressure. This value must match an existing grid file.
        kappa: float [default: np.inf 
               The kappa value. This value must match an existing grid file.
        struct: string [default: 'pp']
                spherical ('sph') or plane-parallel ('pp') HII regions. This value 
                must match an existing reference grid file.
        sampling: int [default: 1]
                  Use a resampled grid ?
        color_mode: string [default: 'Tot[O]+12']
                    Color the grid according to 'Tot[O]+12', 'gas[O]+12' or 'LogQ'.    
        figname: string [default: None]
                  'path+name+format' to save the Figure to.
        show_plot: bool [default: True]
                  Do you want to display the Figure ?
        data: list of numpy array [default: None]
              List of Arrays of the line ratio values. One array per line ratio.
        interp_data: numpy array [default: 'linear']
                     interpolated line ratios (via pyqz.interp_qz)
   ''' 

    # 0) Let's get the data in question
    [grid, grid_cols, metadata] = pyqz.get_grid(ratios, coeffs=coeffs, Pk=Pk, kappa=kappa,     
                                                struct=struct, sampling = sampling)
                                            
    # 1) What are the bad segments in this grid ?
    bad_segs = pyqz.check_grid(ratios, coeffs=coeffs, Pk = Pk, kappa=kappa, struct=struct, 
                               sampling = sampling)                  
                                     
    # 2) Start the plotting
    fig = plt.figure(figsize=(10,8))
    
    gs = gridspec.GridSpec(1,2, height_ratios=[1], width_ratios=[1,0.05])
    gs.update(left=0.14,right=0.88,bottom=0.14,top=0.92,
                wspace=0.1,hspace=0.1)    
    ax1 = fig.add_subplot(gs[0,0])  

    if not(color_mode in grid_cols):
        sys.exit('color_mode unknown: %s' % color_mode)

    # 2) Plot the grid points 
    # Let's make the distinction between the 'TRUE' MAPPINGS point, 
    # and those that were interpolated in a finer grid using Akima splines
    pts = ax1.scatter(grid[:,grid_cols.index('Mix_x')],
                      grid[:,grid_cols.index('Mix_y')],
                      marker='o',
                      c=grid[:,grid_cols.index(color_mode)],
                      s=30, cmap=pyqz_cmap_0, edgecolor='none', 
                      vmin=np.min(grid[:,grid_cols.index(color_mode)]), 
                      vmax=np.max(grid[:,grid_cols.index(color_mode)]), 
                      zorder=3)
           
    # Now mark the "original" points with a black outline. First, which are they ?
    if sampling > 1:
        origin_cond = [n for n in range(len(grid)) if 
                         (grid[n,metadata['columns'].index('LogQ')] in 
                                                      metadata['resampled']['LogQ']) and 
                         (grid[n,metadata['columns'].index('Tot[O]+12')] in 
                                                      metadata['resampled']['Tot[O]+12'])]
    else:
        origin_cond = [n for n in range(len(grid))]
    
    # Now plot the black outlines.
    original_pts = ax1.scatter(grid[origin_cond, grid_cols.index('Mix_x')],
                               grid[origin_cond, grid_cols.index('Mix_y')],
                               marker='o',
                               c=grid[origin_cond, grid_cols.index(color_mode)],
                               s=60, cmap=pyqz_cmap_0, edgecolor='k', facecolor='white',
                               vmin=np.min(grid[:,grid_cols.index(color_mode)]), 
                               vmax=np.max(grid[:,grid_cols.index(color_mode)]), 
                               zorder=5)          


    # 2-1) Draw the grid lines
    # Check as a function of LogQ and Tot[O]+12. Where are these ?
    u = grid_cols.index('LogQ')
    v = grid_cols.index('Tot[O]+12')

    for i in [u,v]:  
        # Here, 'var' plays the role of 'q' or 'z' depending on 'i'.
        for var in np.unique(grid[:,i]):
            # Plot the grid line
            ax1.plot(grid[grid[:,i]==var][:,grid_cols.index('Mix_x')],
                            grid[grid[:,i]==var][:,grid_cols.index('Mix_y')],
                            'k-', lw = 1, zorder=1)
                            
    # Plot the bad segments
    for bad_seg in bad_segs:
        ax1.plot([bad_seg[0][0],bad_seg[1][0]],[bad_seg[0][1],bad_seg[1][1]],  'r-',
                 linewidth=4, zorder=0)
                            
    # Now, also plot the data, if anything was provided !             
    if not(interp_data is None):
        
        # Compute the combined "observed" ratios
        data_comb = [np.zeros_like(data[0]),np.zeros_like(data[1])]    
        for k in range(len(ratios.split(';'))): 
            data_comb[0] += coeffs[0][k]*data[k]
            data_comb[1] += coeffs[1][k]*data[k]
        
        ax1.scatter(data_comb[0][interp_data == interp_data], 
                    data_comb[1][interp_data == interp_data],
                    marker='s', c=interp_data[interp_data == interp_data],
                    s=15, cmap = pyqz_cmap_0, edgecolor='k',
                    vmin = np.min(grid[:,grid_cols.index(color_mode)]),
                    vmax = np.max(grid[:,grid_cols.index(color_mode)]),
                    zorder=2, alpha=0.35)

        # Plot also the points outside the grid ?
        # Which are they ? Need to check if they have a valid input first !
        # mind the "~" to invert the bools ! isn't this cool ?
        my_out_pts = ~np.isnan(data_comb[0]) * ~np.isnan(data_comb[1]) * \
            np.isnan(interp_data)
  
        # Don't do this if this is a test with fullgrid_x ...
        ax1.scatter(data_comb[0][my_out_pts], data_comb[1][my_out_pts],
                    marker = '^', facecolor = 'none', edgecolor = 'k', s=60)           
                               
    # 3) Plot the colorbar
    cb_ax = plt.subplot(gs[0,1])
    cb = Colorbar(ax = cb_ax, mappable = pts, orientation='vertical')
        
    # Colorbar legend
    cb.set_label(color_mode, labelpad = 10)
        
    # 4) Axis names, kappa value, etc ...
    rats = ratios.split(';')
    # Make sure the labels look pretty in ALL cases ...
    labelx,labely = get_plot_labels(rats,coeffs)
                                                  
    ax1.set_xlabel(labelx,labelpad = 10)
    ax1.set_ylabel(labely,labelpad = 10)
        
    if not(kappa in [np.inf, 'inf']) :
        kappa_str = r'$\kappa$ = '+str(kappa)    
    else :
        kappa_str = r'$\kappa$ = $\infty$'
        
    ax1.text(0.85,0.9,kappa_str, horizontalalignment='left',verticalalignment='bottom',
             transform=ax1.transAxes)
    ax1.grid(True)
        
    if figname :
        fig.savefig(figname, bbox_inches='tight')
    if show_plot:
        plt.show()
    else:
        plt.close()