【问题标题】:How to add space between PDB coordinates only when there is no space in between?仅当两者之间没有空格时,如何在 PDB 坐标之间添加空格?
【发布时间】:2019-09-04 18:46:00
【问题描述】:

当任意两个 XYZ 坐标之间没有空格时,我使用的软件不接受输入。例如,“38.420 -6.206-108.383”只有写成“38.420 -6.206 -108.383”才能处理。 由于我有 1000 多个 PDB 文件要处理,每个文件都包含数百行坐标,我迫切需要一种有效的方法来检测是否需要在任意两个坐标之间添加空格,如果是,插入一个空间。 插入空格后,“.inp”文件中的旧坐标需要替换为新坐标作为输入。

我怎么可能使用 python 实现这一点?

我尝试手动更改坐标,但后来意识到这几乎是不可能的......下面的代码确实有效,但它只粘贴原始坐标而不在必要时插入空格。

目前的代码如下:

'''

input = open("hole.inp").readlines()
old_cpoint = input[16][7:29]

for i in range(1002):
    with open(dir + str(i) + '.pdb') as file:
        c = file.readlines()
        new_cpoint = c[2849][31:54]

        f_a = open("hole_"+str(i)+".inp").read()
        f_a = f_a.replace(str(old_cpoint),str(new_cpoint))
        f_b = open("hole_"+str(i)+".inp", 'w')
        f_b.write(f_a)
        f_b.close()

'''

【问题讨论】:

  • 坐标总是有破折号吗?如果他们没有破折号,你怎么知道“38.4206.206108.383”中的x、y和z是什么——你能对这些坐标的长度做出任何假设吗?例如,如果点后面总是有 3 位数字,或者破折号总是在那里(我可以快速发布解决方案),这是可能的。如果你不能区分每个坐标的开始/结束,我认为这是不可能的。
  • 是的。通常坐标如下所示: "30.604 -29.297 76.055" 小数点后始终保留 3 位;并且大多数时候之间有1-2个空格。唯一的例外是当两列有一个“-”符号时,它会占用原始示例中所示的空间。提前感谢 Kacper!
  • 更正:当有两个“-”符号且一个坐标在小数点前有 3 位时,空格会被填满。

标签: python formatting coordinates biopython pdb


【解决方案1】:

解决方案

请查看此解决方案 - 希望它足以成功解析您的所有数据。您应该使用parse_coordinates 函数。我试图对 cme​​ts 明确表示,但如果有不清楚的地方请告诉我!

# Declare the string separator to insert it between the coordinates
SEPARATOR = " "

# Declare the offset - there are always 3 digits after the dots - it will be used to distinguish each coordinate
OFFSET = 3


def parse_coordinates(data):

    # You can remove this line if you don't need to save a copy of your data
    data = data.copy()

    # Iterate over the coordinates - we will need the iterator ("i") to access and modify the elements at each position
    for i, coordinates in enumerate(data):

        # Since there are always 3 coordinates we can extract the information about first 2 dots and add the offset
        sep_index_0 = coordinates.find(".") + OFFSET + 1
        sep_index_1 = coordinates.find(".", sep_index_0 + 1) + OFFSET + 1

        # Insert the separator if needed - need to increase sep_index_1 because the string is now longer
        if coordinates[sep_index_0] != SEPARATOR:
            coordinates = str.join(SEPARATOR, (coordinates[:sep_index_0], coordinates[sep_index_0:]))
            sep_index_1 += 1

        # Similarly for the second place where there should be a separator, except no need to increase the index anymore
        if coordinates[sep_index_1] != SEPARATOR:
            coordinates = str.join(SEPARATOR, (coordinates[:sep_index_1], coordinates[sep_index_1:]))

        # You haven't explicitly mentioned it, but this ensures there are single spaces
        coordinates = coordinates.replace(SEPARATOR * 2, SEPARATOR)

        # Modify the existing value to match the expected pattern
        data[i] = coordinates

    return data


# Read your input - can't really get simpler!
with open("input.in") as f:
    to_parse = f.readlines()

# Write to your output - this also makes sure there are exactly 2 spaces in the parsed coordinates
with open("output.out", "w") as f:
    for parsed_coordinates in parse_coordinates(to_parse):
        assert parsed_coordinates.count(SEPARATOR) == 2
        f.write(parsed_coordinates)

输入如下(应该够全面,但也要自己测试!):

38.420 -6.206-108.383
38.420-6.206-108.383
38.420-6.206 -108.383
38.420 -6.206 -108.383
38.420 6.206 108.383
38.4206.206 108.383
38.420 6.206108.383
38.4206.206108.383
38.420  6.206  108.383

输出如下:

38.420 -6.206 -108.383
38.420 -6.206 -108.383
38.420 -6.206 -108.383
38.420 -6.206 -108.383
38.420 6.206 108.383
38.420 6.206 108.383
38.420 6.206 108.383
38.420 6.206 108.383
38.420 6.206 108.383

奖金

一些额外的想法:

  1. 避免使用 input 作为变量名 - 它已经是 Python 中的内置函数
  2. 您打开文件有点多 - 避免它,因为它会大大减慢计算速度
  3. 您可能想查看os.path.join 来构建文件路径 - 它使用起来非常简单且非常有用

【讨论】:

  • 非常感谢 Kacper 的详细回答,我真的很感激奖金的想法!最后一件事。我试图在不创建新副本的情况下修改 pdb 文件。似乎修改的唯一方法是使用 fileinput.input(data, inplace=1)?但我一直无法将此函数合并到 parse_coordinates()...
  • 您可以使用with open("file") as f 读取输入并将其存储在变量中,然后使用with open("file", "w") as f 擦除文件并写入解析的输入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
相关资源
最近更新 更多