session_max_open_files

本文介绍Oracle数据库中并行执行的相关参数配置方法及其对性能的影响,包括并行执行消息大小、线程数量及服务器进程等,并详细阐述了如何设置归档日志的目标状态。
说明: 指定可在任一给定会话中打开的 BFILE 的最大数量。一旦达到这个数量, 此后将无法在该会话中打开更多文件。该参数还取决于操作系统参数 MAX_OPEN_FILES。
  值范围: 1 - 至少为 (50, OS 级上的 MAX_OPEN_FILES)。
  默认值: 10
  parallel_execution_message_size:
  说明: 指定并行执行 (并行查询, PDML, 并行恢复和复制) 消息的大小。如果值大于 2048 或 4096, 就需要更大的共享池。如果 PARALLEL_AUTOMATIC_TUNING = TRUE, 将在大存储池之外指定消息缓冲区。
  值范围: 2148 - 无穷大。
  默认值: 如果 PARALLEL_AUTOMATIC_TUNING 为 FALSE, 通常值为 2148; 如果 PARALLEL_AUTOMATIC_TUNING 为 TRUE , 则值为 4096 (根据操作系统而定)。
  Paralle_min_percent:
  说明: 指定并行执行要求的线程的最小百分比。设置该参数, 可以确保并行执行在没有可用的恰当查询从属进程时, 会显示一个错误消息, 并且该查询会因此而不予执行。
  值范围: 0 -100
  默认值: 0, 表示不使用该参数。
  Parallel_automatic_tuning:
  说明: 如果设置为 TRUE, Oracle 将为控制并行执行的参数确定默认值。除了设置该参数外, 你还必须为系统中的表设置并行性。
  值范围: TRUE | FALSE
  默认值: FALSE
  parallel_threads_per_cpu:
  说明: 说明一个 CPU 在并行执行过程中可处理的进程或线程的数量, 并优化并行自适应算法和负载均衡算法。如果计算机在执行一个典型查询时有超负荷的迹象, 应减小该数值。
  值范围: 任何非零值。
  默认值: 根据操作系统而定 (通常为 2)
  parallel_broadcast_enabled:
  说明 : 通过使用一个散列联接或合并联接, 可以在将多个大结果集联接到一个小结果集 (以字节而不是行为单位来衡量大小) 时改善性能。如果该值设置为 TRUE, 优化程序可以将小结果集内的每个行都传播到大型集内的每个集群数据库处理行中。
  值范围: TRUE | FALSE
  默认值 : FALSE
  parallel_adaptive_multi_user:
  说明: 启用或禁用一个自适应算法, 旨在提高使用并行执行方式的多用户环境的性能。通过按系统负荷自动降低请求的并行度, 在启动查询时实现此功能。当 PARALLEL_AUTOMATIC_TUNING = TRUE 时, 其效果最佳。
  值范围: TRUE | FALSE
  默认值: 如果 PARALLEL_AUTOMATIC_TUNING = TRUE, 则该值为 TRUE; 否则为 FALSE
  parallel_max_servers:
  说明: 指定一个例程的并行执行服务器或并行恢复进程的最大数量。如果需要, 例程启动时分配的查询服务器的数量将增加到该数量。
  值范围: 0 -256
  默认值: 由 CPU_COUNT, PARALLEL_AUTOMATIC_TUNING 和 PARALLEL_ADAPTIVE_MULTI_USER 确定
  parallel_min_servers
  说明: 指定为并行执行启动例程后, Oracle 创建的查询服务器进程的最小数量。
  值范围: 0 - PARALLEL_MAX_SERVERS。
  默认值: 0
  log_archive_dest_state_3:
  说明: 指定相应的归档日志目标参数 (仅 LOG_ARCHIVE_DEST_3) 的可用性状态。如果启用, 日志目标将被归档。如果延迟, 该目标将被排除在归档操作之外直至重新启用。
  值范围: ENABLE | DEFER
  默认值: ENABLE
  log_archive_dest_state_4:
  说明: 指定相应的归档日志目标参数 (仅 LOG_ARCHIVE_DEST_4) 的可用性状态。如果启用, 日志目标将被归档。如果延迟, 该目标将被排除在归档操作之外直至重新启用。
  值范围: ENABLE | DEFER
  默认值: ENABLE
  log_archive_dest_state_5:
  说明: 指定相应的归档日志目标参数 (仅 LOG_ARCHIVE_DEST_5) 的可用性状态。如果启用, 日志目标将被归档。如果延迟, 该目标将被排除在归档操作之外直至重新启用。
  值范围: ENABLE | DEFER
  默认值: ENABLE
  log_archive_dest_state_6:
  说明: 标识特定日志归档目标的最近的用户定义状态。
  值范围: ENABLE--如果目标属性有效, 则启用归档日志目标; DEFER--即使目标属性有效, 也要延迟处理归档日志目标; 或者是 ALTERNATE--延迟处理归档日志目标, 直到另一个目标的失败导致自动启用了此目标 (前提是备用目标的属性必须有效)。
  log_archive_dest_state_7:
  说明: 标识特定日志归档目标的最近的用户定义状态。
  值范围: ENABLE--如果目标属性有效, 则启用归档日志目标; DEFER--即使目标属性有效, 也要延迟处理归档日志目标; 或者是 ALTERNATE--延迟处理归档日志目标, 直到另一个目标的失败导致自动启用了此目标 (前提是备用目标的属性必须有效)。
  log_archive_dest_state_8:
  说明: 标识特定日志归档目标的最近的用户定义状态。
  值范围: ENABLE--如果目标属性有效, 则启用归档日志目标; DEFER--即使目标属性有效, 也要延迟处理归档日志目标; 或者是 ALTERNATE--延迟处理归档日志目标, 直到另一个目标的失败导致自动启用了此目标 (前提是备用目标的属性必须有效)。

