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

Annotation of /trunk/pyvisi/py_src/datacollector.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1148 - (hide annotations)
Wed May 16 22:45:33 2007 UTC (12 years, 5 months ago) by jongui
File MIME type: text/x-python
File size: 12531 byte(s)
Added the updated files for pyvisi and removed some incorrect reference images.
1 ksteube 1147 """
2     @author: John NGUI
3     """
4    
5     import vtk
6     import tempfile, os, sys
7 jongui 1148 from constant import Source, ColorMode
8 ksteube 1147 try:
9     import esys.escript
10     except ImportError:
11     print "Warning: importing esys.escript failed."
12    
13     class DataCollector:
14     """
15     Class that defines a data collector. A data collector is used to read
16 jongui 1148 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 ksteube 1147
20     @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
22     second scalar, vector or tensor attribute needs to be specified from the
23     same source, a second DataCollector instance must be created.
24     """
25    
26     def __init__(self, source = Source.XML):
27     """
28     Initialise the data collector.
29    
30     @type source: L{Source <constant.Source>} constant
31     @param source: Source type
32     """
33    
34     self.__source = source
35 jongui 1148 # 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 ksteube 1147
43     if(source == Source.XML): # Source is an XML file.
44     self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
45     # Source is a escript data object using a temp file in the background.
46     elif (self.__source == Source.ESCRIPT):
47     self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
48     # Create a temporary .xml file and retrieve its path.
49     self.__tmp_file = tempfile.mkstemp(suffix=".xml")[1]
50    
51     def __del__(self):
52     """
53     Perform some clean up of the temporary file.
54     """
55    
56     if (self.__source == Source.ESCRIPT):
57     if os.access(self.__tmp_file,os.F_OK): os.unlink(self.__tmp_file)
58    
59     def setFileName(self, file_name):
60     """
61     Set the XML file name to read.
62    
63     @type file_name: String
64     @param file_name: Name of the file to read
65     """
66    
67 jongui 1148 self.__modified = True
68    
69 ksteube 1147 if(self.__source == Source.XML):
70     # Check whether the specified file exists, otherwise exit.
71     if not(os.access(file_name, os.F_OK)):
72 jongui 1148 raise IOError("\nERROR: '%s' file does NOT exists.\n" % \
73     file_name)
74 ksteube 1147
75     self.__vtk_xml_reader.SetFileName(file_name)
76     # Update must be called after SetFileName to make the reader
77     # up-to-date. Otherwise, some output values may be incorrect.
78     self.__vtk_xml_reader.Update()
79     self.__get_attribute_lists()
80     else:
81     raise ValueError("Source type %s does not support \
82     'setFileName'\n" % self.__source)
83    
84     def setData(self,**args):
85     """
86     Create data using the <name>=<data> pairing. Assumption is made
87     that the data will be given in the appropriate format.
88     """
89    
90 jongui 1148 self.__modified = True
91    
92 ksteube 1147 if self.__source == Source.ESCRIPT:
93     esys.escript.saveVTK(self.__tmp_file,**args)
94     self.__vtk_xml_reader.SetFileName(self.__tmp_file)
95 jongui 1148
96 ksteube 1147 # Modified must be called for setData but NOT for
97     # setFileName. If Modified is not called, only the first file
98     # will always be displayed. The reason Modified is used is
99     # because the same temporary file name is always used
100     # (previous file is overwritten). Modified MUST NOT be used in
101     # setFileName, it can cause incorrect output such as map.
102     self.__vtk_xml_reader.Modified()
103 jongui 1148
104 ksteube 1147 # Update must be called after Modified. If Update is called before
105     # Modified, then the first/second image(s) may not be updated
106     # correctly.
107     self.__vtk_xml_reader.Update()
108     self.__get_attribute_lists()
109     else:
110     raise ValueError("Source type %s does not support 'setData'\n" \
111     % self.__source)
112    
113 jongui 1148 # This method is used to delay the execution of setting the active scalar
114     # until 'setFileName' or 'setData' have been executed.
115 ksteube 1147 def setActiveScalar(self, scalar):
116     """
117     Specify the scalar field to load.
118    
119     @type scalar: String
120     @param scalar: Scalar field to load from the file.
121     """
122 jongui 1148
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 ksteube 1147 # Check whether the specified scalar is available in either point
132     # or cell data. If not available, program exits.
133    
134     # NOTE: This check is similar to the check used in _getScalarRange
135     # but this is used only when a scalar attribute has been specified.
136 jongui 1148 if self.__active_scalar in self.__point_attribute['scalars']:
137     self._getDataCollectorOutput().GetPointData().SetActiveScalars(
138     self.__active_scalar)
139     elif self.__active_scalar in self.__cell_attribute['scalars']:
140     self._getDataCollectorOutput().GetCellData().SetActiveScalars(
141     self.__active_scalar)
142 ksteube 1147 else:
143 jongui 1148 raise IOError("ERROR: No scalar called '%s' is available." % \
144     self.__active_scalar)
145 ksteube 1147
146 jongui 1148 # This method is used to delay the execution of setting the active vector
147     # until 'setFileName' or 'setData' have been executed.
148 ksteube 1147 def setActiveVector(self, vector):
149     """
150     Specify the vector field to load.
151    
152     @type vector: String
153     @param vector: Vector field to load from the file.
154     """
155 jongui 1148
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 ksteube 1147 # Check whether the specified vector is available in either point
165     # or cell data. If not available, program exits.
166    
167     # NOTE: This check is similar to the check used in _getVectorRange
168     # but this is used only when a vector attribute has been specified.
169 jongui 1148 if self.__active_vector in self.__point_attribute['vectors']:
170     self._getDataCollectorOutput().GetPointData().SetActiveVectors(
171     self.__active_vector)
172     elif self.__active_vector in self.__cell_attribute['vectors']:
173     self._getDataCollectorOutput().GetCellData().SetActiveVectors(
174     self.__active_vector)
175 ksteube 1147 else:
176 jongui 1148 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 ksteube 1147 def setActiveTensor(self, tensor):
182     """
183     Specify the tensor field to load.
184    
185     @type tensor: String
186     @param tensor: Tensor field to load from the file.
187     """
188    
189 jongui 1148 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 ksteube 1147 # Check whether the specified tensor is available in either point
198     # or cell data. If not available, program exits.
199    
200     # NOTE: This check is similar to the check used in _getTensorRange
201     # but this is used only when a tensor attribute has been specified.
202 jongui 1148 if self.__active_tensor in self.__point_attribute['tensors']:
203     self._getDataCollectorOutput().GetPointData().SetActiveTensors(
204     self.__active_tensor)
205     elif self.__active_tensor in self.__cell_attribute['tensors']:
206     self._getDataCollectorOutput().GetCellData().SetActiveTensors(
207     self.__active_tensor)
208 ksteube 1147 else:
209 jongui 1148 raise IOError("ERROR: No tensor called '%s' is available." % \
210     self.__active_tensor)
211 ksteube 1147
212     def __get_array_type(self, arr):
213     """
214     Return whether an array type is scalar, vector or tensor by looking
215     at the number of components in the array.
216    
217     @type arr: vtkDataArray
218     @param arr: An array from the source.
219     @rtype: String
220     @return: Array type ('scalar', vector' or 'tensor')
221     """
222    
223     # Number of components in an array.
224     num_components = arr.GetNumberOfComponents()
225    
226     if num_components == 1:
227     return 'scalars'
228     elif num_components == 3:
229     return 'vectors'
230     elif num_components == 9:
231     return 'tensors'
232    
233     def __get_attribute_list(self, data):
234     """
235     Return the available scalar, vector and tensor attributes
236     (either point or cell data).
237    
238     @type data: vtkPointData or vtkCellData
239     @param data: Available point data or cell data from the source
240     @rtype: Dictionary
241     @return: Dictionary containing the available scalar, vector and \
242     tensor attributes
243     """
244    
245     attribute = {'scalars':[], 'vectors':[], 'tensors':[]}
246     if data:
247     num_arrays = data.GetNumberOfArrays() # Number of arrays.
248     for i in range(num_arrays):
249     name = data.GetArrayName(i) # Get an array name.
250     type = self.__get_array_type(data.GetArray(i)) # Get array type.
251     attribute[type].extend([name]) # Add array name to dictionary.
252    
253     return attribute
254    
255     def __get_attribute_lists(self):
256     """
257     Get all the available point and cell data attributes from the source.
258     """
259    
260     # Get all the available point data attributes into a list.
261     self.__point_attribute = \
262 jongui 1148 self.__get_attribute_list(
263     self._getDataCollectorOutput().GetPointData())
264    
265 ksteube 1147 # Get all the available cell data attribute into another list.
266     self.__cell_attribute = \
267 jongui 1148 self.__get_attribute_list(
268     self._getDataCollectorOutput().GetCellData())
269 ksteube 1147
270     def _getScalarRange(self):
271     """
272     Return the scalar range.
273    
274     @rtype: Two column tuple containing numbers
275     @return: Scalar range
276     """
277    
278     # Check whether any scalar is available in either point or cell data.
279     # If not available, program exits.
280    
281     # NOTE: This check is similar to the check used in _setActiveScalar
282     # but this is used only when no scalar attribute has been specified.
283     if(len(self.__point_attribute['scalars']) != 0):
284 jongui 1148 return self._getDataCollectorOutput().GetPointData().\
285     GetScalars().GetRange(-1)
286 ksteube 1147 elif(len(self.__cell_attribute['scalars']) != 0):
287 jongui 1148 return self._getDataCollectorOutput().GetCellData().\
288     GetScalars().GetRange(-1)
289 ksteube 1147 else:
290 jongui 1148 raise IOError("\nERROR: No scalar is available.\n")
291 ksteube 1147
292     def _getVectorRange(self):
293     """
294     Return the vector range.
295    
296     @rtype: Two column tuple containing numbers
297     @return: Vector range
298     """
299    
300     # Check whether any vector is available in either point or cell data.
301     # If not available, program exits.
302    
303     # NOTE: This check is similar to the check used in _setActiveVector
304     # but this is used only when no vector attribute has been specified.
305    
306     # NOTE: Generally GetRange(-1) returns the correct vector range.
307     # However, there are certain data sets where GetRange(-1) seems
308     # to return incorrect mimimum vector although the maximum vector is
309     # correct. As a result, the mimimum vector has been hard coded to 0.0
310     # to accommodate for the incorrect cases.
311     if(len(self.__point_attribute['vectors']) != 0):
312     vector_range = \
313 jongui 1148 self._getDataCollectorOutput().GetPointData().\
314     GetVectors().GetRange(-1)
315 ksteube 1147 return (0.0, vector_range[1])
316     elif(len(self.__cell_attribute['vectors']) != 0):
317     vector_range = \
318 jongui 1148 self._getDataCollectorOutput().GetCellData().\
319     GetVectors().GetRange(-1)
320 ksteube 1147 return (0.0, vector_range[1])
321     else:
322 jongui 1148 raise IOError("\nERROR: No vector is available.\n")
323 ksteube 1147
324     def _getTensorRange(self):
325     """
326     Return the tensor range.
327    
328     @rtype: Two column tuple containing numbers
329     @return: Tensor range
330     """
331    
332     # Check whether any tensor is available in either point or cell data.
333     # If not available, program exits.
334    
335     # NOTE: This check is similar to the check used in _setActiveTensor
336     # but this is used only when no tensor attribute has been specified.
337     if(len(self.__point_attribute['tensors']) != 0):
338 jongui 1148 return self._getDataCollectorOutput().GetPointData().\
339     GetTensors().GetRange(-1)
340 ksteube 1147 elif(len(self.__cell_attribute['tensors']) != 0):
341 jongui 1148 return self._getDataCollectorOutput().GetCellData().\
342     GetTensors().GetRange(-1)
343 ksteube 1147 else:
344 jongui 1148 raise IOError("\nERROR: No tensor is available.\n")
345 ksteube 1147
346 jongui 1148 def _getDataCollectorOutput(self):
347 ksteube 1147 """
348     Return the output of the data collector.
349    
350     @rtype: vtkUnstructuredGrid
351     @return: Unstructured grid
352     """
353 jongui 1148 return self.__vtk_xml_reader.GetOutput()
354 ksteube 1147
355 jongui 1148 def _isModified(self):
356     """
357     Return whether the DataCollector has been modified.
358 ksteube 1147
359 jongui 1148 @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     @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    

  ViewVC Help
Powered by ViewVC 1.1.26