1

I have an array as follows:

xyz = [[ 0.08778,  0.99666,  0.30648],
       [ 0.41688,  2.70076,  1.10135],
       [ 1.90494,  0.91685, -0.26984],
       [-0.44512,  1.73972, -1.24406],
       [-1.68572,  1.01617,  1.01221],
       [-0.1977 , -0.77177, -0.35553],
       [ 0.61588,  3.6995 ,  1.59813],
       [ 2.98863,  0.86173, -0.59616],
       [-0.78312,  2.20935, -2.22362],
       [-2.73208,  1.02071,  1.44702],
       [-0.36006, -1.82939, -0.72827]]

I want to add 0.005 to the first element (0.08778), and then save this array to a new file 'output0.xyz'. I then want to add 0.005 to the second element (0.99666) and keep the first element as its original value, and save this array to a new file 'output1.xyz', and so on. So I need to write 33 new files, each with just one of the numbers in xyz changed. Here is my code:

i = 30
number_atoms = 12
at_nums = [26.,  6.,  6.,  6.,  6.,  6.,  8.,  8.,  8.,  8.,  8.])

for atom in xyz:
    for coordinate in atom:
        coordinate += 0.005
       
        with open('output{}.xyz'.format(i), 'w') as f:
            f.write('{:.0f}\n\n'.format(number_atoms))
            for at_num_i, xyz_disp_i in zip(at_nums, xyz):
                f.write('{:.0f}\t{:.8f}\t{:.8f}\t{:.8f}\n'.format(at_num_i, *xyz_disp_i))

Currently this code is just saving the original array into a file called 'output30.xyz'. I've been stumped on this for a while now!

1 Answer 1

1

You need copy xyz each iteration and change the values in the copy in order to keep track of original values:

number_atoms = 12
at_nums = [26., 6., 6., 6., 6., 6., 8., 8., 8., 8., 8.]

xyz = [
    [0.08778, 0.99666, 0.30648], [0.41688, 2.70076, 1.10135],
    [1.90494, 0.91685, -0.26984], [-0.44512, 1.73972, -1.24406],
    [-1.68572, 1.01617, 1.01221], [-0.1977, -0.77177, -0.35553],
    [0.61588, 3.6995, 1.59813], [2.98863, 0.86173, -0.59616],
    [-0.78312, 2.20935, -2.22362], [-2.73208, 1.02071, 1.44702],
    [-0.36006, -1.82939, -0.72827]
]

for i, atom in enumerate(xyz):
    for j, item in enumerate(atom):
        new_xyz = [row.copy() for row in xyz]
        new_xyz[i][j] += .005

        with open('/tmp/output{}.xyz'.format(i * 3 + j), 'w') as f:
            f.write('{:.0f}\n\n'.format(number_atoms))
            for at_num_i, xyz_disp_i in zip(at_nums, new_xyz):
                f.write(
                    '{:.0f}\t{:.8f}\t{:.8f}\t{:.8f}\n'.format(
                        at_num_i, *xyz_disp_i
                    )
                )
Sign up to request clarification or add additional context in comments.

7 Comments

So this adds 0.005 to all three items [0.08778, 0.99666, 0.30648], and then all three [0.41688, 2.70076, 1.10135], ect.. And creates 11 new output files. I need it to add to each number individually, so that I will have 33 output files, one file for every number having 0.005 added to it.
@Dragmoogle: But there are just 11 elements in xyz, can you clarify that in the question ?
So there are 11 elements in xyz. But there are 3 elements within each element. So I need it to create 33 new output files
I don't know how to clarify this question any more! My first output file needs to have 0.08778 + 0.005, with all other numbers the same. My 33rd output file needs to have -0.72827 + 0.005 with all other numbers the same.
Ah you are correct. I didn't notice that you have changed your original answer, Apologies for that, and thank you very much for your help. I will accept your answer now.
|

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.