为了满足 NCBI 的严格要求,并体现所有序列均为环状(circular),我们需要在 FASTA 头部添加 [topology=circular]。同时,我为你设计了一套符合国际命名规范的质粒名称(以 p 开头,结合亚型缩写和编号,去除了连字符以防止 NCBI 解析报错)。
1. 质粒命名设计 (Plasmid Names)
基于你提供的映射表,质粒将被命名为 p{Subtype}_{Number}:
- WT 亚型:
pWT_1,pWT_2… - O 亚型:
pO_1,pO_2… - T 亚型:
pT_1,pT_2… - O-T (O_Trans):
pOT_1,pOT_2… - T-T (WT_Trans):
pTT_1,pTT_2… (去除了连字符以防NCBI解析错误) - S2-O (S2_Dark):
pS2O_1,pS2O_2… - S2-T (S2_Light):
pS2T_1,pS2T_2…
2. 自动化修复脚本
这个 Python 脚本会自动完成以下工作:
- 识别最长的 contig 标记为
[location=chromosome]。 - 将较短的 contig 标记为
[plasmid-name=pXXX_1]。 - 为所有序列(染色体和质粒)添加
[topology=circular]。 - 自动备份原文件为
.original_backup。
在你的 FASTA 文件所在目录下(trycycler-medaka_polished_genomes),创建并运行以下脚本:
nano fix_ncbi_circular.py
复制以下代码,保存并退出 (Ctrl+O, Enter, Ctrl+X):
#!/usr/bin/env python3
import os
import shutil
# 映射文件名到亚型名称
FILE_MAPPING = {
"WT-trycycler-medaka_polished_genome.fa": "WT",
"O-trycycler-medaka_polished_genome.fa": "O",
"T-trycycler-medaka_polished_genome.fa": "T",
"WT_Trans-trycycler-medaka_polished_genome.fa": "T-T",
"O_Trans-trycycler-medaka_polished_genome.fa": "O-T",
"S2_Dark-trycycler-medaka_polished_genome.fa": "S2-O",
"S2_Light-trycycler-medaka_polished_genome.fa": "S2-T"
}
ORGANISM = "Acinetobacter baumannii"
def process_fasta(filepath, subtype):
sequences = []
with open(filepath, 'r') as f:
header = None
seq_parts = []
for line in f:
line = line.strip()
if not line:
continue
if line.startswith('>'):
if header is not None:
sequences.append((header, ''.join(seq_parts)))
# 提取纯净的ID,去掉原来的多余描述
header = line[1:].split()[0]
seq_parts = []
else:
seq_parts.append(line)
if header is not None:
sequences.append((header, ''.join(seq_parts)))
if not sequences:
print(f"⚠️ 文件为空: {filepath}")
return
# 按长度降序排序(最长的是染色体)
sequences.sort(key=lambda x: len(x[1]), reverse=True)
# 备份原文件 (只备份一次)
backup_path = filepath + ".original_backup"
if not os.path.exists(backup_path):
shutil.copy(filepath, backup_path)
# 重写文件
plasmid_idx = 1
with open(filepath, 'w') as out_f:
for i, (hdr, seq) in enumerate(sequences):
if i == 0:
# 最长的序列 -> 染色体
new_hdr = f">{hdr} [organism={ORGANISM}] [location=chromosome] [topology=circular]"
else:
# 较短的序列 -> 质粒
# 将 T-T 转换为 TT 以避免 ID 中的特殊字符问题
safe_subtype = subtype.replace("-", "")
p_name = f"p{safe_subtype}_{plasmid_idx}"
new_hdr = f">{hdr} [organism={ORGANISM}] [plasmid-name={p_name}] [topology=circular]"
plasmid_idx += 1
out_f.write(new_hdr + '\n')
# NCBI 要求序列按 80 个字符一行折叠
for j in range(0, len(seq), 80):
out_f.write(seq[j:j+80] + '\n')
print(f"✅ 成功处理: {filepath} (1 个染色体, {plasmid_idx - 1} 个质粒)")
print("==========================================")
print("🧬 开始格式化 FASTA 文件以符合 NCBI 规范")
print("==========================================")
for filename, subtype in FILE_MAPPING.items():
if os.path.exists(filename):
process_fasta(filename, subtype)
else:
print(f"❌ 未找到文件: {filename}")
print("\n🎉 所有文件格式化完成!现在可以重新上传至 NCBI。")
3. 运行脚本
python3 fix_ncbi_circular.py
4. 脚本运行后的 FASTA 头部示例
脚本会将你的 FASTA 头部修改为完美的 NCBI 格式,例如对于 WT 样本:
>cluster_001_consensus [organism=Acinetobacter baumannii] [location=chromosome] [topology=circular]
ATCGATCG... (80 chars per line)
>cluster_002_consensus [organism=Acinetobacter baumannii] [plasmid-name=pWT_1] [topology=circular]
ATCGATCG... (80 chars per line)
>cluster_005_consensus [organism=Acinetobacter baumannii] [plasmid-name=pWT_2] [topology=circular]
ATCGATCG... (80 chars per line)
5. 重新上传
修改完成后,直接在 NCBI 提交页面的 Files 选项卡中重新上传这 7 个修改后的 .fa 文件。
因为现在每个文件都明确声明了 chromosome、plasmid-name 以及 topology=circular,NCBI 的验证器(Validator)将会直接放行,不会再报 FATAL 错误。
Yes. In the script, all contigs are first sorted by length in descending order:
sequences.sort(key=lambda x: len(x[1]), reverse=True)
Then the naming proceeds in that order:
- Index 0 (longest, ~3.9 Mb) →
[location=chromosome] - Plasmid
_1→ the longest plasmid - Plasmid
_2→ the second‑longest plasmid - …and so on.
Example (WT): if the plasmids are 100 kb, 60 kb and 20 kb, they will be named:
pWT_1= 100 kbpWT_2= 60 kbpWT_3= 20 kb
Note that the output FASTA is also rewritten in this sorted order (chromosome first, then plasmids from largest to smallest), which is a common convention for finished bacterial genomes.
If you would rather have the smallest plasmid = _1 (ascending), just change the plasmid assignment to count from the end:
n_plasmids = len(sequences) - 1
...
else:
p_name = f"p{safe_subtype}_{n_plasmids - plasmid_idx + 1}"
plasmid_idx += 1
But as written, yes — _1 is always the largest plasmid.