RELION *.star坐标文件 与 EMAN1.9版本的 *.box文件 格式互转换
基于RELION 3.1.0中star坐标文件格式编写
RELION 和EMAN 中图像的坐标原点不同:relion是图像的中心为原点,而eman是以图像的左上角为原点,所以转换时要注意变换关系(相差 boxsize/2)。
1 *.star 文件转 *.box文件
运行后
目录截图:
![](https://img-blog.csdnimg.cn/691036e11aaf4780bccc827156e57127.png)
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 22 15:30:48 2021
@author: junquan
"""
import json
import os
#本程序与 *.star 文件放置同一文件夹下运行
boxsize=60 #手动设置boxsize
#==============================read================================================
def readstar(starfileName):
with open(starfileName,'r',encoding='utf8')as fp:
xylist=[]
for line in fp.readlines()[11:]:
xy_val=line.split()[0:2]
x=xy_val[0]
y=xy_val[1]
xylist.append([x,y])
print(xylist)
return xylist
#==============================write==============================================
def writeBox(xylist,starfileName):
boxfilename=starfileName.replace("_manualpick.star",".box")
with open(boxfilename,"w") as fp:
for ln in xylist:
x=int(float(ln[0])-boxsize/2)
y=int(float(ln[1])-boxsize/2)
if x>=0 and y>=0:
fp.write(str(x)+" "+str(y)+" "+str(boxsize)+" "+str(boxsize)+" -3 \n")
print("写入成功")
else:
print("pick out")
#=========================================================================
cFileNumber = 0
dir = cur_path = os.getcwd() #指定文件夹的路径
if not os.path.exists("boxs"):
os.makedirs("boxs")
for root, dirs, files in os.walk(dir): #遍历该文件夹
for file in files:
(starfileName, extension) = os.path.splitext(file)
if (extension == '.star'):
cFileNumber= cFileNumber+1
#print(cFileNumber, os.path.join(root,filename))
print("文件名(" + starfileName + ')')
xylist=readstar(file)
os.chdir("boxs")
writeBox(xylist,file)
os.chdir("../")
运行该程序时,需要手动改 boxsize 的值
2 *.box文件 转 *.star 文件
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Jun 29 15:16:48 2021
@author: junquan
"""
import os
# star文件中的文件头(relion 3.1.0)
headstr="\n\
# version 30001\n\
\n\
data_\n\
\n\
loop_ \n\
_rlnCoordinateX #1 \n\
_rlnCoordinateY #2 \n\
_rlnClassNumber #3 \n\
_rlnAnglePsi #4 \n\
_rlnAutopickFigureOfMerit #5 \n"
#================================read=========================
def readXY(file):
with open(cur_path+'/'+file,'r',encoding='utf8')as fp:
xylist=[]
for line in fp.readlines()[0:]:
xy_val=line.split()[0:2]
xylist.append(xy_val)
return xylist
#================================write=========================
def writeXY(xylist,filename):
starfile=filename+after_suffix
if os.path.exists(starfile):
print("文件已存在")
fp = open(starfile,"w")
else:
fp = open(starfile,"w")
fp.write(headstr)
print("head写入成功")
if xylist==[]:
print("没框")
with open('result.txt','a')as f:
f.write("\n没框的文件:"+filename+before_suffix)
f.close()
else:
for each in xylist:
xi=int(float(each[0])+boxsize/2)
yi=int(float(each[1])+boxsize/2)
x=format(xi,".6f")
y=format(yi,".6f")
lx=x.rjust(12) #数据右对齐
ly=y.rjust(12)
print(lx+" "+ly+" 2 -999.00000 -999.00000 ")
fp.write(lx+" "+ly+" 2 -999.00000 -999.00000 \n")
fp.close()
#=================================main==============================
boxsize==int(input("eman的box大小,即.box文件中的第三列数值:")) #即.box的第三列数值,因为eman记录box左上角的坐标,而relion记录的是box中心的坐标
before_suffix=".box"
after_suffix="_manualpick.star"
cFileNumber = 0
dir = cur_path = os.getcwd()
if not os.path.exists("starx"):
os.makedirs("starx")
for root, dirs, files in os.walk(dir): #遍历该文件夹
for file in files:
(filename, extension) = os.path.splitext(file)
if (extension == before_suffix): #判断该后缀是否为.box文件
cFileNumber= cFileNumber+1
#print(cFileNumber, os.path.join(root,filename))
#print("文件名(" + filename + ')')
xylist=readXY(filename+before_suffix)
#print(xylist)
os.chdir("starx")
writeXY(xylist,filename)
os.chdir("../")
注意
:Linux系统和window系统的文档中 回车符 格式不同,在window下运行代码生成的文档,Linux系统下可能识别会有问题,反之亦然。