示例#1
0
def get_shell_mass_wrapper(dir_NM, model_1d):
#def load_model_info(dir_base, RadialPNM_info, r_q, r_q_vals):

    # Load radius information for 3-D modes.
    _, header, _, _ = load_vsh_coefficients(dir_NM, 1, i_radius = 'all')

    # Calculate the mid-points.
    r_inner, r_outer = get_mid_points(header['i_sample'], header['r_sample'])

    # Extract the portions of the density model for each shell.
    shell_mass = get_shell_mass(header['i_sample'], r_inner, r_outer, model_1d, normalise = True)

    return shell_mass
示例#2
0
def projection_wrapper_one_mode(dir_NM, i_mode, f, mode_info_1d, run_info_1d, l_max, shell_mass, max_f_diff = 0.2):

    # Dictionary for saving mode type as integer.
    mode_type_to_int_dict = {'R' : 0, 'S' : 1, 'T' : 2, 'T1' : 2, 'I' : 3, 'T0' : 3}

    # Find 1-D modes which are close in frequency to the 3-D mode.
    mode_info_1d = find_close_modes(f, mode_info_1d, max_f_diff)

    # Load the eigfunction of the 3-D mode.
    coeffs, header, _, _ = load_vsh_coefficients(dir_NM, i_mode, i_radius = 'all')
    r = header['r_sample']
    n_radii = len(r)

    # Convert to real spherical harmonics.
    l_coeffs, m_coeffs, coeffs = convert_to_real_spherical_harmonics(coeffs, l_max)

    # Multiply V and W components by k.
    k = np.sqrt(l_coeffs * (l_coeffs + 1))
    k[k == 0.0] = 1.0
    coeffs[1, :, :] = k * coeffs[1, :, :]
    coeffs[2, :, :] = k * coeffs[2, :, :]
    coeffs[4, :, :] = k * coeffs[4, :, :]
    coeffs[5, :, :] = k * coeffs[5, :, :]

    #mode_type_test = 'T1'
    #mode_info_1d = {mode_type_test : mode_info_1d[mode_type_test]}

    # Count the modes.
    num_modes_1d_by_type_no_multiplets = dict()
    num_modes_1d_by_type_with_multiplets = dict()
    num_modes_1d_total_no_multiplets = 0
    num_modes_1d_total_with_multiplets = 0
    # 
    for mode_type in mode_info_1d.keys():
        
        num_modes_1d_by_type_no_multiplets[mode_type] = len(mode_info_1d[mode_type]['l'])
        #
        num_modes_1d_total_no_multiplets = num_modes_1d_total_no_multiplets + \
                                        num_modes_1d_by_type_no_multiplets[mode_type]
        
        num_modes_1d_by_type_with_multiplets[mode_type] = 0
        for j in range(num_modes_1d_by_type_no_multiplets[mode_type]):
            
            l_j = mode_info_1d[mode_type]['l'][j]
            num_modes_1d_by_type_with_multiplets[mode_type] = \
                    num_modes_1d_by_type_with_multiplets[mode_type] + ((2 * l_j) + 1)

        num_modes_1d_total_with_multiplets = num_modes_1d_total_with_multiplets + \
                num_modes_1d_by_type_with_multiplets[mode_type]

    # Prepare to loop over all the 1-D modes and evaluate scalar product with the 3-D mode.
    #
    mode_type_out_array = np.zeros(num_modes_1d_total_with_multiplets, dtype = np.int)
    n                   = np.zeros(num_modes_1d_total_with_multiplets, dtype = np.int)
    l                   = np.zeros(num_modes_1d_total_with_multiplets, dtype = np.int)
    m                   = np.zeros(num_modes_1d_total_with_multiplets, dtype = np.int)
    product_real_part   = np.zeros(num_modes_1d_total_with_multiplets)
    product_imag_part   = np.zeros(num_modes_1d_total_with_multiplets)
    #
    i0 = 0

    # Loop over mode types.
    for mode_type_1d in mode_info_1d.keys():

        # Get mode type integer for saving output.
        mode_type_int = mode_type_to_int_dict[mode_type_1d]

        # Loop over modes of the given mode type.
        for j in range(num_modes_1d_by_type_no_multiplets[mode_type_1d]):

            print('Mode_type {:>2}, mode {:>4d} of {:>4d}'.format(mode_type_1d,
                    j + 1, num_modes_1d_by_type_no_multiplets[mode_type_1d]))

            # Get n, l and multiplicity of current 1-D mode.
            n_j = mode_info_1d[mode_type_1d]['n'][j]
            l_j = mode_info_1d[mode_type_1d]['l'][j]
            multiplicity_j = (2 * l_j) + 1

            # Get upper index in output array.
            i1 = i0 + multiplicity_j       

            # All modes in the multiplet have the same mode type.
            mode_type_out_array[i0 : i1] = mode_type_int

            # All (2l + 1) modes in the multiplet have the same n and l value.
            n[i0 : i1] = n_j
            l[i0 : i1] = l_j

            # Find the indices of the given l value in the coefficient list.
            k = np.where((l_coeffs == l_j))[0]

            # Get the m values from the coefficient list.
            m[i0 : i1] = m_coeffs[k]

            # Do projection of real part.
            product_real_part[i0 : i1] = project_one_mode_onto_one_multiplet(
                                    header['r_sample'], header['i_sample'],
                                    shell_mass,
                                    coeffs[0, :, k], coeffs[1, :, k],
                                    coeffs[2, :, k], run_info_1d, mode_type_1d,
                                    mode_info_1d[mode_type_1d]['n'][j],
                                    mode_info_1d[mode_type_1d]['l'][j],
                                    mode_info_1d[mode_type_1d]['f'][j])

            # Do projection of imaginary part.
            product_imag_part[i0 : i1] = project_one_mode_onto_one_multiplet(
                                    header['r_sample'], header['i_sample'],
                                    shell_mass,
                                    coeffs[3, :, k], coeffs[4, :, k],
                                    coeffs[5, :, k], run_info_1d, mode_type_1d,
                                    mode_info_1d[mode_type_1d]['n'][j],
                                    mode_info_1d[mode_type_1d]['l'][j],
                                    mode_info_1d[mode_type_1d]['f'][j])

            # Prepare for next iteration of loop.
            i0 = i1

    # Save output.
    out_fmt = '{:>2d} {:>5d} {:>5d} {:>+6d} {:>+19.12e} {:>+19.12e}\n'
    dir_processed = os.path.join(dir_NM, 'processed')
    dir_projections = os.path.join(dir_processed, 'projections')
    mkdir_if_not_exist(dir_projections)
    file_out = 'mode_{:>05d}.txt'.format(i_mode)
    path_out = os.path.join(dir_projections, file_out)
    print('Writing to {:}'.format(path_out))
    with open(path_out, 'w') as out_id:

        for k in range(num_modes_1d_total_with_multiplets):

            out_id.write(out_fmt.format(
                    mode_type_out_array[k],
                    n[k], l[k], m[k],
                    product_real_part[k], product_imag_part[k]))

    return
