ABE8e四种distance的特征筛选

1. 结构复核与处理
从原始CIF重算确认：PT14_L20/model_1位置1跨链C–C距离1.909137 Å，相关原子pLDDT为27.40/34.76；S12_L16_17/model_3位置9距离1.336289 Å，pLDDT为38.83/66.16。两对残基PAE分别为13.0/9.9 Å、13.1/8.6 Å。两结构has_clash均为0，但该指标不能排除局部少量碰撞。
本轮将“第1–20位到另一整条DNA链的最小C–C距离<2 Å”设为严重近接触筛查规则。这是本项目保守的几何QC规则，不是AF3官方阈值或完整的原子碰撞检查。
clean：剔除触发规则的完整候选结构，其所有20个位点、四种distance共同剔除；不删除target或实验样本。当前恰好剔除两个结构，178个结构、3560条逐模型位置记录，36个条件仍保留；两个条件n_models=4，其余=5。
all：保留全部180个结构作为敏感性分析，不能按哪套成绩更好来选择QC策略。
S12还有2.02 Å和2.33 Å近接触，未触发本轮<2 Å规则；不能据此宣称其余结构已完全通过物理质量检查。当前最短长度组仍有较高结构不确定性。不按SD大小选择性剔除候选，以免把真实预测分歧隐藏。
structure_contact_review.tsv包含两组共10个结构的最短接触及置信度。

2. 筛选目标及范围
使用统一的轻量HistGradientBoostingRegressor进行受控比较。结果用于distance初筛，不能当作CRISPRon-BE最终模型成绩。入选特征需回到原CRISPRon-BE架构做确认。
共9组：baseline（序列、outcome mask、长度、CRISPRoff/CRISPRon评分）；baseline+四种绝对distance（分别）；baseline+四种Δdistance（分别）。本轮不搜索特征组合或逐位点子集。
每种distance提供完整20位曲线及第3–10位曲线×outcome mask交互项。Δdistance=同一target当前长度距离−L20距离；L20的Δ为0。不同编辑器必须使用该编辑器自己的L20作为参照。
输入outcome_pos3–10仅描述待预测编辑组合，是已知候选产物编码；不输入实验editing_efficiency、outcome_frequency_sd或target编号。标签为outcome_frequency，单位百分比（0–100）。不执行bystander筛选。
沿用既有outcome表：第3–10位所有可编辑A的非空A→G组合，包括频率为0的组合。未编辑产物和窗口外产物不纳入本轮评分；不能声称覆盖全部类型的测序产物。本轮不更改旧产物计数口径。
原模型表sgRNA_length_numeric作为基线长度变量保留。审计表的真实spacer/连续匹配长度仅用于核对，不静默替换原长度变量。

3. 数据划分与指标
外层12折LOTO：每次1个target全部长度与产物作为测试，其余11个用于训练和内部筛选。
内层3折GroupKFold：只在外层训练target内比较9组特征。同一target始终不跨训练/验证。固定回归器参数，不进行额外调参；early_stopping关闭，避免内部随机按行留验证集。
训练时各实验条件总权重相等。主指标为每条件先计算outcome MAE、再在target内平均、最后跨target平均，单位百分点。提供汇总MAE/RMSE和Pearson/Spearman作为辅助指标。
每种候选均输出外层预测以作比较；nested_selected每折使用内层选出的特征，是评价整个筛选流程的成绩。不能从外层成绩挑出最佳候选后，把它的同一外层成绩当作完全独立的最终验证。
预测截断到[0,100]；若某条件所有非空产物预测总和>100，则等比例缩放到100。不使用该条件真实editing_efficiency进行归一化。不同候选使用同一后处理。
本轮数据曾用于此前研发，所以嵌套划分不能抹去此前研发选择对该数据的接触。新的独立target仍是最终外部验证的更强证据。

4. 运行
依赖：numpy、pandas、scipy、scikit-learn。无需GPU；脚本默认每进程数值线程为1。
bash run_abe8e.sh /path/to/current_outcome_model_table.tsv /path/to/distance_per_model.tsv /path/to/structure_audit.tsv /path/to/feature_selection_results
建议使用服务器当前确认过的canonical outcome表。包中的outcomes_reference_20260826.tsv是此前上传的修订版abe8e_outcome_model_table(1).tsv，含984行、36条件、12target；用于接口验证和可复现参考，不保证是服务器后续更新后的最终版本。若替换为当前表，必须维持相同的列与产物口径。
单折检查：
python select_distance_features.py --outcomes /path/to/outcomes.tsv --per-model /path/to/distance_per_model.tsv --audit /path/to/structure_audit.tsv --editor ABE8e --qc-mode clean --outer-target ABE25 --iterations 30 --outdir /path/to/smoke
完整运行省略--outer-target及--iterations，使用默认150轮。单折检查仅验证程序，不能用于筛选结论。

5. 后续编辑器接口
每次选一个editor独立运行，同架构比较。outcome表可含editor列（如ABE8e、TeABE、D699）；没有此列时，整个输入表必须只属于--editor指定的一种编辑器。
distance-map.tsv列：editor、target_id、length_group_id、af3_condition_id。
ABE8e会从job_name自动构建映射，也会输出distance_map.tsv。其它编辑器可显式传--distance-map路径，af3_condition_id对应其距离文件condition_id，不要求AF3任务名沿用ABE8e命名。每次输入对应编辑器的per-model和audit文件，程序会核对target_20mer与protospacer20。
若暂时共用一套参考结构，需主动提供该映射并在论文中注明；本代码不会自动把ABE8e距离复制为其它编辑器的特异结构。
新结构无需重写筛选逻辑，只需换距离表、审计表及映射。默认要求两条完全互补DNA和当前相同的20nt目标定位口径，距离表由已有提取程序生成。

6. 输出
feature_selection_summary.tsv：两种QC模式的候选指标、内层入选折数、优于baseline的target数量。
qc_sensitivity.tsv：相同候选在clean/all之间的MAE变化。
clean/或all/内：distance_features.tsv（四种距离及SD）、flagged_structures.tsv、distance_map.tsv、inner_scores.tsv、selected_features_by_fold.tsv、outer_predictions.tsv、metrics.tsv、metrics_by_target.tsv、run_settings.json。
先检查clean是否为36条件、2条件各4个结构，再检查每种候选是否均预测了12个target；这些完成后再解释特征排序。

参考
AlphaFold3补充方法说明has_clash为整体阈值标记，可存在未触发标记的少量局部碰撞：https://www.nature.com/articles/s41586-024-07487-w
嵌套交叉验证：https://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html
