/[escript]/temp/pyvisi/py_src/datacollector.py
ViewVC logotype

Diff of /temp/pyvisi/py_src/datacollector.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1147 by ksteube, Wed May 16 06:39:11 2007 UTC revision 1148 by jongui, Wed May 16 22:45:33 2007 UTC
# Line 4  Line 4 
4    
5  import vtk  import vtk
6  import tempfile, os, sys  import tempfile, os, sys
7  from constant import Source, VizType, ColorMode  from constant import Source, ColorMode
8  try:  try:
9      import esys.escript      import esys.escript
10  except ImportError:  except ImportError:
11      print "Warning: importing esys.escript failed."      print "Warning: importing esys.escript failed."
12    
 try:  
      PYVISI_WORKDIR=os.environ['PYVISI_WORKDIR']  
 except KeyError:  
      PYVISI_WORKDIR='.'  
 try:  
      PYVISI_TEST_DATA_ROOT=os.environ['PYVISI_TEST_DATA_ROOT']  
 except KeyError:  
      PYVISI_TEST_DATA_ROOT='.'  
       
13  class DataCollector:  class DataCollector:
14      """      """
15      Class that defines a data collector. A data collector is used to read      Class that defines a data collector. A data collector is used to read
16      data from an XML file or from an escript object directly.      data from an XML file or from an escript object directly. Writing XML
17        files are expensive, but this approach has the advantage given that the
18        results can be analyzed easily after the simulation has completed.  
19    
20      @attention: A DataCollector instance can only be used to specify one      @attention: A DataCollector instance can only be used to specify one
21      scalar, vector and tensor attribute from a source at any one time. If a      scalar, vector and tensor attribute from a source at any one time. If a
22      second scalar, vector or tensor attribute needs to be specified from the      second scalar, vector or tensor attribute needs to be specified from the
23      same source, a second DataCollector instance must be created.      same source, a second DataCollector instance must be created.
   
     @attention: When a series of XML files or escript objects are read  
     (using 'setFileName' or 'setData' in a for-loop), the 'setActiveScalar' /  
     'setActiveVector' / 'setActiveTensor' have to be called for each new file  
     (provided a specific field needs to be loaded) as all active fields  
     specified from the previous file goes back to the default once a new file  
     is read.  
24      """      """
25    
26      def __init__(self, source = Source.XML):      def __init__(self, source = Source.XML):
# Line 46  class DataCollector: Line 32  class DataCollector:
32          """          """
33    
34          self.__source = source          self.__source = source
35          self.__count = 0 # Keeps track of the number of files/sources read.          # Keeps track on whether DataCollector have been modified.
36            self.__modified = True
37            # Keeps track on whether any specific scalar, vector or tensor
38            # field have been specified.
39            self.__set_scalar = False
40            self.__set_vector= False
41            self.__set_tensor= False
42    
43          if(source == Source.XML): # Source is an XML file.          if(source == Source.XML): # Source is an XML file.
44              self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()              self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
# Line 72  class DataCollector: Line 64  class DataCollector:
64          @param file_name: Name of the file to read          @param file_name: Name of the file to read
65          """          """
66    
67            self.__modified = True
68    
69          if(self.__source == Source.XML):          if(self.__source == Source.XML):
70              # Check whether the specified file exists, otherwise exit.              # Check whether the specified file exists, otherwise exit.
71              if not(os.access(file_name, os.F_OK)):              if not(os.access(file_name, os.F_OK)):
72                  raise IOError("ERROR: '%s' file does NOT exists." % file_name)                        raise IOError("\nERROR: '%s' file does NOT exists.\n" % \
73                            file_name)
74    
75              self.__vtk_xml_reader.SetFileName(file_name)              self.__vtk_xml_reader.SetFileName(file_name)
76              # Update must be called after SetFileName to make the reader              # Update must be called after SetFileName to make the reader
77              # up-to-date. Otherwise, some output values may be incorrect.              # up-to-date. Otherwise, some output values may be incorrect.
78              self.__vtk_xml_reader.Update()              self.__vtk_xml_reader.Update()
             self.__output = self.__vtk_xml_reader.GetOutput()  