示例#3
0
def plot_all_coeff_profiles(dir_PM,
                            dir_NM,
                            i_mode,
                            l,
                            l_max,
                            fmt='png',
                            mode_real_or_complex='real',
                            multiply_by_k=True,
                            compare_info=None,
                            show=True):

    # Load comparison eigenfunction.
    if compare_info is not None:

        eigfunc_dict = load_compare_eigfunc(compare_info)

    # Load the mode frequency.
    dir_processed = os.path.join(dir_NM, 'processed')
    file_eigval_list = os.path.join(dir_processed, 'eigenvalue_list.txt')
    i_mode_list, freq_list = read_eigenvalues(file_eigval_list)
    i_mode_list = np.array(i_mode_list, dtype=np.int)
    freq_list = np.array(freq_list)
    freq = freq_list[np.where(i_mode_list == i_mode)[0][0]]

    # Create the title.
    title = 'Mode {:>5d}, frequency {:>7.3f} mHz'.format(i_mode, freq)

    # Read the discontinuity radius information.
    path_discon_info = os.path.join(dir_PM, 'radii.txt')
    r_discons, state_outer = read_discon_file(path_discon_info)
    n_discons = len(r_discons)

    # Load the coefficients and radial coordinates.
    coeffs, header, _, _ = load_vsh_coefficients(dir_NM,
                                                 i_mode,
                                                 i_radius='all')
    r = header['r_sample']

    ## Remove scaling factor.
    #coeffs = coeffs * header['eigvec_max']

    # Convert to real.
    l_coeffs, m_coeffs, coeffs = convert_to_real_spherical_harmonics(
        coeffs, l_max)

    i_choose = np.where(l_coeffs == l)[0]
    m_choose = m_coeffs[i_choose]
    coeffs = coeffs[:, :, i_choose]
    num_choose = len(m_choose)

    #
    fig, ax_arr = plt.subplots(3,
                               2,
                               figsize=(14.0, 11.0),
                               sharex=True,
                               sharey=True,
                               constrained_layout=True)

    map_coeffs_to_ax = {
        0: [0, 0],
        1: [0, 1],
        2: [0, 2],
        3: [1, 0],
        4: [1, 1],
        5: [1, 2]
    }

    # Create colour scale.
    c_map = plt.get_cmap('rainbow_r')
    c_norm = mpl_colors.Normalize(vmin=0.0, vmax=(num_choose - 1.0))

    for i in range(6):

        ax_i, ax_j = map_coeffs_to_ax[i]
        ax = ax_arr[ax_j, ax_i]

        for j in range(num_choose):

            color = c_map(c_norm(j))

            ax.plot(coeffs[i, :, j],
                    r,
                    label='{:>+3d}'.format(m_choose[j]),
                    color=color,
                    alpha=0.5)

        #ax.legend()

    plt.show()

    return
