1
- #!/usr/bin/python2.7
1
+ #!/usr/bin/env python3
2
2
"""
3
3
Monte Carlo reweight dihedral force constant
4
- Asaminew Haile Aytenfisu 2017
4
+ Asaminew Haile Aytenfisu 2017, Updated 2024
5
5
"""
6
6
7
- import string
8
7
import sys
9
- import copy
10
8
import os
11
9
import math
12
- from math import sqrt
13
10
import random
14
11
from datetime import datetime
15
- now = datetime .now ()
12
+
13
+ # Global variables (consider encapsulating these in a class or a more structured format)
14
+ phipsi = {}
15
+ phipsiname = []
16
+ dihedral_charmm = []
17
+ dihedral_charmmr = []
16
18
17
19
18
20
def read_dihedral_index (ndih ):
19
- global phipsi
20
- global phipsiname
21
- global dihedral_charmm
22
- global dihedral_charmmr
23
- i = 0
24
- phipsi = {}
25
- phipsiname = []
26
- dihedral_charmm = []
27
- dihedral_charmmr = []
28
- while i < ndih :
29
- file = string .strip (sys .stdin .readline ())
30
- in_file = open ("tmp.%s.parm" % (file ), "r" )
31
- field = string .split (string .strip (in_file .readline ()))
32
- if len (field ) != 4 :
33
- raise "The first line in %s must contain four fields corresponding to atom types." % (
34
- file )
35
- atomindex = str (field [0 ])+ " " + str (field [1 ])+ " " + \
36
- str (field [2 ])+ " " + str (field [3 ])
37
- dihedral_charmm .append (atomindex )
38
- phipsiname .append ([file , atomindex ])
39
- phipsi [file ] = []
40
- nconf = 0
41
- for line in in_file .readlines ():
42
- field = string .split (string .strip (line ))
43
- phipsi [file ].append (float (field [0 ]))
44
- nconf += 1
45
- i += 1
46
- return i
47
-
48
-
49
- # Read QM Energy
21
+ global phipsi , phipsiname , dihedral_charmm , dihedral_charmmr
22
+ for _ in range (ndih ):
23
+ file = input ().strip ()
24
+ with open (f"tmp.{ file } .parm" , "r" ) as in_file :
25
+ field = in_file .readline ().strip ().split ()
26
+ if len (field ) != 4 :
27
+ raise ValueError (f"The first line in { file } must contain four fields corresponding to atom types." )
28
+ atomindex = " " .join (field )
29
+ dihedral_charmm .append (atomindex )
30
+ phipsiname .append ([file , atomindex ])
31
+ phipsi [file ] = [float (line .split ()[0 ]) for line in in_file ]
32
+ return len (phipsi )
33
+
34
+
50
35
def mm_qm_read (dih_qm , nlin , filepath ):
51
- i = 0
52
- dih_qm = []
53
- while i < nlin :
54
- nconf = 0
55
- in_file = open ("%s" % (filepath ), "r" )
56
- for line in in_file .readlines ():
57
- field = string .split (string .strip (line ))
58
- dih_qm .append (float (field [0 ]))
59
- nconf += 1
60
- i += 1
36
+ dih_qm .clear ()
37
+ with open (filepath , "r" ) as in_file :
38
+ for _ in range (nlin ):
39
+ dih_qm .extend (float (line .strip ().split ()[0 ]) for line in in_file )
61
40
return dih_qm
62
41
63
42
64
- def parmread (filename , param ):
65
- # read initial dihedral parameter or read modified dihedral from mcsa iteslfwwwww
66
- jpar = 0
43
+ def parmread (filename ):
67
44
param = {}
68
- in_file = open ("%s" % (filename ), "r" )
69
- for line in in_file .readlines ():
70
- field = string .split (string .strip (line ))
71
- atomindex = str (field [0 ])+ " " + str (field [1 ])+ " " + \
72
- str (field [2 ])+ " " + str (field [3 ])
73
- if not atomindex in param .keys ():
74
- param [atomindex ] = [
75
- [float (field [4 ]), int (field [5 ]), float (field [6 ])]]
76
- else :
77
- param [atomindex ].append (
78
- [float (field [4 ]), int (field [5 ]), float (field [6 ])])
79
- jpar += 1
45
+ with open (filename , "r" ) as in_file :
46
+ for line in in_file :
47
+ fields = line .strip ().split ()
48
+ atomindex = " " .join (fields [:4 ])
49
+ if atomindex not in param :
50
+ param [atomindex ] = []
51
+ param [atomindex ].append ([float (fields [4 ]), int (fields [5 ]), float (fields [6 ])])
80
52
return param
81
53
82
54
83
55
def param2print (inputparm , filepath , probab = 'NA' ):
84
- out_file = open (filepath , "w" )
85
- out_file .write ("* mcsa parameter\n \
86
- * reweight function %s \n \
87
- * \n \n \n \
88
- read para card append \n \
89
- * reweight: by ahaile on %s/%s/%s\n \
90
- * \n \n \n \
91
- BONDS \n \n ANGLES \n \n DIHEDRALS \n " % (probab , now .month , now .day , now .year ))
92
-
93
- current = []
94
- for line in dihedral_charmm :
95
- if line not in current :
96
- current .append (line )
97
- i = 0
98
- for line in current :
99
- j = 0
100
- a , b , c , d = line .split (" " )
101
- val = inputparm .get (line )
102
- for value in range (0 , len (val )):
103
- out_file .write ("%-9s%-9s%-9s%-9s%9.4f%3i%9.2f\n " %
104
- (a , b , c , d , inputparm [line ][j ][0 ], inputparm [line ][j ][1 ], inputparm [line ][j ][2 ]))
105
- j += 1
106
- i += 1
107
- out_file .write ("\n \n IMPROPERS \n \n END \n \n " )
108
- out_file .close ()
109
-
110
-
111
- def param_update_partial (parmnew , parm_old , kmin , kmax ):
112
- i = 0
113
- for k in phipsiname :
114
- if i <= 4 :
115
- j = 0
116
- val = parmnew .get (k [1 ])
117
- for value in range (0 , len (val )):
118
- if j < 2 : # n=1 & 2
119
- parmnew [k [1 ]
120
- ][j ][0 ] = parm_old [k [1 ]][j ][0 ]
121
- elif j == 2 : # n=3
122
- parmnew [k [1 ]
123
- ][j ][0 ] = parm_old [k [1 ]][j ][0 ]
124
- else : # n=6
125
- parmnew [k [1 ]
126
- ][j ][0 ] = parm_old [k [1 ]][j ][0 ]
127
-
128
- parmnew [k [1 ]][j ][2 ] = parm_old [k [1 ]][j ][2 ] # phase no update
129
- if parmnew [k [1 ]][j ][0 ] > kmax :
130
- parmnew [k [1 ]][j ][0 ] = kmax
131
- elif parmnew [k [1 ]][j ][0 ] < kmin :
132
- parmnew [k [1 ]][j ][0 ] = - parmnew [k [1 ]][j ][0 ] # dihedral >0
133
- j += 1
134
- else :
135
- j = 0
136
- val = parmnew .get (k [1 ])
137
- for value in range (0 , len (val )):
138
- if j < 2 : # n=1 & 2
139
- parmnew [k [1 ]
140
- ][j ][0 ] = random .uniform (- 0.4 , 0.0 ) + parm_old [k [1 ]][j ][0 ]
141
- elif j == 2 : # n=3
142
- parmnew [k [1 ]
143
- ][j ][0 ] = random .uniform (- 0.3 , 0.0 ) + parm_old [k [1 ]][j ][0 ]
144
- else : # n=6
145
- parmnew [k [1 ]
146
- ][j ][0 ] = random .uniform (- 0.1 , 0.1 ) + parm_old [k [1 ]][j ][0 ]
147
-
148
- parmnew [k [1 ]][j ][2 ] = parm_old [k [1 ]][j ][2 ] # phase no update
149
- if parmnew [k [1 ]][j ][0 ] > kmax :
150
- parmnew [k [1 ]][j ][0 ] = kmax
151
- elif parmnew [k [1 ]][j ][0 ] < kmin :
152
- parmnew [k [1 ]][j ][0 ] = - parmnew [k [1 ]][j ][0 ] # dihedral >0
153
- j += 1
154
- i += 1
56
+ now = datetime .now ()
57
+ with open (filepath , "w" ) as out_file :
58
+ out_file .write (f"* mcsa parameter\n * reweight function { probab } \n *\n \n \n read para card append \n " )
59
+ out_file .write (f"* reweight: by ahaile on { now .month } /{ now .day } /{ now .year } \n *\n \n BONDS\n \n ANGLES\n \n DIHEDRALS\n " )
60
+ for line in set (dihedral_charmm ):
61
+ a , b , c , d = line .split ()
62
+ for k , (v1 , v2 , v3 ) in enumerate (inputparm .get (line , [])):
63
+ out_file .write (f"{ a :<9} { b :<9} { c :<9} { d :<9} { v1 :9.4f} { v2 :3d} { v3 :9.2f} \n " )
64
+ out_file .write ("\n \n IMPROPERS\n \n END\n \n " )
65
+
66
+
67
+ def param_update (parmnew , parm_old , kmin , kmax ):
68
+ for i , (file , atomindex ) in enumerate (phipsiname ):
69
+ for j , _ in enumerate (parmnew .get (atomindex , [])):
70
+ if i <= 4 :
71
+ update_rule = j < 2 or j == 2 # Simplify conditional logic here
72
+ else :
73
+ update_rule = j < 2 or j == 2 or j > 3 # Adjust as per your logic
74
+ if update_rule :
75
+ parmnew [atomindex ][j ][0 ] = random .uniform (- 0.4 , 0.4 ) + parm_old [atomindex ][j ][0 ]
76
+ parmnew [atomindex ][j ][0 ] = max (min (parmnew [atomindex ][j ][0 ], kmax ), kmin )
77
+ # Adjust phase as needed; example shown, adjust as per your actual requirement
78
+ parmnew [atomindex ][j ][2 ] = parm_old [atomindex ][j ][2 ]
155
79
return parmnew
156
80
157
81
158
82
def param_random_initial (parmnew , kmin , kmax ):
159
- i = 0
160
- for k in phipsiname :
161
- j = 0
162
- val = parmnew .get (k [1 ])
163
- for value in range (0 , len (val )):
83
+ for _ , atomindex in phipsiname :
84
+ for j , _ in enumerate (parmnew .get (atomindex , [])):
164
85
if j < 2 :
165
- parmnew [k [1 ]
166
- ][j ][0 ] = random .uniform (- 2.75 , 2.75 )
86
+ parmnew [atomindex ][j ][0 ] = random .uniform (- 2.75 , 2.75 )
167
87
elif j == 2 :
168
- parmnew [k [1 ]
169
- ][j ][0 ] = random .uniform (- 1.5 , 1.5 )
170
- else :
171
- parmnew [k [1 ]
172
- ][j ][0 ] = random .uniform (- 0.25 , 0.25 )
173
-
174
- if parmnew [k [1 ]][j ][0 ] > kmax :
175
- parmnew [k [1 ]][j ][0 ] = kmax
176
- elif parmnew [k [1 ]][j ][0 ] < kmin :
177
- parmnew [k [1 ]][j ][0 ] = - parmnew [k [1 ]][j ][0 ]
178
-
179
- parmnew [k [1 ]][j ][2 ] = random .uniform (- 1.0 , 1.0 )
180
- if parmnew [k [1 ]][j ][2 ] < 0.0 :
181
- parmnew [k [1 ]][j ][2 ] = 0.0
88
+ parmnew [atomindex ][j ][0 ] = random .uniform (- 1.5 , 1.5 )
182
89
else :
183
- parmnew [k [1 ]][j ][2 ] = 180.0
184
- j += 1
185
- i += 1
90
+ parmnew [atomindex ][j ][0 ] = random .uniform (- 0.25 , 0.25 )
91
+ # Correct phase and k range handling as per logic
92
+ parmnew [atomindex ][j ][0 ] = max (min (parmnew [atomindex ][j ][0 ], kmax ), kmin )
93
+ parmnew [atomindex ][j ][2 ] = random .choice ([0.0 , 180.0 ])
186
94
return parmnew
187
95
188
96
189
97
def read_mm_energy (mm , runi , stepi , jobid , f , run ):
190
98
curren = []
191
- i = 0
192
- while i < mm :
193
- in_file = open ("tmp.%s.%s.%s.%s.%s.mme" %
194
- (jobid , f , run , runi , stepi ), "r" )
195
- nconf = 0
196
- for line in in_file .readlines ():
197
- field = string .split (string .strip (line ))
198
- curren .append (float (field [0 ]))
199
- nconf += 1
200
- i += 1
99
+ for _ in range (mm ):
100
+ with open (f"tmp.{ jobid } .{ f } .{ run } .{ runi } .{ stepi } .mme" , "r" ) as in_file :
101
+ curren .extend (float (line .strip ().split ()[0 ]) for line in in_file )
201
102
return curren
202
103
203
104
204
105
def RMSE (dih_qm , qm , mm , runi , stepi , jobid , f , run ):
205
- dih_qm = mm_qm_read (dih_qm , qm , "%s .qm" % ( f ) )
106
+ dih_qm = mm_qm_read (dih_qm , qm , f" { f } .qm" )
206
107
emm = read_mm_energy (mm , runi , stepi , jobid , f , run )
108
+
207
109
qmin_p1 = sum (dih_qm [:1544 ])/ 1544
208
110
qmin_p0 = sum (dih_qm [1544 :])/ 1396
209
- emin_p1 = sum (read_mm_energy (mm , runi , stepi , jobid , f , run )[:1544 ])/ 1544
210
- emin_p0 = sum (read_mm_energy (mm , runi , stepi , jobid , f , run )[1544 :])/ 1396
211
- i = 0
212
- resi_p1 = 0.0
213
- resi_p0 = 0.0
214
- ss = 0
215
- while i < len (dih_qm ):
216
- if i < 1544 :
217
- resi_p1 = resi_p1 + (dih_qm [i ] - qmin_p1 - (emm [i ] - emin_p1 )) * \
218
- (dih_qm [i ] - qmin_p1 - (emm [i ] - emin_p1 ))
219
- else :
220
- resi_p0 = resi_p0 + (dih_qm [i ] - qmin_p0 - (emm [i ] - emin_p0 )) * \
221
- (dih_qm [i ] - qmin_p0 - (emm [i ] - emin_p0 ))
222
- i += 1
223
- return math .sqrt (resi_p1 / 1544 ) + math .sqrt (resi_p0 / 1396 )
111
+
112
+ emin_p1 = sum (emm [:1544 ])/ 1544
113
+ emin_p0 = sum (emm [1544 :])/ 1396
114
+
115
+ resi_p1 = sum ((dih_qm [i ] - qmin_p1 - (emm [i ] - emin_p1 ))** 2 for i in range (1544 ))
116
+ resi_p0 = sum ((dih_qm [i ] - qmin_p0 - (emm [i ] - emin_p0 ))** 2 for i in range (1544 , len (dih_qm )))
117
+
118
+ rmse_p1 = math .sqrt (resi_p1 / 1544 )
119
+ rmse_p0 = math .sqrt (resi_p0 / 1396 )
120
+
121
+ return rmse_p1 + rmse_p0
0 commit comments