Imported from yf8578/cfdna-motif-tss-pipeline (
AGENTS.md). Install upstream withnpx skills add yf8578/cfdna-motif-tss-pipeline. Copyright stays with the author.
AGENTS.md
本文件用于帮助 clone 仓库后的 AI agent 快速理解项目。开始修改前必须先阅读 README.md
和本文件。
项目目标
本仓库计算 35 bp 单端 NIPT/cfDNA BAM 的特征:
- 参考基因组 5′ end motif count、frequency 和 MDS。
- 可选的单端 read-span TSS coverage、中心覆盖和中心/背景比。
- 两列 TSV 驱动的批量 motif 计算、矩阵合并、QC 汇总、并行和安全断点续跑。
本仓库不负责 FASTQ 比对、样本发现/清单生成、数据下载、临床解释或下游模型训练。
数据类型和不可改变的语义
- 目标数据是约 35 bp 的 single-end NIPT/cfDNA reads。
- 正链 motif:参考序列
[reference_start, reference_start + k)。 - 负链 motif:参考序列
[reference_end - k, reference_end)的反向互补。 - motif 来自参考 FASTA,不是直接截取 read sequence。
- paired-end BAM 不会重建 fragment;两个 mate 会作为独立 read 处理。
- TSS coverage 使用
read.get_blocks()返回的实际 aligned blocks,不使用假定片段长度延伸。 - 负链 TSS profile 必须翻转,使负坐标代表转录上游,正坐标代表转录下游。
- BAM/FASTA 参考版本和所用 contig 长度必须一致,不允许静默继续。
若需求会改变以上任一语义,必须在实现前明确告诉使用者,并同步修改 README、测试和版本。
参数责任
参数由使用者选择,程序不自动推断最佳阈值。未显式设置的参数使用 AnalysisConfig 默认值:
AnalysisConfig(
k=4,
min_mapq=20,
max_nm=2,
keep_duplicates=False,
canonical_only=True,
ignore_truncation=False,
reference_backend="auto",
tss_window=1000,
tss_mid_start=-250,
tss_mid_end=250,
)
这些默认值仅是 35 bp 单端 NIPT 的起始建议。不要把默认参数描述成跨平台、跨 read 长度或 跨研究的唯一标准。任何默认值变更必须同时更新:
cfdna_features/analysis.py- CLI parser/help
- README 参数表和实例
- safe-resume provenance 校验
- 相应测试
核心文件
| 文件 | 职责 |
|---|---|
cfdna_features/analysis.py |
AnalysisConfig、结果对象和高层 analyze_sample() |
cfdna_features/motif.py |
FASTA 访问、read 过滤、motif 提取、过滤原因统计 |
cfdna_features/tss.py |
TSS BED 解析、方向统一的 read-span coverage |
extract_motif_batch.py |
TSV 解析、单样本输出、矩阵、并行、锁和断点续跑 |
tests/ |
toy BAM/FASTA 行为测试和 CLI 端到端测试 |
.github/workflows/tests.yml |
Python 3.10/3.12 CI |
公共调用接口
Python 高层入口:
from cfdna_features import AnalysisConfig, analyze_sample
result = analyze_sample(
"sample.bam",
"reference.fa",
config=AnalysisConfig(k=4, min_mapq=20, max_nm=2),
)
批处理入口:
python extract_motif_batch.py \
-i samples.tsv -r reference.fa -o results \
--k 4 --min-mapq 20 --max-nm 2 \
--workers 4 --skip-existing
安装后等价入口为 cfdna-motif-batch。
批处理输入输出约束
输入 TSV 只有两列:sample 和 bam。不要重新加入样本清单生成或目录自动发现逻辑。
每个成功样本必须产生:
<sample>.motif.<k>mer.tsv
<sample>.motif.<k>mer.summary.tsv
每批必须产生:
motif.<k>mer.frequency_matrix.tsv
motif.<k>mer.count_matrix.tsv
motif.<k>mer.batch_summary.tsv
矩阵中的样本顺序必须与输入 TSV 一致。失败样本进入 batch summary,但不进入特征矩阵。
过滤统计约束
过滤原因互斥,每条 read 只属于第一个失败原因。对于未使用 limit 的标准批处理,应满足:
total_reads_seen == motif_records + sum(filter_counts.values())
reads_passing_filters == motif_records + motif_extraction_rejections
新增或改变过滤原因时,必须同步更新 safe-resume 校验、单样本 summary、batch summary、README 和 synthetic BAM 测试。
安全断点续跑约束
--skip-existing 不能只判断文件是否存在。只有以下条件全部满足才能跳过:
- 软件版本一致。
- BAM/FASTA 路径、大小和纳秒修改时间一致。
- 计算参数一致。
- motif 行顺序、count、frequency 均有效。
- summary 必需字段齐全。
- count、frequency、MDS、read totals 和 filter totals 内部一致。
- 不接受 NaN、Infinity、负 count/frequency 或截断文件。
如果无法证明旧结果完整,应重新计算。
并发和文件安全
- 单次批处理可以按样本并行,但同一输出目录只允许一个批任务。
- 不得移除输出目录 advisory lock,除非提供同等或更强的跨进程保护。
extract_motif_batch.py的批处理输出必须先写随机、独占创建的同目录临时文件,再原子 替换最终文件;不得退回可预测临时文件名或跟随预置 symlink。- 大小写或 Unicode 归一化后会映射到同一输出名的样本必须拒绝。
- 失败重跑不得留下看起来有效的旧样本结果。
隐私和仓库卫生
禁止提交:
- 真实患者/样本清单和标识。
- BAM、CRAM、FASTQ、真实参考 FASTA。
- 本机绝对路径、挂载盘路径或云端内部路径。
real_test_output/、日志和生成矩阵。- 密钥、token、凭据或私有服务地址。
示例必须使用 sample01、/data/... 等虚构值。用户明确提供的真实数据可以在本地测试,
但结果应留在 git 忽略目录中。
修改流程
- 明确修改的是 motif 核心、TSS 核心还是批处理编排。
- 先添加或更新可观察行为测试。
- 只在对应模块实现,避免在 CLI 中复制核心算法。
- 运行目标测试,再运行全部测试。
- 更新 README、版本和输出 provenance(若行为或格式改变)。
- 构建 wheel 并确认
cfdna-motif-batchentry point 仍存在。 - 检查 diff,确认没有真实路径、样本和输出被加入。
必须执行:
python -m unittest discover -s tests -v
python -m compileall -q cfdna_features extract_motif_batch.py
python -m pip wheel . --no-deps --wheel-dir dist
git diff --check
已知限制
- 当前 batch CLI 只批量计算 motif;TSS 通过 Python
analyze_sample(..., tss_bed=...)调用。 - 输入指纹使用路径、大小和修改时间,不是全文件加密哈希。
- MDS、MAPQ 和 NM 默认值需要在正式队列中进行技术验证。
- 机械盘、NAS 和共享存储上的最佳 worker 数必须实测,不能只按 CPU 核数决定。
- TSS coverage 未自动进行 GC bias 校正或表达量推断。
cfdna_features.tss.write_tss_outputs()仍使用旧式 PID 临时文件;若扩展或公开依赖该写文件 辅助函数,应改用与批处理相同的随机、独占创建和 symlink-safe 原子写入方式。