79              self.__get_attribute_lists()              self.__get_attribute_lists()
               
             # Count has to be larger than zero because when setFileName is  
             # called for the first time, the data set mapper has not yet been  
             # instantiated. Therefore, the range of the mapper can only be  
             # updated after the first file/source has been read.  
             if(self.__count > 0):  
                 self._updateRange()  
   
             self.__count+=1  
   
80          else:          else:
81              raise ValueError("Source type %s does not support \              raise ValueError("Source type %s does not support \
82              'setFileName'\n" % self.__source)              'setFileName'\n" % self.__source)
# Line 103  class DataCollector: Line 87  class DataCollector:
87          that the data will be given in the appropriate format.          that the data will be given in the appropriate format.
88          """          """
89    
90            self.__modified = True
91    
92          if self.__source == Source.ESCRIPT:          if self.__source == Source.ESCRIPT:
93              esys.escript.saveVTK(self.__tmp_file,**args)              esys.escript.saveVTK(self.__tmp_file,**args)
94              self.__vtk_xml_reader.SetFileName(self.__tmp_file)              self.__vtk_xml_reader.SetFileName(self.__tmp_file)
95    
96              # Modified must be called for setData but NOT for              # Modified must be called for setData but NOT for
97              # setFileName. If Modified is not called, only the first file              # setFileName. If Modified is not called, only the first file
98              # will always be displayed. The reason Modified is used is              # will always be displayed. The reason Modified is used is
# Line 113  class DataCollector: Line 100  class DataCollector:
100              # (previous file is overwritten). Modified MUST NOT be used in              # (previous file is overwritten). Modified MUST NOT be used in
101              # setFileName, it can cause incorrect output such as map.              # setFileName, it can cause incorrect output such as map.
102              self.__vtk_xml_reader.Modified()              self.__vtk_xml_reader.Modified()
103    
104              # Update must be called after Modified. If Update is called before              # Update must be called after Modified. If Update is called before
105              # Modified, then the first/second image(s) may not be updated              # Modified, then the first/second image(s) may not be updated
106              # correctly.              # correctly.
107              self.__vtk_xml_reader.Update()              self.__vtk_xml_reader.Update()
             self.__output = self.__vtk_xml_reader.GetOutput()  
108              self.__get_attribute_lists()              self.__get_attribute_lists()
   
             if(self.__count > 0):  
                 self._updateRange()  
   
             self.__count+=1  
