def initialzeVisualisation(self): ''' ''' # to be changed self.loadVascularNetwork() # find min max pressures and apply it to LUT self.findMinMaxPressure() # create LUT self.cLUT = LUT(self.quantitiyMaxima) # creat 3d vessel representations self.createVessel3D() start = time.clock() # apply number total timesteps self.timeStepsTotal = len(self.vascularNetwork.vessels[self.vascularNetwork.root].Psol) # evaluate maximum area factor self.findMaximumAreaFactor() # evaluate visualisation time step self.evaluateUpdateRate() # small stuff self.set_caption(self.vascularNetwork.name) self.networkName = self.vascularNetwork.name # evaluate movie count from already saved movies: for dirName, dirNames, fileNames in os.walk(self.movieSaveDirectory): for fileName in fileNames: if self.networkName in fileName: try: number = int(fileName.split('_')[-1].split(self.movieFileType)[0]) self.movieNumber = max(self.movieNumber,1 + number) except: pass # evaluate the screenshot count from already saved screenshots for dirName, dirNames, fileNames in os.walk(self.screenShotDataDirectory): for fileName in fileNames: if self.networkName in fileName: try: number = int(fileName.split('_')[-1].split('.png')[0]) self.screenShotNumber = max(self.screenShotNumber,1 + number) except: pass
class Visualisation3D(Visualisation3DGUI): ''' This class defines the 3D visualisation it is an inheritance of Visualisation3DGui which defines the GUI ''' def __init__(self, networkName = None, dataSetNumber = None, connect = False): Visualisation3DGUI.__init__(self) # load functions self.networkName = networkName self.dataSetNumber = dataSetNumber self.connect = connect # vascularNewtor Instance self.vascularNetwork = None # dictionary with 3D vessels self.vessels3D = {} self.nPointsPerCircle = 8 # points for the circle at one gridpoint should bee around 8-16-32 # vessel area/wall self.areaFactor = [2] self.areaFactorMaximum = 200 self.wallMovement = [True] # look up table self.pressureMaxima = None self.pressureMaximaSplit = None self.cLUT = None # color look up table class self.quantityLUT = ['Pressure'] # enable waveSplit LUT self.waveSplit = [False] # us an array as it is behaving like a pointer # simulation timing and update self.updateTime = 1./60. self.totalTime = 0 self.timeStepsTotal = 50 # get this from solution length e.g. len(area) self.timeStepCurrent = 0 self.timeStepIncrement = 1 # time step increment from [1, ... self.totalTimeSteps-1 ] ## create movie self.recordMovieData = False self.movieCount = 0 self.movieCount = 0 self.templateMovDataDirectory = ''.join([cur,'/.movieTemplateData']) self.movieSaveDirectory = ''.join([cur+'/Movies']) try: os.mkdir(self.movieSaveDirectory) except: pass self.movieNumber = 0 self.movieFileType = '.mp4' ## create screen shot self.screenShotNumber = 0 self.screenShotDataDirectory = ''.join([cur,'/screenShots']) self.initialzeVisualisation() #--- functions for initialisation def initialzeVisualisation(self): ''' ''' # to be changed self.loadVascularNetwork() # find min max pressures and apply it to LUT self.findMinMaxPressure() # create LUT self.cLUT = LUT(self.quantitiyMaxima) # creat 3d vessel representations self.createVessel3D() start = time.clock() # apply number total timesteps self.timeStepsTotal = len(self.vascularNetwork.vessels[self.vascularNetwork.root].Psol) # evaluate maximum area factor self.findMaximumAreaFactor() # evaluate visualisation time step self.evaluateUpdateRate() # small stuff self.set_caption(self.vascularNetwork.name) self.networkName = self.vascularNetwork.name # evaluate movie count from already saved movies: for dirName, dirNames, fileNames in os.walk(self.movieSaveDirectory): for fileName in fileNames: if self.networkName in fileName: try: number = int(fileName.split('_')[-1].split(self.movieFileType)[0]) self.movieNumber = max(self.movieNumber,1 + number) except: pass # evaluate the screenshot count from already saved screenshots for dirName, dirNames, fileNames in os.walk(self.screenShotDataDirectory): for fileName in fileNames: if self.networkName in fileName: try: number = int(fileName.split('_')[-1].split('.png')[0]) self.screenShotNumber = max(self.screenShotNumber,1 + number) except: pass def loadVascularNetwork(self): ''' load vascularNetwork inclusiv all solution data from solution data set uses local variables networkName and dataSetNumber saves vascularNetwork instance in self.vascularNetwork ''' if self.networkName and self.dataSetNumber: vascularNetwork, solutionDataSets, simulationCaseDescriptions = loadSolutionDataFile(self.networkName, self.dataSetNumber) self.vascularNetwork = vascularNetwork def createVessel3D(self): ''' method to create a Vessel3D instance for each vessel in the current vascularNetwork and stores it in self.vessels3D = {vesselId: vessel3D} ''' if self.vascularNetwork is not None: for vesselId,vessel in self.vascularNetwork.vessels.iteritems(): self.vessels3D[vesselId] = Vessel3D( vessel, self.batch, self.nPointsPerCircle, self.wallMovement, self.areaFactor, self.cLUT, self.quantityLUT, self.waveSplit) #--- functions for update def updateVisualisation(self, dt): ''' method to update the visualisation of the network depending on the timeStep this method is call continously if the "play button is clicked" ''' timeStepCurrent = self.timeStepCurrent ## update all visualisations of all vessel3D instances # update vessel Positions, 3dgeometry and colour of vertices for vesselId in self.vascularNetwork.treeTraverseList: self.vessels3D[vesselId].update3Dposition(timeStepCurrent,None, None) # update the time step for next call self.timeStepCurrent = self.timeStepCurrent+self.timeStepIncrement # restart simulation if end reached if self.timeStepCurrent >= self.timeStepsTotal: self.timeStepCurrent = 0 self.timeElapsed = 0 # record movie data if self.recordMovieData == True: ## save screenshots self.switch_to() pyglet.image.get_buffer_manager().get_color_buffer().save(''.join([self.templateMovDataDirectory,'/.screenShot',str(self.movieCount),'.png'])) self.movieCount = self.movieCount + 1 def recordMovie(self): ''' start end end recording movies ''' # start recording if self.recordMovieData == False: try: os.mkdir(self.templateMovDataDirectory) except: pass self.movieCount = 0 self.recordMovieData = True else: # create movie out of recorded data self.recordMovieData = False self.createMovie() filelist = [ f for f in os.listdir(self.templateMovDataDirectory) if f.endswith(".png")] for f in filelist: os.remove(''.join([self.templateMovDataDirectory,'/',f])) def saveScreenShot(self): ''' save screenshot to disk ''' try: os.mkdir(self.screenShotDataDirectory) except: pass self.switch_to() pyglet.image.get_buffer_manager().get_color_buffer().save(''.join([self.screenShotDataDirectory,'/',self.networkName,'_',str(self.screenShotNumber),'.png'])) self.screenShotNumber = self.screenShotNumber +1 def createMovie(self): ''' open all movie-template-*.png's and create a movie out of it ''' print "createMovie(): writing image data" frameSizeImage = read_png(''.join([self.templateMovDataDirectory,'/.screenShot',str(0),'.png'])) frameSize = (np.shape(frameSizeImage)[1],np.shape(frameSizeImage)[0]) try: FFMpegWriter = animation.writers['mencoder'] except: print "ERROR: Visualisation3D.createMovie(): mencoder libary is not installed, could not create movie!"; return try: fileName = ''.join([self.movieSaveDirectory,'/',self.networkName,'_',str(self.movieNumber),self.movieFileType]) imageName = ''.join(['mf://',self.templateMovDataDirectory,'/.screenShot%d.png']) imageType = ''.join(['type=png:w=',str(frameSize[0]),':h=',str(frameSize[1]),':fps=24']) command = ('mencoder', imageName, '-mf', imageType, '-ovc', 'lavc', '-lavcopts', 'vcodec=mpeg4', '-oac', 'copy', '-o', fileName) os.spawnvp(os.P_WAIT, 'mencoder', command) self.movieNumber = self.movieNumber+1 print "createMovie(): created movie sucessfull" except: print "ERROR: Visualisation3D.createMovie(): mencoder libary is not installed, could not create movie!"; return #--- functions for the visualisation speed def evaluateUpdateRate(self): ''' evaluate the visualisation update rate and the timeStepIncrement to get realtime visualisation i.e. synchronise update times ''' maxFrameRate = 60. minFrameRate = 24. numberOfUpdates = 50. dtSim = self.vascularNetwork.dt timeSteps = len(self.vessels3D[self.vessels3D.keys()[0]].Psol)-1 # number of dt is one less then number of solutions totalTime = timeSteps*dtSim # approximate frame rate timeSolverSolve = [] self.timeStepCurrent = int(self.timeStepsTotal/2.) for i in xrange(int(numberOfUpdates)): timeSolverSolveStart = time.clock() self.updateVisualisation(0.0) timeSolverSolve.append(time.clock()-timeSolverSolveStart) approximatedFrameRateUpdate = (1./(sum(timeSolverSolve[2::])/(numberOfUpdates-2)))-1 if maxFrameRate < approximatedFrameRateUpdate: minFrameRate = maxFrameRate else: minFrameRate = approximatedFrameRateUpdate x = 1./(dtSim*minFrameRate) x = int(np.ceil(x))+1 frameRate = 1.0/(dtSim*x) self.numberOfCalls = timeSteps/x self.timeStepIncrement = x self.timeStepIncrementRealTime = x self.updateTime = totalTime/self.numberOfCalls self.totalTime = totalTime # reset initial state self.timeStepCurrent = 0 self.updateVisualisation(0.0) self.timeStepCurrent = self.timeStepIncrement def visualisationSpeedHalfTime(self): self.timeStepIncrement = int(self.timeStepIncrementRealTime/2.) def visualisationSpeedRealTime(self): self.timeStepIncrement = int(self.timeStepIncrementRealTime) def visualisationSpeedUp(self): self.timeStepIncrement = min(int(self.timeStepIncrement+1),int(self.timeStepIncrementRealTime)) def visualisationSpeedDown(self): self.timeStepIncrement = max(int(self.timeStepIncrement-1),1) def setVisualisationSpeed(self, value): self.timeStepIncrement = max(int(self.timeStepIncrementRealTime*value),1) #--- functions for the area movement def setAreaFactor(self,value): self.areaFactor[0] = np.min([np.max([1,value*self.areaFactorMaximum]),self.areaFactorMaximum]) def enableWallMovement(self): self.wallMovement[0] = [True,False][self.wallMovement[0]] def findMaximumAreaFactor(self): ''' Function to find the maximum area factor that r is allways greater then 0.2 * r0 ''' rfmax = 5000 for vessel in self.vascularNetwork.vessels.itervalues(): A0 = vessel.Asol[0] devisor = ((vessel.Asol[1::]-A0)) devisor[devisor==0] = 1 rf = ((0.1*vessel.Asol[1::]-A0))/ devisor ## take out values close to -inf rf[rf<0] = 5000 rf = np.min(rf) rfmax = np.min([rfmax,rf]) self.areaFactorMaximum = rfmax self.areaFactor[0] = 1 #--- functions for the look up tables def changeColorTable(self): self.cLUT.changeColorTable() def changeQuantityLUT(self, quantity): self.quantityLUT[0] = quantity self.cLUT.changeLUTquantity(quantity) def enableWaveSplitLookUp(self): self.waveSplit[0] = [True,False][self.waveSplit[0]] self.cLUT.enableWaveSplitLookUp() def enableLeftRightColoring(self): self.cLUT.enableLeftRightColoring() def findMinMaxPressure(self): maximaP = [1.e20, 0] maximaQ = [1.e20, 0] for vessel in self.vascularNetwork.vessels.itervalues(): # maximum maximaP[1] = np.max([maximaP[1], np.max(vessel.Psol)]) maximaQ[1] = np.max([maximaQ[1], np.max(vessel.Qsol)]) # minimum maximaP[0] = np.min([maximaP[0], np.min(vessel.Psol)]) maximaQ[0] = np.min([maximaQ[0], np.min(vessel.Qsol)]) self.quantitiyMaxima = {'Pressure':maximaP, 'Flow':maximaQ}