示例#4
0
def plot_eigenfunction_wrapper(dir_PM,
                               dir_NM,
                               i_mode,
                               fmt='png',
                               mode_real_or_complex='real',
                               multiply_by_k=True,
                               compare_info=None,
                               show=True):

    # Load comparison eigenfunction.
    if compare_info is not None:

        eigfunc_dict = load_compare_eigfunc(compare_info)

    # Load the mode frequency.
    dir_processed = os.path.join(dir_NM, 'processed')
    file_eigval_list = os.path.join(dir_processed, 'eigenvalue_list.txt')
    i_mode_list, freq_list = read_eigenvalues(file_eigval_list)
    i_mode_list = np.array(i_mode_list, dtype=np.int)
    freq_list = np.array(freq_list)
    freq = freq_list[np.where(i_mode_list == i_mode)[0][0]]

    # Create the title.
    title = 'Mode {:>5d}, frequency {:>7.3f} mHz'.format(i_mode, freq)

    # Read the discontinuity radius information.
    path_discon_info = os.path.join(dir_PM, 'radii.txt')
    r_discons, state_outer = read_discon_file(path_discon_info)
    n_discons = len(r_discons)

    # Load the coefficients and radial coordinates.
    coeffs, header, _, _ = load_vsh_coefficients(dir_NM,
                                                 i_mode,
                                                 i_radius='all')
    r = header['r_sample']

    # Remove scaling factor.
    coeffs = coeffs * header['eigvec_max']

    # Calculate radial profiles from the coefficients.
    if mode_real_or_complex == 'real':

        U, V, W = get_radial_profiles_real(coeffs)

    elif mode_real_or_complex == 'complex':

        U, V, W = get_radial_profiles_complex(coeffs)

    #
    if multiply_by_k:

        # Load the mode identification information.
        path_ids = os.path.join(dir_processed, 'mode_ids_full.txt')
        _, l_list, _, _ = np.loadtxt(path_ids, dtype=np.int).T
        l = l_list[i_mode - 1]  # Not 0- and 1-based indexing.
        k = np.sqrt(l * (l + 1))

        V = k * V
        W = k * W

    # Adjust sign according to convention.
    U, V, W, X_max = check_sign_radial_profiles(r, U, V, W)

    fig = plt.figure(figsize=(6.0, 8.0))
    ax = plt.gca()

    if compare_info is None:

        labels = ['U', 'V', 'W']

    else:

        labels = ['{:} (NormalModes)'.format(x) for x in ['U', 'V', 'W']]

    arrays = [U, V, W]
    color_U = 'orangered'
    color_V = 'royalblue'
    color_W = 'mediumseagreen'
    colors = [color_U, color_V, color_W]

    for i in range(3):

        ax.plot(arrays[i], r, label=labels[i], color=colors[i])
        ax.scatter(arrays[i], r, color=colors[i], s=3)

    if compare_info is not None:

        if compare_info['type'] == 'S':

            # Adjust sign according to convention.
            #eigfunc_dict['U'], eigfunc_dict['V'], _, _ = \
            #    check_sign_radial_profiles(eigfunc_dict['r'],
            #        eigfunc_dict['U'], eigfunc_dict['V'],
            #        np.zeros(len(eigfunc_dict['r'])))
            if np.sign(eigfunc_dict['U'][-1]) != np.sign(U[0]):

                eigfunc_dict['U'] = -1.0 * eigfunc_dict['U']
                eigfunc_dict['V'] = -1.0 * eigfunc_dict['V']

            rms_amp = get_rms_amp(r, U, V, W)
            rms_compare = get_rms_amp(eigfunc_dict['r'], eigfunc_dict['U'],
                                      eigfunc_dict['V'],
                                      np.zeros(len(eigfunc_dict['r'])))
            rms_ratio = rms_amp / rms_compare

            colors = [color_U, color_V]
            components = ['U', 'V']

            for key in components:

                eigfunc_dict[key] = eigfunc_dict[key] * rms_ratio

        else:

            raise NotImplementedError

        #labels = ['{:} (Ouroboros)'.format(x) for x in components]
        labels = ['{:} (Mineos)'.format(x) for x in components]
        arrays = [eigfunc_dict[key] for key in components]

        n_components = len(components)
        for i in range(n_components):

            ax.plot(arrays[i],
                    eigfunc_dict['r'],
                    color=colors[i],
                    linestyle=':',
                    label=labels[i])

    # Set axis limits.
    x_buff = 1.1
    ax.set_xlim([-x_buff * X_max, x_buff * X_max])
    ax.set_ylim([0.0, r_discons[0]])

    # Draw guidelines.
    guideline_kwargs = {'linestyle': ':', 'color': 'k'}
    ax.axvline(**guideline_kwargs)

    if n_discons > 1:

        for i in range(1, n_discons):

            ax.axhline(r_discons[i], **guideline_kwargs)

    ax.legend()

    font_size_label = 12
    font_size_title = 16
    ax.set_xlabel('Eigenfunction', fontsize=font_size_label)
    ax.set_ylabel('Radius / km', fontsize=font_size_label)
    ax.set_title(title, fontsize=font_size_title)

    plt.tight_layout()

    # Save the figure.
    dir_plot = os.path.join(dir_processed, 'plots')
    name_fig = 'eigenfunctions_{:>05d}.{:}'.format(i_mode, fmt)
    path_fig = os.path.join(dir_plot, name_fig)
    print('Saving figure to {:}'.format(path_fig))
    save_figure(path_fig, fmt)

    if show:

        plt.show()

    plt.close()

    return