109          else:          else:
110              raise ValueError("Source type %s does not support 'setData'\n" \              raise ValueError("Source type %s does not support 'setData'\n" \
111                      % self.__source)                      % self.__source)
112    
113        # This method is used to delay the execution of setting the active scalar
114        # until 'setFileName' or 'setData' have been executed.
115      def setActiveScalar(self, scalar):      def setActiveScalar(self, scalar):
116          """          """
117          Specify the scalar field to load.          Specify the scalar field to load.
# Line 135  class DataCollector: Line 119  class DataCollector:
119          @type scalar: String          @type scalar: String
120          @param scalar: Scalar field to load from the file.          @param scalar: Scalar field to load from the file.
121          """          """
122            
123            self.__set_scalar = True
124            self.__active_scalar = scalar
125    
126        def _setActiveScalar(self):
127            """
128            Load the specified scalar field.
129            """
130    
131          # Check whether the specified scalar is available in either point          # Check whether the specified scalar is available in either point
132          # or cell data. If not available, program exits.          # or cell data. If not available, program exits.
133    
134          # NOTE: This check is similar to the check used in _getScalarRange          # NOTE: This check is similar to the check used in _getScalarRange
135          # but this is used only when a scalar attribute has been specified.          # but this is used only when a scalar attribute has been specified.
136          if scalar in self.__point_attribute['scalars']:          if self.__active_scalar in self.__point_attribute['scalars']:
137              self._getOutput().GetPointData().SetActiveScalars(scalar)              self._getDataCollectorOutput().GetPointData().SetActiveScalars(
138          elif scalar in self.__cell_attribute['scalars']:                      self.__active_scalar)
139              self._getOutput().GetCellData().SetActiveScalars(scalar)          elif self.__active_scalar in self.__cell_attribute['scalars']:
140                self._getDataCollectorOutput().GetCellData().SetActiveScalars(
141                        self.__active_scalar)
142          else:          else:
143              raise IOError("ERROR: No scalar called '%s' is available." % scalar)              raise IOError("ERROR: No scalar called '%s' is available." % \
144                        self.__active_scalar)
145    
146        # This method is used to delay the execution of setting the active vector
147        # until 'setFileName' or 'setData' have been executed.
148      def setActiveVector(self, vector):      def setActiveVector(self, vector):
149          """          """
150          Specify the vector field to load.          Specify the vector field to load.
# Line 155  class DataCollector: Line 152  class DataCollector:
152          @type vector: String          @type vector: String
153          @param vector: Vector field to load from the file.          @param vector: Vector field to load from the file.
154          """          """
155            
156            self.__set_vector = True
157            self.__active_vector = vector
158    
159        def _setActiveVector(self):
160            """
161            Load the specified vector field.
162            """
163    
164          # Check whether the specified vector is available in either point          # Check whether the specified vector is available in either point
165          # or cell data. If not available, program exits.          # or cell data. If not available, program exits.
166    
167          # NOTE: This check is similar to the check used in _getVectorRange          # NOTE: This check is similar to the check used in _getVectorRange
168          # but this is used only when a vector attribute has been specified.          # but this is used only when a vector attribute has been specified.
169          if vector in self.__point_attribute['vectors']:          if self.__active_vector in self.__point_attribute['vectors']:
170              self._getOutput().GetPointData().SetActiveVectors(vector)              self._getDataCollectorOutput().GetPointData().SetActiveVectors(
171          elif vector in self.__cell_attribute['vectors']:                      self.__active_vector)
172              self._getOutput().GetCellData().SetActiveVectors(vector)          elif self.__active_vector in self.__cell_attribute['vectors']:
173                self._getDataCollectorOutput().GetCellData().SetActiveVectors(
174                        self.__active_vector)
175          else:          else:
176              raise IOError("ERROR: No vector called '%s' is available." % vector)              raise IOError("ERROR: No vector called '%s' is available." % \
177                                    self.__active_vector)
178    
179        # This method is used to delay the execution of setting the active tensor
180        # until 'setFileName' or 'setData' have been executed.
181      def setActiveTensor(self, tensor):      def setActiveTensor(self, tensor):
182          """          """
183          Specify the tensor field to load.          Specify the tensor field to load.
# Line 176  class DataCollector: Line 186  class DataCollector:
186          @param tensor: Tensor field to load from the file.          @param tensor: Tensor field to load from the file.
187          """          """
188    
189            self.__set_tensor = True
190            self.__active_tensor = tensor
191    
192        def _setActiveTensor(self):
193            """
194            Load the the specified tensor field.
195            """
196    
197          # Check whether the specified tensor is available in either point          # Check whether the specified tensor is available in either point
198          # or cell data. If not available, program exits.          # or cell data. If not available, program exits.
199    
200          # NOTE: This check is similar to the check used in _getTensorRange          # NOTE: This check is similar to the check used in _getTensorRange
201          # but this is used only when a tensor attribute has been specified.          # but this is used only when a tensor attribute has been specified.
202          if tensor in self.__point_attribute['tensors']:          if self.__active_tensor in self.__point_attribute['tensors']:
203              self._getOutput().GetPointData().SetActiveTensors(tensor)              self._getDataCollectorOutput().GetPointData().SetActiveTensors(
204          elif tensor in self.__cell_attribute['tensors']:                      self.__active_tensor)
205              self._getOutput().GetCellData().SetActiveTensors(tensor)          elif self.__active_tensor in self.__cell_attribute['tensors']:
206                self._getDataCollectorOutput().GetCellData().SetActiveTensors(
207                        self.__active_tensor)
208          else:          else:
209              raise IOError("ERROR: No tensor called '%s' is available." % tensor)              raise IOError("ERROR: No tensor called '%s' is available." % \
210                        self.__active_tensor)
     # 'object' is set to 'None' because some types of visualization have  
     # two ranges that needs to be updated while others only have one.  
     def _paramForUpdatingMultipleSources(self, viz_type, color_mode, mapper,  
             object = None):  
         """  
         Parameters required to update the necessary data when two or more  
         files or escript objects are read.  
   
         @type viz_type: : L{VizType <constant.VizType>} constant  
         @param viz_type: Type if visualization  
         @type color_mode: L{ColorMode <constant.ColorMode>} constant  
         @param color_mode: Type of color mode  
         @type mapper: vtkDataSetMapper  
         @param mapper: Mapped data  
         @type object: vtkPolyDataAlgorithm (i.e. vtkContourFilter, vtkGlyph3D, \  
                 etc)  
         @param object: Polygonal data  
         """  
   
         self.__viz_type = viz_type  
         self.__color_mode = color_mode  
         self.__mapper = mapper  
         self.__object = object  
   
     def _updateRange(self):  
         """  
         Update the necessary range(s) when two or more files or escript objects  
         are read.  
         """  
   
         if self.__viz_type == VizType.MAP or \  
                 self.__viz_type == VizType.ELLIPSOID or \  
                 self.__viz_type == VizType.CARPET:  
             self.__mapper.SetScalarRange(self._getScalarRange())  
         elif self.__viz_type == VizType.VELOCITY:  
             if self.__color_mode == ColorMode.VECTOR:  
                 self.__object.SetRange(self._getVectorRange())  
                 self.__mapper.SetScalarRange(self._getVectorRange())  
             elif self.__color_mode == ColorMode.SCALAR:  
                 self.__object.SetRange(self._getScalarRange())  
                 self.__mapper.SetScalarRange(self._getScalarRange())  
         elif self.__viz_type == VizType.CONTOUR:  
             self.__object.GenerateValues(  
                     self.__object.GetNumberOfContours(),  
                     self._getScalarRange()[0],  
                     self._getScalarRange()[1])  
             self.__mapper.SetScalarRange(self._getScalarRange())  
         elif self.__viz_type == VizType.STREAMLINE:  
             if self.__color_mode == ColorMode.VECTOR:  
                 self.__mapper.SetScalarRange(self._getVectorRange())  
             elif self.__color_mode == ColorMode.SCALAR:  
                 self.__mapper.SetScalarRange(self._getScalarRange())  
