socbag-manager 0.0.5
单帧 soc bag 目录的发现与路径解析，仅返回路径信息，不提供文件读写
Requires Python: >=3.10

# socbag-manager

单帧 soc bag 目录的**发现与路径解析**库，仅返回路径信息，不读取/写入文件内容。

## 输入模式（V0.0.4）

| 模式 | 输入含义 | 说明 |
|------|----------|------|
| **multi** | 多 `base_paths` + `bag_path` | 与 V0.0.3 一致：在多数据根下按 priority 查找同一 bag。 |
| **single** | 单一路径（如 `.../static_data`） | 将该路径视为**父目录**，自动扫描其下符合约定的 soc 目录（可配置层级，见下），每个子目录即一个 bag 根。 |

**single 模式输入示例**：`/media/mini/T9/03_single_frame/AB6_HW3_XZB600019/static_data` → 扫描该目录下符合约定的子目录作为 bag 根列表；对每个 bag 根可调用 `resolve_frame_paths_from_bag_root` 等 API，输出格式与 multi 模式一致（`images` / `pcds` 字典）。

**可配置搜索层级**：`discover_bags_under(parent_dir, ..., max_depth=1, min_size_mb=None)` 中，`max_depth=1` 表示仅扫描第一层子目录；`2` 表示两层；`-1` 表示**所有层级**（全递归）。不要求文件夹名称，仅按规则判定（见下）。

## 目录约定与 soc 规则

- **soc 规则**（multi/single 共用）：目录被视为 soc bag 当且仅当：**同时存在 `camera/` 与 `lidar/` 子目录，且该目录总大小 ≥ 阈值（默认 1MB）**。不依赖文件夹名；名称模式 `bag_name_pattern` 为可选过滤。
- **bag 目录**: `{base_path}/{bag_path}/` 或 single 模式下直接为上述符合规则的子目录。
- **相机图像**: `{bag_root}/camera/{camera_name}/data/{sequence}.png`（或 .jpg）
- **雷达点云**: `{bag_root}/lidar/{lidar_name}/pcd/{sequence}.pcd`

## 安装

```bash
pip install socbag-manager
```

## 统一设置

所有 API 基于 `SocbagManagerSettings`，可从代码构造或 YAML 加载（兼容 C03 `base_paths`/`priority_base_path` 与 C04 `data_dirs`/`default_main_dir`）：

```python
from socbag_manager import SocbagManagerSettings

settings = SocbagManagerSettings(
    base_paths={"pandar": "/data/pandar", "at128": "/data/at128"},
    priority_source="pandar",
    bag_name_pattern="*_soc*",
)
# 或
settings = SocbagManagerSettings.from_yaml("/path/to/config.yaml")
```

## 主要 API

- **发现（multi）**: `get_ordered_base_paths`, `discover_bags`, `discover_bags_from_scan_root`, `discover_cameras`, `discover_lidars`, `discover_sequences`
- **发现（single）**: `discover_bags_under(parent_dir, bag_name_pattern="*_soc*", max_depth=1, min_size_mb=None)` — 按层级扫描（`max_depth=1` 仅第一层，`-1` 全部层级）；`discover_sequences_from_bag_root`, `discover_cameras_from_bag_root`, `discover_lidars_from_bag_root`
- **规则**：`soc_rules.is_soc_bag_dir(dir_path, min_size_mb)` — 判定目录是否符合 soc 解构（camera+lidar+大小）
- **路径解析**: `resolve_camera_paths`, `resolve_lidar_paths`, `resolve_frame_paths`（multi）；`resolve_frame_paths_from_bag_root(bag_root, sequence, ...)`（single，输出格式同 `resolve_frame_paths`）
- **候选枚举**: `list_frame_candidates`, `choose_one_candidate`（`CandidatePath`）
- **目录树**: `TreeNode`, `build_folder_tree(settings, scope="roots"|"bags"|"sequences", ...)`

## 使用示例

```python
from socbag_manager import (
    SocbagManagerSettings,
    discover_bags,
    discover_sequences,
    resolve_frame_paths,
    build_folder_tree,
)

settings = SocbagManagerSettings.from_yaml("config.yaml")
bag_names = discover_bags(settings)
sequences = discover_sequences(settings, bag_names[0])
paths = resolve_frame_paths(settings, bag_names[0], sequences[0])
# paths["images"], paths["pcds"]

tree_roots = build_folder_tree(settings, scope="bags")
for root in tree_roots:
    for bag in root.children:
        print(bag.name, bag.path)
```

### single 模式示例

```python
from socbag_manager import (
    discover_bags_under,
    discover_sequences_from_bag_root,
    resolve_frame_paths_from_bag_root,
)

static_data_dir = "/media/mini/T9/03_single_frame/AB6_HW3_XZB600019/static_data"
bag_roots = discover_bags_under(static_data_dir, max_depth=1, min_size_mb=0)  # 第一层级；min_size_mb=0 仅按结构
for bag_root in bag_roots:
    sequences = discover_sequences_from_bag_root(bag_root)
    if sequences:
        paths = resolve_frame_paths_from_bag_root(bag_root, sequences[0])
        # paths["images"], paths["pcds"] 与 multi 模式格式一致
```

YAML 可选配置 single 模式入口：`input_mode: single`、`static_data_dir: /path/to/static_data`（加载后可用 `discover_bags_under(settings.static_data_dir)`）。

## 约束

- 所有接口**仅返回路径**（字符串或树节点中的 path），不读取/解析图像或点云文件。
- 依赖：Python >=3.10，PyYAML。

## 开发与测试

```bash
pip install -e ".[dev]"
python -m pytest tests/ -v
```