def func_radiation_patter_show(singlerun_data_folder, ff_data_sub_folder_name):
    np_theta = 360
    np_phi = 5

    ff_export_folder = os.path.join(singlerun_data_folder,
                                    ff_data_sub_folder_name)

    # Get all the farfield export data file
    farfield_data_file_list = pycst_ctrl.func_file_list_get(ff_export_folder,
                                                            ext='.txt')

    for export_file in farfield_data_file_list:
        theta_vec, dir_co_arr, dir_cx_arr, dir_abs_arr, \
            dir_co_norm_arr, dir_cx_norm_arr, dir_abs_norm_arr, \
            peak_co_cvec, peak_cx_cvec, peak_abs_cvec, \
            ar_arr, ar_boresight_cvec = \
            PyCstDataAnalyser.func_exp_ff_data_proc(ff_export_folder, export_file, np_theta, np_phi)

        plt.figure()
        plt.plot(theta_vec, dir_co_norm_arr[0, :], 'r-')
        plt.plot(theta_vec, dir_co_norm_arr[1, :], 'b-')
        plt.plot(theta_vec, dir_co_norm_arr[2, :], 'k-')
        plt.plot(theta_vec, dir_cx_norm_arr[1, :], 'b--')
        plt.xlim(-180, 180)
        plt.ylim(-40, 0)
        plt.minorticks_on()
        plt.grid(True, which='both', linestyle=':')
        plt.show()
Exemple #2
0
    def __init__(self, proj_cfg_dic, data_analyser_cfg_dic, optimizer_cfg_dic):

        # Project configuration
        # Settings from users
        self.env = proj_cfg_dic.get('env', 'hpc')
        self.solver = proj_cfg_dic.get('solver', 'T')
        self.gpu_num = proj_cfg_dic.get('gpu_num', 1)
        # Indicate if this is an optimization resumed from previous one
        self.resume_flag = proj_cfg_dic.get('resume_flag', False)
        self.project_folder = proj_cfg_dic.get('project_folder',
                                               "/data/home/eex181/SmoothWallHornProfileRelative_Python")
        self.sim_name = proj_cfg_dic.get('sim_name', "SmoothWallHornProfileRelative_Python")
        self.base_para_file_name = proj_cfg_dic.get('base_para_file_name', "ProfiledSmoothWallHornRelativePara.txt")
        # CST project controlled by matlab will be Farfields
        self.ff_export_subfolder_name = proj_cfg_dic.get('ff_export_subfolder_name', "Farfield")

        # Record csv files of parameters and objective values during optimization
        self.rec_para_file_name = proj_cfg_dic.get('rec_para_file_name', 'opt_para_list.csv')
        self.rec_para_name_lst = proj_cfg_dic.get('rec_para_name_lst', ['EMPTY'])

        self.rec_objval_file_name = proj_cfg_dic.get('rec_objval_file_name', 'opt_obj_val.csv')
        self.rec_obj_name_lst = proj_cfg_dic.get('rec_obj_name_lst', ['EMPTY'])

        # Define cma object saved file name for resuming
        self.cma_object_save_file_name = proj_cfg_dic.get('cma_object_save_file_name', '_saved-cma-object.pkl')
        self.full_cma_object_save_file = os.path.join(self.project_folder, self.cma_object_save_file_name)

        # Initialize run_id
        self.run_id = proj_cfg_dic.get('init_run_id', 1)  # Default run_id starts from 1

        # Settings to generate
        self.cst_file_name = self.sim_name + '.cst'
        self.export_path = os.path.join(self.project_folder, self.sim_name, 'Export')
        self.export_py_path = os.path.join(self.project_folder, self.sim_name, 'ExportPy')
        self.parafile_subfolder_name = 'ParaFiles'
        self.full_sim_para_file = os.path.join(self.project_folder, 'CurrentPara.txt')
        self.full_cst_file = os.path.join(self.project_folder, self.cst_file_name)

        # Create data analyser instance
        self.data_analyser_ins = PyCstDataAnalyser(data_analyser_cfg_dic)

        # Create optimizer instance
        self.optimizer_ins = self.func_opt_cma_create(optimizer_cfg_dic)