session_max_open_files: 说明: 指定可在任一给定会话中打开的 BFILE 的最大数量。一旦达到这个数量, 此后将无法在该会话中打开更多文件。该参数还取决于操作系统参数 MAX_OPEN_FILES。 值范围: 1 - 至少为 (50, OS 级上的 MAX_OPEN_FILES)。 默认值: 10 parallel_execution_message_size: 说明: 指定并行执行 (并行查询, PDML, 并行恢复和复制) 消息的大小。如果值大于 2048 或 4096, 就需要更大的共享池。如果 PARALLEL_AUTOMATIC_TUNING = TRUE, 将在大存储池之外指定消息缓冲区。 值范围: 2148 - 无穷大。 默认值: 如果 PARALLEL_AUTOMATIC_TUNING 为 FALSE, 通常值为 2148; 如果 PARALLEL_AUTOMATIC_TUNING 为 TRUE , 则值为 4096 (根据操作系统而定)。 Paralle_min_percent: 说明: 指定并行执行要求的线程的最小百分比。设置该参数, 可以确保并行执行在没有可用的恰当查询从属进程时, 会显示一个错误消息, 并且该查询会因此而不予执行。 值范围: 0 -100 默认值: 0, 表示不使用该参数。 Parallel_automatic_tuning: 说明: 如果设置为 TRUE, Oracle 将为控制并行执行的参数确定默认值。除了设置该参数外, 你还必须为系统中的表设置并行性。 值范围: TRUE | FALSE 默认值: FALSE parallel_threads_per_cpu: 说明: 说明一个 CPU 在并行执行过程中可处理的进程或线程的数量, 并优化并行自适应算法和负载均衡算法。如果计算机在执行一个典型查询时有超负荷的迹象, 应减小该数值。 值范围: 任何非零值。 默认值: 根据操作系统而定 (通常为 2) parallel_broadcast_enabled: 说明 : 通过使用一个散列联接或合并联接, 可以在将多个大结果集联接到一个小结果集 (以字节而不是行为单位来衡量大小) 时改善性能。如果该值设置为 TRUE, 优化程序可以将小结果集内的每个行都传播到大型集内的每个集群数据库处理行中。 值范围: TRUE | FALSE 默认值 : FALSE parallel_adaptive_multi_user: 说明: 启用或禁用一个自适应算法, 旨在提高使用并行执行方式的多用户环境的性能。通过按系统负荷自动降低请求的并行度, 在启动查询时实现此功能。当 PARALLEL_AUTOMATIC_TUNING = TRUE 时, 其效果最佳。 值范围: TRUE | FALSE 默认值: 如果 PARALLEL_AUTOMATIC_TUNING = TRUE, 则该值为 TRUE; 否则为 FALSE parallel_max_servers: 说明: 指定一个例程的并行执行服务器或并行恢复进程的最大数量。如果需要, 例程启动时分配的查询服务器的数量将增加到该数量。 值范围: 0 -256 默认值: 由 CPU_COUNT, PARALLEL_AUTOMATIC_TUNING 和 PARALLEL_ADAPTIVE_MULTI_USER 确定 parallel_min_servers 说明: 指定为并行执行启动例程后, Oracle 创建的查询服务器进程的最小数量。 值范围: 0 - PARALLEL_MAX_SERVERS。 默认值: 0 log_archive_dest_state_3: 说明: 指定相应的归档日志目标参数 (仅 LOG_ARCHIVE_DEST_3) 的可用性状态。如果启用, 日志目标将被归档。如果延迟, 该目标将被排除在归档操作之外直至重新启用。 值范围: ENABLE | DEFER 默认值: ENABLE log_archive_dest_state_4: 说明: 指定相应的归档日志目标参数 (仅 LOG_ARCHIVE_DEST_4) 的可用性状态。如果启用, 日志目标将被归档。如果延迟, 该目标将被排除在归档操作之外直至重新启用。 值范围: ENABLE | DEFER 默认值: ENABLE log_archive_dest_state_5: 说明: 指定相应的归档日志目标参数 (仅 LOG_ARCHIVE_DEST_5) 的可用性状态。如果启用, 日志目标将被归档。如果延迟, 该目标将被排除在归档操作之外直至重新启用。 值范围: ENABLE | DEFER 默认值: ENABLE log_archive_dest_state_6: 说明: 标识特定日志归档目标的最近的用户定义状态。 值范围: ENABLE--如果目标属性有效, 则启用归档日志目标; DEFER--即使目标属性有效, 也要延迟处理归档日志目标; 或者是 ALTERNATE--延迟处理归档日志目标, 直到另一个目标的失败导致自动启用了此目标 (前提是备用目标的属性必须有效)。 log_archive_dest_state_7: 说明: 标识特定日志归档目标的最近的用户定义状态。 值范围: ENABLE--如果目标属性有效, 则启用归档日志目标; DEFER--即使目标属性有效, 也要延迟处理归档日志目标; 或者是 ALTERNATE--延迟处理归档日志目标, 直到另一个目标的失败导致自动启用了此目标 (前提是备用目标的属性必须有效)。 log_archive_dest_state_8: 说明: 标识特定日志归档目标的最近的用户定义状态。 值范围: ENABLE--如果目标属性有效, 则启用归档日志目标; DEFER--即使目标属性有效, 也要延迟处理归档日志目标; 或者是 ALTERNATE--延迟处理归档日志目标, 直到另一个目标的失败导致自动启用了此目标 (前提是备用目标的属性必须有效)。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-628200/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/35489/viewspace-628200/

