parse parameter

博客提及了参数解析(parse parameter),这在信息技术中是常见操作,可用于处理输入数据等。
parse parameter
import os import json import itertools import shutil import re import ast from collections import defaultdict # Global variable - path to common parameter file OTHER_JSON_PATH = "Channel_H_Generator/config_file/simulation_parameter_basic.json" def clear_config_folder(folder_path): """Clear specified folder, create if not exists""" if os.path.exists(folder_path): for filename in os.listdir(folder_path): file_path = os.path.join(folder_path, filename) try: if os.path.isfile(file_path) or os.path.islink(file_path): os.unlink(file_path) elif os.path.isdir(file_path): shutil.rmtree(file_path) except Exception as e: print(f'Failed to delete {file_path}. Reason: {e}') else: os.makedirs(folder_path, exist_ok=True) def parse_range_or_list(value_str): """解析范围字符串(如10:10:30)或逗号分隔列表,支持嵌套列表""" # 尝试直接解析整个字符串 try: parsed = ast.literal_eval(value_str) if isinstance(parsed, list): return parsed except (ValueError, SyntaxError): pass # 继续后续解析 # 尝试解析范围语法 if ':' in value_str and value_str.count(':') >= 2: parts = value_str.split(':') if len(parts) == 3: try: start = float(parts[0]) step = float(parts[1]) end = float(parts[2]) values = [] current = start while current <= end: # 如果是整数则转为int if current.is_integer(): values.append(int(current)) else: values.append(current) current += step return values except ValueError: pass # 回退到其他处理方式 # 尝试解析嵌套列表(多个方括号结构) if re.match(r'^(\s*\[[^\]]*\]\s*,)+\s*\[[^\]]*\]\s*$', value_str): list_items = re.findall(r'\[[^\]]*\]', value_str) parsed_values = [] for item in list_items: try: clean_item = item.strip()[1:-1].strip() inner_values = [] for v in clean_item.split(','): inner_v = v.strip() try: inner_values.append(ast.literal_eval(inner_v)) except (ValueError, SyntaxError): inner_values.append(inner_v) parsed_values.append(inner_values) except (ValueError, SyntaxError): parsed_values.append(item) return parsed_values # 尝试解析单个列表结构 if re.match(r'^\s*\[.*\]\s*$', value_str): try: # 移除可能的空格干扰后解析 cleaned = re.sub(r'\s+', '', value_str) return ast.literal_eval(cleaned) except (ValueError, SyntaxError): pass # 继续后续处理 # 尝试解析逗号分隔值 if ',' in value_str: # 先尝试整体解析 try: parsed = ast.literal_eval(value_str) if isinstance(parsed, (tuple, list)): return list(parsed) except (ValueError, SyntaxError): pass # 保底的分割逻辑 values = [] for v in value_str.split(','): v = v.strip() try: # 尝试解析每个部分 parsed = ast.literal_eval(v) values.append(parsed) except (ValueError, SyntaxError): values.append(v) return values # 单值处理 try: parsed = ast.literal_eval(value_str) return [parsed] except (ValueError, SyntaxError): return [value_str] def parse_cell_id_special(value_str): """Special parsing for cell_id format like [0;8],[3],[4;5;6]""" matches = re.findall(r'\[([^\]]*)\]', value_str) if not matches: return [value_str] # Return original if no match cell_id_groups = [] for group in matches: try: ids = [int(x.strip()) for x in group.split(';') if x.strip()] cell_id_groups.append(ids) except ValueError: cell_id_groups.append([group]) return cell_id_groups def parse_cell_based_parameter(value_str): """Parse cell-based parameter values using the same logic as cell_id""" matches = re.findall(r'\[([^\]]*)\]', value_str) if not matches: return [[value_str]] param_groups = [] for group in matches: try: parsed = ast.literal_eval(f'[{group}]') param_groups.append(parsed) except (ValueError, SyntaxError): values = [v.strip() for v in group.split(';') if v.strip()] try: parsed_values = [ast.literal_eval(v) for v in values] param_groups.append(parsed_values) except (ValueError, SyntaxError): param_groups.append(values) return param_groups def parse_parameter_file(file_path): """Parse parameter combination file, preserving original value types""" parameters = {} combo_parameters = defaultdict(list) allowed_prefixes = [ "simulation_parameter_case_", "bs_parameter_case_", "user_specific_parameter_", "3gpp_params_", "3gpp_params_bound_" ] with open(file_path, 'r') as f: for line in f: line = line.strip() if not line or line.startswith('#'): continue if '=' not in line: continue key, value = line.split('=', 1) key = key.strip() value = value.strip() key_lower = key.lower() prefix_found = None for prefix in allowed_prefixes: if key_lower.startswith(prefix.lower()): prefix_found = prefix break if key_lower.startswith('combo'): pure_key = re.sub(r'^combo_?', '', key, flags=re.IGNORECASE).strip() for prefix in allowed_prefixes: if pure_key.startswith(prefix.lower()): prefix_found = prefix if prefix_found: param_name = pure_key[len(prefix_found):] if param_name.lower() in ["cell_id"] or prefix_found in ["bs_parameter_case_"]: combo_values = parse_cell_based_parameter(value) else: combo_values = parse_range_or_list(value) combo_parameters[f"{prefix_found}{param_name}"] = combo_values elif pure_key.lower() in ["cell_id"] : combo_parameters[pure_key] = parse_cell_based_parameter(value) else: combo_parameters[pure_key] = parse_range_or_list(value) else: for prefix in allowed_prefixes: if key_lower.startswith(prefix.lower()): prefix_found = prefix if prefix_found: param_name = key_lower[len(prefix_found):] if param_name.lower() in ["cell_id"]or prefix_found in ["bs_parameter_case_"]: parsed_values = parse_cell_based_parameter(value) else: parsed_values = parse_range_or_list(value) parameters[f"{prefix_found}{param_name}"] = parsed_values elif key_lower.lower() in ["cell_id"]: parameters[key] = parse_cell_based_parameter(value) else: parameters[key] = parse_range_or_list(value) return parameters, combo_parameters def generate_combinations(normal_params, combo_params): """Generate all parameter combinations""" normal_combinations = [] if normal_params: keys = list(normal_params.keys()) value_lists = [normal_params[k] for k in keys] for combo in itertools.product(*value_lists): normal_combinations.append(dict(zip(keys, combo))) combo_combinations = [] if combo_params: num_values = None for key, values in combo_params.items(): if num_values is None: num_values = len(values) elif len(values) != num_values: raise ValueError(f"Combo parameter {key} has {len(values)} values, inconsistent with others ({num_values})") if num_values > 0: for i in range(num_values): combo_dict = {} for key, values in combo_params.items(): combo_dict[key] = values[i] combo_combinations.append(combo_dict) all_combinations = [] if combo_combinations: if normal_combinations: for norm_combo in normal_combinations: for combo in combo_combinations: merged = norm_combo.copy() merged.update(combo) all_combinations.append(merged) else: all_combinations = combo_combinations else: all_combinations = normal_combinations return all_combinations def find_and_update_parameter(data, path, value): """Recursively find and update matching parameters in JSON structure""" count = 0 if isinstance(data, dict): for k, v in list(data.items()): clean_key = k.strip().lower() clean_target = path[0].strip().lower() if clean_key == clean_target: if len(path) == 1: data[k] = value count += 1 else: count += find_and_update_parameter(v, path[1:], value) else: if isinstance(v, (dict, list)): count += find_and_update_parameter(v, path, value) elif isinstance(data, list): for item in data: if isinstance(item, (dict, list)): count += find_and_update_parameter(item, path, value) return count def update_json_with_parameters(json_data, parameters): """Update JSON data with all matching parameters""" updated_params = set() not_found = set() for param, value in parameters.items(): path_list = [p.strip() for p in param.split('.')] update_count = find_and_update_parameter(json_data, path_list, value) if update_count > 0: updated_params.add(param) else: not_found.add(param) return json_data, not_found def create_case_folders(config_dir, case_combinations, template_dir): """Create folders and config files for each case""" os.makedirs(config_dir, exist_ok=True) try: with open(OTHER_JSON_PATH, 'r') as f: other_json_data = json.load(f) except FileNotFoundError: other_json_data = {} print(f"Warning: Common parameter file not found: {OTHER_JSON_PATH}") case_list_path = os.path.join(config_dir, "case_list.txt") with open(case_list_path, 'w') as case_file: for i, combo in enumerate(case_combinations): case_file.write(f"Case_{i}: {'; '.join(f'{k} = {v}' for k, v in combo.items())}\n") allowed_prefixes = [ "simulation_parameter_case_", "bs_parameter_case_", "user_specific_parameter_", "3gpp_params_", "3gpp_params_bound_" ] DEFAULT_CELL_ID = [[0, 8]] for i, combo in enumerate(case_combinations): case_dir = os.path.join(config_dir, str(i)) os.makedirs(case_dir, exist_ok=True) template_files = [ "simulation_parameter_case.json", "bs_parameter_case.json", "user_specific_parameter.json", "3gpp_params.json", "3gpp_params_bound.json" ] for file_name in template_files: src_path = os.path.join(template_dir, file_name) dst_path = os.path.join(case_dir, file_name) if os.path.exists(src_path): shutil.copy(src_path, dst_path) no_prefix_combo = {} if 'cell_id' in combo: cell_id_value = combo['cell_id'] combo_without_cell_id = {k: v for k, v in combo.items() if k != 'cell_id'} else: cell_id_value = None combo_without_cell_id = combo.copy() for key, value in combo_without_cell_id.items(): if not any(key.lower().startswith(prefix.lower()) for prefix in allowed_prefixes): no_prefix_combo[key] = value sim_data, bs_data, user_data = {}, {}, {} not_found = set(no_prefix_combo.keys()) file_parameters = { "simulation_parameter_case": [], "bs_parameter_case": [], "user_specific_parameter": [] } processed_params = set() for param in combo.keys(): if param.startswith("simulation_parameter_case_"): pure_param = param.replace("simulation_parameter_case_", "") file_parameters["simulation_parameter_case"].append((pure_param, combo[param])) not_found.discard(param) elif param.startswith("bs_parameter_case_"): pure_param = param.replace("bs_parameter_case_", "") file_parameters["bs_parameter_case"].append((pure_param, combo[param])) not_found.discard(param) elif param.startswith("user_specific_parameter_"): pure_param = param.replace("user_specific_parameter_", "") file_parameters["user_specific_parameter"].append((pure_param, combo[param])) not_found.discard(param) bs_object_fields = {"ue_count", "ue_speed", "ue_direction", "ue_positions", "ue_doppler_sampling_pattern", "ue_freq_sampling_pattern"} global_bs_params = {k: v for k, v in combo_without_cell_id.items() if k in bs_object_fields} # 1. Update simulation_parameter_case.json sim_path = os.path.join(case_dir, "simulation_parameter_case.json") if os.path.exists(sim_path): with open(sim_path, 'r') as f: sim_data = json.load(f) for param, value in file_parameters["simulation_parameter_case"]: updated, missing = update_json_with_parameters(sim_data, {param: value}) if missing: print(f"Warning: Case_{i} parameter not found: {param} (in simulation_parameter_case.json)") sim_data, sim_not_found = update_json_with_parameters(sim_data, no_prefix_combo) not_found = set(not_found) & set(sim_not_found) with open(sim_path, 'w') as f: json.dump(sim_data, f, indent=2) cell_id_value = combo.get('cell_id', []) if cell_id_value and not isinstance(cell_id_value[0], list): cell_id_value = [cell_id_value] # 2. Update bs_parameter_case.json bs_path = os.path.join(case_dir, "bs_parameter_case.json") bs_data_templates={} if os.path.exists(bs_path): with open(bs_path, 'r') as f: bs_data = json.load(f) bs_data_templates = bs_data['bs_parameters'][0] prefixed_params = {} regular_params = {} prefix = "bs_parameter_case_" for key, value in combo.items(): if key.startswith(prefix): pure_key = key[len(prefix):] prefixed_params[pure_key] = value elif key not in ["cell_id"]: # # regular_params[key] = value # # cell_id_value = combo.get('cell_id', DEFAULT_CELL_ID) if not isinstance(cell_id_value[0], list): cell_id_value = [cell_id_value] # param_groups = {} for param, value in prefixed_params.items(): # if not isinstance(value, list) or not value or not isinstance(value[0], list): if isinstance(value, list): value = [value] # else: value = [[value]] # param_groups[param] = value # bs_data["bs_parameters"] = [] for group_idx, cell_group in enumerate(cell_id_value): for cell_idx, cell_id in enumerate(cell_group): bs_data_templates["cell_id"]=cell_id cell_obj = bs_data_templates.copy() # for param, value_groups in param_groups.items(): if group_idx < len(value_groups) and cell_idx < len(value_groups[group_idx]): cell_obj[param] = value_groups[group_idx][cell_idx] bs_data["bs_parameters"].append(cell_obj) # if regular_params: bs_data, reg_not_found = update_json_with_parameters(bs_data, regular_params) not_found = not_found & reg_not_found with open(bs_path, 'w') as f: json.dump(bs_data, f, indent=2) # 3. Update user_specific_parameter.json user_path = os.path.join(case_dir, "user_specific_parameter.json") if os.path.exists(user_path): with open(user_path, 'r') as f: user_data = json.load(f) for param, value in file_parameters["user_specific_parameter"]: updated, missing = update_json_with_parameters(user_data, {param: value}) if missing: print(f"Warning: Case_{i} parameter not found: {param} (in user_specific_parameter.json)") user_data, user_not_found = update_json_with_parameters(user_data, no_prefix_combo) not_found = set(not_found) & set(user_not_found) with open(user_path, 'w') as f: json.dump(user_data, f, indent=2) # 4. Check in common parameters if not_found: for param in list(not_found): path_list = [p.strip() for p in param.split('.')] if find_and_update_parameter(other_json_data, path_list, no_prefix_combo[param]) > 0: print(f"Overridden common parameter: {param} = {no_prefix_combo[param]}") not_found.remove(param) if not_found: print(f"Warning: Case_{i} parameters not found: {', '.join(not_found)}") with open(OTHER_JSON_PATH, 'w') as f: json.dump(other_json_data, f, indent=2) print(f"Common parameter file updated: {OTHER_JSON_PATH}") def main(): param_file = "Configuration parameter combination.txt" config_dir = "Config" template_dir = "templates" print("Initializing Config folder...") clear_config_folder(config_dir) print(f"Cleared/created: {config_dir}") normal_params, combo_params = parse_parameter_file(param_file) print(f"Parsed normal parameters: {len(normal_params)}, combo parameters: {len(combo_params)}") case_combinations = generate_combinations(normal_params, combo_params) print(f"Generated {len(case_combinations)} parameter combinations") create_case_folders(config_dir, case_combinations, template_dir) print("All case configurations completed") print(f"Each case folder contains:") print("- simulation_parameter_case.json") print("- bs_parameter_case.json") print("- user_specific_parameter.json") print("- 3gpp_params.json") print("- 3gpp_params_bound.json") print(f"Common parameter file location: {OTHER_JSON_PATH}") if __name__ == "__main__": main() 请在不改变原有功能的基础上,如果我的输入为interference_cell_id_list=[1]或interference_cell_id_list=[1,2,3]则输出一个case interference_cell_id_list=[1]或interference_cell_id_list=[1,2,3](列表格式) 如果interference_cell_id_list=1,2,3则输出三个case 为1 2 3,给出修改部分代码(尽可能小的修改)
最新发布
11-29
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值