CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   ParaView (https://www.cfd-online.com/Forums/paraview/)
-   -   [General] Python Programmable vtkImageData (https://www.cfd-online.com/Forums/paraview/136923-python-programmable-vtkimagedata.html)

joshuawd June 6, 2014 16:01

Python Programmable vtkImageData
 
I am trying to write a Python programmable filter that converts point data to a structured grid (i.e., vtkImageData). There is example code here that allegedly does this: http://www.paraview.org/Wiki/Python_Programmable_Filter
(see the "Changing Data Type" section). I opened a new Paraview 4.1.0 file, added a sphere source, applied an elevation filter, then applied a programmable filter, selected "vtkImageData" as the output type, and pasted in the code from the above link. However, when I tried to use this code I ran into 2 problems. First, there were a couple of errors (likely because the code was for an old version of Paraview). Second, when I figured out how to correct the errors (see my corrected version below), the filter produced no data. I am at my wits' end as to why this simple code is not working. Any help you can provide is much appreciated.

Thanks,
Josh

Code:

#this example creates an Nx1x1 imagedata output
#and populates its cells with the point centered
#scalars of the input dataset
 
#get a hold of the input
pdi = self.GetInput()
numPts = pdi.GetNumberOfPoints()
 
#create the output dataset with one cell per point
ido = self.GetOutput()
ido.SetDimensions(numPts+1,2,2)
ido.SetOrigin(-1,-1,-1)
ido.SetSpacing(.1,.1,.1)
ido.AllocateScalars(vtk.VTK_FLOAT,1)
 
#choose an input point data array to copy
ivals = pdi.GetPointData().GetScalars()
ca = vtk.vtkFloatArray()
ca.SetName(ivals.GetName())
ca.SetNumberOfComponents(1)
ca.SetNumberOfTuples(numPts)
 
#add the new array to the output
ido.GetCellData().AddArray(ca)
 
#copy the values over element by element
for i in range(0, numPts):
  ca.SetValue(i, ivals.GetValue(i))


wyldckat June 8, 2014 11:23

Greetings Joshua and welcome to the forum!

Well, this is a bit sad... this example you're trying to follow from the wiki page was apparently last tested with ParaView 3.3.1, according to the images; and according to the wiki page history, this example has not been updated since then, and it's not the only example.

I've even tried with ParaView 3.6.2, in hope that this would help make the transition from the old version to the newer versions of ParaView, but it doesn't work with 3.6.2 either.

I'll update this post as soon as I can figure out how to fix this. My first guess is that the object of type "vtkImageData" is the one that isn't being properly set-up for proper use in this filter and the first place I'm looking for answers is here: http://www.vtk.org/doc/release/5.10/...ImageData.html

Best regards,
Bruno

----------
edit: So here's what I've figured out:
  1. The following code works on ParaView 3.12.0, using a "Programmable Source":
    Code:

    numPts = 1000
    ido = self.GetOutput()
    ido.SetDimensions(numPts+1,2,2)
    ido.SetOrigin(-1,-1,-1)
    ido.SetSpacing(.1,.1,.1)
    ido.SetWholeExtent(0,numPts,0,1,0,1)
    ido.AllocateScalars()

    ca = vtk.vtkFloatArray()
    ca.SetName("MINE")
    ca.SetNumberOfComponents(1)
    ca.SetNumberOfTuples(numPts)
     
    #add the new array to the output
    ido.GetCellData().AddArray(ca)

    for i in range(0, numPts):
      ca.SetValue(i, i)

  2. But a similar code will not work on ParaView 4.1.0, namely this one:
    Code:

    numPts = 1000
    ido = self.GetOutput()
    ido.SetDimensions(numPts+1,2,2)
    ido.SetOrigin(-1,-1,-1)
    ido.SetSpacing(.1,.1,.1)
    ido.SetExtent(0,numPts,0,1,0,1)
    ido.AllocateScalars(vtk.VTK_FLOAT,1)

    ca = vtk.vtkFloatArray()
    ca.SetName("MINE")
    ca.SetNumberOfComponents(1)
    ca.SetNumberOfTuples(numPts)
     
    for i in range(0, numPts):
      ca.SetValue(i, i)

    #add the new array to the output
    ido.GetCellData().SetScalars(ca)

    From what I can figure out, the pipeline is broken for the "vtkImageData" option in the "Programmable Source" and probably in the "Programmable Filter" as well.
---------------

edit 2: It looks like my hunch on the pipeline being broken was half right. The following code is needed in the section "Script (RequestInformation)" in the "Programmable Source" on ParaView 4.1.0:
Code:

from paraview import util
 
 numPts = 1000
 util.SetOutputWholeExtent(self, [0,numPts,0,1,0,1])

--------------
edit 3: Yep, the information on edit 2 solves the issue on both situations, namely for both the programmable source and filter. I've updated the wiki page accordingly: http://www.paraview.org/Wiki/Python_...ging_Data_Type

joshuawd August 15, 2014 10:26

1 Attachment(s)
Thanks very much for your help! That code works beautifully. What I'm really trying to do is create a programmable source that will load image data from a file. I can successfully parse the file, and the image data grid shows up correctly, but the scalar array that I want to use to color the data does not show up. Here's my code, and I'm attaching an example file that I want to load. I'm at a loss as to why this code is not working, since it's nearly identical to the programmable filter code that you posted.

Thanks,
Josh

Code:

def RequestData():
    #this example creates an Nx1x1 imagedata output
    #and populates its cells with the point centered
    #scalars of the input dataset
    #create the output dataset with one cell per point
    numPts = 10
    ido = self.GetOutput()
    ido.SetDimensions(numPts+1,2,2)
    ido.SetOrigin(-1,-1,-1)
    ido.SetSpacing(.1,.1,.1)
   
    # On ParaView 3.8 to 3.12
    #ido.SetWholeExtent(0,numPts,0,1,0,1)
    #ido.AllocateScalars()
   
    # On ParaView 3.98, 4.0 and 4.1
    ido.SetExtent(0,numPts,0,1,0,1)
    ido.AllocateScalars(vtk.VTK_FLOAT,1)
   
    ca = vtk.vtkFloatArray()
    ca.SetName("InteractionFreq")
    ca.SetNumberOfComponents(1)
    ca.SetNumberOfTuples(numPts)
    ido.GetCellData().AddArray(ca)
    f = open("test_file.txt")
    i = 0
    for line in f:
        for pos,word in enumerate(line.split("\t")):
          if pos == 0:
            chr = word
          if pos == 1:
            x = float(word)
          if pos == 2:
            y = float(word)
          if pos == 3:           
                ca.SetValue(i,float(word))
                #print "x " + x + " y " + y + " value " + float(word)
        i += 1
       
def RequestInformation():
    #
    # This part of the code is to be placed in the "RequestInformation Script" entry:
    #
    from paraview import util
    numPts = 10
    util.SetOutputWholeExtent(self, [0,numPts,0,1,0,1])


wyldckat August 17, 2014 14:29

Hi Joshua,

You're going to find this hard to believe, but the error is pretty simple: "def" is not necessary when defining a programmable source, nor programmable filter. The following worked for me:
  1. Output Data Set Type: "vtkImageData"
  2. Script:
    Code:

      #this example creates an Nx1x1 imagedata output
      #and populates its cells with the point centered
      #scalars of the input dataset
      #create the output dataset with one cell per point
      numPts = 10
      ido = self.GetOutput()
      ido.SetDimensions(numPts+1,2,2)
      ido.SetOrigin(-1,-1,-1)
      ido.SetSpacing(.1,.1,.1)
     
      # On ParaView 3.8 to 3.12
      #ido.SetWholeExtent(0,numPts,0,1,0,1)
      #ido.AllocateScalars()
     
      # On ParaView 3.98, 4.0 and 4.1
      ido.SetExtent(0,numPts,0,1,0,1)
      ido.AllocateScalars(vtk.VTK_FLOAT,1)
     
      ca = vtk.vtkFloatArray()
      ca.SetName("InteractionFreq")
      ca.SetNumberOfComponents(1)
      ca.SetNumberOfTuples(numPts)
     
      ido.GetCellData().AddArray(ca)

      f = open("test_file.txt")
      i = 0
      for line in f:
        for pos,word in enumerate(line.split("\t")):
          if pos == 0:
            chr = word
          if pos == 1:
            x = float(word)
          if pos == 2:
            y = float(word)
          if pos == 3:           
            ca.SetValue(i,float(word))
            i += 1
            print "x ", x, " y ", y, " value ", float(word)

      f.close()

  3. Script (RequestInformation):
    Code:

        #
        # This part of the code is to be placed in the "RequestInformation Script" entry:
        #
        from paraview import util
        numPts = 10
        util.SetOutputWholeExtent(self, [0,numPts,0,1,0,1])

And make sure the file is in the same folder where ParaView is running from!


I only did a few minor tune-ups to the "print" line and added a close for the file. In addition, improved the indentation of the source code, so that it would be consistent. Keep in mind that Python is very sensitive to indentation.


Best regards,
Bruno

joshuawd August 18, 2014 09:33

1 Attachment(s)
Bruno,

Thanks for the reply. Unfortunately, the code you posted gives me the same results I was getting before. The data loads into Paraview, but the issue is that I want to color the image data by the value of field 3 (i.e., the values stored in the scalar array "ca"). As it stands right now, the only option is solid color. Apparently, for some reason the scalar array is not getting passed through correctly or something.

Thanks,
Josh

wyldckat August 18, 2014 15:56

Hi Josh,

Did you notice the option that is selected for "Representation"? Change it from "Outline" to "Surface" and then check if it's possible to represent the new array.
Although it's strange that it selected "Outline" by default... ParaView usually only does that automatically when it estimates that the necessary amount of RAM needed for performing the surface representation might be a bit higher than desirable.

If it also does not work, uncomment the line that prints out the values that were loaded from the file. Those values should appear in the "Output Window", which is a new window that ParaView will open to show error messages, as well as other similar messages and warnings. If they do not appear, then the file is not being opened/loaded with success :(.

Best regards,
Bruno

joshuawd August 18, 2014 16:08

...and now I feel foolish. The scalar data shows up just fine under "surface" representation. Thanks much for your help!

Josh


All times are GMT -4. The time now is 21:05.