I have a file that looks like this:
JavaScript
x
10
10
1
;
2
[ atomtypes ]
3
opls_BZCG BCG1 78.113999 0.000 A 2.9310E-01 1.9173E-01
4
[ moleculetype ]
5
; Name nrexcl
6
BZCG 1
7
[ atoms ]
8
; nr type resnr residue atom cgnr charge mass
9
1 opls_BZCG 1 BZCG BCG1 1 0 78.113999
10
I am trying to use python to change the values in the second last and last field under the [ atomtypes ]
title. The deal is that I am running a code which iteratively updates this file, so I specifically want that field to be targeted, not the regular expression “2.931E-01” or “1.9173E-01”. I know we can use things like awk, but I was wondering if this is possible from python itself.
This is what I am doing so far:
JavaScript
1
15
15
1
flag = 0
2
with open("file.itp") as f:
3
for line in f:
4
iterable = line.strip().split()
5
if flag:
6
line.strip().split()[5] = sigma
7
line.strip().split()[6]) = eps
8
print("epsilon is {} and sigma is {}".format(eps, sigma))
9
if "atomtypes" in iterable:
10
flag = 1
11
else:
12
flag = 0
13
14
f.close()
15
I am changing the value in python, but I am not able to send that change to the file itself. How do I pull this off?
Any advice you have would be appreciated!
Advertisement
Answer
Use enumerate on lines so we can access current line and next line
Code
JavaScript
1
22
22
1
def update_line(filenm, eps, sigma):
2
with open(filenm, 'r') as fin:
3
lines = fin.readlines()
4
5
for idx, line in enumerate(lines):
6
if "atomtypes" in line:
7
# Current line has marker, so change next line (i.e. index idx + 1)
8
# Split next line into fields
9
# split from end so so only have three fields, namely:
10
# 1) everything before next to last field,
11
# 2) next to last field,
12
# 3) last field)
13
arr = lines[idx+1].rsplit(' ', maxsplit = 3)
14
arr[-3], arr[-1] = f"{eps:e}", f"{sigma:e}"
15
lines[idx+1] = ' '.join(arr) + "n" # last_val dropped the 'n' so add back
16
break
17
18
with open(filenm, 'w') as fout:
19
# Updated lines placed back into file
20
fout.writelines(lines)
21
22
Test
JavaScript
1
2
1
update_line('test.txt', 4.573133E-02, 8.2737123E-01)
2
File test.txt prior:
JavaScript
1
10
10
1
;
2
[ atomtypes ]
3
opls_BZCG BCG1 78.113999 0.000 A 2.9310E-01 1.9173E-01
4
[ moleculetype ]
5
; Name nrexcl
6
BZCG 1
7
[ atoms ]
8
; nr type resnr residue atom cgnr charge mass
9
1 opls_BZCG 1 BZCG BCG1 1 0 78.113999
10
File test.txt after
JavaScript
1
10
10
1
;
2
[ atomtypes ]
3
opls_BZCG BCG1 78.113999 0.000 A 4.573133e-02 8.273712e-01
4
[ moleculetype ]
5
; Name nrexcl
6
BZCG 1
7
[ atoms ]
8
; nr type resnr residue atom cgnr charge mass
9
1 opls_BZCG 1 BZCG BCG1 1 0 78.113999
10