0

I have a python code that is pasted below. It works fine for what I need to do. You can notice that I load in a single dump file. How can I loop through all dump files that have the same ending pattern of *.dump and have each new file just add a new column of data to the output file? Essentially I want to add a loop so I do not have to manually re-write the code for each dump file.

from ovito.io import *
from ovito.data import *
from ovito.modifiers import *
import numpy as np

node = import_file("../200eV.dump",multiple_frames = True)

# Perform Wigner-Seitz analysis:
ws = WignerSeitzAnalysisModifier(
    per_type_occupancies = True, 
    eliminate_cell_deformation = True)
ws.reference.load("../../../WS_Ref/ws.dump")
node.modifiers.append(ws)

# Define a modifier function that selects sites of type A=1 which
# are occupied by exactly one atom of type B=2.
def modify(frame, input, output):

    # Retrieve the two-dimensional Numpy array with the site occupancy numbers.
    occupancies = input.particle_properties['Occupancy'].array

    # Get the site types as additional input:
    site_type = input.particle_properties.particle_type.array

    # Calculate total occupancy of every site:
    total_occupancy = np.sum(occupancies, axis=1)

    # Set up a particle selection by creating the Selection property:

    selection1 = (site_type == 1) & (occupancies[:,0] == 0) & (occupancies[:,1] == 0)

    output.attributes['Ca_Vac'] = np.count_nonzero(selection1)


# Insert Python modifier into the data pipeline.
node.modifiers.append(PythonScriptModifier(function = modify))

# Let OVITO do the computation and export the number of identified 
# antisites as a function of simulation time to a text file:
export_file(node, "defects_200.txt", "txt", 
    columns = ['Timestep', 'Ca_Vac'],
    multiple_frames = True)
5
  • glob.glob('/*.dump') shall return an iterable that would yield(can't remember if generator or list or tuple) the files that ends with .dump in the given relative path. Commented Sep 13, 2018 at 3:30
  • any chance you could show me how to add that to the code?
    – Ben
    Commented Sep 13, 2018 at 3:32
  • You have two different *.dump directories, which one do you want to loop through, and since I don't what is mutable and what's not in that code, if you tell me which directory to loop and what is gonna be the loop body, happy to write it for you. Commented Sep 13, 2018 at 3:36
  • @IşıkKaplan the second dump file, ws.dump, should never change. I want to loop through the eV.dump files. Sorry, I should have been clearer
    – Ben
    Commented Sep 13, 2018 at 3:42
  • Something as simple as passing the filename as an argument to your script could solve your problem - then you would be able to use tools like xargs to handle the rest.
    – Shadow
    Commented Sep 13, 2018 at 5:02

2 Answers 2

1
import numpy as np
from ovito.data import *
from ovito.io import *
from ovito.modifiers import *

ws = WignerSeitzAnalysisModifier(
    per_type_occupancies=True,
    eliminate_cell_deformation=True)
ws.reference.load("../../../WS_Ref/ws.dump")


def modify(frame, input, output):
    occupancies = input.particle_properties['Occupancy'].array

    site_type = input.particle_properties.particle_type.array

    total_occupancy = np.sum(occupancies, axis=1)  # you are also not using, also not using the frame parameter

    selection1 = (site_type == 1) & (occupancies[:, 0] == 0) & (occupancies[:, 1] == 0)

    output.attributes['Ca_Vac'] = np.count_nonzero(selection1)


import glob

for file in glob.glob('../*.glob'):
    node = import_file(file, multiple_frames=True)
    node.modifiers.append(ws)
    node.modifiers.append(PythonScriptModifier(function=modify))
    export_file(
        node, "defects_200.txt", "txt",
        columns=['Timestep', 'Ca_Vac'],
        multiple_frames=True
    )

Without knowing more this is the best I could come up with, I hope it works!

Adding this part as per the OP's request.

for index, file in enumerate(glob.glob('../*.glob')):
    node = import_file(file, multiple_frames=True)
    node.modifiers.append(ws)
    node.modifiers.append(PythonScriptModifier(function=modify))
    export_file(
        node, "defects_{}.txt".format(index), "txt",
        columns=['Timestep', 'Ca_Vac'],
        multiple_frames=True
    )

And again, this is a guess on how the library works and would work only if the original code produces defetcs_200.txt as the result.

13
  • seems like no output script is being generated, im guessing maybe its not finding any files to load or something? Instead of *.glob, shouldn't it be *.dump?
    – Ben
    Commented Sep 13, 2018 at 3:59
  • Oh I'm very sorry, it is about 7 am here, yes it is *.dump. Commented Sep 13, 2018 at 4:01
  • Ok thanks, I do have a follow up question. It creates a single column of data, is there a way for it to create a new column for each new dump file?
    – Ben
    Commented Sep 13, 2018 at 4:26
  • That sounds more like a complete new question as it is related to the libraries it uses which unfortunately I don't. Sorry. Commented Sep 13, 2018 at 4:29
  • Well it only creates one column of data, it seems like it overwrites each old file. There are 1000 rows in the output file, which would correspond to only one dump file
    – Ben
    Commented Sep 13, 2018 at 4:30
0

Try python glob package.

>>> import glob
>>> glob.glob('./[0-9].*')
['./1.gif', './2.txt']
>>> glob.glob('*.gif')
['1.gif', 'card.gif']
>>> glob.glob('?.gif')
['1.gif']

Not the answer you're looking for? Browse other questions tagged or ask your own question.