211    
212      def __get_array_type(self, arr):      def __get_array_type(self, arr):
213          """          """
# Line 291  class DataCollector: Line 259  class DataCollector:
259    
260          # Get all the available point data attributes into a list.          # Get all the available point data attributes into a list.
261          self.__point_attribute = \          self.__point_attribute = \
262                  self.__get_attribute_list(self._getOutput().GetPointData())                  self.__get_attribute_list(
263                    self._getDataCollectorOutput().GetPointData())
264    
265          # Get all the available cell data attribute into another list.            # Get all the available cell data attribute into another list.  
266          self.__cell_attribute = \          self.__cell_attribute = \
267                  self.__get_attribute_list(self._getOutput().GetCellData())                  self.__get_attribute_list(
268                    self._getDataCollectorOutput().GetCellData())
269    
270      def _getScalarRange(self):      def _getScalarRange(self):
271          """          """
# Line 310  class DataCollector: Line 281  class DataCollector:
281          # NOTE: This check is similar to the check used in _setActiveScalar          # NOTE: This check is similar to the check used in _setActiveScalar
282          # but this is used only when no scalar attribute has been specified.          # but this is used only when no scalar attribute has been specified.
283          if(len(self.__point_attribute['scalars']) != 0):          if(len(self.__point_attribute['scalars']) != 0):
284              return self._getOutput().GetPointData().GetScalars().GetRange(-1)              return self._getDataCollectorOutput().GetPointData().\
285                        GetScalars().GetRange(-1)
286          elif(len(self.__cell_attribute['scalars']) != 0):          elif(len(self.__cell_attribute['scalars']) != 0):
287              return self._getOutput().GetCellData().GetScalars().GetRange(-1)              return self._getDataCollectorOutput().GetCellData().\
288                        GetScalars().GetRange(-1)
289          else:          else:
290              raise IOError("ERROR: No scalar is available.")              raise IOError("\nERROR: No scalar is available.\n")
291    
292      def _getVectorRange(self):      def _getVectorRange(self):
293          """          """
# Line 337  class DataCollector: Line 310  class DataCollector:
310          # to accommodate for the incorrect cases.          # to accommodate for the incorrect cases.
311          if(len(self.__point_attribute['vectors']) != 0):          if(len(self.__point_attribute['vectors']) != 0):
312              vector_range = \              vector_range = \
313                      self._getOutput().GetPointData().GetVectors().GetRange(-1)                      self._getDataCollectorOutput().GetPointData().\
314                        GetVectors().GetRange(-1)
315              return (0.0, vector_range[1])              return (0.0, vector_range[1])
316          elif(len(self.__cell_attribute['vectors']) != 0):          elif(len(self.__cell_attribute['vectors']) != 0):
317              vector_range = \              vector_range = \
318                      self._getOutput().GetCellData().GetVectors().GetRange(-1)                      self._getDataCollectorOutput().GetCellData().\
319                        GetVectors().GetRange(-1)
320              return (0.0, vector_range[1])              return (0.0, vector_range[1])
321          else:          else:
322              print "\nERROR: No vector is available.\n"                raise IOError("\nERROR: No vector is available.\n")
             sys.exit(0)  
