0

I have a file that looks like this:

;
[ atomtypes ]
  opls_BZCG BCG1    78.113999   0.000   A   2.9310E-01  1.9173E-01
[ moleculetype ]
; Name      nrexcl
BZCG        1
[ atoms ]
;   nr  type    resnr   residue atom    cgnr    charge  mass
    1   opls_BZCG   1       BZCG    BCG1        1       0       78.113999

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:

flag = 0
with open("file.itp") as f: 
  for line in f:
     iterable = line.strip().split()
        if flag:
            line.strip().split()[5] = sigma 
            line.strip().split()[6]) = eps 
            print("epsilon is {} and sigma is {}".format(eps, sigma))
        if "atomtypes" in iterable:
            flag = 1
        else:
            flag = 0

    f.close()

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!

5
  • I'm not sure about the file format that you're trying to update. However, if you're dealing with a .txt file probably splitting each line may work in my opinion. Commented Mar 17, 2021 at 23:09
  • So I load the entire file, change the 2 numbers, and move on?@TahaJaliliTATI Commented Mar 17, 2021 at 23:13
  • There is no need to load the entire file, you can parse it line by line: stackoverflow.com/a/8010133/2237151 Commented Mar 17, 2021 at 23:21
  • @Pietro, so I go line by line, I perform line.strip().split(), I change the two numbers... but how do I send this information back to the file? I want to change the numbers and update the file itself. Commented Mar 17, 2021 at 23:41
  • You have to write it to a new file with a temporary name, then when you're done, delete the old and rename the new into place. Commented Mar 17, 2021 at 23:54

1 Answer 1

1

Use enumerate on lines so we can access current line and next line

Code

def update_line(filenm, eps, sigma):
    with open(filenm, 'r') as fin:
        lines = fin.readlines()
        
        for idx, line in enumerate(lines):
            if "atomtypes" in line:
                # Current line has marker, so change next line (i.e. index idx + 1)
                #   Split next line into fields 
                #   split from end so so only have three fields, namely:
                #    1) everything before next to last field, 
                #    2) next to last field, 
                #    3) last field)
                arr = lines[idx+1].rsplit(' ', maxsplit = 3)
                arr[-3], arr[-1] = f"{eps:e}", f"{sigma:e}"
                lines[idx+1] = ' '.join(arr) + "\n"  # last_val dropped the '\n' so add back
                break
        
    with open(filenm, 'w') as fout:
        # Updated lines placed back into file
        fout.writelines(lines)
    

Test

update_line('test.txt', 4.573133E-02, 8.2737123E-01)

File test.txt prior:

;
[ atomtypes ]
  opls_BZCG BCG1    78.113999   0.000   A   2.9310E-01  1.9173E-01
[ moleculetype ]
; Name      nrexcl
BZCG        1
[ atoms ]
;   nr  type    resnr   residue atom    cgnr    charge  mass
    1   opls_BZCG   1       BZCG    BCG1        1       0       78.113999

File test.txt after

;
[ atomtypes ]
  opls_BZCG BCG1    78.113999   0.000   A   4.573133e-02  8.273712e-01
[ moleculetype ]
; Name      nrexcl
BZCG        1
[ atoms ]
;   nr  type    resnr   residue atom    cgnr    charge  mass
    1   opls_BZCG   1       BZCG    BCG1        1       0       78.113999
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.