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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1043 - (show annotations)
Mon Mar 19 06:46:34 2007 UTC (13 years, 8 months ago) by jongui
File MIME type: text/x-python
File size: 11921 byte(s)
Map and Contour now able to display cell data correctly. At this stage, it appears that the probe filter cannot be applied on cell data as a segmentation fault will be thrown.
1 """
2 @author: John NGUI
3 """
4
5 import vtk
6 import tempfile, os, sys
7 from constant import Source, VizType, ColorMode
8 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 which deals with the source
16 of data for the visualisation.
17 """
18
19 def __init__(self, source = Source.XML):
20 """
21 Initialise the data collector.
22
23 @type source: L{Source <constant.Source>} constant
24 @param source: Source type
25 """
26
27 self.__source = source
28 self.__count = 0 # Keeps track of the number of files/sources read.
29
30 if(source == Source.XML): # Source is an XML file.
31 self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
32 # Source is a escript data object using a temp file in the background.
33 elif (self.__source == Source.ESCRIPT):
34 self.__vtk_xml_reader = vtk.vtkXMLUnstructuredGridReader()
35 # Create a temporary .xml file and retrieves its path.
36 self.__tmp_file = tempfile.mkstemp(suffix=".xml")[1]
37 #self.__vtk_xml_reader.SetFileName(self.__tmp_file)
38
39 def __del__(self):
40 """
41 Perform some clean up of the temporary file.
42 """
43
44 if (self.__source == Source.ESCRIPT):
45 if os.access(self.__tmp_file,os.F_OK): os.unlink(self.__tmp_file)
46
47 def setFileName(self, file_name):
48 """
49 Set the source file name to read.
50
51 @type file_name: String
52 @param file_name: Name of the file to read
53 """
54
55 if(self.__source == Source.XML):
56 self.__vtk_xml_reader.SetFileName(file_name)
57
58 # Update must be called after SetFileName to make the reader
59 # up to date. Otherwise, some output values may be incorrect.
60 self.__vtk_xml_reader.Update()
61 self.__output = self.__vtk_xml_reader.GetOutput()
62 self.__get_attribute_lists()
63
64 # Count has to be larger than zero because when setFileName is
65 # called for the first time, the data set mapper has not yet been
66 # instantiated. Therefore, the range of the mapper can only be
67 # updated after the first file/source has been read.
68 if(self.__count > 0):
69 self._updateRange(None)
70
71 self.__count+=1
72
73 else:
74 raise ValueError("Source type %s does not support 'setFileName'\n" \
75 % self.__source)
76
77 def setData(self,**args):
78 """
79 Create data using the <name>=<data> pairing. Assumption is made
80 that the data will be given in the appropriate format.
81 """
82
83 if self.__source == Source.ESCRIPT:
84 esys.escript.saveVTK(self.__tmp_file,**args)
85 self.__vtk_xml_reader.SetFileName(self.__tmp_file)
86 # Modified must be called for setData but NOT for
87 # setFileName. If Modified is not called, only the first file
88 # will always be displayed. The reason Modified is used is
89 # because the same temporary file name is always used
90 # (old file is overwritten). Modified MUST NOT be used in
91 # setFileName, it can cause incorrect output such as map.
92 self.__vtk_xml_reader.Modified()
93 # Update must be called after Modified. If Update is called before
94 # Modified, then the first/second image(s) may not be updated
95 # correctly.
96 self.__vtk_xml_reader.Update()
97 self.__output = self.__vtk_xml_reader.GetOutput()
98 self.__get_attribute_lists()
99 else:
100 raise ValueError("Source type %s does not support 'setData'\n" \
101 % self.__source)
102
103 def setActiveScalar(self, scalar):
104 """
105 Specify the scalar field to load.
106
107 @type scalar: String
108 @param scalar: Scalar field to load from the file.
109 """
110
111 # Check whether the specified scalar is available in either point
112 # or cell data. If not available, program exits.
113
114 # NOTE: This check is similar to the check used in _getScalarRange
115 # but is used only when a scalar attribute has been specified.
116 if scalar in self.__point_attribute['scalars']:
117 self._getOutput().GetPointData().SetActiveScalars(scalar)
118 print "SCALAR POINT DATA"
119 elif scalar in self.__cell_attribute['scalars']:
120 self._getOutput().GetCellData().SetActiveScalars(scalar)
121 print "SCALAR CELL DATA"
122 else:
123 print "\nERROR: No scalar called '%s' is available.\n" % scalar
124 sys.exit(1)
125
126 def setActiveVector(self, vector):
127 """
128 Specify the vector field to load.
129
130 @type vector: String
131 @param vector: Vector field to load from the file.
132 """
133
134 # Check whether the specified vector is available in either point
135 # or cell data. If not available, program exits.
136
137 # NOTE: This check is similar to the check used in _getVectorRange
138 # but is used only when a vector attribute has been specified.
139 if vector in self.__point_attribute['vectors']:
140 self._getOutput().GetPointData().SetActiveVectors(vector)
141 print "VECTOR POINT DATA"
142 elif vector in self.__cell_attribute['vectors']:
143 self._getOutput().GetCellData().SetActiveVectors(vector)
144 print "VECTOR CELL DATA"
145 else:
146 print "\nERROR: No vector called '%s' is available.\n" % vector
147 sys.exit(1)
148
149 def setActiveTensor(self, tensor):
150 """
151 Specify the tensor field to load.
152
153 @type tensor: String
154 @param tensor: Tensor field to load from the file.
155 """
156
157 # Check whether the specified tensor is available in either point
158 # or cell data. If not available, program exits.
159
160 # NOTE: This check is similar to the check used in _getTensorRange
161 # but is used only when a tensor attribute has been specified.
162 if tensor in self.__point_attribute['tensors']:
163 self._getOutput().GetPointData().SetActiveTensors(tensor)
164 elif tensor in self.__cell_attribute['tensors']:
165 self._getOutput().GetCellData().SetActiveTensors(tensor)
166 else:
167 print "\nERROR: No tensor called '%s' is available.\n" % tensor
168 sys.exit(0)
169
170 # 'object' is set to 'None' because some types of visualization have
171 # two different ranges that need to be updated while others only have one.
172 def _paramForUpdatingMultipleSources(self, viz_type, color_mode, mapper,
173 object = None):
174 """
175 Parameters required to update the necessary range when two or more
176 files are read.
177
178 @type viz_type: : L{VizType <constant.VizType>} constant
179 @param viz_type: Type if visualization (i.e. Map, Velocity, etc)
180 @type color_mode: L{ColorMode <constant.ColorMode>} constant
181 @param color_mode: Type of color mode
182 @type mapper: vtkDataSetMapper
183 @param mapper: Mapped data
184 @type object: vtkPolyDataAlgorith (i.e. vtkContourFilter, vtkGlyph3D, \
185 etc)
186 @param object: Poly data
187 """
188
189 self.__viz_type = viz_type
190 self.__color_mode = color_mode
191 self.__mapper = mapper
192 self.__object = object
193
194 def _updateRange(self, range):
195 """
196 Update the necessary range when two or more sources are read in.
197 """
198
199 if self.__viz_type == VizType.MAP or \
200 self.__viz_type == VizType.ELLIPSOID or \
201 self.__viz_type == VizType.CARPET:
202 self.__mapper.SetScalarRange(self._getScalarRange())
203 elif self.__viz_type == VizType.VELOCITY:
204 if self.__color_mode == ColorMode.VECTOR:
205 self.__object.SetRange(self._getVectorRange())
206 self.__mapper.SetScalarRange(self._getVectorRange())
207 elif self.__color_mode == ColorMode.SCALAR:
208 self.__object.SetRange(self._getScalarRange())
209 self.__mapper.SetScalarRange(self._getScalarRange())
210 elif self.__viz_type == VizType.CONTOUR:
211 self.__object.GenerateValues(
212 self.__object.GetNumberOfContours(),
213 self._getScalarRange()[0],
214 self._getScalarRange()[1])
215 self.__mapper.SetScalarRange(self._getScalarRange())
216 elif self.__viz_type == VizType.STREAMLINE:
217 if self.__color_mode == ColorMode.VECTOR:
218 self.__mapper.SetScalarRange(self._getVectorRange())
219 elif self.__color_mode == ColorMode.SCALAR:
220 self.__mapper.SetScalarRange(self._getScalarRange())
221
222 def __get_array_type(self, arr):
223 """
224 Return if the array type is a scalar, vector or tensor by looking
225 at the number of components in the array.
226
227 @type arr: vtkDataArray
228 @param arr: An array from the source.
229 @rtype: String
230 @return: Array type ('scalar', vector', 'tensor')
231 """
232
233 # Number of components in an array.
234 num_components = arr.GetNumberOfComponents()
235
236 if num_components == 1:
237 return 'scalars'
238 elif num_components == 3:
239 return 'vectors'
240 elif num_components == 9:
241 return 'tensors'
242
243 def __get_attribute_list(self, data):
244 """
245 Return the available scalar, vector and tensor attributes
246 (either point or cell data).
247
248 @type data: vtkPointData or vtkCellData
249 @param data: Available point data or cell data from the source
250 @rtype: Dictionary
251 @return: Dictionary containing the available scalar, vector and \
252 tensor attributes
253 """
254
255 attribute = {'scalars':[], 'vectors':[], 'tensors':[]}
256 if data:
257 num_arrays = data.GetNumberOfArrays() # Number of arrays.
258 for i in range(num_arrays):
259 name = data.GetArrayName(i) # Get an array name.
260 type = self.__get_array_type(data.GetArray(i)) # Get array type.
261 attribute[type].extend([name]) # Add array name to dictionary.
262
263 return attribute
264
265 def __get_attribute_lists(self):
266 """
267 Get all the available point and cell data attributes from the source.
268 """
269
270 # Get all the available point data attributes into a list.
271 self.__point_attribute = \
272 self.__get_attribute_list(self._getOutput().GetPointData())
273 # Get all the available cell data attribute into another list.
274 self.__cell_attribute = \
275 self.__get_attribute_list(self._getOutput().GetCellData())
276
277 def _getScalarRange(self):
278 """
279 Return the scalar range.
280
281 @rtype: Two column tuple containing numbers
282 @return: Scalar range
283 """
284
285 # Check whether any tensor is available in either point or cell data.
286 # If not available, program exits.
287
288 # NOTE: This check is similar to the check used in _setActiveScalar
289 # but is used only when no scalar attribute has been specified.
290 if(len(self.__point_attribute['scalars']) != 0):
291 return self._getOutput().GetPointData().GetScalars().GetRange(-1)
292 elif(len(self.__cell_attribute['scalars']) != 0):
293 return self._getOutput().GetCellData().GetScalars().GetRange(-1)
294 else:
295 print "\nERROR: No scalar is available.\n"
296 sys.exit(1)
297
298 def _getVectorRange(self):
299 """
300 Return the vector range.
301
302 @rtype: Two column tuple containing numbers
303 @return: Vector range
304 """
305
306 # Check whether any vector is available in either point or cell data.
307 # If not available, program exits.
308
309 # NOTE: This check is similar to the check used in _setActiveVector
310 # but is used only when no vector attribute has been specified.
311
312 # NOTE: Generally GetRange(-1) returns the correct vector range.
313 # However, there are certain data sets where GetRange(-1) seems
314 # to return incorrect mimimum vector although the maximum vector is
315 # correct. As a result, the mimimum vector has been hard coded to 0.0
316 # to accommodate the incorrect cases.
317 if(len(self.__point_attribute['vectors']) != 0):
318 vector_range = \
319 self._getOutput().GetPointData().GetVectors().GetRange(-1)
320 return (0.0, vector_range[1])
321 elif(len(self.__cell_attribute['vectors']) != 0):
322 vector_range = \
323 self._getOutput().GetCellData().GetVectors().GetRange(-1)
324 return (0.0, vector_range[1])
325 else:
326 print "\nERROR: No vector is available.\n"
327 sys.exit(0)
328
329 def _getTensorRange(self):
330 """
331 Return the tensor range.
332
333 @rtype: Two column table
334 @return: Tensor range
335 """
336
337 # Check whether any tensor is available in either point or cell data.
338 # If not available, program exits.
339
340 # NOTE: This check is similar to the check used in _setActiveTensor
341 # but is used only when no tensor attribute has been specified.
342 if(len(self.__point_attribute['tensors']) != 0):
343 return self._getOutput().GetPointData().GetTensors().GetRange(-1)
344 elif(len(self.__cell_attribute['tensors']) != 0):
345 return self._getOutput().GetCellData().GetTensors().GetRange(-1)
346 else:
347 print "\nERROR: No tensor is available.\n"
348 sys.exit(1)
349
350 def _getOutput(self):
351 """
352 Return the output of the data collector.
353
354 @rtype: vtkUnstructuredGrid
355 @return: Unstructured grid
356 """
357
358 return self.__output
359

  ViewVC Help
Powered by ViewVC 1.1.26