我写了一个python脚本,它从CIF文件生成一个字典。我用像[1qpe这样的文件测试了它,有4105行 - >时间:383毫秒(毫秒)]或这个(1d66,有3274行 - >时间:225毫秒),但是当我尝试使用这个(4tvx,170925行)时,需要一个很长一段时间,我决定阻止这个过程。我当时想要拆分CIF文件,从中推断出以ATOM和HETATM开头的行:
实际上,从每个原始CIF文件开始,目的是获得4个文件,最初是:
在这里我解决了,1d66需要34ms,1qpe需要43ms,4tvx需要1.923s。 现在,得到了第三个文件(所有这个过程的目标,因为是字典的输入),我想从它中推断出具有相同第七列的所有行,将它们写在保存有值的专用文件中第7列作为文件名,对第7列的所有值重复此操作。
这是我的代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
import os.path
scriptdir = os.path.dirname(os.path.abspath(__file__))
cif_dir = os.path.join(scriptdir, 'cif/')
def get_line_number(phrase, file_name):
with open(file_name) as f:
for i, line in enumerate(f, 1):
if phrase in line:
return i
def my_header_splitfile(infilepath, chunksize):
fname, ext = infilepath.rsplit('.',1)
with open(infilepath) as infile:
outfilepath = "{}_header.{}".format(fname, ext)
with open(outfilepath, 'w') as outfile:
for line in (infile.readline() for _ in range(0,(chunksize-2))):
outfile.write(line) # END
temp_lines = open(infilepath).readlines()
temp_outfilepath = "{}_temp.{}".format(fname, ext)
atom_hetatm_header_outfilepath = "{}_atom_hetatm_header.{}".format(fname, ext)
with open(atom_hetatm_header_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize-2):(chunksize+25)])
with open(temp_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize+25):-1]) # END
footer_lines = open(temp_outfilepath).readlines()
footer_outfilepath = "{}_footer.{}".format(fname, ext)
with open(footer_outfilepath, 'w') as outfile:
for line in footer_lines:
if not (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
temp_atom_hetatm_lines = open(temp_outfilepath).readlines()
temp_atom_hetatm_outfilepath = "{}_atom_hetatm.{}".format(fname, ext)
with open(temp_atom_hetatm_outfilepath, 'w') as outfile:
for line in temp_atom_hetatm_lines:
if (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
os.remove(temp_outfilepath) # FINISH
"""BEGIN TO SPLIT THE 'ATOM'"""
"""
with open(temp_atom_hetatm_outfilepath,'r') as infile:
lines = infile.readlines()
rows_list = list()
chains_list = list()
for line in lines:
col = line.split(None)
rows_list.append(col)
#print line
#if col[0] == "HETATM":
# print "HETATM record"
if col[0] == "ATOM":
#print col[0]
# FILTER FOR ONLY PROTEINS AND NUCLEIC ACIDS
if (col[3] == "N" or col[3] == "N1"):
chains_list.append(col[6])
chains_list_cleaned = list(set(chains_list))
for chain in chains_list_cleaned:
if col[6] == chain:
atom_chain_outfilepath = "{}_atom_chain_{}.{}".format(fname, chain, ext)
with open(atom_chain_outfilepath, 'w') as outfile:
#outfile.writelines("Hello")
outfile.writelines(line) # END
"""
cif_code = '1d66'.upper() # CHANGE HERE THE PID CODE. i.e. 1D66, 1QPE, 4TVX
filename = '%s%s.cif' % (cif_dir,cif_code.upper())
begin_atom = get_line_number("_atom_site.group_PDB", filename)
#print begin_atom
my_header_splitfile(filename, begin_atom)
如果取消注释最后一行:
""" with open(temp_atom_hetatm_outfilepath,'r') as infile:
lines = infile.readlines()
rows_list = list()
chains_list = list()
for line in lines:
col = line.split(None)
rows_list.append(col)
#print line
#if col[0] == "HETATM":
# print "HETATM record"
if col[0] == "ATOM":
#print col[0]
# LIMITO ALLE SOLE PROTEINE E ACIDI NUCLEICI
if (col[3] == "N" or col[3] == "N1"):
chains_list.append(col[6])
chains_list_cleaned = list(set(chains_list))
for chain in chains_list_cleaned:
if col[6] == chain:
atom_chain_outfilepath = "{}_atom_chain_{}.{}".format(fname, chain, ext)
with open(atom_chain_outfilepath, 'w') as outfile:
#outfile.writelines("Hello")
outfile.writelines(line) # END
"""
您将看到我可以为每个链保存一个文件(例如,生成的' 1d66_atom_hetatm.cif'文件中的第七列),但在每个文件中只写入一行,而不是全部该链的线(第七列)。怎么做到这一点?
谢谢,
的Riccardo
编辑1: 您只需要使用下载的cif文件更改第72行来测试它!
============================================ ========================== 的 =============================================== =======================
编辑2: 这是生成的" 1D66_atom_hetatm.cif"中的内容示例:
ATOM 378 C C8 . DG A 1 19 ? 34.329 11.346 27.800 1.00 29.46 ? ? ? ? ? ? 19 DG D C8 1
ATOM 379 N N7 . DG A 1 19 ? 34.046 11.420 26.537 1.00 31.63 ? ? ? ? ? ? 19 DG D N7 1
ATOM 380 C C5 . DG A 1 19 ? 32.698 11.672 26.542 1.00 26.85 ? ? ? ? ? ? 19 DG D C5 1
ATOM 381 C C6 . DG A 1 19 ? 31.860 11.863 25.447 1.00 26.53 ? ? ? ? ? ? 19 DG D C6 1
ATOM 382 O O6 . DG A 1 19 ? 32.175 11.864 24.251 1.00 32.03 ? ? ? ? ? ? 19 DG D O6 1
ATOM 383 N N1 . DG A 1 19 ? 30.569 12.079 25.868 1.00 23.18 ? ? ? ? ? ? 19 DG D N1 1
ATOM 384 C C2 . DG A 1 19 ? 30.136 12.115 27.159 1.00 23.53 ? ? ? ? ? ? 19 DG D C2 1
ATOM 385 N N2 . DG A 1 19 ? 28.819 12.261 27.325 1.00 19.29 ? ? ? ? ? ? 19 DG D N2 1
ATOM 386 N N3 . DG A 1 19 ? 30.949 11.949 28.200 1.00 26.27 ? ? ? ? ? ? 19 DG D N3 1
ATOM 387 C C4 . DG A 1 19 ? 32.213 11.729 27.819 1.00 25.75 ? ? ? ? ? ? 19 DG D C4 1
ATOM 388 O "O5'" . DC B 2 1 ? 20.466 11.694 21.639 1.00 40.14 ? ? ? ? ? ? 20 DC E "O5'" 1
ATOM 389 C "C5'" . DC B 2 1 ? 21.891 11.609 21.791 1.00 29.52 ? ? ? ? ? ? 20 DC E "C5'" 1
ATOM 390 C "C4'" . DC B 2 1 ? 22.246 11.659 23.274 1.00 28.85 ? ? ? ? ? ? 20 DC E "C4'" 1
ATOM 391 O "O4'" . DC B 2 1 ? 23.643 11.328 23.562 1.00 27.78 ? ? ? ? ? ? 20 DC E "O4'" 1
ATOM 392 C "C3'" . DC B 2 1 ? 22.093 13.078 23.713 1.00 26.83 ? ? ? ? ? ? 20 DC E "C3'" 1
ATOM 393 O "O3'" . DC B 2 1 ? 21.761 13.021 25.064 1.00 26.10 ? ? ? ? ? ? 20 DC E "O3'" 1
ATOM 394 C "C2'" . DC B 2 1 ? 23.541 13.575 23.586 1.00 27.66 ? ? ? ? ? ? 20 DC E "C2'" 1
ATOM 395 C "C1'" . DC B 2 1 ? 24.295 12.435 24.176 1.00 21.82 ? ? ? ? ? ? 20 DC E "C1'" 1
我想在1d66_A.txt文件中保存第7列中的A(从0开始),以及1d66_B.txt文件中第7列中包含B的所有行,依此类推从脚本生成的该文件的第七列的值。
最终输出应为:
文件1D66_A.txt:
ATOM 378 C C8 . DG A 1 19 ? 34.329 11.346 27.800 1.00 29.46 ? ? ? ? ? ? 19 DG D C8 1
ATOM 379 N N7 . DG A 1 19 ? 34.046 11.420 26.537 1.00 31.63 ? ? ? ? ? ? 19 DG D N7 1
ATOM 380 C C5 . DG A 1 19 ? 32.698 11.672 26.542 1.00 26.85 ? ? ? ? ? ? 19 DG D C5 1
ATOM 381 C C6 . DG A 1 19 ? 31.860 11.863 25.447 1.00 26.53 ? ? ? ? ? ? 19 DG D C6 1
ATOM 382 O O6 . DG A 1 19 ? 32.175 11.864 24.251 1.00 32.03 ? ? ? ? ? ? 19 DG D O6 1
ATOM 383 N N1 . DG A 1 19 ? 30.569 12.079 25.868 1.00 23.18 ? ? ? ? ? ? 19 DG D N1 1
ATOM 384 C C2 . DG A 1 19 ? 30.136 12.115 27.159 1.00 23.53 ? ? ? ? ? ? 19 DG D C2 1
ATOM 385 N N2 . DG A 1 19 ? 28.819 12.261 27.325 1.00 19.29 ? ? ? ? ? ? 19 DG D N2 1
ATOM 386 N N3 . DG A 1 19 ? 30.949 11.949 28.200 1.00 26.27 ? ? ? ? ? ? 19 DG D N3 1
ATOM 387 C C4 . DG A 1 19 ? 32.213 11.729 27.819 1.00 25.75 ? ? ? ? ? ? 19 DG D C4 1
文件1D66_B.txt:
ATOM 388 O "O5'" . DC B 2 1 ? 20.466 11.694 21.639 1.00 40.14 ? ? ? ? ? ? 20 DC E "O5'" 1
ATOM 389 C "C5'" . DC B 2 1 ? 21.891 11.609 21.791 1.00 29.52 ? ? ? ? ? ? 20 DC E "C5'" 1
ATOM 390 C "C4'" . DC B 2 1 ? 22.246 11.659 23.274 1.00 28.85 ? ? ? ? ? ? 20 DC E "C4'" 1
ATOM 391 O "O4'" . DC B 2 1 ? 23.643 11.328 23.562 1.00 27.78 ? ? ? ? ? ? 20 DC E "O4'" 1
ATOM 392 C "C3'" . DC B 2 1 ? 22.093 13.078 23.713 1.00 26.83 ? ? ? ? ? ? 20 DC E "C3'" 1
ATOM 393 O "O3'" . DC B 2 1 ? 21.761 13.021 25.064 1.00 26.10 ? ? ? ? ? ? 20 DC E "O3'" 1
ATOM 394 C "C2'" . DC B 2 1 ? 23.541 13.575 23.586 1.00 27.66 ? ? ? ? ? ? 20 DC E "C2'" 1
ATOM 395 C "C1'" . DC B 2 1 ? 24.295 12.435 24.176 1.00 21.82 ? ? ? ? ? ? 20 DC E "C1'" 1
我试图以最好的方式解释自己,抱歉,谢谢你的帮助。
这些步骤是连接起来的,所以我不能分割脚本:你可以尝试一下......问题只是我想要获得编辑2中所说的内容,即阅读第6列(从0开始,在那里读取AAAAAAABBBBBB,在该示例中),将包含A的所有行复制到名为" 1d66_A.txt"的文件中。以及包含B的所有行,在另一个文本文件" 1d66_B.txt"中,就像编辑2.要测试我所做的,只需将该脚本复制并粘贴到带有扩展名的文本文件中。 py(例如my_script.py);在该脚本的同一文件夹中,创建一个文件夹" cif"并从这些链接下载一个cif文件(例如,如果你不想编辑脚本的第72行,则为1d66);最后使用命令" python my_script.py"在shell中运行脚本。 (我使用Linux):该脚本生成四个文件。在本主题中,我将自己引用到生成的" 1d66_atom_hetatm.cif"文件,我想按照我的说法拆分," 1d66_A.txt"," 1d66_B.txt"," 1d66_C.txt"," 1d66_D .TXT" (4个文件,因为在1d66中,以ATOM开头的所有行的第6列(从0开始)有4个不同的字母),例如 EDIT 2 。
============================================ ========================== 的 =============================================== =======================
编辑3 - @qwwqwwq
我会尝试用文字来解释剧本;假设这个序列:
HHHHH LLLLL的 AAAAA BBBBB的 FFFFF
这是一个CIF文件的起点和终点的方案,我已经对我做过,在cthon文件合理化之前在python中详细说明,其中:
H = header
L = loop for ATOM and HETATM rows
A = chain A (= column 7) in ATOM
B = chain B (= column 7) in ATOM
F = footer
现在,我需要拆分通用cif文件的所有这些部分;要做到这一点,我写这个脚本,现在可以生成:
H
L
A+B
F
所以我需要将A从B中拆分掉! 为什么我使用临时文件?让我解释;这些步骤:
现在,对于A,B和F,我使用了那个临时文件(临时文件,因为我最后删除了它)。我从循环结束时生成临时文件[=(" begin_atom" +26),即25,因为范围从0开始到文件末尾(行" -1& #34;),并将其保存为临时文件,用作写入页脚的输入(F);怎么做?使用构造:
if not (line.startswith('ATOM') or line.startswith('HETATM'))
所以我现在也可以保存页脚了!
现在仍然要拆分以ATOM和HETATM开头的记录中的所有链(列7),为此我打开了这个主题。我想我在编辑中编写的内容2.实际上,链(第7列)只能是一个(如文件1QPE中)或许多(如4TVX文件中,有22个链,即22个不同的字母)在以ATOM或HETATM开头的每一行的第7列中。
我在我的脚本中尝试了这种注释方式(参见编辑1 之前),它为每个链保存一个文件(第7列中的不同字母),但在每个文件中只有一个ATOM行是写的.....我希望我已经清楚而正确地表达了自己
============================================ ========================== 的 =============================================== =======================
已解决 - 感谢@qwwqwwq
@qwwqwwq :-)谢谢。我一直在寻找" cif"输出文件夹,没有意识到,在对代码进行小编辑后(参见我的编辑),脚本将文件保存在同一文件夹中:-D。完美!
最终版本:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
import os.path
scriptdir = os.path.dirname(os.path.abspath(__file__))
cif_dir = os.path.join(scriptdir, 'cif/')
def get_line_number(phrase, file_name):
with open(file_name) as f:
for i, line in enumerate(f, 1):
if phrase in line:
return i
def my_header_splitfile(infilepath, chunksize):
fname, ext = infilepath.rsplit('.',1)
with open(infilepath) as infile:
outfilepath = "{}_header.{}".format(fname, ext)
with open(outfilepath, 'w') as outfile:
for line in (infile.readline() for _ in range(0,(chunksize-2))):
outfile.write(line) # END
temp_lines = open(infilepath).readlines()
temp_outfilepath = "{}_temp.{}".format(fname, ext)
atom_hetatm_header_outfilepath = "{}_atom_hetatm_header.{}".format(fname, ext)
with open(temp_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize+25):-1]) # END
with open(atom_hetatm_header_outfilepath, 'w') as outfile:
outfile.writelines(temp_lines[(chunksize-2):(chunksize+25)])
footer_lines = open(temp_outfilepath).readlines()
footer_outfilepath = "{}_footer.{}".format(fname, ext)
with open(footer_outfilepath, 'w') as outfile:
for line in footer_lines:
if not (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
temp_atom_hetatm_lines = open(temp_outfilepath).readlines()
temp_atom_hetatm_outfilepath = "{}_atom_hetatm.{}".format(fname, ext)
with open(temp_atom_hetatm_outfilepath, 'w') as outfile:
for line in temp_atom_hetatm_lines:
if (line.startswith('ATOM') or line.startswith('HETATM')):
outfile.writelines(line) # END
"""NEW ENTRY"""
with open(temp_atom_hetatm_outfilepath) as infile:
for line in infile:
if line.startswith("ATOM"):
atom_chain_outfilepath = "{}_atom_chain_{}.{}".format(fname, line.split()[6], ext)
with open(atom_chain_outfilepath, "a") as outfile:
outfile.write(line)
elif line.startswith("HETATM"):
atom_chain_outfilepath = "{}_hetatm_chain_{}.{}".format(fname, line.split()[6], ext)
with open(atom_chain_outfilepath, "a") as outfile:
outfile.write(line)
os.remove(temp_outfilepath) # REMOVE "temp_outfilepath"
os.remove(temp_atom_hetatm_outfilepath) # REMOVE "temp_atom_hetatm_outfilepath" - FINISH
cif_code = '1d66'.upper() # CHANGE HERE THE PID CODE. i.e. 1D66, 1QPE, 4TVX
filename = '%s%s.cif' % (cif_dir,cif_code.upper())
begin_atom = get_line_number("_atom_site.group_PDB", filename)
#print begin_atom
my_header_splitfile(filename, begin_atom)
现在您需要编辑PID条目的第55行(即1d66,1qpe,4tvx,...,从Protein Data Bank下载)。
答案 0 :(得分:1)
很难说出你在这里问的是什么,对不起。提供适合您问题正文的样本输入和输出将有很长的路要走。
听起来您想要根据文件第六列中的值拆分文件。
我会做类似的事情:
def meets_criteria(line):
return line.startswith("ATOM") or line.startswith("HETATM")
with open(large_file) as f:
for line in f:
if meets_criteria(line):
with open(line.split()[6], "a") as of:
of.write(line)
因此,您将拥有以第6列(0索引)中的值命名的文件。
您似乎正在使用.readlines
方法,请注意这会将所有数据读入内存,没有理由这样做,这可能就是您的脚本挂在大输入上的原因。< / p>