source: util/src/CutBlockFromPDB.py.in@ 7b991d

Last change on this file since 7b991d was e1a46d, checked in by Frederik Heber <heber@…>, 16 years ago

All of my python script put into ESPACK and adapted with @PYTHON@ and so on.

  • Property mode set to 100755
File size: 5.3 KB
Line 
1#!@PYTHON@
2#
3# Cuts a specific block from a given PDB file
4
5import sys, string, re, math
6wrerr = sys.stderr.write
7wrout = sys.stdout.write
8
9def 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
18if 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
22input = open(sys.argv[1], "r")
23output = open(sys.argv[1]+".blk.pdb", "w")
24offsetID=int(sys.argv[2])
25offset=int(sys.argv[3])
26offsetSeqID=int(sys.argv[4])
27offsetNeighbours=int(sys.argv[5])
28offsetImproper=int(sys.argv[6])
29
30# 1. determine box boundary vectors
31a=[ 115., 0., 30. ] # x
32b=[ 150., 0., 30. ] # offset
33c=[ 150., 64., 30. ] # y
34d=[ 150., 0., 66. ] # z
35origin=[ 115., 0., 30. ]
36line1=[0., 0., 0.]
37line2=[0., 0., 0.]
38line3=[0., 0., 0.]
39norma=0
40normb=0
41normc=0
42for 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
51ids={}
52for 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
72input.seek(0)
73id=0
74idmap={}
75for 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
91wrout("The following ids will be removed due to NON-Triple-TIP3 criterium: ")
92for key in ids.keys():
93 if ids[key] < 3:
94 wrout("(%d = %d) " % (key, ids[key]))
95wrout("\n")
96
97
98# 3. write out the block with changed ids and neighbours and impropers
99input.seek(0)
100for 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
Note: See TracBrowser for help on using the repository browser.