Loading multiple files for a custom Python reader

Hi, I’m writing a reader in Python based on this documentation util.vtkAlgorithm Module — ParaView/Python 5.9.1 documentation How can I load multiple files and assign them a timestep as Paraview does automatically when loading multiple VTK files with a similar filename such as 0000, 0001, etc.?

When I load multiple files using a wildcard, say *.ovf , Paraview only reads the first file from the list. In the documentation, time steps are implemented but this is only done by reading the input’s file time column. In my case I need to assign a “time” based on the filenames. I also found this https://www.paraview.org/Wiki/Animating_legacy_VTK_file_series but I’m not sure how to implement that using the @smproperty decorators .

Is there a way to obtain/access the list of files loaded by Paraview when selecting multiple files so to assign them a time step?

Also, is vtkFileSeriesReader involved when reading multiple files with similar names?

I’m no expert but I believe that in general readers that accept multiple files actually read them in as an explicit list. The wildcard/family selection mechanism is only implemented in the file dialog, but the wildcard is expanded to an explicit list before being passed to the reader.

For example, the XDMFReader Python signature is

reader = XDMFReader(registrationName='name', FileNames=['/path/to/file_001.xmf2', '/path/to/file_002.xmf2', '/path/to/file_003.xmf2'])

The XDMF format has a way to define time for each file. If a format does not (or if the times are not defined) then I think each file is given an arbitrary time of 1s,2s,3s, etc. If a format does not support time, then you can create a wrapper meta-file where you define times for each file.

Check out https://discourse.paraview.org/t/assign-time-to-a-timestep/3505

And yes I believe that in general readers are written for an individual file, and the vtkFileSeriesReader is used as a manager to hold all the file names and pass them to the reader as requested.

Thank you, but I thought there was a Python way to register the filenames using the decorators. I think I can try to do something with the XML strings

Sorry I misunderstood.

From a Python-based reader I wrote, here is the method used to ingest files.
Note that I’m using the vtkXdmfReader internally.

    @smproperty.stringvector(name="FileNames",
                                label="File Names",
                                animateable="1",
                                clean_command="RemoveAllFileNames",
                                command="AddFileName",
                                repeat_command="1",
                                number_of_elements="1",
                                panel_visibility="never"
                                )
    @smdomain.filelist()
    @smhint.filechooser(extensions="xmf", file_description="Velodyne Lagrangian XMF files")
    def AddFileName(self, name):

        if name == 'None':
            return

        _ndata = vtkXdmfReader()
        _ndata.CanReadFile(name)
        _ndata.SetFileName(name)
        _ndata.UpdateInformation()

        #-- Timestep stuff
        #- Get timesteps
        executive = self.GetExecutive()
        timesteps = _ndata.GetOutputInformation(0).Get(executive.TIME_STEPS())
        #- Add timestep(s) to internal tracking
        self._timesteps.extend(timesteps)
        self._timesteps = sorted(self._timesteps)

This method will run on all files passed from the file browser dialog.
Later on I use the collected time information like so:

    def RequestInformation(self, request, inInfoVec, outInfoVec):

        executive = self.GetExecutive()
        outInfo = outInfoVec.GetInformationObject(0)
        outInfo.Remove(executive.TIME_STEPS())
        outInfo.Remove(executive.TIME_RANGE())
        timesteps = self._timesteps
        if timesteps != []:
            for t in timesteps:
                outInfo.Append(executive.TIME_STEPS(), t)
            outInfo.Append(executive.TIME_RANGE(), timesteps[0])
            outInfo.Append(executive.TIME_RANGE(), timesteps[-1])

Check out this link:
https://public.kitware.com/pipermail/paraview/2013-September/029316.html

1 Like

Thanks, this is very helpful. Do you know where exactly the data changes when updating the time step in Paraview? Is this done in the RequestData method?

Yup, in RequestData.

The “util.vtkAlgorithm Module” link you originally posted has a few good examples of how to implement RequestData.

I personally followed the PythonCSVReader example pretty closely for updating the timestep and pulling the raw data, except I used an internal dictionary to map timesteps to the associated files (I appended the mappings in the AddFileName method, which is not part of the PythonCSVReader example, and also not shown in the posted code above - I clipped out some of the more complicated/usage-specific stuff).

I see, I ended up doing the same, although it’s a bit hard to map time step floating numbers in a dictionary or list, so for now I’m only using integers. Do you know if there is a way to get the time step index directly from Paraview’s interface?

Thanks so much for the help :slight_smile: