# 后端部分说明

## 文件夹概览

```bash
.
├── bci_core                                // bci核心代码
│   ├── __init__.py
│   ├── feature_extractors.py               // 特征提取：主要为连续数据带通滤波及取包络
│   ├── frequencybandselection_helpers.py   // 频率选择：用于评估不同频带的可分性差异
│   ├── model.py                            // Riemann和Wiener两种模型的embedder构建
│   ├── online.py                           // HMM模型
│   ├── pipeline.py                         // 模型载入及调用流程接口
│   ├── utils.py                            // 评价函数、数据切分、重参考等功能
│   ├── viz.py                              // 可视化
│   └── setup.py                            // 安装bci_core, pip install -e .
├── data                                    // 数据文件夹
│   └── suject_name
│       ├── train_info.yml                  // 训练数据及参数
│       ├── val_info.yml                    // 测试数据及参数
│       └── model_config.yml                // 受试模型配置
├── dataloaders                             // 数据读取接口
│   ├── __init__.py
│   ├── neo.py
│   └── utils.py
├── device                                  // 外设控制接口
│   ├── __init__.py
│   ├── data_client.py                      // NEO软件转发
│   ├── fubo_pneumatic_finger.py            // fubo气动手
│   └── trigger_box.py                      // NEO triggerbox接口
├── settings                                // 全局设置
│   └── config.py
├── static
│   ├── audios
│   ├── images
│   └── models   
├── band_selection.py                       // 频带选择脚本
├── daily_routine.psyexp                    // 日常范式
├── daily_routine.py                        
├── free_grasp.psyexp                       // 自由抓握范式
├── free_grasp.py 
├── general_grasp_training.psyexp           // 抓握训练范式
├── general_grasp_training.py   
├── online_sim.py                           // 在线模拟脚本
├── train_hmm.py                            // HMM参数拟合
├── training.py                             // 模型训练范式
├── validation.py                           // 模型验证范式
└── tests                                   // 单元测试
```

## 主要功能接口

### 模型训练
* training.py 拟合分类模型
  * `--subj`: 受试名
  * `--model-type`: 模型类型（riemann或baseline），默认为baseline，建议设为riemann
  * 保存路径：`./static/models/{subject_name}/{model_type}_{events}_{datetime}.pkl`
* train_hmm.py 拟合HMM模型
  * `--subj`: 受试名
  * `--model-filename`: 分类模型的文件名，不需要前置路径
  * 保存路径：`./static/models/{subject_name}/{model_name}_transmat.txt`
* 参数配置文件
  * train_info.yml
    * sessions：训练分类器所用数据列表
    * hmm_sessions：训练HMM所有数据列表，建议使用自由抓握范式数据
    * ori_epoch_length：不同事件的持续时长。对于抓握任务，一般设为1.5s（不考虑实际时长）
  * val_info.yml
    * sessions：测试分类器所用数据列表
    * ori_epoch_length：不同事件的持续时长。对于抓握任务，一般设为1.5s（不考虑实际时长）
  * model_config.yml
    * 模型频带配置，参见如下示例：
    ```yaml
    baseline:
        freqs: [20, 150, 15]
    riemann:
        lf_bands: 
            - [25, 35]
        hg_bands: 
            - [55, 95]
    ```

### 模型评估
* validation.py 片段层面评估
  * `--subj`: 受试名
  * `--model-filename`: 分类模型的文件名，不需要前置路径
  * 运行结果为数据ersd图，分类混淆矩阵图，保存在受试data文件夹下，以及AUC, accuracy, f1-score等指标
* online_sim.py 事件层面评估
  * `--subj`: 受试名
  * `--state-change-threshold`: 状态切换阈值，只有HMM似然概率大于该阈值才会切换状态
  * `--state-trans-prob`: 状态切换概率，如果没有运行过HMM拟合，则使用该处输入定义HMM中的状态转移概率
  * `--momentum`: 概率平滑系数，数值越大概率约平滑
  * `--model-filename`: 分类模型的文件名，不需要前置路径
  * 运行结果包括使用了HMM和未使用HMM的预测状态转移图、precision, recall, f1-score, accuracy等指标

### 