def func_norm_radiation_pattern_freq_sim_show(ff_data_dir, ff_file_name,
                                              np_theta, np_phi, axes_cfg_dic,
                                              freq_str, pol_ind):
    """Display simulated radiation pattern in 0/45/90 deg at one frequency"""

    # Parse the exported farfield data file
    theta_vec, dir_co_arr, dir_cx_arr, dir_abs_arr, \
        dir_co_norm_arr, dir_cx_norm_arr, dir_abs_norm_arr, \
        peak_co_cvec, peak_cx_cvec, peak_abs_cvec, \
        ar_arr, ar_boresight_cvec = \
        PyCstDataAnalyser.func_exp_ff_data_proc(ff_data_dir, ff_file_name, np_theta, np_phi, pol_ind)

    # Create plot configuration
    data_plot_cfg_sim_radpat_dic = {
        'x_data_vec': theta_vec,
        'y_data_group_dic': {
            r'LHCP, $\phi=0\degree$': dir_co_norm_arr[0, :],
            r'LHCP, $\phi=45\degree$': dir_co_norm_arr[1, :],
            r'LHCP, $\phi=90\degree$': dir_co_norm_arr[2, :],
            r'RHCP, $\phi=45\degree$': dir_cx_norm_arr[1, :]
        },
        'color_list': ['r', 'k', 'b', 'k'],
        'line_style': ['-', '-', '-', '--'],
        # 'marker': [None]*4,
        # 'marker_edge_color': None,
        'line_width': 2
    }

    data_plot_cfg_dic_lst = [data_plot_cfg_sim_radpat_dic]

    x_label = 'Theta (deg)'
    y_label = 'Directivity (dB)'
    fig_title = pol_ind + ' (%s)' % freq_str

    func_group_data_show(data_plot_cfg_dic_lst, axes_cfg_dic, x_label, y_label,
                         fig_title)
def func_cst_radpat_cocx_subplot_show(np_theta, np_phi, pol_ind, ff_data_dir,
                                      ff_data_file_dic, nrow, ncol,
                                      axes_cfg_dic):
    """
    This function is used to plot radiation patterns with co-pol and cx-pol
    :param np_theta: number of sample points for theta, normally 360
    :param np_phi: number of sample points for phi, if step is 45deg, np_phi is 5
    :param pol_ind: 'LHCP', 'RHCP' or 'lin_dir'
    :param ff_data_dir: directory path which contains farfield data
    :param ff_data_file_dic: a dictionary list of radiation patterns to be shown, should be like:
    ff_data_file_dic = {'75 GHz': "farfield_(f=75)_[1].txt",
                        '85 GHz': "farfield_(f=85)_[1].txt",
                        '90 GHz': "farfield_(f=90)_[1].txt",
                        '95 GHz': "farfield_(f=95)_[1].txt",
                        '100 GHz': "farfield_(f=100)_[1].txt",
                        '110 GHz': "farfield_(f=110)_[1].txt"
                        }
    :param nrow: number of rows
    :param ncol: number of columns
    :param axes_cfg_dic:  see func_group_data_plot() for details
    :return:
    """

    # Create label (legend) list according to the polarization
    if pol_ind == 'LHCP':
        lable_lst = [
            'LHCP, ' + r'$\phi=0\degree$', 'LHCP, ' + r'$\phi=45\degree$',
            'LHCP, ' + r'$\phi=90\degree$', 'RHCP, ' + r'$\phi=45\degree$'
        ]
        unit_str = 'dBic'
    elif pol_ind == 'RHCP':
        lable_lst = [
            'RHCP, ' + r'$\phi=0\degree$', 'RHCP, ' + r'$\phi=45\degree$',
            'RHCP, ' + r'$\phi=90\degree$', 'LHCP, ' + r'$\phi=45\degree$'
        ]
        unit_str = 'dBic'
    else:
        lable_lst = [
            'Co-pol, ' + r'$\phi=0\degree$', 'Co-pol, ' + r'$\phi=45\degree$',
            'Co-pol, ' + r'$\phi=90\degree$', 'Cx-pol, ' + r'$\phi=45\degree$'
        ]
        unit_str = 'dBi'

    data_plot_cfg_dic_lst = []
    anno_text_lst = []
    for freq_str, ff_file_name in ff_data_file_dic.items():

        # Parse the exported farfield data file
        theta_vec, dir_co_arr, dir_cx_arr, dir_abs_arr, \
            dir_co_norm_arr, dir_cx_norm_arr, dir_abs_norm_arr, \
            peak_co_cvec, peak_cx_cvec, peak_abs_cvec, \
            ar_arr, ar_boresight_cvec = \
            PyCstDataAnalyser.func_exp_ff_data_proc(ff_data_dir, ff_file_name, np_theta, np_phi, pol_ind)

        # Create plot configuration
        data_plot_cfg_sim_radpat_dic = {
            'x_data_vec': theta_vec,
            'y_data_group_dic': {
                lable_lst[0]: dir_co_norm_arr[0, :],
                lable_lst[1]: dir_co_norm_arr[1, :],
                lable_lst[2]: dir_co_norm_arr[2, :],
                lable_lst[3]: dir_cx_norm_arr[1, :]
            },
            'color_list': ['r', 'k', 'b', 'g'],
            'line_style': ['-', '--', '-.', ':'],
            # 'marker': [None]*4,
            # 'marker_edge_color': None,
            'line_width': 1.5
        }

        # Create data list, one data_dic for each subplot
        data_plot_cfg_dic_lst.append(data_plot_cfg_sim_radpat_dic)

        # Create annotation text
        anno_text_lst.append('D={0:.1f} {1}'.format(np.amax(peak_co_cvec),
                                                    unit_str))

    x_label = 'Theta (deg)'
    y_label = 'Normalized Magnitude (dB)'
    sub_titles = [sub_title for sub_title in ff_data_file_dic.keys()]

    func_group_data_subplot_show(data_plot_cfg_dic_lst, axes_cfg_dic, nrow,
                                 ncol, x_label, y_label, sub_titles,
                                 anno_text_lst)