示例#5
0
def characterise_all_modes_full(dir_NM):

    option = 'full'
    #i_radius = None

    # Get a list of modes.
    #i_mode_list = get_list_of_modes_from_output_files(dir_NM)
    i_mode_list = get_list_of_modes_from_coeff_files(dir_NM, option)
    n_modes = len(i_mode_list)

    # Define directories.
    dir_processed = os.path.join(dir_NM, 'processed')

    # Loop over all modes.
    first_iteration = True
    for i, i_mode in enumerate(i_mode_list):

        print('Characterising mode {:>5d}, item {:>5d} of {:>5d}'.format(
            i_mode, i + 1, n_modes))

        # Load the complex VSH coefficients.
        coeffs, header_info, _, _ = load_vsh_coefficients(dir_NM,
                                                          i_mode,
                                                          i_radius='all')

        if coeffs.shape[1] == 3:

            modes_are_complex = False

        elif coeffs.shape[1] == 6:

            modes_are_complex = True
            coeffs_new = np.zeros((coeffs.shape[0], 3, coeffs.shape[2]),
                                  dtype=np.complex)
            coeffs_new[:, 0, :] = coeffs[:, 0, :] + 1.0j * coeffs[:, 3, :]
            coeffs_new[:, 1, :] = coeffs[:, 1, :] + 1.0j * coeffs[:, 4, :]
            coeffs_new[:, 2, :] = coeffs[:, 2, :] + 1.0j * coeffs[:, 5, :]

            coeffs = coeffs_new

        if first_iteration:

            # Infer the maximum l-value used.
            n_coeffs = coeffs.shape[2]
            l_max = (int((np.round(np.sqrt(8 * n_coeffs + 1)) - 1)) // 2) - 1

            # Get the list of l and m values of the coefficients.
            l, m = make_l_and_m_lists(l_max)

            # Prepare output arrays.
            E_UVW = np.zeros((3, n_modes))
            E_of_l = np.zeros((l_max + 1, n_modes))
            r_max = np.zeros(n_modes)
            i_region_max = np.zeros(n_modes, dtype=np.int)

            # Calculate weights of each shell.
            volume_weights = calculate_weights(header_info['r_sample'])

            first_iteration = False

        # Calculate the power distribution.
        EU_i, EV_i, EW_i, E_i, E_of_l_i = calculate_power_distribution_full(
            coeffs, l, volume_weights, print_=False)

        # Normalise by the sum.
        EU_i = EU_i / E_i
        EV_i = EV_i / E_i
        EW_i = EW_i / E_i
        E_of_l_i = E_of_l_i / E_i

        # Store.
        E_UVW[0, i] = EU_i
        E_UVW[1, i] = EV_i
        E_UVW[2, i] = EW_i
        E_of_l[:, i] = E_of_l_i
        #
        r_max[i] = header_info['r_max']
        i_region_max[i] = header_info['i_region_max']

    # Save mode characterisation information.
    array_out = np.array([*E_UVW, *E_of_l, r_max, i_region_max])
    path_out = os.path.join(dir_NM, 'processed', 'characterisation_full.npy')
    print('Saving mode characterisation information to {:}'.format(path_out))
    np.save(path_out, array_out)

    # Find l-value and type for each mode.
    l = np.zeros(n_modes, dtype=np.int)
    shell = np.zeros(n_modes, dtype=np.int)
    # type_: 0: radial, 1: spheroidal, 2: toroidal
    type_ = np.zeros(n_modes, dtype=np.int)
    for i in range(n_modes):

        shell[i] = i_region_max[i] // 3

        # Find dominant l-value.
        l[i] = np.argmax(E_of_l[:, i])

        if l[i] == 0:

            type_[i] = 0

        else:

            # Check if spheroidal or toroidal power is greater.
            if ((E_UVW[0, i] + E_UVW[1, i]) > E_UVW[2, i]):

                type_[i] = 1

            else:

                type_[i] = 2

    path_out_ids = os.path.join(dir_NM, 'processed', 'mode_ids_full.txt')
    out_array_ids = np.array([i_mode_list, l, type_, shell])
    print('Saving mode identifications to {:}'.format(path_out_ids))
    np.savetxt(path_out_ids, out_array_ids.T, fmt='%i')

    return
示例#6
0
def characterise_all_modes_quick(dir_NM):

    option = 'quick'
    i_radius = None

    # Get a list of modes.
    #i_mode_list = get_list_of_modes_from_output_files(dir_NM)
    i_mode_list = get_list_of_modes_from_coeff_files(dir_NM, option)

    n_modes = len(i_mode_list)

    # Define directories.
    dir_processed = os.path.join(dir_NM, 'processed')

    # Loop over all modes.
    first_iteration = True
    for i, i_mode in enumerate(i_mode_list):

        print('Characterising mode {:>5d}'.format(i_mode))

        coeffs, header_info, r_sample, i_sample = \
            load_vsh_coefficients(dir_NM, i_mode, i_radius = i_radius)

        if coeffs.shape[0] == 3:

            modes_are_complex = False
            Ulm, Vlm, Wlm = coeffs

        elif coeffs.shape[0] == 6:

            modes_are_complex = True
            Ulm_real, Vlm_real, Wlm_real, Ulm_imag, Vlm_imag, Wlm_imag = coeffs

        else:

            raise ValueError

        if first_iteration:

            # Infer the maximum l-value used.
            if modes_are_complex:

                n_coeffs = len(Ulm_real)

            else:

                n_coeffs = len(Ulm)

            l_max = (int((np.round(np.sqrt(8 * n_coeffs + 1)) - 1)) // 2) - 1

            # Get the list of l and m values of the coefficients.
            l, m = make_l_and_m_lists(l_max)

            # Prepare output arrays.
            E_UVW = np.zeros((3, n_modes))
            E_of_l = np.zeros((l_max + 1, n_modes))
            r_max = np.zeros(n_modes)
            i_region_max = np.zeros(n_modes, dtype=np.int)

            first_iteration = False

        # Calculate the power distribution.
        if modes_are_complex:

            EU_i, EV_i, EW_i, E_i, E_of_l_i = \
                calculate_power_distribution_quick_cplx(
                    Ulm_real, Vlm_real, Wlm_real,
                    Ulm_imag, Vlm_imag, Wlm_imag,
                    l, print_ = False)

        else:

            EU_i, EV_i, EW_i, E_i, E_of_l_i = calculate_power_distribution_quick_real(
                Ulm, Vlm, Wlm, l, print_=False)

        # Normalise by the sum.
        EU_i = EU_i / E_i
        EV_i = EV_i / E_i
        EW_i = EW_i / E_i
        E_of_l_i = E_of_l_i / E_i

        # Store.
        E_UVW[0, i] = EU_i
        E_UVW[1, i] = EV_i
        E_UVW[2, i] = EW_i
        E_of_l[:, i] = E_of_l_i
        #
        r_max[i] = r_sample
        i_region_max[i] = i_sample

    # Save mode characterisation information.
    array_out = np.array([*E_UVW, *E_of_l, r_max, i_region_max])
    path_out = os.path.join(dir_NM, 'processed', 'characterisation_quick.npy')
    print('Saving mode characterisation information to {:}'.format(path_out))
    np.save(path_out, array_out)

    # Find l-value and type for each mode.
    l = np.zeros(n_modes, dtype=np.int)
    shell = np.zeros(n_modes, dtype=np.int)
    # type_: 0: radial, 1: spheroidal, 2: toroidal
    type_ = np.zeros(n_modes, dtype=np.int)
    for i in range(n_modes):

        shell[i] = i_region_max[i] // 3

        # Find dominant l-value.
        l[i] = np.argmax(E_of_l[:, i])

        if l[i] == 0:

            type_[i] = 0

        else:

            # Check if spheroidal or toroidal power is greater.
            if ((E_UVW[0, i] + E_UVW[1, i]) > E_UVW[2, i]):

                type_[i] = 1

            else:

                type_[i] = 2

    path_out_ids = os.path.join(dir_NM, 'processed', 'mode_ids_quick.txt')
    out_array_ids = np.array([i_mode_list, l, type_, shell])
    print('Saving mode identifications to {:}'.format(path_out_ids))
    np.savetxt(path_out_ids, out_array_ids.T, fmt='%i')

    return