# -*- coding: utf-8 -*- import scipy.io import numpy as np import matplotlib.pyplot as plt from scipy import signal import pandas as pd import seaborn as sns import os from scipy import stats # 图表中文配置 plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑体显示中文 plt.rcParams['axes.unicode_minus'] = False # 解决负号 '-' 显示为方块的问题 def process_alpha_eeg_data(mat_file_path): """ 处理脑电数据 参数: mat_file_path: .mat文件路径 返回: fig_time_series: 时间序列图表对象 fig_comparison: 条件比较图表对象 fig_alpha_power: Alpha功率随时间变化图表对象 results_df: 包含所有分析结果的DataFrame p_value: 统计显著性p值 """ # 1. 加载.mat文件数据 mat_data = scipy.io.loadmat(mat_file_path) # 2. 提取数据矩阵 if 'data' not in mat_data: # 改进的数据矩阵检测 valid_keys = [k for k in mat_data.keys() if not k.startswith('__') and isinstance(mat_data[k], np.ndarray) and mat_data[k].ndim == 2] if not valid_keys: raise ValueError("未找到有效的2D数据矩阵") # 选择最大的数据矩阵 data_matrix = mat_data[max(valid_keys, key=lambda k: mat_data[k].size)] print(f"使用自动检测的数据矩阵: {max(valid_keys, key=lambda k: mat_data[k].size)}") else: data_matrix = mat_data['data'] # 3. 解析数据矩阵结构 timestamps = data_matrix[:, 0] # 时间戳 # 检查数据列数 num_columns = data_matrix.shape[1] if num_columns < 19: raise ValueError(f"数据矩阵只有 {num_columns} 列,需要至少19列 (时间戳 + 16个EEG通道 + 2个触发器)") eeg_data = data_matrix[:, 1:17] # 16个EEG通道 trigger_eyes_closed = data_matrix[:, 17] # 闭眼触发器 trigger_eyes_open = data_matrix[:, 18] # 睁眼触发器 # 固定采样率512Hz sampling_rate = 512.0 # 4. 预处理 - 带通滤波和陷波滤波 def preprocess(data): """应用带通滤波和陷波滤波预处理EEG数据""" # 带通滤波提取Alpha波 (8-12Hz) nyquist = 0.5 * sampling_rate low = 8 / nyquist high = 12 / nyquist b, a = signal.butter(4, [low, high], btype='bandpass') alpha_data = signal.filtfilt(b, a, data) # 陷波滤波去除50/60Hz工频干扰 notch_freq = 50.0 # 根据实际工频干扰调整 notch_width = 2.0 freq = notch_freq / nyquist q = freq / (notch_width / nyquist) b, a = signal.iirnotch(freq, q) return signal.filtfilt(b, a, alpha_data) # 应用预处理到所有通道 eeg_data_filtered = np.apply_along_axis(preprocess, 0, eeg_data) # 5. 计算注意力指数 def calculate_attention(alpha_data): """计算基于Alpha波的注意力指数""" # 计算Alpha波能量 (RMS) alpha_energy = np.sqrt(np.mean(alpha_data**2)) # 计算注意力指数 (与Alpha能量负相关) attention_index = 1 / (1 + alpha_energy) # 归一化到0-100范围 attention_index = np.clip(attention_index * 100, 0, 100) return attention_index # 6. 识别所有会话块 def find_sessions(trigger): """识别所有会话的开始和结束""" # 找到所有上升沿(会话开始) trigger_diff = np.diff(trigger) session_starts = np.where(trigger_diff == 1)[0] + 1 # 找到所有下降沿(会话结束) session_ends = np.where(trigger_diff == -1)[0] + 1 # 确保每个开始都有对应的结束 sessions = [] for start in session_starts: # 找到下一个结束点 ends_after_start = session_ends[session_ends > start] if len(ends_after_start) > 0: end = ends_after_start[0] sessions.append((start, end)) return sessions # 获取所有会话块(闭眼和睁眼) closed_eye_sessions = find_sessions(trigger_eyes_closed) open_eye_sessions = find_sessions(trigger_eyes_open) # 7. 处理每个会话块 - 使用固定10秒时长 session_results = [] session_duration_sec = 10.0 # 每个会话固定10秒 # 为不同条件创建单独的计数器 closed_counter = 1 open_counter = 1 # 处理闭眼会话块 for session_idx, (start_idx, end_idx) in enumerate(closed_eye_sessions): # 提取会话数据 session_eeg = eeg_data_filtered[start_idx:end_idx, :] # 计算整个会话块的平均注意力指数 channel_attention = [] for ch in range(session_eeg.shape[1]): attention = calculate_attention(session_eeg[:, ch]) channel_attention.append(attention) session_avg_attention = np.mean(channel_attention) # 存储会话结果 session_results.append({ 'session_id': f"闭眼{closed_counter}", 'condition': '闭眼', 'start_time': timestamps[start_idx], 'duration': session_duration_sec, 'avg_attention': session_avg_attention, 'channel_attention': channel_attention }) # 更新闭眼会话计数器 closed_counter += 1 # 处理睁眼会话块 for session_idx, (start_idx, end_idx) in enumerate(open_eye_sessions): # 提取会话数据 session_eeg = eeg_data_filtered[start_idx:end_idx, :] # 计算整个会话块的平均注意力指数 channel_attention = [] for ch in range(session_eeg.shape[1]): attention = calculate_attention(session_eeg[:, ch]) channel_attention.append(attention) session_avg_attention = np.mean(channel_attention) # 存储会话结果 session_results.append({ 'session_id': f"睁眼{open_counter}", 'condition': '睁眼', 'start_time': timestamps[start_idx], 'duration': session_duration_sec, 'avg_attention': session_avg_attention, 'channel_attention': channel_attention }) # 更新睁眼会话计数器 open_counter += 1 # 创建结果DataFrame results_df = pd.DataFrame(session_results) # 8. 可视化结果 - 拆分为三张独立的图表 # 图表1: 随时间变化的注意力指数 fig_time_series = plt.figure(figsize=(14, 7)) ax1 = fig_time_series.add_subplot(111) # 为不同条件设置不同颜色 colors = {'闭眼': 'blue', '睁眼': 'orange'} # 为每个会话块创建三个子点 segment_results = [] # 处理所有会话块,为每个会话块创建三个子点 for i, row in results_df.iterrows(): # 计算三个子点的位置和值 for seg_idx in range(3): # 子点值 = 主点值 + 随机偏移(模拟变化) offset = np.random.uniform(-5, 5) # 小范围随机偏移 segment_value = max(0, min(100, row['avg_attention'] + offset)) segment_results.append({ 'session_id': row['session_id'], 'condition': row['condition'], 'session_idx': i, # 会话索引 'segment_idx': seg_idx, 'value': segment_value, 'x_position': i + seg_idx * 0.3 # 在x轴上均匀分布 }) segment_df = pd.DataFrame(segment_results) # 绘制每个会话块的三个子点 for session_id in segment_df['session_id'].unique(): session_data = segment_df[segment_df['session_id'] == session_id] condition = session_data['condition'].iloc[0] color = colors[condition] # 绘制折线连接三个子点(同一会话块内) ax1.plot(session_data['x_position'], session_data['value'], 'o-', markersize=8, color=color, alpha=0.7, linewidth=1.5) # 添加数值标签 - 增大字号到11 for _, seg_row in session_data.iterrows(): ax1.text(seg_row['x_position'], seg_row['value'] + 2, f"{seg_row['value']:.1f}", ha='center', va='bottom', fontsize=11) # 字号从9增大到11 # 连接同一条件下相邻会话块的首尾点 for condition in ['闭眼', '睁眼']: condition_data = segment_df[segment_df['condition'] == condition] # 按会话索引排序 condition_data = condition_data.sort_values('session_idx') # 获取所有会话索引 session_indices = condition_data['session_idx'].unique() session_indices.sort() # 连接相邻会话块 for i in range(len(session_indices) - 1): # 前一个会话的最后一个点(segment_idx=2) prev_session = condition_data[ (condition_data['session_idx'] == session_indices[i]) & (condition_data['segment_idx'] == 2) ] # 后一个会话的第一个点(segment_idx=0) next_session = condition_data[ (condition_data['session_idx'] == session_indices[i+1]) & (condition_data['segment_idx'] == 0) ] # 确保找到两个点 if len(prev_session) == 1 and len(next_session) == 1: prev_point = prev_session.iloc[0] next_point = next_session.iloc[0] # 绘制连接线(使用与子点相同的样式) ax1.plot( [prev_point['x_position'], next_point['x_position']], [prev_point['value'], next_point['value']], '-', color=colors[condition], alpha=0.7, linewidth=1.5 ) # 设置x轴刻度和标签 ax1.set_xticks(results_df.index) ax1.set_xticklabels(results_df['session_id'], rotation=45, ha='right', fontsize=10) # 调整x轴标签字号 # 设置y轴范围到10-60 ax1.set_ylim(10, 60) ax1.set_title('不同条件下注意力指数随时间变化', fontsize=16) ax1.set_xlabel('会话块ID', fontsize=14) ax1.set_ylabel('平均注意力指数 (%)', fontsize=14) # 添加图例 from matplotlib.lines import Line2D legend_elements = [ Line2D([0], [0], marker='o', color='w', markerfacecolor='blue', markersize=10, label='闭眼'), Line2D([0], [0], marker='o', color='w', markerfacecolor='orange', markersize=10, label='睁眼') ] ax1.legend(handles=legend_elements, loc='best', fontsize=12) ax1.grid(True, linestyle='--', alpha=0.3) # 添加分隔线区分不同会话块 for i in range(1, len(results_df)): ax1.axvline(i - 0.5, color='gray', linestyle='--', alpha=0.5) plt.tight_layout() # 图表2: 闭眼与睁眼条件下的注意力比较 fig_comparison = plt.figure(figsize=(10, 6)) ax2 = fig_comparison.add_subplot(111) # 箱线图展示条件间差异 sns.boxplot(x='condition', y='avg_attention', data=results_df, ax=ax2, palette='Set2', hue='condition', legend=False) # 添加散点图显示个体数据点 sns.stripplot(x='condition', y='avg_attention', data=results_df, ax=ax2, color='black', alpha=0.7, size=7, jitter=True) ax2.set_title('闭眼与睁眼条件下注意力比较', fontsize=16) ax2.set_xlabel('条件', fontsize=14) ax2.set_ylabel('平均注意力指数 (%)', fontsize=14) # 添加统计显著性标记(使用独立样本t检验) closed_data = results_df[results_df['condition'] == '闭眼']['avg_attention'] open_data = results_df[results_df['condition'] == '睁眼']['avg_attention'] t_stat, p_value = stats.ttest_ind(closed_data, open_data) # 添加显著性标记 y_max = max(results_df['avg_attention']) + 5 ax2.plot([0, 0, 1, 1], [y_max, y_max+2, y_max+2, y_max], lw=1.5, c='black') ax2.text(0.5, y_max+3, f"p = {p_value:.4f}", ha='center', va='bottom', fontsize=12) plt.tight_layout() # 图表3: Alpha功率随时间变化(使用固定10秒时长) fig_alpha_power = plt.figure(figsize=(15, 8)) ax3 = fig_alpha_power.add_subplot(111) # 计算每个时间点的Alpha功率(所有通道的平均RMS) # 使用滑动窗口平均平滑数据(窗口大小=1秒) window_size = int(sampling_rate) # 512个采样点(1秒) alpha_power = np.sqrt(np.mean(eeg_data_filtered**2, axis=1)) # 所有通道的RMS smoothed_alpha_power = np.convolve(alpha_power, np.ones(window_size)/window_size, mode='same') # 绘制整个实验期间的Alpha功率 ax3.plot(timestamps, smoothed_alpha_power, 'b-', linewidth=1.5, alpha=0.8, label='Alpha功率') # 增强背景标注 - 闭眼会话(使用固定10秒时长) for session_idx, (start_idx, end_idx) in enumerate(closed_eye_sessions): start_time = timestamps[start_idx] end_time = start_time + session_duration_sec # 固定10秒时长 # 增强背景色 ax3.axvspan(start_time, end_time, color='royalblue', alpha=0.3, label='闭眼' if session_idx == 0 else "") # 添加文字标注(居中) mid_time = start_time + session_duration_sec/2 y_min, y_max = ax3.get_ylim() label_y = y_min + 0.05 * (y_max - y_min) ax3.text(mid_time, label_y, '闭眼', ha='center', va='bottom', fontsize=12, fontweight='bold', bbox=dict(facecolor='white', alpha=0.7, edgecolor='royalblue', boxstyle='round,pad=0.2')) # 增强背景标注 - 睁眼会话(使用固定10秒时长) for session_idx, (start_idx, end_idx) in enumerate(open_eye_sessions): start_time = timestamps[start_idx] end_time = start_time + session_duration_sec # 固定10秒时长 # 增强背景色 ax3.axvspan(start_time, end_time, color='darkorange', alpha=0.3, label='睁眼' if session_idx == 0 else "") # 添加文字标注(居中) mid_time = start_time + session_duration_sec/2 y_min, y_max = ax3.get_ylim() label_y = y_min + 0.05 * (y_max - y_min) ax3.text(mid_time, label_y, '睁眼', ha='center', va='bottom', fontsize=12, fontweight='bold', bbox=dict(facecolor='white', alpha=0.7, edgecolor='darkorange', boxstyle='round,pad=0.2')) # 添加标记和标签 ax3.set_title('Alpha功率随时间变化(闭眼与睁眼期间)', fontsize=18, fontweight='bold') ax3.set_xlabel('时间 (秒)', fontsize=14) ax3.set_ylabel('Alpha功率 (RMS)', fontsize=14) ax3.grid(True, linestyle='--', alpha=0.3) # 添加图例(只显示曲线图例) ax3.legend(loc='upper right', fontsize=12) # 添加垂直参考线标记每个会话的开始(使用更明显的颜色) all_sessions = closed_eye_sessions + open_eye_sessions for start_idx, _ in all_sessions: ax3.axvline(x=timestamps[start_idx], color='darkred', linestyle='--', alpha=0.7, linewidth=1.2) # 添加时间轴刻度增强 ax3.xaxis.set_major_locator(plt.MaxNLocator(20)) # 增加刻度数量 # 添加背景色图例说明 from matplotlib.patches import Patch legend_elements = [ Patch(facecolor='royalblue', alpha=0.3, edgecolor='royalblue', label='闭眼期间'), Patch(facecolor='darkorange', alpha=0.3, edgecolor='darkorange', label='睁眼期间'), plt.Line2D([0], [0], color='darkred', linestyle='--', label='会话开始') ] ax3.legend(handles=legend_elements, loc='upper left', fontsize=10) # 添加会话时长信息 ax3.text(0.02,0.95, f"每个会话时长: {session_duration_sec}秒", transform=ax3.transAxes, fontsize=12, bbox=dict(facecolor='white', alpha=0.8)) plt.tight_layout() # 9. 保存结果 base_name = os.path.splitext(os.path.basename(mat_file_path))[0] # 保存图像 fig_time_series.savefig(f"{base_name}_time_series.png", dpi=300, bbox_inches='tight') fig_comparison.savefig(f"{base_name}_comparison.png", dpi=300, bbox_inches='tight') fig_alpha_power.savefig(f"{base_name}_alpha_power.png", dpi=300, bbox_inches='tight') # 保存结果到CSV results_df.to_csv(f"{base_name}_results.csv", index=False, encoding='utf-8-sig') return fig_time_series, fig_comparison, fig_alpha_power, results_df, p_value # 主程序入口 if __name__ == "__main__": # 输入文件路径 mat_file = "F:/Grade2/attention/2348892/subject_02.mat" try: # 处理数据并生成可视化 fig1, fig2, fig3, results_df, p_value = process_alpha_eeg_data(mat_file) # 显示图像 plt.show() # 打印会话结果和统计显著性 - 英文输出 print("EEG Analysis Results:") print(results_df[['session_id', 'condition', 'duration', 'avg_attention']]) print(f"\nStatistical Significance: p = {p_value:.4f}") # 根据p值输出不同结论 - 英文输出 if p_value < 0.05: print("There is a significant difference between eyes-closed and eyes-open conditions (p < 0.05)") else: print("No significant difference between eyes-closed and eyes-open conditions") except Exception as e: # 错误处理 - 保持英文错误信息 print(f"Error during processing: {str(e)}") import traceback traceback.print_exc() 将该代码修改为,提供一个文件夹的路径后,可以读取该文件内全部的mat文件,并且图1、图2和图3的输出为所有mat文件的结果的平均值
06-28
import asyncio from datetime import datetime from io import BytesIO import streamlit as st import pandas as pd from autogen_agentchat.agents import AssistantAgent import json import os # import xmind import re from autogen_agentchat.messages import TextMessage, AgentEvent, ModelClientStreamingChunkEvent, MultiModalMessage from autogen_core import CancellationToken from autogen_ext.models.openai import OpenAIChatCompletionClient from autogen_core import Image as AGImage from PIL import Image as PILImage import re def extract_json_from_markdown(markdown_text: str) -> str: """ 从Markdown文本中提取所有JSON代码块的内容 参数: markdown_text: 包含JSON代码块的Markdown文本 返回: 包含所有JSON代码块内容的列表(按出现顺序) 如果没有找到则返回空列表 """ # 正则表达式匹配 ```json 开头的代码块(不区分大小写,允许空格) pattern = r'```json\s*?\n(.*?)```' matches = re.findall(pattern, markdown_text, re.DOTALL | re.IGNORECASE) # 移除每项内容首尾的空白字符 return matches[0] def get_current_datetime(): now = datetime.now() return now.strftime("%Y%m%d%H%M%S") def validate_json(json_str): """验证并清理JSON字符串""" try: # 尝试直接解析 return json.loads(json_str), True except json.JSONDecodeError: # 如果失败,尝试清理并重新解析 try: # 移除可能存在的非法字符 cleaned = re.sub(r'\u001b$$[^m]*m', '', json_str) # 移除不完整的转义序列 cleaned = re.sub(r'(?<!\)\(?!\\)', r'\\', cleaned) # 只保留有效的JSON内容 json_match = re.search(r'\{(?:[^{}]|(?R))*\}|$$(?:[^$$]|(?R))*$$', cleaned) if json_match: return json.loads(json_match.group()), True return json_str, False except Exception: return json_str, False # 设置页面配置 st.set_page_config(page_title="测试用例生成器", page_icon="🧪", layout="wide") # 初始化会话状态 if 'test_cases' not in st.session_state: st.session_state.test_cases = "" if '需求' not in st.session_state: st.session_state.需求 = "" if 'api_key_set' not in st.session_state: st.session_state.api_key_set = False if 'input_str' not in st.session_state: st.session_state.input_str = "" if 'model_client' not in st.session_state: st.session_state.model_client = None if 'image_files' not in st.session_state: st.session_state.image_files = [] # 定义提示词模板 SYSTEM_PROMPT = """你是一个专业的测试工程师,能够根据用户提供的需求进行分析需求,生成测试用例。 请根据以下要求生成测试用例: 0. 内容约束:不编造未说明的内容 1. 必须包含用例编号、用例名称、优先级、前置条件、操作步骤、预期结果等要素 2. 优先级:高、中、低 4. 返回一个包含多个测试用例的数组 5. 使用中文描述 6. 确保测试用例覆盖各种场景,包括正常流程和边界情况 7. 消除冗余用例,合并重复验证点,冗余用例不要重复生成 8. 步骤描述和预期结果的要一一对应,步骤之间用换行符连接,预期结果之间也用换行符连接 输出格式示例: ```markdown # 测试需求分析文档 ## 测试目标 - [清晰的功能目标描述] ## 需求拆解 | 需求ID | 需求描述 | 测试类型 | 优先级 | 验收标准 | |--------|----------|----------|--------|----------| ## 风险分析 - **高优先级风险**: - [风险描述] → [缓解方案] ## 测试策略 - [功能测试]: - 覆盖场景: - [场景1] - [场景2] - [非功能测试]: - 性能指标: [RPS ≥ 1000] - 安全要求: [OWASP TOP10覆盖] ## 待澄清项 - [问题1] (需业务方确认) - [问题2] (需架构师确认) ``` 对应生成的用例: ```json ``` 工作流 先进行需求分析输出以上格式的需求分析结果 - 根据需求分析列出测试点 - 根据不同测试点生成测试用例 - 将生成的测试用例用markdown格式的json进行标注 """ APPROVE_PROMPT = """你是一位资深测试架构师,拥有10年复杂系统测试经验,擅长在评审用例中识别隐性漏洞与需求偏差,并补充相应的测试用例。。 以下是补充用例时的限制: 1. 包含用例编号、用例名称、前置条件、操作步骤、预期结果等要素 2. 优先级:高、中、低 3. 每个测试用例使用JSON格式表示 4. 返回一个包含多个测试用例的数组 5. 使用中文描述 6. 确保测试用例覆盖各种场景,包括正常流程和边界情况 7. 步骤描述和预期结果的要一一对应,步骤之间用换行符连接,预期结果之间也用换行符连接 8. 消除冗余用例,合并重复验证点,冗余用例不要重复生成 输出格式示例: ### 用例评审结果 根据提供的需求和现有测试用例,以下是对现有用例的评审结果: 1. **TC001 - 正确用户名和密码登录** - 评审结果:合理,覆盖了正常登录场景。 ### 需要补充的测试用例 虽然现有用例覆盖了基本的登录和进件列表查看、筛选功能,但仍需补充以下测试用例以确保全面覆盖各种场景,包括边界情况和异常情况: ```json [ { "用例编号": "TC008", "用例名称": "空用户名和密码登录", "优先级": "中", "前置条件": "无", "操作步骤": "1. 打开登录页面\n2. 不输入用户名\n3. 不输入密码\n4. 点击登录按钮", "预期结果": "1. 系统显示用户名和密码不能为空的提示\n2. 页面停留在登录页" }, { "用例编号": "TC009", "用例名称": "未记住账号登录", "优先级": "低", "前置条件": "无", "操作步骤": "1. 打开登录页面\n2. 输入正确的用户名\n3. 输入正确的密码\n4. 取消记住账号选项\n5. 点击登录按钮", "预期结果": "1. 系统显示登录成功提示\n2. 页面跳转至首页或进件列表页\n3. 关闭浏览器后重新打开,用户名和密码不自动填充" } ] ``` ### 结论 [给出覆盖率评测] 工作流 进行用例评审 - 根据需求和用例给出评审结果 - 根据评审结果生成需要补充测试用例,不需要补充用例输出[],以上生成的测试用例格式要以markdown格式的json进行标注 """ # 页面标题 st.title("🧪 测试用例生成器") tabs1, tabs2 = st.tabs(["测试用例生成器", "模型配置"]) with tabs1: # 需求输入区域 col1, col2 = st.columns([2, 1]) with col1: requirement = st.text_area("请输入测试需求:", value=st.session_state.需求, height=200) upload_images=st.file_uploader("请上传图片", type=["png", "jpg", "jpeg"], accept_multiple_files= True) # upload_images=st.file_uploader("请上传图片", type=["png", "jpg", "jpeg"]) if upload_images: for upload_image in upload_images: st.image(upload_image, caption=upload_image.name, use_container_width=True) input_str = st.text_area("请输入要求:", value=st.session_state.input_str, height=200, placeholder="请按照需求生成测试用例") generate_btn = st.button("生成测试用例") # 测试用例展示区域 st.markdown("### 生成结果") # 创建一个空容器用于流式显示 generate_start_out = st.empty() test_case_output = st.empty() approve_start_output = st.empty() approve_test_output = st.empty() # merger_test_output = st.empty() with col2: st.markdown("### 测试用例列表") async def stream_response(requirement, input_str): """处理流式响应并逐字显示""" if not st.session_state.api_key_set: st.error("请先输入有效的API密钥") return "" # 创建一个空容器用于流式显示 generate_start = generate_start_out.empty() stream_container = test_case_output.empty() approve_start = approve_start_output.empty() approve_stream_container = approve_test_output.empty() if upload_images: # 生成用例智能体 assistant = AssistantAgent( name="assistant_stream", system_message=SYSTEM_PROMPT, model_client=st.session_state.model_client_vl, model_client_stream=True ) # 评审智能体 approve = AssistantAgent( name="assistant_stream", system_message=APPROVE_PROMPT, model_client=st.session_state.model_client_vl, model_client_stream=True ) else: assistant = AssistantAgent( name="assistant_stream", system_message=SYSTEM_PROMPT, model_client=st.session_state.model_client, model_client_stream=True ) # 评审智能体 approve = AssistantAgent( name="assistant_stream", system_message=APPROVE_PROMPT, model_client=st.session_state.model_client, model_client_stream=True ) # 初始化消息历史 generate_message = "" generate_start.markdown("【现在开始生成测试用例:】\n") # 消息队列 message_sequence = [] # 生成测试用例 approve_message_sequence = [] # 评审用例的消息队列 def get_images(up_images): images_temp=[] for uploaded_file in up_images: uploaded_file.seek(0) image_file = PILImage.open(uploaded_file) image_temp = AGImage(image_file) images_temp.append(image_temp) return images_temp if upload_images: content=[f"先根据上传的图片和需求:{requirement},先进行需求分析,给出需求分析结果然后生成测试用例,以上生成的测试用例要以markdown的json格式返回,另外要求:{input_str}"] input_images=get_images(upload_images) content.extend(input_images) print(content) multi_message=MultiModalMessage(content=content, source="user") message_sequence.append(multi_message) else: content=f"先根据需求:{requirement},先进行需求分析,给出需求分析结果然后生成测试用例,以上生成的测试用例要以markdown的json格式返回,另外要求:{input_str}" input_messages = TextMessage( content=content, source="user") message_sequence.append(input_messages) assistant.run_stream() # 测试用例生成. async for res in assistant.on_messages_stream( # type: ignore message_sequence, cancellation_token=CancellationToken(), ): if isinstance(res, ModelClientStreamingChunkEvent): generate_message += res.content print(res.content, end="", flush=True) # 尝试解析并清理JSON cleaned_message, is_valid = validate_json(generate_message) if is_valid: # 如果是有效JSON,格式化显示 try: formatted = json.dumps(cleaned_message, indent=2, ensure_ascii=False) stream_container.code(formatted, language="json") except Exception: stream_container.markdown(cleaned_message) # stream_container.write(cleaned_message) else: # 如果不是有效JSON,直接显示原始内容 stream_container.markdown(generate_message) # stream_container.write(message) generate_test = extract_json_from_markdown(generate_message) generate_test_list = json.loads(generate_test) # 测试用例评审 approve_promt = """ 需求为:{requirement},测试用例列表{generate_test},请根据需求和用例列表,先进行用例评审决定是否补充用例,另外限制:步骤描述和预期结果的要一一对应,步骤之间用换行符连接,预期结果之间也用换行符连接 """ approve_message = "" if upload_images: approve_content=[approve_promt.format(requirement=requirement, generate_test=generate_test)] approve_images = get_images(upload_images) # upload_images.seek(0) # images = PILImage.open(upload_images) # print(type(images)) # agImage = AGImage(images) approve_content.extend(approve_images) approve_multi_message=MultiModalMessage(content=approve_content, source="user") approve_message_sequence.append(approve_multi_message) else: approve_content=approve_promt.format(requirement=requirement, generate_test=generate_test) approve_input_messages = TextMessage( content=approve_content, source="user") approve_message_sequence.append(approve_input_messages) approve_start.markdown("【现在进行用例评审:】\n") async for res in approve.on_messages_stream( approve_message_sequence, cancellation_token=CancellationToken(), ): if isinstance(res, ModelClientStreamingChunkEvent): approve_message += res.content print(res.content, end="", flush=True) # 尝试解析并清理JSON cleaned_message, is_valid = validate_json(approve_message) if is_valid: # 如果是有效JSON,格式化显示 try: formatted = json.dumps(cleaned_message, indent=2, ensure_ascii=False) approve_stream_container.code(formatted, language="json") except Exception: approve_stream_container.markdown(cleaned_message) # stream_container.write(cleaned_message) else: # 如果不是有效JSON,直接显示原始内容 approve_stream_container.markdown(approve_message) # stream_container.write(message) approve_test = extract_json_from_markdown(approve_message) approve_test_list = json.loads(approve_test) if approve_test: generate_test_list.extend(approve_test_list) return generate_test_list async def handle_generate(rem, input_str): with st.spinner('正在生成测试用例...'): return await stream_response(rem, input_str) # 保存生成的测试用例到会话状态 if generate_btn and requirement: print(f"模型配置:{os.getenv('OPENAI_API_MODEL')}") print(f"视觉模型配置:{os.getenv('VL_OPENAI_API_MODEL')}") st.session_state.需求 = requirement st.session_state.test_cases = asyncio.run(handle_generate(requirement, input_str)) # 显示测试用例 if st.session_state.test_cases: # 用可折叠的样式展示测试用例 for i, case in enumerate(st.session_state.test_cases): with st.expander(f"{case['用例编号']}: {case['用例名称']}"): st.markdown(f"**优先级**: {case['优先级']}") st.markdown(f"**前置条件**: {case['前置条件']}") st.markdown("**测试步骤**:") st.text(case['操作步骤']) st.markdown("**预期结果**:") st.text(case['预期结果']) st.subheader("下载测试用例") excel_data = BytesIO() # 创建一个DataFrame rows = [] for case in st.session_state.test_cases: rows.append(case) # 创建DataFrame df = pd.DataFrame(rows) # 保证字段顺序 columns = ['用例编号', '用例名称', '优先级', '前置条件', '操作步骤', '预期结果'] df = df.reindex(columns=columns) # 保存为Excel文件 df.to_excel(excel_data, index=False,engine="openpyxl") excel_data.seek(0) st.download_button( label="下载Excel", data=excel_data, file_name=f"test_cases_{get_current_datetime()}.xlsx", mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ) with tabs2: st.subheader("模型配置") # API密钥输入 api_key = st.text_input("请输入API密钥:", type="password", value=os.getenv("OPENAI_API_KEY", "sk-d3yLWf4sx4zuDm8sEKwd5jxf8qDDSNLBX0FOteJLGgUPjbv7")) #https://dashscope.aliyuncs.com/compatible-mode/v1 api_base_url = st.text_input("请输入model地址:", type="default", value=os.getenv("OPENAI_API_BASE", "https://api.qingyuntop.top/v1")) api_model = st.text_input("请输入使用的模型:", type="default", value=os.getenv("OPENAI_API_MODEL", "qwen-plus-latest")) st.subheader("视觉模型配置") vl_api_key = st.text_input("请输入视觉模型API密钥:", type="password", value=os.getenv("VL_OPENAI_API_KEY", "sk-d3yLWf4sx4zuDm8sEKwd5jxf8qDDSNLBX0FOteJLGgUPjbv7")) vl_api_base_url = st.text_input("请输入视觉模型model地址:", type="default", value=os.getenv("VL_OPENAI_API_BASE", "https://api.qingyuntop.top/v1")) vl_api_model = st.text_input("请输入视觉模型使用的模型:", type="default", value=os.getenv("VL_OPENAI_API_MODEL", "qwen-vl-max")) if api_key: os.environ["OPENAI_API_KEY"] = api_key os.environ["OPENAI_API_BASE"] = api_base_url os.environ["OPENAI_API_MODEL"] = api_model st.session_state.api_key_set = True else: st.warning("请先输入API密钥以启用模型交互功能") if vl_api_key: os.environ["VL_OPENAI_API_KEY"] = vl_api_key os.environ["VL_OPENAI_API_BASE"] = vl_api_base_url os.environ["VL_OPENAI_API_MODEL"] = vl_api_model st.session_state.api_key_set = True else: st.warning("请先输入API密钥以启用模型交互功能") # 创建AutoGen代理 model_config = { # "model": "deepseek-r1", "model": os.getenv("OPENAI_API_MODEL"), "api_key": os.getenv("OPENAI_API_KEY"), "base_url": os.getenv("OPENAI_API_BASE"), "model_info": { "vision": False, # 是否启用视觉 "function_calling": True, "json_output": True, "family": "unknown", "multiple_system_messages": True, "structured_output": True }, } vl_model_config = { # "model": "deepseek-r1", "model": os.getenv("VL_OPENAI_API_MODEL"), "api_key": os.getenv("VL_OPENAI_API_KEY"), "base_url": os.getenv("VL_OPENAI_API_BASE"), "model_info": { "vision": True, # 是否启用视觉 "function_calling": True, "json_output": True, "family": "unknown", "multiple_system_messages": True, "structured_output": True }, } st.session_state.model_client= OpenAIChatCompletionClient(**model_config) st.session_state.model_client_vl= OpenAIChatCompletionClient(**vl_model_config) 我的代码是这样的怎么修改
08-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值