Exemple #5
0
class PyCstProjSimulator:
    """ Define the simulation project"""

    def __init__(self, proj_cfg_dic, data_analyser_cfg_dic, optimizer_cfg_dic):

        # Project configuration
        # Settings from users
        self.env = proj_cfg_dic.get('env', 'hpc')
        self.solver = proj_cfg_dic.get('solver', 'T')
        self.gpu_num = proj_cfg_dic.get('gpu_num', 1)
        # Indicate if this is an optimization resumed from previous one
        self.resume_flag = proj_cfg_dic.get('resume_flag', False)
        self.project_folder = proj_cfg_dic.get('project_folder',
                                               "/data/home/eex181/SmoothWallHornProfileRelative_Python")
        self.sim_name = proj_cfg_dic.get('sim_name', "SmoothWallHornProfileRelative_Python")
        self.base_para_file_name = proj_cfg_dic.get('base_para_file_name', "ProfiledSmoothWallHornRelativePara.txt")
        # CST project controlled by matlab will be Farfields
        self.ff_export_subfolder_name = proj_cfg_dic.get('ff_export_subfolder_name', "Farfield")

        # Record csv files of parameters and objective values during optimization
        self.rec_para_file_name = proj_cfg_dic.get('rec_para_file_name', 'opt_para_list.csv')
        self.rec_para_name_lst = proj_cfg_dic.get('rec_para_name_lst', ['EMPTY'])

        self.rec_objval_file_name = proj_cfg_dic.get('rec_objval_file_name', 'opt_obj_val.csv')
        self.rec_obj_name_lst = proj_cfg_dic.get('rec_obj_name_lst', ['EMPTY'])

        # Define cma object saved file name for resuming
        self.cma_object_save_file_name = proj_cfg_dic.get('cma_object_save_file_name', '_saved-cma-object.pkl')
        self.full_cma_object_save_file = os.path.join(self.project_folder, self.cma_object_save_file_name)

        # Initialize run_id
        self.run_id = proj_cfg_dic.get('init_run_id', 1)  # Default run_id starts from 1

        # Settings to generate
        self.cst_file_name = self.sim_name + '.cst'
        self.export_path = os.path.join(self.project_folder, self.sim_name, 'Export')
        self.export_py_path = os.path.join(self.project_folder, self.sim_name, 'ExportPy')
        self.parafile_subfolder_name = 'ParaFiles'
        self.full_sim_para_file = os.path.join(self.project_folder, 'CurrentPara.txt')
        self.full_cst_file = os.path.join(self.project_folder, self.cst_file_name)

        # Create data analyser instance
        self.data_analyser_ins = PyCstDataAnalyser(data_analyser_cfg_dic)

        # Create optimizer instance
        self.optimizer_ins = self.func_opt_cma_create(optimizer_cfg_dic)

    def func_opt_cma_create(self, optimizer_cfg_dic):

        if self.resume_flag is False:
            # Create optimizer object
            cma_init_para_list = optimizer_cfg_dic.get('cma_init_para_list', None)
            cma_sigma = optimizer_cfg_dic.get('cma_sigma', 0.3)
            cma_opts = optimizer_cfg_dic.get('cma_opts', None)
            es = cma.CMAEvolutionStrategy(cma_init_para_list, cma_sigma, cma_opts)
        else:
            # resuming from saved file
            es = pycst_ctrl.func_load_ins_from_file(self.full_cma_object_save_file)

            # overwrite the log directory for outcmaes to current project directory
            # because cmaes recorded the absolute path in es.logger.name_prefix
            es.logger.name_prefix = os.path.join(self.project_folder, 'outcmaes')
            es.logger.name_prefix = es.logger.name_prefix + os.sep

            # Set max iteration number when we know the approximate iteration number for one run (10-day)
            cma_opts = optimizer_cfg_dic.get('cma_opts', None)
            if cma_opts is not None:
                max_iter_num = cma_opts.get('maxiter', None)
                if max_iter_num is not None:
                    es.opts['maxiter'] = max_iter_num

        return es

    @staticmethod
    def func_cst_sim_run(env, solver, gpu_num, full_para_file, full_cst_file):

        if solver == 'F':
            solver_cmd = '-f'
        elif solver == 'T_GPU':
            solver_cmd = '-r -withgpu=%d' % gpu_num
        elif solver == 'I_GPU':
            solver_cmd = '-q -withgpu=%d' % gpu_num
        elif solver == 'T':
            solver_cmd = '-r'
        else:
            solver_cmd = '-r'

        if env == "linux_pc":  # Linux_PC:
            cmd_cst = '"/opt/cst/CST_STUDIO_SUITE_2019/cst_design_environment" -m -par "%s" -r "%s"' % (
                full_para_file, full_cst_file)
        elif env == "hpc":
            cmd_cst = "singularity run --nv /data/containers/cst/cst cst_design_environment -numthreads=${NSLOTS} " \
                      "-m -par \"%s\" %s \"%s\"" % (full_para_file, solver_cmd, full_cst_file)
        elif env == "win":
            cmd_cst = '"C:\\Program Files (x86)\\CST STUDIO SUITE 2019\\CST DESIGN ENVIRONMENT.exe" ' \
                      '-m -par \"%s\" %s \"%s\"' % (full_para_file, solver_cmd, full_cst_file)
        elif env == "test":
            cmd_cst = ""
        else:
            cmd_cst = ""

        if cmd_cst != "":
            if env == "win":
                os.system('"' + cmd_cst + '"')
            else:
                os.system(cmd_cst)

    @staticmethod
    def func_cst_parafile_gen(project_folder, parafile_subfolder_name, base_para_file_name, run_id, cst_para_val_vec):

        # Get full path to the base para file
        full_para_file = os.path.join(project_folder, parafile_subfolder_name, base_para_file_name)

        # Update parameters and generate new para file
        with open(full_para_file, 'r') as fread:
            content_list = fread.readlines()

            for i in range(len(cst_para_val_vec)):
                para_val = cst_para_val_vec[i]
                para_set_str = content_list[i]
                para_set_str = para_set_str % para_val
                content_list[i] = para_set_str

        para_sweep_file_name = os.path.splitext(base_para_file_name)[0] + '_' + str(run_id) + '.txt'
        full_para_sweep_file = os.path.join(project_folder, parafile_subfolder_name, para_sweep_file_name)

        with open(full_para_sweep_file, 'w') as fwrite:
            fwrite.writelines(content_list)

        # Prepare the para file for current simulation
        full_cur_para_file = os.path.join(project_folder, 'CurrentPara.txt')
        shutil.copy(full_para_sweep_file, full_cur_para_file)

    @staticmethod
    def func_cst_opt_res_save(project_folder, para_list_file_name, obj_val_file_name, para_val_vec, para_name_list,
                              obj_val_vec, obj_name_list, run_id):

        # Convert ndarray to pandas series
        para_df = pd.DataFrame(data=para_val_vec.reshape(1, -1), index=[run_id], columns=para_name_list)
        obj_df = pd.DataFrame(data=obj_val_vec.reshape(1, -1), index=[run_id], columns=obj_name_list)

        # prepare the file to write
        full_para_list_file = os.path.join(project_folder, para_list_file_name)
        full_obj_val_file = os.path.join(project_folder, obj_val_file_name)

        if 1 != run_id:
            write_mode = 'a'  # append if already exists
            header_mode = False
        else:
            write_mode = 'w'  # make a new file if not
            header_mode = True

        para_df.to_csv(full_para_list_file, mode=write_mode, header=header_mode)
        obj_df.to_csv(full_obj_val_file, mode=write_mode, header=header_mode)

    def func_cst_proj_sim(self, opt_para_val_vec):

        # Read project configuration
        project_folder = self.project_folder
        export_path = self.export_path
        export_py_path = self.export_py_path
        ff_export_subfolder_name = self.ff_export_subfolder_name
        parafile_subfolder_name = self.parafile_subfolder_name
        base_para_file_name = self.base_para_file_name
        full_sim_para_file = self.full_sim_para_file
        full_cst_file = self.full_cst_file

        # Get current run_id
        run_id = self.run_id

        # Create parameter list
        cst_para_val_vec = opt_para_val_vec

        # Generate the parameter file for simulation
        self.func_cst_parafile_gen(project_folder, parafile_subfolder_name, base_para_file_name, run_id,
                                   cst_para_val_vec)

        # Run the simulation
        self.func_cst_sim_run(self.env, self.solver, self.gpu_num, full_sim_para_file, full_cst_file)

        if self.env == "test":
            # objval_vec = np.random.random_sample((5,)) * 5
            # fitness = objval_vec.sum()
            export_sim_subfolder_name = 'run' + str(run_id)
            bak_sim_subfolder_path = os.path.join(export_py_path, export_sim_subfolder_name)
            # Analyse the export data
            fitness, objval_vec = self.data_analyser_ins.func_cst_data_analyse(bak_sim_subfolder_path, run_id,
                                                                               ff_export_subfolder_name)
        else:
            # Backup the export data of the current simulation
            export_sim_subfolder_name = 'run' + str(run_id)
            bak_sim_subfolder_path = os.path.join(export_py_path, export_sim_subfolder_name)
            shutil.copytree(export_path, bak_sim_subfolder_path)

            # Analyse the export data
            fitness, objval_vec = self.data_analyser_ins.func_cst_data_analyse(bak_sim_subfolder_path, run_id,
                                                                               ff_export_subfolder_name)

        # Save parameter values and objective values of this simulation to .csv record files
        rec_objval_vec = np.append(objval_vec, fitness)
        self.func_cst_opt_res_save(project_folder, self.rec_para_file_name, self.rec_objval_file_name,
                                   opt_para_val_vec, self.rec_para_name_lst,
                                   rec_objval_vec, self.rec_obj_name_lst, run_id)

        # Save cma object to file for resume later
        pycst_ctrl.func_save_ins_to_file(project_folder, self.cma_object_save_file_name, self.optimizer_ins)

        # Update run_id
        self.run_id += 1

        return fitness