FQC 文件格式
.fqc 格式是 fq-compressor 的自定义归档格式,专为高压缩、随机访问和并行处理设计。
格式布局
┌─────────────────────────────────────────────┐
│ 文件头 (64 bytes) │
│ ├─ 魔数 (8 bytes): "FQC\x00\x01" │
│ ├─ 版本号 │
│ ├─ 标志位(PE、重排序等) │
│ └─ 全局元数据 │
├─────────────────────────────────────────────┤
│ Block 1(例如 10 MB 未压缩) │
│ ├─ Block 头 (32 bytes) │
│ │ ├─ Block 大小 / CRC32 │
│ │ └─ Block 内 read 数量 │
│ ├─ ID 流(Delta + Tokenized) │
│ ├─ 序列流(ABC 编码) │
│ └─ 质量流(SCM 编码) │
├─────────────────────────────────────────────┤
│ Block 2 │
├─────────────────────────────────────────────┤
│ ... │
├─────────────────────────────────────────────┤
│ 重排序映射(可选) │
│ ├─ ZigZag varint 编码 │
│ └─ 压缩顺序 → 原始顺序映射 │
├─────────────────────────────────────────────┤
│ Block 索引 │
│ ├─ Block ID → 文件偏移映射 │
│ └─ 支持 O(1) 随机访问 │
├─────────────────────────────────────────────┤
│ 文件尾 (32 bytes) │
│ ├─ 总 read 数 │
│ ├─ 索引偏移 │
│ └─ 文件校验和 │
└─────────────────────────────────────────────┘
设计理念
列式流分离
每个 block 内部,数据被物理分离为三个独立流:
| 流 | 内容 | 压缩方式 |
|---|---|---|
| ID 流 | Read 标识符 | Tokenization + Delta |
| 序列流 | DNA 碱基(A/C/G/T/N) | ABC 或 Zstd |
| 质量流 | Phred 质量分数 | SCM 算术编码 |
确保每种流使用最适合其数据类型的算法。
Block 独立性
每个 block 完全自包含:
- 压缩模型在 block 边界处重置
- 各 block 可以并行解压,无依赖关系
- 损坏的 block 不影响其他 block
随机访问
文件末尾的 block 索引将逻辑 read 范围映射到文件偏移:
Read 0-9999 → Block 0 在偏移 64
Read 10000-19999 → Block 1 在偏移 1048640
Read 20000-29999 → Block 2 在偏移 2097216
...
要访问第 15000-16000 条 reads,fq-compressor:
- 在索引中查找 Block 1 — O(1)
- 跳转到 block 偏移位置
- 仅解压 Block 1
- 提取请求的 reads
重排序映射
启用 ABC 重排序时,原始 read 顺序保存在重排序映射中:
- 使用 ZigZag varint 编码紧凑存储
- 允许解压后恢复原始 FASTQ 顺序
- 如不需要保留顺序则可跳过
为什么不使用现有格式?
| 格式 | 局限性 |
|---|---|
| BAM/CRAM | 需要参考基因组;为比对数据设计 |
| BGZF | 仅 block 级压缩;无领域特定建模 |
| gzip/xz | 无随机访问;无列式分离 |
.fqc 格式结合了这些格式的最佳思路,同时为原始 FASTQ 数据添加了领域特定的压缩能力。