123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- r"""This module is used to export catalyst defined data products directly
- within the ParaView GUI."""
- from paraview.simple import *
- haveCinemaC = True
- try:
- import paraview.tpl.cinema_python.adaptors.paraview.pv_introspect as pvi
- except:
- haveCinemaC = False
- import os
- class CinemaDHelper(object):
- """ A helper that we funnel file save commands through so that we can build up a CinemaD table for them. """
- def __init__(self, mcd, rd):
- self.__EnableCinemaDTable = mcd
- self.__RootDirectory = rd
- if rd and not rd.endswith("/"):
- self.__RootDirectory = rd + "/"
- self.Keys = set()
- self.Contents = []
- self.KeysWritten = None
- def __StripRootDir(self, filename):
- if self.__RootDirectory:
- return filename[filename.startswith(self.__RootDirectory) and len(self.__RootDirectory):]
- return filename
- def __MakeCinDFileNamesUnderRootDir(self, filename=""):
- """ filename wrangling for root directory placement """
- indexfilename = 'data.csv'
- datafilename = filename
- if self.__RootDirectory:
- indexfilename = self.__RootDirectory + "data.csv"
- # strip leading root directory from filename if present
- datafilename = self.__StripRootDir(filename)
- return indexfilename, datafilename
- def AppendToCinemaDTable(self, time, producer, filename):
- """ keep a record of every standard file written out so that we can list it later """
- if not self.__EnableCinemaDTable:
- return
- indexfilename, datafilename = self.__MakeCinDFileNamesUnderRootDir(filename)
- self.Keys.add("timestep")
- self.Keys.add("producer")
- self.Keys.add("FILE")
- self.Contents.append({'timestep':time,'producer':producer,'FILE':datafilename})
- def AppendCViewToCinemaDTable(self, time, producer, filelist):
- """ keep a record of every new file that cinema image writes along with the keys that produced them so that we can list them all later """
- if not self.__EnableCinemaDTable or not haveCinemaC:
- return
- self.Keys.add("timestep")
- self.Keys.add("producer")
- self.Keys.add("FILE")
- #unroll the contents into key lists and filenames
- for viewname in filelist:
- for entry in filelist[viewname]:
- keylist = entry[0]
- # avoid redundancy from name change
- if 'time' in keylist:
- time = keylist['time']
- del keylist['time']
- for k in keylist:
- self.Keys.add(k)
- keylist['timestep']=time
- keylist['producer']=producer
- keylist['FILE']=self.__StripRootDir(entry[1])
- self.Contents.append(keylist)
- def Finalize(self):
- """ Finish off the table and write it to a file """
- # this is necessary because we don't really know keys (from cinema image) until the end.
- if not self.__EnableCinemaDTable:
- return
- indexfilename, datafilename = self.__MakeCinDFileNamesUnderRootDir()
- if self.__RootDirectory and not os.path.exists(self.__RootDirectory):
- os.makedirs(self.__RootDirectory)
- f = open(indexfilename, "w")
- # write the header line
- f.write("timestep,")
- f.write("producer,")
- for k in self.Keys:
- if k != 'timestep' and k != 'producer' and k != 'FILE':
- f.write("%s,"%k)
- f.write("FILE\n")
- # write all of the contents
- for l in self.Contents:
- f.write("%s,"%l['timestep'])
- f.write("%s,"%l['producer'])
- for k in self.Keys:
- if k != 'timestep' and k != 'producer' and k != 'FILE':
- v = ''
- if k in l:
- v = l[k]
- f.write("%s,"%v)
- f.write("%s\n"%self.__StripRootDir(l['FILE']))
- f.close()
- def WriteNow(self):
- """ For Catalyst, we don't generally have a Final state, so we call this every CoProcess call and fixup the table if we have to. """
- if not self.__EnableCinemaDTable:
- return
- indexfilename, datafilename = self.__MakeCinDFileNamesUnderRootDir()
- if self.KeysWritten == self.Keys:
- # phew nothing new, we can just append a record
- f = open(indexfilename, "a+")
- for l in self.Contents:
- f.write("%s,"%l['timestep'])
- f.write("%s,"%l['producer'])
- for k in self.Keys:
- if k != 'timestep' and k != 'producer' and k != 'FILE':
- v = ''
- if k in l:
- v = l[k]
- f.write("%s,"%v)
- f.write("%s\n"%self.__StripRootDir(l['FILE']))
- f.close()
- self.Contents = []
- return
- #dang, whatever we wrote recently had a new variable
- #we may have to extend and rewrite the old output file
- readKeys = None
- readContents = []
- if os.path.exists(indexfilename):
- #yep we have to do it
- #parse the old file
- f = open(indexfilename, "r")
- for line in f:
- read = line[0:-1].split(",") #-1 to skip trailing\n
- if readKeys is None:
- readKeys = read
- else:
- entry = {}
- for idx in range(0,len(read)):
- entry.update({readKeys[idx]:read[idx]})
- readContents.append(entry)
- #combine contents
- if readKeys is not None:
- self.Keys = self.Keys.union(readKeys)
- readContents.extend(self.Contents)
- self.Contents = readContents
- #finally, write
- self.Finalize()
- self.KeysWritten = self.Keys.copy()
- self.Contents = []
- class __CinemaACHelper(object):
- """ Another helper that connects up to cinema_python's export function. """
- def __init__(self, rd, vsel, tsel, asel):
- self.__RootDirectory = rd
- self.__ViewSelection = vsel
- self.__TrackSelection = tsel
- self.__ArraySelection = asel
- self.NewFiles = None
- if haveCinemaC:
- def ExportNow(self, time):
- r = pvi.export_scene(baseDirName=self.__RootDirectory,
- viewSelection=dict(self.__ViewSelection),
- trackSelection=dict(self.__TrackSelection),
- arraySelection=dict(self.__ArraySelection),
- forcetime=time)
- self.NewFiles = r
- else:
- def ExportNow(self, time):
- pass
- def _fixup_and_makedir_if_needed(rootdir):
- if rootdir and not rootdir.endswith("/"):
- rootdir = rootdir + "/"
- if rootdir and not os.path.exists(rootdir):
- os.makedirs(rootdir)
- return rootdir
- def ExportNow(image_root_directory,
- data_root_directory,
- file_name_padding,
- make_cinema_table,
- cinema_tracks,
- cinema_arrays,
- rendering_info):
- """The user facing entry point. Here we get a hold of ParaView's animation controls, step through the animation, and export the things we've been asked to be the caller."""
- CIND = CinemaDHelper(make_cinema_table, image_root_directory)
- image_root_directory = _fixup_and_makedir_if_needed(image_root_directory)
- data_root_directory = _fixup_and_makedir_if_needed(data_root_directory)
- # get a hold of the scene
- spm = servermanager.vtkSMProxyManager.GetProxyManager().GetActiveSessionProxyManager()
- ed = spm.GetExportDepot()
- s = GetAnimationScene()
- s.GoToFirst()
- et = s.EndTime
- tnow = s.AnimationTime
- numTimesteps = len(paraview.simple.GetAnimationScene().TimeKeeper.TimestepValues)
- timesteps = {}
- # We must perform the export loop at least once, even in the case where
- # the input data contains no timesteps
- if (numTimesteps == 0):
- timesteps = list(range(1))
- else:
- timesteps = list(range(numTimesteps))
- # export loop
- for tstep in timesteps:
- padded_tstep = str(tstep).rjust(file_name_padding, '0')
- helpers = []
- # loop through the configured writers and export at the requested times
- ed.InitNextWriterProxy()
- wp = ed.GetNextWriterProxy()
- writercnt = 0
- while wp:
- freq = wp.GetProperty("WriteFrequency").GetElement(0)
- if ((tstep % freq==0) and
- (not (wp.GetXMLName() == "Cinema image options"))):
- # this isn't pretty. I couldn't find a way to write
- # directly with the writer proxy. So what I do here
- # is find the input and filename and make a new writer
- # to use.
- proxyname = spm.GetProxyName("export_writers", wp)
- inputname = proxyname[0:proxyname.find("|")]
- inputproxy = FindSource(inputname)
- if wp.GetProperty("ChooseArraysToWrite").GetElement(0) == 1:
- point_arrays = []
- cell_arrays = []
- arrays_property = wp.GetProperty("PointDataArrays")
- for i in range(arrays_property.GetNumberOfElements()):
- point_arrays.append(arrays_property.GetElement(i))
- arrays_property = wp.GetProperty("CellDataArrays")
- for i in range(arrays_property.GetNumberOfElements()):
- cell_arrays.append(arrays_property.GetElement(i))
- if not point_arrays:
- point_arrays = [' ']
- if not cell_arrays:
- cell_arrays = [' ']
- # create a temporary array culling filter
- pass_arrays = PassArrays(Input=inputproxy, \
- PointDataArrays=point_arrays, CellDataArrays=cell_arrays)
- inputproxy = pass_arrays
- helpers.append(inputproxy)
- fname = wp.GetProperty("CatalystFilePattern").GetElement(0)
- if wp.GetXMLName() == "ExodusIIWriter":
- fnamefilled = data_root_directory+fname+padded_tstep
- else:
- fnamefilled = data_root_directory+fname.replace("%t", padded_tstep)
- kwargs = {}
- DataMode = wp.GetProperty("DataMode")
- if DataMode is not None:
- kwargs["DataMode"] = wp.GetProperty("DataMode").GetElement(0)
- HeaderType = wp.GetProperty("HeaderType")
- if HeaderType is not None:
- kwargs["HeaderType"] = wp.GetProperty("HeaderType").GetElement(0)
- EncodeAppendedData = wp.GetProperty("EncodeAppendedData")
- if EncodeAppendedData is not None:
- kwargs["EncodeAppendedData"] = wp.GetProperty("EncodeAppendedData").GetElement(0)
- CompressorType = wp.GetProperty("CompressorType")
- if CompressorType is not None:
- kwargs["CompressorType"] = wp.GetProperty("CompressorType").GetElement(0)
- CompressionLevel = wp.GetProperty("CompressionLevel")
- if CompressionLevel is not None:
- kwargs["CompressionLevel"] = wp.GetProperty("CompressionLevel").GetElement(0)
- # finally after all of the finageling above, save the data
- SaveData(fnamefilled, inputproxy, **kwargs)
- # don't forget to tell cinema D about it
- CIND.AppendToCinemaDTable(tnow, "writer_%s" % writercnt, fnamefilled)
- wp = ed.GetNextWriterProxy()
- writercnt = writercnt + 1
- # loop through the configured screenshots and export at the requested times
- ed.InitNextScreenshotProxy()
- ssp = ed.GetNextScreenshotProxy()
- viewcnt = 0
- while ssp:
- if not ssp.HasAnnotation("enabled") or not (ssp.GetAnnotation("enabled") == '1'):
- ssp= ed.GetNextScreenshotProxy()
- continue
- freq = ssp.GetProperty("WriteFrequency").GetElement(0)
- if tstep % freq==0:
- fname = ssp.GetProperty("CatalystFilePattern").GetElement(0)
- if fname.endswith("cdb"):
- CINAC = __CinemaACHelper(image_root_directory,
- rendering_info,
- cinema_tracks,
- cinema_arrays)
- # special treatment for cinema image data bases
- CINAC.ExportNow(tnow)
- # don't forget to tell cinema D about it
- CIND.AppendCViewToCinemaDTable(tnow, "cview_%s"%viewcnt, CINAC.NewFiles)
- else:
- fnamefilled = image_root_directory+fname.replace("%t", padded_tstep)
- # save the screenshot
- ssp.WriteImage(fnamefilled)
- # don't forget to tell cinema D about it
- CIND.AppendToCinemaDTable(tnow, "view_%s"%viewcnt, fnamefilled)
- ssp = ed.GetNextScreenshotProxy()
- viewcnt = viewcnt + 1
- tstep = tstep + 1
- s.GoToNext()
- tnow = s.AnimationTime
- # destroy array culling filters
- for x in helpers:
- Delete(x)
- # defer actual cinema D output until the end because we only know now what the full set of cinema D columns actually are
- CIND.Finalize()
|