323    
324      def _getTensorRange(self):      def _getTensorRange(self):
325          """          """
# Line 361  class DataCollector: Line 335  class DataCollector:
335          # NOTE: This check is similar to the check used in _setActiveTensor          # NOTE: This check is similar to the check used in _setActiveTensor
336          # but this is used only when no tensor attribute has been specified.          # but this is used only when no tensor attribute has been specified.
337          if(len(self.__point_attribute['tensors']) != 0):          if(len(self.__point_attribute['tensors']) != 0):
338              return self._getOutput().GetPointData().GetTensors().GetRange(-1)              return self._getDataCollectorOutput().GetPointData().\
339                        GetTensors().GetRange(-1)
340          elif(len(self.__cell_attribute['tensors']) != 0):          elif(len(self.__cell_attribute['tensors']) != 0):
341              return self._getOutput().GetCellData().GetTensors().GetRange(-1)              return self._getDataCollectorOutput().GetCellData().\
342                        GetTensors().GetRange(-1)
343          else:          else:
344              print "\nERROR: No tensor is available.\n"                raise IOError("\nERROR: No tensor is available.\n")
             sys.exit(1)  
345    
346      def _getOutput(self):      def _getDataCollectorOutput(self):
347          """          """
348          Return the output of the data collector.          Return the output of the data collector.
349    
350          @rtype: vtkUnstructuredGrid          @rtype: vtkUnstructuredGrid
351          @return: Unstructured grid          @return: Unstructured grid
352          """          """
353            return self.__vtk_xml_reader.GetOutput()
354    
355        def _isModified(self):
356            """
357            Return whether the DataCollector has been modified.
358    
359            @rtype: Boolean
360            @return: True or False
361            """
362    
363            if(self.__modified == True):
364                self.__modified = False
365                return True
366            else:
367                return False
368        
369        def _isScalarSet(self):
370            """
371            Return whether a specific scalar field has been specified.
372    
373            @rtype: Boolean
374            @return: True or False
375            """
376    
377            return self.__set_scalar
378    
379        def _isVectorSet(self):
380            """
381            Return whether a specific vector field has been specified.
382    
383            @rtype: Boolean
384            @return: True or False
385            """
386    
387            return self.__set_vector
388    
389        def _isTensorSet(self):
390            """
391            Return whether a specific tensor field has been specified.
392    
393          return self.__output          @rtype: Boolean
394            @return: True or False
395            """
396    
397            return self.__set_tensor
398    
399        def _getCenter(self):
400            """
401            Return the center of the rendered object.
402    
403            @rtype: Three column tuple containing numbers
404            @return: Center of the rendered object
405            """
406    
407            return self._getDataCollectorOutput().GetCenter()
408            

Legend:
Removed from v.1147  
changed lines
  Added in v.1148

  ViewVC Help
Powered by ViewVC 1.1.26