Я работаю над программой, для которой мне нужны комбинации расстояний между атомами или различные точки в трехмерном пространстве. Вот пример:Сопоставление индексов комбинации со значением
Файл «тест» содержит следующую информацию: (!, Который я сделал)
Ti 1.0 1.0 1.0
O 0.0 2.0 0.0
O 0.0 0.0 0.0
Ti 1.0 3.0 4.0
O 2.0 5.0 0.0
Я хотел бы мой код, чтобы вычислить все комбинации расстояний между точками, то, Мне нужно подсчитать количество раз, когда расстояние между одним атомом и другим меньше 2,2.
Это сбивает с толку слова, поэтому я покажу вам, что у меня есть.
#!/usr/bin/env python
import sys, math, scipy, itertools
import numpy as np
try:
infile = sys.argv[1]
except:
print "Needs file name"
sys.exit(1)
#opening files for first part
ifile = open(infile, 'r')
coordslist = []
#Creating a file of just coordinates that can be 'mathed on'
for line in ifile:
pair = line.split()
atom = (pair[0]); x = float(pair[1]); y = float(pair[2]); z = float(pair[3])
coordslist += [(x,y,z)]
ifile.close()
#Define distance
def distance(p0,p1):
return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2 + (p0[2] - p1[2])** 2)
#Initializing for next section
dislist = []
bondslist = []
#Compute distances between all points 1-2, 1-3, 1-4, etc.
for p0, p1 in itertools.combinations(coordslist,2):
print p0, p1, distance(p0,p1)
dislist += [distance(p0, p1)]
if distance(p0,p1) < 2.2:
bondslist += [(p0, distance(p0,p1))]
print bondslist
print dislist
Я не был уверен, что если бы эти списки помогли мне или нет. Пока нет.
Выход:
(1.0, 1.0, 1.0) (0.0, 2.0, 0.0) 1.73205080757
(1.0, 1.0, 1.0) (0.0, 0.0, 0.0) 1.73205080757
(1.0, 1.0, 1.0) (1.0, 3.0, 4.0) 3.60555127546
(1.0, 1.0, 1.0) (2.0, 5.0, 0.0) 4.24264068712
(0.0, 2.0, 0.0) (0.0, 0.0, 0.0) 2.0
(0.0, 2.0, 0.0) (1.0, 3.0, 4.0) 4.24264068712
(0.0, 2.0, 0.0) (2.0, 5.0, 0.0) 3.60555127546
(0.0, 0.0, 0.0) (1.0, 3.0, 4.0) 5.09901951359
(0.0, 0.0, 0.0) (2.0, 5.0, 0.0) 5.38516480713
(1.0, 3.0, 4.0) (2.0, 5.0, 0.0) 4.58257569496
[((1.0, 1.0, 1.0), 1.7320508075688772), ((1.0, 1.0, 1.0), 1.7320508075688772), ((0.0, 2.0, 0.0), 2.0)]
[1.7320508075688772, 1.7320508075688772, 3.605551275463989, 4.242640687119285, 2.0, 4.242640687119285, 3.605551275463989, 5.0990195135927845, 5.385164807134504, 4.58257569495584]
Одно мне нужно из этого вывода есть число раз каждый атом имеет расстояние меньше, чем 2,2, например:
1 2 (because atom 1 has two distances less than 2.2 associated with it)
2 2
3 2
4 0
5 0
Я также нужно видеть, что два атома делают это расстояние менее 2,2. Я делаю это, чтобы рассчитать обвинения Полинга; это то, где вам нужно посмотреть на атом, определить, сколько у него связей (атомов меньше, чем на 2,2 ангстрема), а затем взглянуть на атомы , прикрепленные к этому атому, и посмотреть, сколько атомов прикреплено к тем. Это ужасно расстраивает, но все это будет зависеть от отслеживания каждого атома, а не только их комбинаций. Массив, вероятно, будет чрезвычайно полезен.
Я проверил here и here за помощью, и мне кажется, что мне нужно каким-то образом объединить эти методы. Любая помощь невероятно ценится!
Это было невероятно ясно и полезно! Я закончил свой код благодаря вам :) Я видел pdist, но почему-то отклонил его и не думал, что это послужит моей цели. Как только я это осуществил, я смог построить несколько вложенных циклов для петли над значениями k, а затем петлю над значениями в каждом ближнем [k].Ты спасатель. Мне нужно стать лучше на numpy! – jd423
@ jd423 Я очень рад, что смог помочь :) Numpy замечательно (но, конечно, вы всегда должны знать, когда остановиться, потому что есть много вещей, которые не вырезаны). –
это правда! Знаете ли вы аналогичный способ сделать это, но вместо расстояния вычисляете q1q2/r (кулоновское взаимодействие)? И заполнение массива numpy с этими значениями, близкими к заполнению с значениями расстояния? Документация Scipy, похоже, не включает такой пакет, но, возможно, мне придется определить функцию, которая будет использоваться. – jd423