/[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 1197 - (hide annotations)
Mon Jun 18 02:08:34 2007 UTC (13 years, 9 months ago) by jongui
File MIME type: text/x-python
File size: 13737 byte(s)
Update the way movies are generated. Please refer to the examples. 

The user can now either specify the image range(first and last images inclusive):
mov.imageRange(input_directory = PYVISI_EXAMPLE_IMAGES_PATH,
        first_image = IMAGE_NAME + "000938.jpg",
		last_image = IMAGE_NAME + "000948.jpg")
mov.makeMovie(os.path.join(PYVISI_EXAMPLE_IMAGES_PATH, "movie.mpg"))

or the user can specify a list of images:

lst = ['image1.jpg', 'image5.jpg', 'image7.jpg]
mov.imageList(input_directory = PYVISI_EXAMPLE_IMAGES_PATH, image_list = lst)
mov.makeMovie(os.path.join(PYVISI_EXAMPLE_IMAGES_PATH, "movie.mpg"))


1 ksteube 1147 """
2 jongui 1197 @var __author__: name of author
3     @var __copyright__: copyrights
4     @var __license__: licence agreement
5     @var __url__: url entry point on documentation
6     @var __version__: version
7     @var __date__: date of the version
8 ksteube 1147 """
9    
10 jongui 1197 __author__="John Ngui, john.ngui@uq.edu.au"
11     __copyright__=""" Copyright (c) 2006 by ACcESS MNRF
12     http://www.access.edu.au
13     Primary Business: Queensland, Australia"""
14     __license__="""Licensed under the Open Software License version 3.0
15     http://www.opensource.org/licenses/osl-3.0.php"""
16     __url__="http://www.iservo.edu.au/esys"
17     __version__="$Revision$"
18     __date__="$Date$"
19    
20    
21 ksteube 1147 import vtk
22     import tempfile, os, sys
23 jongui 1148 from constant import Source, ColorMode
24 ksteube 1147 try:
25     import esys.escript
26     except ImportError:
27     print "Warning: importing esys.escript failed."
28    
29     class DataCollector:
30     """
31     Class that defines a data collector. A data collector is used to read
32 jongui 1154 data from a XML file or from an escript object directly. Writing XML
33 jongui 1148 files are expensive, but this approach has the advantage given that the
34     results can be analyzed easily after the simulation has completed.
35 ksteube 1147
36     @attention: A DataCollector instance can only be used to specify one
37     scalar, vector and tensor attribute from a source at any one time. If a
38     second scalar, vector or tensor attribute needs to be specified from the
39     same source, a second DataCollector instance must be created.
40     """
41    
42     def __init__(self, source = Source.XML):
43     """
44     Initialise the data collector.
45    
46     @type source: L{Source <constant.Source>} constant
47     @param source: Source type
48     """
49    
50     self.__source = source
51 jongui 1148 # Keeps track on whether DataCollector have been modified.
52     self.__modified = True
53 jongui 1197 # Keeps track of the number of times the 'setFileName' or 'setData'
54     # method have been executed.
55     self.__count = 0
56 jongui 1148 # Keeps track on whether any specific scalar, vector or tensor
57     # field have been specified.
58     self.__set_scalar = False
59     self.__set_vector= False
60     self.__set_tensor= False
61 ksteube 1147
62     if(source == Source.XML): # Source is an XML file.
63     self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
64     # Source is a escript data object using a temp file in the background.
65     elif (self.__source == Source.ESCRIPT):
66     self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
67     # Create a temporary .xml file and retrieve its path.
68     self.__tmp_file = tempfile.mkstemp(suffix=".xml")[1]
69    
70     def __del__(self):
71     """
72     Perform some clean up of the temporary file.
73     """
74    
75     if (self.__source == Source.ESCRIPT):
76     if os.access(self.__tmp_file,os.F_OK): os.unlink(self.__tmp_file)
77    
78     def setFileName(self, file_name):
79     """
80     Set the XML file name to read.
81    
82     @type file_name: String
83     @param file_name: Name of the file to read
84     """
85    
86 jongui 1148 self.__modified = True
87 jongui 1197 self.__count += 1
88 jongui 1148
89 ksteube 1147 if(self.__source == Source.XML):
90     # Check whether the specified file exists, otherwise exit.
91     if not(os.access(file_name, os.F_OK)):
92 jongui 1148 raise IOError("\nERROR: '%s' file does NOT exists.\n" % \
93     file_name)
94 ksteube 1147
95     self.__vtk_xml_reader.SetFileName(file_name)
96     # Update must be called after SetFileName to make the reader
97     # up-to-date. Otherwise, some output values may be incorrect.
98     self.__vtk_xml_reader.Update()
99     self.__get_attribute_lists()
100     else:
101     raise ValueError("Source type %s does not support \
102     'setFileName'\n" % self.__source)
103    
104     def setData(self,**args):
105     """
106     Create data using the <name>=<data> pairing. Assumption is made
107     that the data will be given in the appropriate format.
108     """
109    
110 jongui 1148 self.__modified = True
111 jongui 1197 self.__count += 1
112 jongui 1148
113 ksteube 1147 if self.__source == Source.ESCRIPT:
114     esys.escript.saveVTK(self.__tmp_file,**args)
115     self.__vtk_xml_reader.SetFileName(self.__tmp_file)
116 jongui 1148
117 ksteube 1147 # Modified must be called for setData but NOT for
118     # setFileName. If Modified is not called, only the first file
119     # will always be displayed. The reason Modified is used is
120     # because the same temporary file name is always used
121     # (previous file is overwritten). Modified MUST NOT be used in
122     # setFileName, it can cause incorrect output such as map.
123     self.__vtk_xml_reader.Modified()
124 jongui 1148
125 ksteube 1147 # Update must be called after Modified. If Update is called before
126     # Modified, then the first/second image(s) may not be updated
127     # correctly.
128     self.__vtk_xml_reader.Update()
129     self.__get_attribute_lists()
130     else:
131     raise ValueError("Source type %s does not support 'setData'\n" \
132     % self.__source)
133    
134 jongui 1148 # This method is used to delay the execution of setting the active scalar
135     # until 'setFileName' or 'setData' have been executed.
136 ksteube 1147 def setActiveScalar(self, scalar):
137     """
138     Specify the scalar field to load.
139    
140     @type scalar: String
141     @param scalar: Scalar field to load from the file.
142     """
143 jongui 1148
144     self.__set_scalar = True
145     self.__active_scalar = scalar
146    
147     def _setActiveScalar(self):
148     """
149     Load the specified scalar field.
150     """
151    
152 ksteube 1147 # Check whether the specified scalar is available in either point
153 jongui 1153 # or cell data. If not available, error is raised.
154 ksteube 1147
155     # NOTE: This check is similar to the check used in _getScalarRange
156     # but this is used only when a scalar attribute has been specified.
157 jongui 1148 if self.__active_scalar in self.__point_attribute['scalars']:
158     self._getDataCollectorOutput().GetPointData().SetActiveScalars(
159     self.__active_scalar)
160     elif self.__active_scalar in self.__cell_attribute['scalars']:
161     self._getDataCollectorOutput().GetCellData().SetActiveScalars(
162     self.__active_scalar)
163 ksteube 1147 else:
164 jongui 1148 raise IOError("ERROR: No scalar called '%s' is available." % \
165     self.__active_scalar)
166 ksteube 1147
167 jongui 1148 # This method is used to delay the execution of setting the active vector
168     # until 'setFileName' or 'setData' have been executed.
169 ksteube 1147 def setActiveVector(self, vector):
170     """
171     Specify the vector field to load.
172    
173     @type vector: String
174     @param vector: Vector field to load from the file.
175     """
176 jongui 1148
177     self.__set_vector = True
178     self.__active_vector = vector
179    
180     def _setActiveVector(self):
181     """
182     Load the specified vector field.
183     """
184    
185 ksteube 1147 # Check whether the specified vector is available in either point
186 jongui 1153 # or cell data. If not available, error is raised.
187 ksteube 1147
188     # NOTE: This check is similar to the check used in _getVectorRange
189     # but this is used only when a vector attribute has been specified.
190 jongui 1148 if self.__active_vector in self.__point_attribute['vectors']:
191     self._getDataCollectorOutput().GetPointData().SetActiveVectors(
192     self.__active_vector)
193     elif self.__active_vector in self.__cell_attribute['vectors']:
194     self._getDataCollectorOutput().GetCellData().SetActiveVectors(
195     self.__active_vector)
196 ksteube 1147 else:
197 jongui 1148 raise IOError("ERROR: No vector called '%s' is available." % \
198     self.__active_vector)
199    
200     # This method is used to delay the execution of setting the active tensor
201     # until 'setFileName' or 'setData' have been executed.
202 ksteube 1147 def setActiveTensor(self, tensor):
203     """
204     Specify the tensor field to load.
205    
206     @type tensor: String
207     @param tensor: Tensor field to load from the file.
208     """
209    
210 jongui 1148 self.__set_tensor = True
211     self.__active_tensor = tensor
212    
213     def _setActiveTensor(self):
214     """
215     Load the the specified tensor field.
216     """
217    
218 ksteube 1147 # Check whether the specified tensor is available in either point
219 jongui 1153 # or cell data. If not available, error is raised.
220 ksteube 1147
221     # NOTE: This check is similar to the check used in _getTensorRange
222     # but this is used only when a tensor attribute has been specified.
223 jongui 1148 if self.__active_tensor in self.__point_attribute['tensors']:
224     self._getDataCollectorOutput().GetPointData().SetActiveTensors(
225     self.__active_tensor)
226     elif self.__active_tensor in self.__cell_attribute['tensors']:
227     self._getDataCollectorOutput().GetCellData().SetActiveTensors(
228     self.__active_tensor)
229 ksteube 1147 else:
230 jongui 1148 raise IOError("ERROR: No tensor called '%s' is available." % \
231     self.__active_tensor)
232 ksteube 1147
233     def __get_array_type(self, arr):
234     """
235     Return whether an array type is scalar, vector or tensor by looking
236     at the number of components in the array.
237    
238     @type arr: vtkDataArray
239     @param arr: An array from the source.
240     @rtype: String
241     @return: Array type ('scalar', vector' or 'tensor')
242     """
243    
244     # Number of components in an array.
245     num_components = arr.GetNumberOfComponents()
246    
247     if num_components == 1:
248     return 'scalars'
249     elif num_components == 3:
250     return 'vectors'
251     elif num_components == 9:
252     return 'tensors'
253    
254     def __get_attribute_list(self, data):
255     """
256     Return the available scalar, vector and tensor attributes
257     (either point or cell data).
258    
259     @type data: vtkPointData or vtkCellData
260     @param data: Available point data or cell data from the source
261     @rtype: Dictionary
262     @return: Dictionary containing the available scalar, vector and \
263     tensor attributes
264     """
265    
266     attribute = {'scalars':[], 'vectors':[], 'tensors':[]}
267     if data:
268     num_arrays = data.GetNumberOfArrays() # Number of arrays.
269     for i in range(num_arrays):
270     name = data.GetArrayName(i) # Get an array name.
271     type = self.__get_array_type(data.GetArray(i)) # Get array type.
272     attribute[type].extend([name]) # Add array name to dictionary.
273    
274     return attribute
275    
276     def __get_attribute_lists(self):
277     """
278     Get all the available point and cell data attributes from the source.
279     """
280    
281     # Get all the available point data attributes into a list.
282     self.__point_attribute = \
283 jongui 1148 self.__get_attribute_list(
284     self._getDataCollectorOutput().GetPointData())
285    
286 ksteube 1147 # Get all the available cell data attribute into another list.
287     self.__cell_attribute = \
288 jongui 1148 self.__get_attribute_list(
289     self._getDataCollectorOutput().GetCellData())
290 ksteube 1147
291     def _getScalarRange(self):
292     """
293     Return the scalar range.
294    
295     @rtype: Two column tuple containing numbers
296     @return: Scalar range
297     """
298    
299     # Check whether any scalar is available in either point or cell data.
300     # If not available, program exits.
301    
302     # NOTE: This check is similar to the check used in _setActiveScalar
303     # but this is used only when no scalar attribute has been specified.
304     if(len(self.__point_attribute['scalars']) != 0):
305 jongui 1148 return self._getDataCollectorOutput().GetPointData().\
306     GetScalars().GetRange(-1)
307 ksteube 1147 elif(len(self.__cell_attribute['scalars']) != 0):
308 jongui 1148 return self._getDataCollectorOutput().GetCellData().\
309     GetScalars().GetRange(-1)
310 ksteube 1147 else:
311 jongui 1148 raise IOError("\nERROR: No scalar is available.\n")
312 ksteube 1147
313     def _getVectorRange(self):
314     """
315     Return the vector range.
316    
317     @rtype: Two column tuple containing numbers
318     @return: Vector range
319     """
320    
321     # Check whether any vector is available in either point or cell data.
322     # If not available, program exits.
323    
324     # NOTE: This check is similar to the check used in _setActiveVector
325     # but this is used only when no vector attribute has been specified.
326    
327     # NOTE: Generally GetRange(-1) returns the correct vector range.
328     # However, there are certain data sets where GetRange(-1) seems
329     # to return incorrect mimimum vector although the maximum vector is
330     # correct. As a result, the mimimum vector has been hard coded to 0.0
331     # to accommodate for the incorrect cases.
332     if(len(self.__point_attribute['vectors']) != 0):
333     vector_range = \
334 jongui 1148 self._getDataCollectorOutput().GetPointData().\
335     GetVectors().GetRange(-1)
336 ksteube 1147 return (0.0, vector_range[1])
337     elif(len(self.__cell_attribute['vectors']) != 0):
338     vector_range = \
339 jongui 1148 self._getDataCollectorOutput().GetCellData().\
340     GetVectors().GetRange(-1)
341 ksteube 1147 return (0.0, vector_range[1])
342     else:
343 jongui 1148 raise IOError("\nERROR: No vector is available.\n")
344 ksteube 1147
345     def _getTensorRange(self):
346     """
347     Return the tensor range.
348    
349     @rtype: Two column tuple containing numbers
350     @return: Tensor range
351     """
352    
353     # Check whether any tensor is available in either point or cell data.
354     # If not available, program exits.
355    
356     # NOTE: This check is similar to the check used in _setActiveTensor
357     # but this is used only when no tensor attribute has been specified.
358     if(len(self.__point_attribute['tensors']) != 0):
359 jongui 1148 return self._getDataCollectorOutput().GetPointData().\
360     GetTensors().GetRange(-1)
361 ksteube 1147 elif(len(self.__cell_attribute['tensors']) != 0):
362 jongui 1148 return self._getDataCollectorOutput().GetCellData().\
363     GetTensors().GetRange(-1)
364 ksteube 1147 else:
365 jongui 1148 raise IOError("\nERROR: No tensor is available.\n")
366 ksteube 1147
367 jongui 1148 def _getDataCollectorOutput(self):
368 ksteube 1147 """
369     Return the output of the data collector.
370    
371     @rtype: vtkUnstructuredGrid
372     @return: Unstructured grid
373     """
374 jongui 1148 return self.__vtk_xml_reader.GetOutput()
375 ksteube 1147
376 jongui 1148 def _isModified(self):
377     """
378     Return whether the DataCollector has been modified.
379 ksteube 1147
380 jongui 1148 @rtype: Boolean
381     @return: True or False
382     """
383    
384     if(self.__modified == True):
385 jongui 1197 # 'self.__modified' is set to False only if the 'setFileName' or
386     # 'setData' method have been called once. This is to prevent
387     # the scalar range and active field (i.e. scalar, vector or tensor)
388     # from being updated as no changes has taken place (for performance
389     # reasons). However if the 'setFileName' or 'setData' method is
390     # called more than once, then 'self.__modified' remains True.
391     if(self.__count == 1):
392     self.__modified = False
393 jongui 1148 return True
394     else:
395     return False
396    
397     def _isScalarSet(self):
398     """
399     Return whether a specific scalar field has been specified.
400    
401     @rtype: Boolean
402     @return: True or False
403     """
404    
405     return self.__set_scalar
406    
407     def _isVectorSet(self):
408     """
409     Return whether a specific vector field has been specified.
410    
411     @rtype: Boolean
412     @return: True or False
413     """
414    
415     return self.__set_vector
416    
417     def _isTensorSet(self):
418     """
419     Return whether a specific tensor field has been specified.
420    
421     @rtype: Boolean
422     @return: True or False
423     """
424    
425     return self.__set_tensor
426    
427     def _getCenter(self):
428     """
429     Return the center of the rendered object.
430    
431     @rtype: Three column tuple containing numbers
432     @return: Center of the rendered object
433     """
434    
435     return self._getDataCollectorOutput().GetCenter()
436    

  ViewVC Help
Powered by ViewVC 1.1.26