1 | #!@PYTHON@
|
---|
2 | #
|
---|
3 | # Cuts a specific block from a given PDB file
|
---|
4 |
|
---|
5 | import sys, string, re, math
|
---|
6 | wrerr = sys.stderr.write
|
---|
7 | wrout = sys.stdout.write
|
---|
8 |
|
---|
9 | def SKP(a,b):
|
---|
10 | """ Calculates scalar product of two 3dim vectors
|
---|
11 | """
|
---|
12 | result=0
|
---|
13 | for i in range(3):
|
---|
14 | result+=a[i]*b[i]
|
---|
15 | return(result)
|
---|
16 |
|
---|
17 | # check for parameters
|
---|
18 | if len(sys.argv) < 7:
|
---|
19 | wrerr("Usage: "+sys.argv[0]+" <PDB file> <offset to id> <offset to x> <offsetSeqID> <offset2neighbours> <offset2improper>\n")
|
---|
20 | sys.exit(1)
|
---|
21 |
|
---|
22 | input = open(sys.argv[1], "r")
|
---|
23 | output = open(sys.argv[1]+".blk.pdb", "w")
|
---|
24 | offsetID=int(sys.argv[2])
|
---|
25 | offset=int(sys.argv[3])
|
---|
26 | offsetSeqID=int(sys.argv[4])
|
---|
27 | offsetNeighbours=int(sys.argv[5])
|
---|
28 | offsetImproper=int(sys.argv[6])
|
---|
29 |
|
---|
30 | # 1. determine box boundary vectors
|
---|
31 | a=[ 115., 0., 30. ] # x
|
---|
32 | b=[ 150., 0., 30. ] # offset
|
---|
33 | c=[ 150., 64., 30. ] # y
|
---|
34 | d=[ 150., 0., 66. ] # z
|
---|
35 | origin=[ 115., 0., 30. ]
|
---|
36 | line1=[0., 0., 0.]
|
---|
37 | line2=[0., 0., 0.]
|
---|
38 | line3=[0., 0., 0.]
|
---|
39 | norma=0
|
---|
40 | normb=0
|
---|
41 | normc=0
|
---|
42 | for i in range(3):
|
---|
43 | line1[i]=a[i]-b[i]
|
---|
44 | line2[i]=c[i]-b[i]
|
---|
45 | line3[i]=d[i]-b[i]
|
---|
46 | norma+=line1[i]*line1[i]
|
---|
47 | normb+=line2[i]*line2[i]
|
---|
48 | normc+=line3[i]*line3[i]
|
---|
49 |
|
---|
50 | # 2a. prepare mapping by removing non-trippled TIP3s
|
---|
51 | ids={}
|
---|
52 | for line in input:
|
---|
53 | if "#" in line: # skip comments
|
---|
54 | continue
|
---|
55 | entries=line.split()
|
---|
56 | e=[ float(entries[offset]), float(entries[offset+1]), float(entries[offset+2]) ]
|
---|
57 | for i in range(3):
|
---|
58 | e[i]-=b[i]
|
---|
59 | skp1 = SKP(line1,e)/norma
|
---|
60 | skp2 = SKP(line2,e)/normb
|
---|
61 | skp3 = SKP(line3,e)/normc
|
---|
62 | if ((skp1 >=0) and (skp1 < 1)) and ((skp2 >=0) and (skp2 <1)) and ((skp3 >=0) and (skp3 <1)):
|
---|
63 | if "TIP3" in line: # note down the number of times this SeqID appears, should be 3 for TIP3 clusters (h2o)
|
---|
64 | i=int(entries[offsetSeqID])
|
---|
65 | if ids.has_key(i):
|
---|
66 | ids[i]=ids[i]+1
|
---|
67 | else:
|
---|
68 | ids[i]=1
|
---|
69 | #wrout("for key %d: %d present\n" % (i, ids[i]))
|
---|
70 |
|
---|
71 | # 2b. assign mapping between old and new ids
|
---|
72 | input.seek(0)
|
---|
73 | id=0
|
---|
74 | idmap={}
|
---|
75 | for line in input:
|
---|
76 | if "#" in line: # skip comments
|
---|
77 | continue
|
---|
78 | entries=line.split()
|
---|
79 | e=[ float(entries[offset]), float(entries[offset+1]), float(entries[offset+2]) ]
|
---|
80 | for i in range(3):
|
---|
81 | e[i]-=b[i]
|
---|
82 | skp1 = SKP(line1,e)/norma
|
---|
83 | skp2 = SKP(line2,e)/normb
|
---|
84 | skp3 = SKP(line3,e)/normc
|
---|
85 | if ((skp1 >=0) and (skp1 < 1)) and ((skp2 >=0) and (skp2 <1)) and ((skp3 >=0) and (skp3 <1)):
|
---|
86 | if (("TIP3" in line) and (ids[int(entries[offsetSeqID])] != 3)): # drop TIP3 that are not present as triple
|
---|
87 | continue
|
---|
88 | id+=1
|
---|
89 | idmap[int(entries[offsetID])]=id # note down old id to new id mapping
|
---|
90 |
|
---|
91 | wrout("The following ids will be removed due to NON-Triple-TIP3 criterium: ")
|
---|
92 | for key in ids.keys():
|
---|
93 | if ids[key] < 3:
|
---|
94 | wrout("(%d = %d) " % (key, ids[key]))
|
---|
95 | wrout("\n")
|
---|
96 |
|
---|
97 |
|
---|
98 | # 3. write out the block with changed ids and neighbours and impropers
|
---|
99 | input.seek(0)
|
---|
100 | for line in input:
|
---|
101 | if "#" in line: # skip comments
|
---|
102 | continue
|
---|
103 | entries=line.split()
|
---|
104 | e=[ float(entries[offset]), float(entries[offset+1]), float(entries[offset+2]) ]
|
---|
105 | for i in range(3):
|
---|
106 | e[i]-=b[i]
|
---|
107 | skp1 = SKP(line1,e)/norma
|
---|
108 | skp2 = SKP(line2,e)/normb
|
---|
109 | skp3 = SKP(line3,e)/normc
|
---|
110 | if ((skp1 >=0) and (skp1 < 1)) and ((skp2 >=0) and (skp2 <1)) and ((skp3 >=0) and (skp3 <1)): # check whether coordinate is inside desired block
|
---|
111 | if (("TIP3" in line) and (ids[int(entries[offsetSeqID])] != 3)): # drop TIP3 that are not present as triple
|
---|
112 | continue
|
---|
113 | i=0
|
---|
114 | while (i < len(entries)):
|
---|
115 | if ((i == offsetID)): # change id to new id
|
---|
116 | output.write("%d\t" % (idmap[int(entries[i])]))
|
---|
117 | i+=1
|
---|
118 | continue
|
---|
119 | if ((i >= offset) and (i < offset+3)): # shift block to start at origin
|
---|
120 | output.write("%f\t" % (float(entries[i])-origin[i-offset]))
|
---|
121 | i+=1
|
---|
122 | continue
|
---|
123 | if ((i >= offsetNeighbours) and (i < offsetNeighbours+4)): # change neighbour ids to new ods
|
---|
124 | if idmap.has_key(int(entries[i])):
|
---|
125 | output.write("%d\t" % ( idmap[int(entries[i])] ))
|
---|
126 | else:
|
---|
127 | output.write("0\t")
|
---|
128 | i+=1
|
---|
129 | continue
|
---|
130 | if ((i == offsetImproper)): # change improper ids to new ids
|
---|
131 | if entries[i] != "-": # if it just contains "-" (i.e. no impropers), write "-"
|
---|
132 | neighbours=entries[i].split(',') # there may be several improper terms, separated by ","
|
---|
133 | for k in range(len(neighbours)):
|
---|
134 | neighbour=neighbours[k].split('-') # the improper neighbours are separated by "-"
|
---|
135 | invalid=0
|
---|
136 | for j in range(len(neighbour)): # first check if each improper neighbour is present in the cut-out block
|
---|
137 | if not idmap.has_key(int(neighbour[j])):
|
---|
138 | invalid=1
|
---|
139 | break
|
---|
140 | if invalid == 0: # if all are present, map old ids to new ids
|
---|
141 | if (k != 0):
|
---|
142 | output.write(",")
|
---|
143 | for j in range(len(neighbour)):
|
---|
144 | try:
|
---|
145 | if idmap.has_key(int(neighbour[j])):
|
---|
146 | if j != 0:
|
---|
147 | output.write("-%d" % ( idmap[int(neighbour[j])] ))
|
---|
148 | else:
|
---|
149 | output.write("%d" % ( idmap[int(neighbour[j])] ))
|
---|
150 | except ValueError:
|
---|
151 | wrout("%s is not a valid neighbour\n" % (neighbour[j]))
|
---|
152 | # next improper term for this atom
|
---|
153 | else:
|
---|
154 | if (k == len(neighbours)-1):
|
---|
155 | output.write("-")
|
---|
156 | # next improper neighbour
|
---|
157 | i+=1
|
---|
158 | continue
|
---|
159 | output.write("%s\t" % (entries[i]))
|
---|
160 | i+=1
|
---|
161 | output.write("\n")
|
---|
162 | id+=1
|
---|