1 | #! @PYTHON@
|
---|
2 | #
|
---|
3 | # determines all distances between each atomic pair and prints minimum and respective ids
|
---|
4 |
|
---|
5 | import sys, string, re, math
|
---|
6 | wrerr = sys.stderr.write
|
---|
7 | wrout = sys.stdout.write
|
---|
8 | CELLLENGTH = 5
|
---|
9 |
|
---|
10 | # check for parameters
|
---|
11 | if len(sys.argv) < 5:
|
---|
12 | wrerr("Usage: "+sys.argv[0]+" <datafile> <type1> <type2> <distance>\n")
|
---|
13 | sys.exit(1)
|
---|
14 |
|
---|
15 | #Get box boundaries (open parameter file)
|
---|
16 | input = open(sys.argv[1], "r")
|
---|
17 | type1 = sys.argv[2]
|
---|
18 | type2 = sys.argv[3]
|
---|
19 | distance = float(sys.argv[4])
|
---|
20 | filetype=sys.argv[1].split(".")
|
---|
21 | if (filetype[-1]=="data"):
|
---|
22 | offset=1
|
---|
23 | elementOffset=0
|
---|
24 | while 1:
|
---|
25 | line=input.readline() # skip header (starting with #)
|
---|
26 | if not re.compile("^#").match(line):
|
---|
27 | break
|
---|
28 | elif (filetype[-1]=="xyz"):
|
---|
29 | line=input.readline()
|
---|
30 | line=input.readline()
|
---|
31 | offset=1
|
---|
32 | elementOffset=0
|
---|
33 | elif (filetype[-1]=="pdb"):
|
---|
34 | offset=5
|
---|
35 | elementOffset=2
|
---|
36 |
|
---|
37 | line=input.readline()
|
---|
38 | atoms=line.split()
|
---|
39 | max=[float(atoms[0+offset]), float(atoms[1+offset]), float(atoms[2+offset])]
|
---|
40 | min=[float(atoms[0+offset]), float(atoms[1+offset]), float(atoms[2+offset])]
|
---|
41 | for line in input:
|
---|
42 | if "END" in line or "CONECT" in line or "MASTER" in line:
|
---|
43 | continue
|
---|
44 | atom=line.split()
|
---|
45 | for i in range(3):
|
---|
46 | if float(atom[i+offset]) < min[i]:
|
---|
47 | min[i] = float(atom[i+offset])
|
---|
48 | if float(atom[i+offset]) > max[i]:
|
---|
49 | max[i] = float(atom[i+offset])
|
---|
50 | print "Found Box bounds [%f,%f]x[%f,%f]x[%f,%f]." % (min[0],max[0],min[1],max[1],min[2],max[2])
|
---|
51 | for i in range(3): # shift by minimum if below zero
|
---|
52 | if min[i] < 0:
|
---|
53 | max[i]-=min[i]
|
---|
54 | else:
|
---|
55 | min[i]=0
|
---|
56 | cells_x=int(math.ceil(float(max[0])/CELLLENGTH))
|
---|
57 | cells_y=int(math.ceil(float(max[1])/CELLLENGTH))
|
---|
58 | cells_z=int(math.ceil(float(max[2])/CELLLENGTH))
|
---|
59 | print "Number of cells in each axis direction (%f,%f,%f)." % (cells_x, cells_y, cells_z)
|
---|
60 | input.close()
|
---|
61 |
|
---|
62 | #create 3 dim array to fit in box, each cell has size 5 Ang
|
---|
63 | cell=[]
|
---|
64 |
|
---|
65 | for i in range(cells_x):
|
---|
66 | cell.append([])
|
---|
67 | for j in range(cells_y):
|
---|
68 | cell[i].append([])
|
---|
69 | for k in range(cells_z):
|
---|
70 | cell[i][j].append([0])
|
---|
71 |
|
---|
72 |
|
---|
73 | # open files
|
---|
74 | input = open(sys.argv[1], "r")
|
---|
75 |
|
---|
76 | # parse every atom into appropriate cell
|
---|
77 | n=0
|
---|
78 | line=input.readline()
|
---|
79 | line=input.readline()
|
---|
80 | for line in input:
|
---|
81 | if "END" in line or "CONECT" in line or "MASTER" in line:
|
---|
82 | continue
|
---|
83 | # atom=[]
|
---|
84 | fields=line.split()
|
---|
85 | x=int(math.floor((float(fields[0+offset])-min[0])/CELLLENGTH)) # shift coordinates by box minimum
|
---|
86 | y=int(math.floor((float(fields[1+offset])-min[1])/CELLLENGTH))
|
---|
87 | z=int(math.floor((float(fields[2+offset])-min[2])/CELLLENGTH))
|
---|
88 | typeA=fields[elementOffset]
|
---|
89 | atom=[n, float(fields[0+offset]), float(fields[1+offset]), float(fields[2+offset]), typeA]
|
---|
90 | cell[x][y][z][0] +=1
|
---|
91 | cell[x][y][z].append(atom)
|
---|
92 | n=n+1
|
---|
93 |
|
---|
94 |
|
---|
95 | # go through every cell
|
---|
96 | min = 100000.
|
---|
97 | minid=-1
|
---|
98 | minid2=-1
|
---|
99 | atom1=[0,0.,0.,0.]
|
---|
100 | atom2=[0,0.,0.,0.]
|
---|
101 | v=0
|
---|
102 |
|
---|
103 | for i in range(cells_x):
|
---|
104 | for j in range(cells_y):
|
---|
105 | for k in range(cells_z):
|
---|
106 | v+=cell[i][j][k][0]
|
---|
107 |
|
---|
108 | #go through every atom in cell
|
---|
109 | for l in range(1, cell[i][j][k][0]+1):
|
---|
110 | atom1=cell[i][j][k][l]
|
---|
111 |
|
---|
112 | # go through cell and all lower neighbours
|
---|
113 | for e in range(i-1,i+1):
|
---|
114 | #if on border continue periodic
|
---|
115 | if e>cells_x-1:
|
---|
116 | e=e-cells_x
|
---|
117 | for r in range(j-1,j+1):
|
---|
118 | #if on border continue periodic
|
---|
119 | if r>cells_y-1:
|
---|
120 | r=r-cells_y
|
---|
121 | for t in range(k-1,k+2):
|
---|
122 | #if on boarder continue periodic
|
---|
123 | if t>cells_z-1:
|
---|
124 | t=t-cells_z
|
---|
125 | #efficiency in linked cell: ommit four boxes in middle layer
|
---|
126 | if (i==e and r==j+1):
|
---|
127 | continue
|
---|
128 | if (i==e and r==j+1 and t==k+1):
|
---|
129 | continue
|
---|
130 | w=cell[e][r][t][0]
|
---|
131 | #go through all atoms in cell
|
---|
132 | for m in range(1, w+1):
|
---|
133 | atom2=cell[e][r][t][m]
|
---|
134 | dist=0
|
---|
135 | #when in same cell: ommit identical particles
|
---|
136 | if (atom1[0]==atom2[0]):
|
---|
137 | continue
|
---|
138 | for h in range(1,4):
|
---|
139 | dist += (atom1[h] - atom2[h])*(atom1[h] - atom2[h])
|
---|
140 | if (dist < distance*distance):
|
---|
141 | minid=atom1[0]
|
---|
142 | minid2=atom2[0]
|
---|
143 | min=dist
|
---|
144 | if (type1 in atom1[4] and type2 in atom2[4]) or (type2 in atom[4] and type1 in atom2[4]):
|
---|
145 | #print "%s%d\t%s%d\t%f" % (atom1[4],minid, atom2[4],minid2,min)
|
---|
146 | print "%d\t%d" % (minid, minid2)
|
---|
147 |
|
---|
148 | #print v
|
---|