def __init__(self, exodus_source, **kwargs): super(ExodusSourceLineSampler, self).__init__(**kwargs) if not isinstance(exodus_source, ExodusSource): msg = 'The supplied object of type {} must be a ExodusSource object.' raise mooseutils.MooseException(msg.format(exodus_source.__class__.__name__)) self._distance = [] self._exodus_source = exodus_source self._probe = vtk.vtkCompositeDataProbeFilter()
def __init__(self, exodus_source, **kwargs): super(ExodusSourceLineSampler, self).__init__(**kwargs) if not isinstance(exodus_source, ExodusSource): msg = 'The supplied object of type {} must be a ExodusSource object.' raise mooseutils.MooseException( msg.format(exodus_source.__class__.__name__)) self._distance = [] self._exodus_source = exodus_source self._probe = vtk.vtkCompositeDataProbeFilter()
# simple case, all axes are of length 75 and begins with the first element. For other data, this is probably not the case. # I have to admit however, that I honestly dont know the difference between SetDataExtent() and SetWholeExtent() although # VTK complains if not both are used. dataImporter.SetDataExtent(0, dimensions[0] - 1, 0, dimensions[1] - 1, 0, dimensions[2] - 1) dataImporter.SetWholeExtent(0, dimensions[0] - 1, 0, dimensions[1] - 1, 0, dimensions[2] - 1) dataImporter.SetDataSpacing(spacing) dataImporter.SetDataOrigin(origin) dataImporter.Update() # write one image file for each timestep in mesh for timeID in range(1, ntime): vtkExodusIIReader.SetPointResultArrayStatus("u0", 1) vtkExodusIIReader.SetTimeStep(timeID - 1) vtkExodusIIReader.Update() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput(dataImporter.GetOutput()) vtkResample.SetSource(vtkExodusIIReader.GetOutput()) vtkResample.Update() # FIXME this is prob the longest round about way possible... # FIXME convert to binary first then read back in a single component # For VTK to be able to use the data, it must be stored as a VTK-image. This can be done by the vtkImageImport-class which # imports raw data and stores it. FEMdataImporter = vtk.vtkImageImport() imageData = vtkResample.GetOutput().GetPointData().GetArray("u0") data_array = vtkNumPy.vtk_to_numpy(imageData) # write as binary also # data_array.tofile("background.%04d.raw" % timeID ) # The previously created array is converted to a string of chars and imported. data_string = data_array.tostring()
print "time step = ", timeID fem.UpdateTransientSystemTimeStep("StateSystem", timeID) fem.SystemSolve("StateSystem") #fem.StoreTransientSystemTimeStep("StateSystem",timeID ) fem.WriteTimeStep("fem_data.e", timeID + 1, timeID * deltat) # Interpolate FEM onto imaging data structures if (petscRank == -1): vtkExodusIIReader = vtk.vtkExodusIIReader() vtkExodusIIReader.SetFileName("fem_data.e") vtkExodusIIReader.SetPointResultArrayStatus("u0", 1) vtkExodusIIReader.SetTimeStep(timeID - 1) vtkExodusIIReader.Update() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput(templateImage) vtkResample.SetSource(vtkExodusIIReader.GetOutput()) vtkResample.Update() # FIXME this is prob the longest round about way possible... # FIXME convert to binary first then read back in a single component # For VTK to be able to use the data, it must be stored as a VTK-image. This can be done by the vtkImageImport-class which # imports raw data and stores it. dataImporter = vtk.vtkImageImport() imageData = vtkResample.GetOutput().GetPointData().GetArray('u0') data_array = vtkNumPy.vtk_to_numpy(imageData) # write as binary also #data_array.tofile("background.%04d.raw" % timeID ) # The previously created array is converted to a string of chars and imported. data_string = data_array.tostring()
def ComputeObjective(self,MRTIDataDirectory,VolumeOfInterest ): print self.SEMDataDirectory ObjectiveFunction = 0.0 # loop over time points of interest for idwrite,(SEMtimeID,MRTItimeID) in enumerate([(0,135),(0,136),(0,137),(0,138)]): mrtifilename = '%s/temperature.%04d.vtk' % (MRTIDataDirectory,MRTItimeID) if MRTItimeID in self.DataDictionary: print "already loaded", mrtifilename else: print 'opening' , mrtifilename # FIXME vtk needs to be loaded AFTER kernel is built import vtk import vtk.util.numpy_support as vtkNumPy print "using vtk version", vtk.vtkVersion.GetVTKVersion() print "read SEM data" vtkImageReader = vtk.vtkDataSetReader() vtkImageReader.SetFileName(mrtifilename ) vtkImageReader.Update() ## image_cells = vtkImageReader.GetOutput().GetPointData() ## data_array = vtkNumPy.vtk_to_numpy(image_cells.GetArray('scalars')) # extract voi for QOI vtkVOIExtract = vtk.vtkExtractVOI() vtkVOIExtract.SetInput( vtkImageReader.GetOutput() ) vtkVOIExtract.SetVOI( VolumeOfInterest ) vtkVOIExtract.Update() mrti_point_data= vtkVOIExtract.GetOutput().GetPointData() mrti_array = vtkNumPy.vtk_to_numpy(mrti_point_data.GetArray('image_data')) #print mrti_array #print type(mrti_array) print "project SEM onto MRTI for comparison" vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetSource( vtkVOIExtract.GetOutput() ) vtkResample.SetInput( self.SEMRegister.GetOutput() ) vtkResample.Update() if ( self.DebugObjective ): roifileName = "%s/mrti.%04d.vtu" % (self.SEMDataDirectory,MRTItimeID) print "writing ", roifileName start = time.clock() # setup mrti projection file vtkTemperatureWriter = vtk.vtkXMLUnstructuredGridWriter() vtkTemperatureWriter.SetFileName( roifileName ) vtkTemperatureWriter.SetInput(vtkResample.GetOutput()) vtkTemperatureWriter.Update() elapsed = (time.clock() - start) print "write output", elapsed print " accumulate objective function" fem_point_data= vtkResample.GetOutput().GetPointData() self.DataDictionary[MRTItimeID] = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('image_data')) #print fem_array #print type(fem_array ) h_mrti = self.DataDictionary[MRTItimeID] mf = cl.mem_flags d_mrti = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=h_mrti ) # TODO need to get cl buffer from brainNek d_fem = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=h_mrti ) # storage for output dest_buf = cl.Buffer(self.ctx, mf.WRITE_ONLY, h_mrti.nbytes) self.prg.diff_sq(self.queue, h_mrti.shape, None, d_mrti , d_fem , dest_buf) mrti_minus_fem_squared = numpy.empty_like(h_mrti) cl.enqueue_copy(self.queue, mrti_minus_fem_squared , dest_buf) ObjectiveFunction = ObjectiveFunction + mrti_minus_fem_squared.sum() return ObjectiveFunction
def ProjectImagingMesh(fem_mesh_file): import vtk import vtk.util.numpy_support as vtkNumPy import scipy.io as scipyio # echo vtk version info print "using vtk version", vtk.vtkVersion.GetVTKVersion() # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview AffineTransform = vtk.vtkTransform() # should be in meters AffineTransform.Translate(.0000001,.0000001,.0000001) AffineTransform.RotateZ( 0 ) AffineTransform.RotateY( 0 ) AffineTransform.RotateX( 0 ) AffineTransform.Scale([1.,1.,1.]) # get homogenius 4x4 matrix of the form # A | b # matrix = ----- # 0 | 1 # matrix = AffineTransform.GetConcatenatedTransform(0).GetMatrix() #print matrix RotationMatrix = [[matrix.GetElement(0,0),matrix.GetElement(0,1),matrix.GetElement(0,2)], [matrix.GetElement(1,0),matrix.GetElement(1,1),matrix.GetElement(1,2)], [matrix.GetElement(2,0),matrix.GetElement(2,1),matrix.GetElement(2,2)]] Translation = [matrix.GetElement(0,3),matrix.GetElement(1,3),matrix.GetElement(2,3)] #print RotationMatrix ,Translation #laserTip = AffineTransform.TransformPoint( laserTip ) #laserOrientation = AffineTransform.TransformVector( laserOrientation ) # read imaging data geometry that will be used to project FEM data onto #vtkReader = vtk.vtkXMLImageDataReader() vtkReader = vtk.vtkDataSetReader() #vtkReader.SetFileName('/data/cjmaclellan/mdacc/nano/spio/spioVTK/67_11/tmap_67_11.0000.vtk' ) vtkReader.SetFileName('/data/cjmaclellan/mdacc/deltap_phantom_oct10/VTKtmaps/S695/S695.0000.vtk' ) #vtkReader.SetFileName('/data/cjmaclellan/mdacc/nano/nrtmapsVTK/R695/R695.0000.vtk' ) vtkReader.Update() templateImage = vtkReader.GetOutput() dimensions = templateImage.GetDimensions() spacing = templateImage.GetSpacing() origin = templateImage.GetOrigin() print spacing, origin, dimensions #fem.SetImagingDimensions( dimensions ,origin,spacing) ## project imaging onto fem mesh #if (vtk != None): # vtkImageReader = vtk.vtkDataSetReader() # vtkImageReader.SetFileName('/data/fuentes/mdacc/uqModelStudy/dog1_980/temperature.%04d.vtk' % timeID ) # vtkImageReader.Update() # image_cells = vtkImageReader.GetOutput().GetPointData() # data_array = vtkNumPy.vtk_to_numpy(image_cells.GetArray('scalars')) # v1 = PETSc.Vec().createWithArray(data_array, comm=PETSc.COMM_SELF) # fem.ProjectImagingToFEMMesh("MRTI", v1) # fem.StoreSystemTimeStep("MRTI",timeID ) # # # extract voi for QOI # vtkVOIExtract = vtk.vtkExtractVOI() # vtkVOIExtract.SetInput( vtkImageReader.GetOutput() ) # VOI = [10,100,100,150,0,0] # vtkVOIExtract.SetVOI( VOI ) # vtkVOIExtract.Update() # mrti_point_data= vtkVOIExtract.GetOutput().GetPointData() # mrti_array = vtkNumPy.vtk_to_numpy(mrti_point_data.GetArray('scalars')) # #print mrti_array # #print type(mrti_array) # Interpolate FEM onto imaging data structures vtkExodusIIReader = vtk.vtkExodusIIReader() vtkExodusIIReader.SetFileName( fem_mesh_file ) vtkExodusIIReader.SetPointResultArrayStatus("u0",1) vtkExodusIIReader.SetPointResultArrayStatus("u0*",1) vtkExodusIIReader.SetPointResultArrayStatus("u1",1) matsize = int(dimensions[1])#get matrix size #preallocate size of arrays u0_array_1 = scipy.zeros((matsize,matsize)) u0_array_2 = scipy.zeros((matsize,matsize,ntime*nsubstep)) u1_array_1 = scipy.zeros((matsize,matsize)) u1_array_2 = scipy.zeros((matsize,matsize,ntime*nsubstep)) u0star_array_1 = scipy.zeros((matsize,matsize)) u0star_array_2 = scipy.zeros((matsize,matsize,ntime*nsubstep)) #for timeID in range(1,2): for timeID in range(1,ntime*nsubstep): vtkExodusIIReader.SetTimeStep(timeID-1) vtkExodusIIReader.Update() # apply the transform TransformedFEMMesh = None if vtkExodusIIReader.GetOutput().IsA("vtkMultiBlockDataSet"): AppendBlocks = vtk.vtkAppendFilter() iter = vtkExodusIIReader.GetOutput().NewIterator() iter.UnRegister(None) iter.InitTraversal() # loop over blocks... while not iter.IsDoneWithTraversal(): curInput = iter.GetCurrentDataObject() vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform( AffineTransform ) vtkTransformFEMMesh.SetInput( curInput ) vtkTransformFEMMesh.Update() AppendBlocks.AddInput( vtkTransformFEMMesh.GetOutput() ) AppendBlocks.Update( ) iter.GoToNextItem(); TransformedFEMMesh = AppendBlocks.GetOutput() else: vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform( AffineTransform ) vtkTransformFEMMesh.SetInput( vtkExodusIIReader.GetOutput() ) vtkTransformFEMMesh.Update() TransformedFEMMesh = vtkTransformFEMMesh.GetOutput() # reflect #vtkReflectX = vtk.vtkReflectionFilter() #vtkReflectX.SetPlaneToXMin() #vtkReflectX.SetInput( TransformedFEMMesh ) #vtkReflectX.Update() # reflect #vtkReflectZ = vtk.vtkReflectionFilter() #vtkReflectZ.SetPlaneToZMax() #vtkReflectZ.SetInput( vtkReflectX.GetOutput() ) #vtkReflectZ.Update() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput( templateImage ) vtkResample.SetSource( TransformedFEMMesh ) #vtkResample.SetSource( vtkReflectZ.GetOutput() ) vtkResample.Update() fem_point_data= vtkResample.GetOutput().GetPointData() u0_array = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('u0')) u0star_array = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('u0*')) u1_array = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('u1')) #go from 1x256^2 array to 256X256 array for each timestep for nn in range(0,matsize): u0_array_1[nn,:]=u0_array[nn*matsize:(nn+1)*matsize] u0star_array_1[nn,:]=u0star_array[nn*matsize:(nn+1)*matsize] u1_array_1[nn,:]=u1_array[nn*matsize:(nn+1)*matsize] #apply proper rotations/reflections and combine 2D arrays into 3D array u0_array_2[:,:,timeID-1]=numpy.fliplr(numpy.rot90(u0_array_1,k=3)) u0star_array_2[:,:,timeID-1]=numpy.fliplr(numpy.rot90(u0star_array_1,k=3)) u1_array_2[:,:,timeID-1]=numpy.fliplr(numpy.rot90(u1_array_1,k=3)) # write numpy to disk in matlab #scipyio.savemat("MS795.%04d.mat" % (timeID), {'u0':u1_array,'MRTI0':MRTI0_array }) # write output print "writing ", timeID vtkStatsWriter = vtk.vtkDataSetWriter() vtkStatsWriter.SetFileTypeToBinary() vtkStatsWriter.SetFileName("test.%04d.vtk" % timeID ) vtkStatsWriter.SetInput(vtkResample.GetOutput()) vtkStatsWriter.Update() scipyio.savemat("S695.mat",{'ModelFluence':u1_array_2,'MRTI':u0star_array_2,'ModelTemp':u0_array_2})
def ProjectImagingMesh(ini_file): import vtk.util.numpy_support as vtkNumPy import ConfigParser import scipy.io as scipyio # echo vtk version info print "using vtk version", vtk.vtkVersion.GetVTKVersion() # read config file config = ConfigParser.ConfigParser() config.add_section("imaging") config.add_section("fem") config.set("imaging", "listoffset", "[0]") config.read(ini_file) # get work directory work_dir = config.get('fem', 'work_dir') # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview RotateX = float(config.get('fem', 'rotatex')) RotateY = float(config.get('fem', 'rotatey')) RotateZ = float(config.get('fem', 'rotatez')) Translate = eval(config.get('fem', 'translate')) Scale = eval(config.get('fem', 'scale')) print "rotate", RotateX, RotateY, RotateZ, "translate", Translate, "scale", Scale # read imaging data geometry that will be used to project FEM data onto dimensions = eval(config.get('imaging', 'dimensions')) spacing = eval(config.get('imaging', 'spacing')) origin = eval(config.get('imaging', 'origin')) print spacing, origin, dimensions templateImage = CreateVTKImage(dimensions, spacing, origin) # write template image for position verification vtkTemplateWriter = vtk.vtkDataSetWriter() vtkTemplateWriter.SetFileName("%s/imageTemplate.vtk" % work_dir) vtkTemplateWriter.SetInput(templateImage) vtkTemplateWriter.Update() #setup to interpolate at 5 points across axial dimension TransformList = [] listoffset = eval(config.get('imaging', 'listoffset')) naverage = len(listoffset) try: subdistance = spacing[2] / (naverage - 1) except ZeroDivisionError: subdistance = 0.0 # default is not to offset print "listoffset", listoffset, "subspacing distance = ", subdistance for idtransform in listoffset: AffineTransform = vtk.vtkTransform() AffineTransform.Translate(Translate[0], Translate[1], Translate[2] + subdistance * idtransform) AffineTransform.RotateZ(RotateZ) AffineTransform.RotateY(RotateY) AffineTransform.RotateX(RotateX) AffineTransform.Scale(Scale) TransformList.append(AffineTransform) #laserTip = AffineTransform.TransformPoint( laserTip ) #laserOrientation = AffineTransform.TransformVector( laserOrientation ) # Interpolate FEM onto imaging data structures vtkExodusIIReader = vtk.vtkExodusIIReader() #vtkExodusIIReader.SetFileName( "%s/fem_stats.e" % work_dir ) #vtkExodusIIReader.SetPointResultArrayStatus("Mean0",1) #vtkExodusIIReader.SetPointResultArrayStatus("StdDev0",1) #Timesteps = 120 meshFileList = eval(config.get('fem', 'mesh_files')) print meshFileList for mesh_filename in meshFileList: vtkExodusIIReader.SetFileName("%s/%s" % (work_dir, mesh_filename)) #vtkExodusIIReader.SetPointResultArrayStatus("Vard0Mean",1) #vtkExodusIIReader.SetPointResultArrayStatus("Vard0Kurt",1) vtkExodusIIReader.Update() numberofresultarrays = vtkExodusIIReader.GetNumberOfPointResultArrays() print numberofresultarrays for resultarrayindex in range(numberofresultarrays): resultarrayname = vtkExodusIIReader.GetPointResultArrayName( resultarrayindex) vtkExodusIIReader.SetPointResultArrayStatus( "%s" % (resultarrayname), 1) print resultarrayname vtkExodusIIReader.Update() ntime = vtkExodusIIReader.GetNumberOfTimeSteps() #print ntime #for timeID in range(69,70): for timeID in range(ntime): vtkExodusIIReader.SetTimeStep(timeID) vtkExodusIIReader.Update() # reflect vtkReflectX = vtk.vtkReflectionFilter() vtkReflectX.SetPlaneToXMin() vtkReflectX.SetInput(vtkExodusIIReader.GetOutput()) vtkReflectX.Update() # reflect vtkReflectY = vtk.vtkReflectionFilter() vtkReflectY.SetPlaneToYMax() vtkReflectY.SetInput(vtkReflectX.GetOutput()) vtkReflectY.Update() # apply the average of the transform mean_array = numpy.zeros(dimensions[0] * dimensions[1] * dimensions[2]) std_array = numpy.zeros(dimensions[0] * dimensions[1] * dimensions[2]) for affineFEMTranform in TransformList: # get homogenius 4x4 matrix of the form # A | b # matrix = ----- # 0 | 1 # matrix = affineFEMTranform.GetConcatenatedTransform( 0).GetMatrix() #print matrix RotationMatrix = [[ matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2) ], [ matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2) ], [ matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2) ]] Translation = [ matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3) ] #print RotationMatrix print Translation TransformedFEMMesh = None if vtkReflectY.GetOutput().IsA("vtkMultiBlockDataSet"): AppendBlocks = vtk.vtkAppendFilter() iter = vtkReflectY.GetOutput().NewIterator() iter.UnRegister(None) iter.InitTraversal() # loop over blocks... while not iter.IsDoneWithTraversal(): curInput = iter.GetCurrentDataObject() vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform(affineFEMTranform) vtkTransformFEMMesh.SetInput(curInput) vtkTransformFEMMesh.Update() AppendBlocks.AddInput(vtkTransformFEMMesh.GetOutput()) AppendBlocks.Update() iter.GoToNextItem() TransformedFEMMesh = AppendBlocks.GetOutput() else: vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform(affineFEMTranform) vtkTransformFEMMesh.SetInput(vtkReflectY.GetOutput()) vtkTransformFEMMesh.Update() TransformedFEMMesh = vtkTransformFEMMesh.GetOutput() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput(templateImage) vtkResample.SetSource(TransformedFEMMesh) vtkResample.Update() fem_point_data = vtkResample.GetOutput().GetPointData() #meantmp = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Mean')) #print meantmp.max() #mean_array = mean_array + vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Mean')) #std_array = std_array + vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Kurt')) #print fem_array #print type(fem_array ) # average #mean_array = mean_array/naverage #print mean_array.max() #std_array = std_array /naverage # write numpy to disk in matlab #scipyio.savemat("%s/modelstats.navg%d.%04d.mat" % (work_dir,naverage,timeID), {'spacing':spacing, 'origin':origin,'Vard0Mean':mean_array,'Vard0Kurt':std_array }) # write output print "writing ", timeID, mesh_filename, work_dir vtkStatsWriter = vtk.vtkDataSetWriter() vtkStatsWriter.SetFileTypeToBinary() vtkStatsWriter.SetFileName( "%s/modelstats.navg%d.%s.%04d.vtk" % (work_dir, naverage, mesh_filename, timeID)) vtkStatsWriter.SetInput(vtkResample.GetOutput()) vtkStatsWriter.Update()
def pennesModeling(**kwargs): """ treatment planning model """ # import needed modules import petsc4py, numpy, sys PetscOptions = sys.argv PetscOptions.append("-ksp_monitor") PetscOptions.append("-ksp_rtol") PetscOptions.append("1.0e-15") #PetscOptions.append("-idb") petsc4py.init(PetscOptions) from petsc4py import PETSc # break processors into separate communicators petscRank = PETSc.COMM_WORLD.getRank() petscSize = PETSc.COMM_WORLD.Get_size() sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize)) # set shell context import femLibrary # initialize libMesh data structures libMeshInit = femLibrary.PyLibMeshInit(PetscOptions, PETSc.COMM_WORLD) # the original configuration ini file should be stored config = kwargs['config_parser'] # store control variables getpot = femLibrary.PylibMeshGetPot(PetscOptions) # copy all values from the input file for section in config.sections(): for name, value in config.items(section): #print "%s/%s" % (section,name) , value getpot.SetIniValue("%s/%s" % (section, name), value) # nodeset 1 will be treated as dirichlet dirichletID = 1 getpot.SetIniValue("bc/u_dirichlet", '%d' % dirichletID) # set tissue lookup tables k_0Table = { "default": config.getfloat("thermal_conductivity", "k_0_healthy"), "vessel": config.getfloat("thermal_conductivity", "k_0_healthy"), "grey": config.getfloat("thermal_conductivity", "k_0_grey"), "white": config.getfloat("thermal_conductivity", "k_0_white"), "csf": config.getfloat("thermal_conductivity", "k_0_csf"), "tumor": config.getfloat("thermal_conductivity", "k_0_tumor") } w_0Table = { "default": config.getfloat("perfusion", "w_0_healthy"), "vessel": config.getfloat("perfusion", "w_0_healthy"), "grey": config.getfloat("perfusion", "w_0_grey"), "white": config.getfloat("perfusion", "w_0_white"), "csf": config.getfloat("perfusion", "w_0_csf"), "tumor": config.getfloat("perfusion", "w_0_tumor") } mu_aTable = { "default": config.getfloat("optical", "mu_a_healthy"), "vessel": config.getfloat("optical", "mu_a_healthy"), "grey": config.getfloat("optical", "mu_a_grey"), "white": config.getfloat("optical", "mu_a_white"), "csf": config.getfloat("optical", "mu_a_csf"), "tumor": config.getfloat("optical", "mu_a_tumor") } mu_sTable = { "default": config.getfloat("optical", "mu_s_healthy"), "vessel": config.getfloat("optical", "mu_s_healthy"), "grey": config.getfloat("optical", "mu_s_grey"), "white": config.getfloat("optical", "mu_s_white"), "csf": config.getfloat("optical", "mu_s_csf"), "tumor": config.getfloat("optical", "mu_s_tumor") } labelTable = { config.get("labels", "greymatter"): "grey", config.get("labels", "whitematter"): "white", config.get("labels", "csf"): "csf", config.get("labels", "tumor"): "tumor", config.get("labels", "vessel"): "vessel" } labelCount = { "default": 0, "grey": 0, "white": 0, "csf": 0, "tumor": 0, "vessel": 0 } # imaging params import vtk import vtk.util.numpy_support as vtkNumPy SegmentFile = config.get("exec", "segment_file") # set the default reader based on extension if (SegmentFile.split(".").pop() == "vtk"): vtkImageReader = vtk.vtkDataSetReader elif (SegmentFile.split(".").pop() == "vti"): vtkImageReader = vtk.vtkXMLImageDataReader else: raise RuntimeError("uknown file") # get dimension info from header vtkSetupReader = vtkImageReader() vtkSetupReader.SetFileName(SegmentFile) vtkSetupReader.Update() vtkImageMask = vtkSetupReader.GetOutput() dimensions = vtkSetupReader.GetOutput().GetDimensions() numberPointsImage = vtkSetupReader.GetOutput().GetNumberOfPoints() spacing_mm = vtkSetupReader.GetOutput().GetSpacing() origin_mm = vtkSetupReader.GetOutput().GetOrigin() # convert to meters spacing = [dx * .001 for dx in spacing_mm] origin = [x0 * .001 for x0 in origin_mm] # pass pointer to c++ image_cells = vtkImageMask.GetPointData() data_array = vtkNumPy.vtk_to_numpy(image_cells.GetArray(0)) # need to pass numpy array's w/ Fortran storage... ie painful to debug imageDataVec = PETSc.Vec().createWithArray(numpy.ravel(data_array, order='F'), comm=PETSc.COMM_SELF) # FIXME - center around quadrature in out-of-plane direction # FIXME - need better out of plane cooling model quadratureOffset = 1. / numpy.sqrt(3.0) * spacing[2] / 2.0 # expecting roi and subsample of the form: # roi = [(40,210),(30,220),(6,78)] # subsample = [3,3,2] ROI = eval(config.get('exec', 'roi')) subsample = eval(config.get('exec', 'subsample')) nelemROI = [(pixel[1] - pixel[0] - 1) / sub for pixel, sub in zip(ROI, subsample)] xbounds = [ origin[0] + spacing[0] * (ROI[0][0] + 0.5), origin[0] + spacing[0] * (ROI[0][1] + 0.5) ] ybounds = [ origin[1] + spacing[1] * (ROI[1][0] + 0.5), origin[1] + spacing[1] * (ROI[1][1] + 0.5) ] zbounds = [ origin[2] + spacing[2] * (ROI[2][0] + 0.5), origin[2] + spacing[2] * (ROI[2][1] + 0.5) ] if (petscRank == 0): print "#points", numberPointsImage, "dimensions ", dimensions, "spacing ", spacing, "origin ", origin print "ROI", ROI, "nelemROI ", nelemROI, "bounds", xbounds, ybounds, zbounds #set to steady state solve getpot.SetIniValue("steadystate/domain_0", "true") # initialize FEM Mesh femMesh = femLibrary.PylibMeshMesh() #femMesh.SetupUnStructuredGrid(kwargs['mesh_file'],0,RotationMatrix, Translation ) #femMesh.ReadFile(kwargs['mesh_file']) femMesh.SetupStructuredGrid(nelemROI, xbounds, ybounds, zbounds, [2, 2, 2, 2, 2, 2]) # get output file name else set default name try: MeshOutputFile = config.get("exec", "exodus_file") except ConfigParser.NoOptionError: MeshOutputFile = "fem.e" # add the data structures for the Background System Solve # set deltat, number of time steps, power profile, and add system eqnSystems = femLibrary.PylibMeshEquationSystems(femMesh, getpot) #getpot.SetIniPower(1,[[19,119],[90.0,100.0]] ) getpot.SetIniPower(1, kwargs['powerHistory']) # AddPennesSDASystem # AddPennesRFSystem # AddPennesDeltaPSystem pennesSystem = eval("eqnSystems.%s('StateSystem',kwargs['deltat'])" % kwargs['physics']) pennesSystem.AddStorageVectors(kwargs['ntime'] + 1) # add system for labels # FIXME: need both nodal, for dirichlet bc, and element version, for parameter masks maskElemSystem = eqnSystems.AddExplicitSystem("ElemImageMask") maskElemSystem.AddConstantMonomialVariable("maskElem") # initialize libMesh data structures eqnSystems.init() # print info eqnSystems.PrintSelf() # setup imaging to interpolate onto FEM mesh femImaging = femLibrary.PytttkImaging(getpot, dimensions, origin, spacing) # Project imaging onto libMesh data structures femImaging.ProjectImagingToFEMMesh("ElemImageMask", 0.0, imageDataVec, eqnSystems) femImaging.ProjectImagingToFEMMesh("StateSystem", 0.0, imageDataVec, eqnSystems) # create dirichlet nodes from this mask numNodes = pennesSystem.PetscFEMSystemCreateNodeSetFromMask( config.getfloat("labels", "vessel"), dirichletID) print "# of dirichlet nodes %d" % numNodes # get image label as numpy array imageLabel = maskElemSystem.GetSolutionVector()[...] #imageLabel = numpy.floor(10.0*imageLabel.copy())+1 k_0Label = imageLabel.copy() w_0Label = imageLabel.copy() mu_aLabel = imageLabel.copy() mu_sLabel = imageLabel.copy() for (idpos, label) in enumerate(imageLabel): try: tissueType = labelTable["%d" % int(label)] except KeyError: tissueType = "default" labelCount[tissueType] = labelCount[tissueType] + 1 k_0Label[idpos] = k_0Table[tissueType] w_0Label[idpos] = w_0Table[tissueType] mu_aLabel[idpos] = mu_aTable[tissueType] mu_sLabel[idpos] = mu_sTable[tissueType] # create array of imaging data as petsc vec k_0Vec = PETSc.Vec().createWithArray(k_0Label, comm=PETSc.COMM_SELF) w_0Vec = PETSc.Vec().createWithArray(w_0Label, comm=PETSc.COMM_SELF) mu_aVec = PETSc.Vec().createWithArray(mu_aLabel, comm=PETSc.COMM_SELF) mu_sVec = PETSc.Vec().createWithArray(mu_sLabel, comm=PETSc.COMM_SELF) # copy material properties to the system eqnSystems.GetSystem("k_0").SetSolutionVector(k_0Vec) eqnSystems.GetSystem("w_0").SetSolutionVector(w_0Vec) eqnSystems.GetSystem("mu_a").SetSolutionVector(mu_aVec) eqnSystems.GetSystem("mu_s").SetSolutionVector(mu_sVec) # write IC exodusII_IO = femLibrary.PylibMeshExodusII_IO(femMesh) exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, 1, 0.0) exodusII_IO.WriteParameterSystems(eqnSystems) # setup IC pennesSystem.PetscFEMSystemSetupInitialConditions() # create list of laser positions laserPositionList = [((.015, .015, 2 * spacing[2] + quadratureOffset), (.018, .018, 2 * spacing[2] + quadratureOffset)), ((.015, .015, 2 * spacing[2] + quadratureOffset), (.016, .018, 2 * spacing[2] + quadratureOffset)), ((.015, .015, 1 * spacing[2] + quadratureOffset), (.014, .014, 1 * spacing[2] + quadratureOffset)), ((.015, .015, 1 * spacing[2] + quadratureOffset), (.015, .018, 3 * spacing[2] + quadratureOffset))] # time stamp import pickle, time timeStamp = 0 # set power id to turn laser on pennesSystem.PetscFEMSystemUpdateTimeStep(1) # loop over laser position and solve steady state equations for each position #for (idpos,(pos0,pos1)) in enumerate(laserPositionList): # loop and read new laser parameters while (True): if (os.path.getmtime(fem_params['ini_filename']) > timeStamp): timeStamp = os.path.getmtime(fem_params['ini_filename']) newIni = ConfigParser.SafeConfigParser({}) newIni.read(fem_params['ini_filename']) laserParams = {} laserParams['position1'] = [ newIni.getfloat("probe", varID) for varID in ["x_0", "y_0", "z_0"] ] laserParams['position2'] = [ newIni.getfloat("probe", varID) for varID in ["x_1", "y_1", "z_1"] ] print "laser position = ", newIni.getfloat("timestep", "power"), laserParams pennesSystem.PennesSDASystemUpdateLaserPower( newIni.getfloat("timestep", "power"), 1) pennesSystem.PennesSDASystemUpdateLaserPosition( laserParams['position1'], laserParams['position2']) pennesSystem.SystemSolve() #fem.StoreTransientSystemTimeStep("StateSystem",timeID ) #exodusII_IO.WriteTimeStep(MeshOutputFile ,eqnSystems, idpos+2, idpos*kwargs['deltat']) exodusII_IO.WriteTimeStep(MeshOutputFile, eqnSystems, 2, 1.0) exodusII_IO.WriteParameterSystems(eqnSystems) # write to txt file if (petscRank == 0): time.sleep(1) vtkExodusIIReader = vtk.vtkExodusIIReader() print "opening %s " % MeshOutputFile vtkExodusIIReader.SetFileName(MeshOutputFile) vtkExodusIIReader.Update() ntime = vtkExodusIIReader.GetNumberOfTimeSteps() variableID = "u0" print "ntime %d %s " % (ntime, variableID) vtkExodusIIReader.SetTimeStep(1) vtkExodusIIReader.SetPointResultArrayStatus(variableID, 1) vtkExodusIIReader.Update() curInput = None # multi block if vtkExodusIIReader.GetOutput().IsA("vtkMultiBlockDataSet"): iter = vtkExodusIIReader.GetOutput().NewIterator() iter.UnRegister(None) iter.InitTraversal() curInput = iter.GetCurrentDataObject() else: curInput = vtkExodusIIReader.GetOutput() #fem_point_data= curInput.GetPointData().GetArray('u0') #Soln=vtkNumPy.vtk_to_numpy(fem_point_data) #numpy.savetxt( "temperature.txt" ,Soln) # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview # scale back to millimeter # TODO verify that the data sets are registered in the native slicer coordinate system # TODO segmented data MUST be read in with: # TODO add data -> volume -> show options -> ignore orientation # TODO add data -> volume -> show options -> ignore orientation # TODO add data -> volume -> show options -> ignore orientation AffineTransform = vtk.vtkTransform() AffineTransform.Translate([0.0, 0.0, 0.0]) AffineTransform.RotateZ(0.0) AffineTransform.RotateY(0.0) AffineTransform.RotateX(0.0) AffineTransform.Scale([1000., 1000., 1000.]) # scale to millimeter transformFilter = vtk.vtkTransformFilter() transformFilter.SetInput(curInput) transformFilter.SetTransform(AffineTransform) transformFilter.Update() # setup contour filter vtkContour = vtk.vtkContourFilter() vtkContour.SetInput(transformFilter.GetOutput()) # TODO: not sure why this works... # set the array to process at the temperature == u0 vtkContour.SetInputArrayToProcess(0, 0, 0, 0, 'u0') contourValuesList = eval(newIni.get('exec', 'contours')) vtkContour.SetNumberOfContours(len(contourValuesList)) print "plotting array:", vtkContour.GetArrayComponent() for idContour, contourValue in enumerate(contourValuesList): print "plotting contour:", idContour, contourValue vtkContour.SetValue(idContour, contourValue) vtkContour.Update() # setup threshold filter vtkThreshold = vtk.vtkThreshold() vtkThreshold.SetInput(transformFilter.GetOutput()) vtkThreshold.ThresholdByLower(contourValuesList[0]) #vtkThreshold.SetSelectedComponent( 0 ) vtkThreshold.SetComponentModeToUseAny() vtkThreshold.Update() # resample onto image vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput(vtkImageMask) vtkResample.SetSource(vtkThreshold.GetOutput()) vtkResample.Update() # write output print "writing fem.vtk " vtkImageWriter = vtk.vtkDataSetWriter() vtkImageWriter.SetFileTypeToBinary() vtkImageWriter.SetFileName("fem.vtk") vtkImageWriter.SetInput(vtkResample.GetOutput()) vtkImageWriter.Update() # write stl file stlWriter = vtk.vtkSTLWriter() stlWriter.SetInput(vtkContour.GetOutput()) stlWriter.SetFileName("fem.stl") stlWriter.SetFileTypeToBinary() stlWriter.Write() # write support file to signal full stl file is written # Slicer module will wait for this file to be written # before trying to open stl file to avoid incomplete reads with open('./fem.finish', 'w') as signalFile: signalFile.write("the stl file has been written\n") else: print "waiting on user input.." # echo lookup table if (petscRank == 0): print "lookup tables" print "labeled %d voxels" % len(imageLabel) print "labels", labelTable print "counts", labelCount print "conductivity", k_0Table print "perfusion", w_0Table print "absorption", mu_aTable print "scattering", mu_sTable time.sleep(2)
def ProjectImagingMesh(ini_file): import vtk.util.numpy_support as vtkNumPy import ConfigParser import scipy.io as scipyio # echo vtk version info print "using vtk version", vtk.vtkVersion.GetVTKVersion() # read config file config = ConfigParser.ConfigParser() config.add_section("imaging") config.add_section("fem") config.set("imaging","listoffset","[0]") config.read(ini_file) # get work directory work_dir = config.get('fem','work_dir') # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview RotateX = float(config.get('fem','rotatex')) RotateY = float(config.get('fem','rotatey')) RotateZ = float(config.get('fem','rotatez')) Translate = eval(config.get('fem','translate')) Scale = eval(config.get('fem','scale')) print "rotate", RotateX , RotateY , RotateZ ,"translate", Translate, "scale", Scale # read imaging data geometry that will be used to project FEM data onto dimensions = eval(config.get('imaging','dimensions')) spacing = eval(config.get('imaging','spacing')) origin = eval(config.get('imaging','origin')) print spacing, origin, dimensions templateImage = CreateVTKImage(dimensions,spacing,origin) # write template image for position verification vtkTemplateWriter = vtk.vtkDataSetWriter() vtkTemplateWriter.SetFileName( "%s/imageTemplate.vtk" % work_dir ) vtkTemplateWriter.SetInput( templateImage ) vtkTemplateWriter.Update() #setup to interpolate at 5 points across axial dimension TransformList = [] listoffset = eval(config.get('imaging','listoffset')) naverage = len(listoffset) try: subdistance = spacing[2] / (naverage-1) except ZeroDivisionError: subdistance = 0.0 # default is not to offset print "listoffset",listoffset, "subspacing distance = ", subdistance for idtransform in listoffset: AffineTransform = vtk.vtkTransform() AffineTransform.Translate( Translate[0],Translate[1], Translate[2] + subdistance*idtransform ) AffineTransform.RotateZ( RotateZ ) AffineTransform.RotateY( RotateY ) AffineTransform.RotateX( RotateX ) AffineTransform.Scale( Scale ) TransformList.append( AffineTransform ) #laserTip = AffineTransform.TransformPoint( laserTip ) #laserOrientation = AffineTransform.TransformVector( laserOrientation ) # Interpolate FEM onto imaging data structures vtkExodusIIReader = vtk.vtkExodusIIReader() #vtkExodusIIReader.SetFileName( "%s/fem_stats.e" % work_dir ) #vtkExodusIIReader.SetPointResultArrayStatus("Mean0",1) #vtkExodusIIReader.SetPointResultArrayStatus("StdDev0",1) #Timesteps = 120 meshFileList = eval(config.get('fem','mesh_files')) print meshFileList for mesh_filename in meshFileList: vtkExodusIIReader.SetFileName( "%s/%s" % (work_dir,mesh_filename) ) #vtkExodusIIReader.SetPointResultArrayStatus("Vard0Mean",1) #vtkExodusIIReader.SetPointResultArrayStatus("Vard0Kurt",1) vtkExodusIIReader.Update() numberofresultarrays = vtkExodusIIReader.GetNumberOfPointResultArrays() print numberofresultarrays for resultarrayindex in range(numberofresultarrays): resultarrayname = vtkExodusIIReader.GetPointResultArrayName(resultarrayindex) vtkExodusIIReader.SetPointResultArrayStatus( "%s" % (resultarrayname),1) print resultarrayname vtkExodusIIReader.Update() ntime = vtkExodusIIReader.GetNumberOfTimeSteps() #print ntime #for timeID in range(69,70): for timeID in range(ntime): vtkExodusIIReader.SetTimeStep(timeID) vtkExodusIIReader.Update() # reflect vtkReflectX = vtk.vtkReflectionFilter() vtkReflectX.SetPlaneToXMin() vtkReflectX.SetInput( vtkExodusIIReader.GetOutput() ) vtkReflectX.Update() # reflect vtkReflectY = vtk.vtkReflectionFilter() vtkReflectY.SetPlaneToYMax() vtkReflectY.SetInput( vtkReflectX.GetOutput() ) vtkReflectY.Update() # apply the average of the transform mean_array = numpy.zeros(dimensions[0]*dimensions[1]*dimensions[2]) std_array = numpy.zeros(dimensions[0]*dimensions[1]*dimensions[2]) for affineFEMTranform in TransformList: # get homogenius 4x4 matrix of the form # A | b # matrix = ----- # 0 | 1 # matrix = affineFEMTranform.GetConcatenatedTransform(0).GetMatrix() #print matrix RotationMatrix = [[matrix.GetElement(0,0),matrix.GetElement(0,1),matrix.GetElement(0,2)], [matrix.GetElement(1,0),matrix.GetElement(1,1),matrix.GetElement(1,2)], [matrix.GetElement(2,0),matrix.GetElement(2,1),matrix.GetElement(2,2)]] Translation = [matrix.GetElement(0,3),matrix.GetElement(1,3),matrix.GetElement(2,3)] #print RotationMatrix print Translation TransformedFEMMesh = None if vtkReflectY.GetOutput().IsA("vtkMultiBlockDataSet"): AppendBlocks = vtk.vtkAppendFilter() iter = vtkReflectY.GetOutput().NewIterator() iter.UnRegister(None) iter.InitTraversal() # loop over blocks... while not iter.IsDoneWithTraversal(): curInput = iter.GetCurrentDataObject() vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform( affineFEMTranform ) vtkTransformFEMMesh.SetInput( curInput ) vtkTransformFEMMesh.Update() AppendBlocks.AddInput( vtkTransformFEMMesh.GetOutput() ) AppendBlocks.Update( ) iter.GoToNextItem(); TransformedFEMMesh = AppendBlocks.GetOutput() else: vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform( affineFEMTranform ) vtkTransformFEMMesh.SetInput( vtkReflectY.GetOutput() ) vtkTransformFEMMesh.Update() TransformedFEMMesh = vtkTransformFEMMesh.GetOutput() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput( templateImage ) vtkResample.SetSource( TransformedFEMMesh ) vtkResample.Update() fem_point_data= vtkResample.GetOutput().GetPointData() #meantmp = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Mean')) #print meantmp.max() #mean_array = mean_array + vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Mean')) #std_array = std_array + vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Kurt')) #print fem_array #print type(fem_array ) # average #mean_array = mean_array/naverage #print mean_array.max() #std_array = std_array /naverage # write numpy to disk in matlab #scipyio.savemat("%s/modelstats.navg%d.%04d.mat" % (work_dir,naverage,timeID), {'spacing':spacing, 'origin':origin,'Vard0Mean':mean_array,'Vard0Kurt':std_array }) # write output print "writing ", timeID, mesh_filename, work_dir vtkStatsWriter = vtk.vtkDataSetWriter() vtkStatsWriter.SetFileTypeToBinary() vtkStatsWriter.SetFileName("%s/modelstats.navg%d.%s.%04d.vtk"%(work_dir,naverage,mesh_filename,timeID)) vtkStatsWriter.SetInput(vtkResample.GetOutput()) vtkStatsWriter.Update()
def pennesModeling(**kwargs): """ treatment planning model """ # import needed modules import petsc4py, numpy, sys PetscOptions = sys.argv PetscOptions.append("-ksp_monitor") PetscOptions.append("-ksp_rtol") PetscOptions.append("1.0e-15") #PetscOptions.append("-idb") petsc4py.init(PetscOptions) from petsc4py import PETSc # break processors into separate communicators petscRank = PETSc.COMM_WORLD.getRank() petscSize = PETSc.COMM_WORLD.Get_size() sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize)) # set shell context import femLibrary # initialize libMesh data structures libMeshInit = femLibrary.PyLibMeshInit(PetscOptions,PETSc.COMM_WORLD) # the original configuration ini file should be stored config = kwargs['config_parser'] # store control variables getpot = femLibrary.PylibMeshGetPot(PetscOptions) # copy all values from the input file for section in config.sections(): for name,value in config.items(section): #print "%s/%s" % (section,name) , value getpot.SetIniValue( "%s/%s" % (section,name) , value ) # nodeset 1 will be treated as dirichlet dirichletID = 1 getpot.SetIniValue( "bc/u_dirichlet" , '%d' % dirichletID ) # set tissue lookup tables k_0Table = {"default":config.getfloat("thermal_conductivity","k_0_healthy") , "vessel" :config.getfloat("thermal_conductivity","k_0_healthy") , "grey" :config.getfloat("thermal_conductivity","k_0_grey" ) , "white" :config.getfloat("thermal_conductivity","k_0_white" ) , "csf" :config.getfloat("thermal_conductivity","k_0_csf" ) , "tumor" :config.getfloat("thermal_conductivity","k_0_tumor" ) } w_0Table = {"default":config.getfloat("perfusion","w_0_healthy") , "vessel" :config.getfloat("perfusion","w_0_healthy") , "grey" :config.getfloat("perfusion","w_0_grey" ) , "white" :config.getfloat("perfusion","w_0_white" ) , "csf" :config.getfloat("perfusion","w_0_csf" ) , "tumor" :config.getfloat("perfusion","w_0_tumor" ) } mu_aTable = {"default":config.getfloat("optical","mu_a_healthy") , "vessel" :config.getfloat("optical","mu_a_healthy") , "grey" :config.getfloat("optical","mu_a_grey" ) , "white" :config.getfloat("optical","mu_a_white" ) , "csf" :config.getfloat("optical","mu_a_csf" ) , "tumor" :config.getfloat("optical","mu_a_tumor" ) } mu_sTable = {"default":config.getfloat("optical","mu_s_healthy") , "vessel" :config.getfloat("optical","mu_s_healthy") , "grey" :config.getfloat("optical","mu_s_grey" ) , "white" :config.getfloat("optical","mu_s_white" ) , "csf" :config.getfloat("optical","mu_s_csf" ) , "tumor" :config.getfloat("optical","mu_s_tumor" ) } labelTable= {config.get("labels","greymatter" ):"grey" , config.get("labels","whitematter"):"white", config.get("labels","csf" ):"csf" , config.get("labels","tumor" ):"tumor", config.get("labels","vessel" ):"vessel"} labelCount= {"default":0, "grey" :0, "white" :0, "csf" :0, "tumor" :0, "vessel" :0} # imaging params import vtk import vtk.util.numpy_support as vtkNumPy SegmentFile=config.get("exec","segment_file") # set the default reader based on extension if( SegmentFile.split(".").pop() == "vtk"): vtkImageReader = vtk.vtkDataSetReader elif( SegmentFile.split(".").pop() == "vti"): vtkImageReader = vtk.vtkXMLImageDataReader else: raise RuntimeError("uknown file") # get dimension info from header vtkSetupReader = vtkImageReader() vtkSetupReader.SetFileName(SegmentFile ) vtkSetupReader.Update() vtkImageMask = vtkSetupReader.GetOutput() dimensions = vtkSetupReader.GetOutput().GetDimensions() numberPointsImage = vtkSetupReader.GetOutput().GetNumberOfPoints() spacing_mm = vtkSetupReader.GetOutput().GetSpacing() origin_mm = vtkSetupReader.GetOutput().GetOrigin() # convert to meters spacing = [dx*.001 for dx in spacing_mm] origin = [x0*.001 for x0 in origin_mm] # pass pointer to c++ image_cells = vtkImageMask.GetPointData() data_array = vtkNumPy.vtk_to_numpy( image_cells.GetArray(0) ) # need to pass numpy array's w/ Fortran storage... ie painful to debug imageDataVec = PETSc.Vec().createWithArray(numpy.ravel(data_array,order='F'), comm=PETSc.COMM_SELF) # FIXME - center around quadrature in out-of-plane direction # FIXME - need better out of plane cooling model quadratureOffset = 1./numpy.sqrt(3.0) * spacing[2]/2.0 # expecting roi and subsample of the form: # roi = [(40,210),(30,220),(6,78)] # subsample = [3,3,2] ROI = eval(config.get('exec','roi')) subsample = eval(config.get('exec','subsample')) nelemROI = [ (pixel[1] - pixel[0] - 1 )/sub for pixel,sub in zip(ROI,subsample)] xbounds = [ origin[0]+spacing[0]*(ROI[0][0]+0.5),origin[0]+spacing[0]*(ROI[0][1]+0.5) ] ybounds = [ origin[1]+spacing[1]*(ROI[1][0]+0.5),origin[1]+spacing[1]*(ROI[1][1]+0.5) ] zbounds = [ origin[2]+spacing[2]*(ROI[2][0]+0.5),origin[2]+spacing[2]*(ROI[2][1]+0.5) ] if( petscRank ==0 ): print "#points",numberPointsImage , "dimensions ",dimensions , "spacing ",spacing , "origin ",origin print "ROI",ROI , "nelemROI ",nelemROI , "bounds", xbounds, ybounds, zbounds #set to steady state solve getpot.SetIniValue("steadystate/domain_0","true") # initialize FEM Mesh femMesh = femLibrary.PylibMeshMesh() #femMesh.SetupUnStructuredGrid(kwargs['mesh_file'],0,RotationMatrix, Translation ) #femMesh.ReadFile(kwargs['mesh_file']) femMesh.SetupStructuredGrid(nelemROI,xbounds,ybounds,zbounds, [2,2,2,2,2,2]) # get output file name else set default name try: MeshOutputFile = config.get("exec","exodus_file" ) except ConfigParser.NoOptionError: MeshOutputFile = "fem.e" # add the data structures for the Background System Solve # set deltat, number of time steps, power profile, and add system eqnSystems = femLibrary.PylibMeshEquationSystems(femMesh,getpot) #getpot.SetIniPower(1,[[19,119],[90.0,100.0]] ) getpot.SetIniPower(1,kwargs['powerHistory'] ) # AddPennesSDASystem # AddPennesRFSystem # AddPennesDeltaPSystem pennesSystem = eval("eqnSystems.%s('StateSystem',kwargs['deltat'])" % kwargs['physics']) pennesSystem.AddStorageVectors( kwargs['ntime']+1 ) # add system for labels # FIXME: need both nodal, for dirichlet bc, and element version, for parameter masks maskElemSystem = eqnSystems.AddExplicitSystem( "ElemImageMask" ) maskElemSystem.AddConstantMonomialVariable( "maskElem" ) # initialize libMesh data structures eqnSystems.init( ) # print info eqnSystems.PrintSelf() # setup imaging to interpolate onto FEM mesh femImaging = femLibrary.PytttkImaging(getpot, dimensions ,origin,spacing) # Project imaging onto libMesh data structures femImaging.ProjectImagingToFEMMesh("ElemImageMask" ,0.0,imageDataVec,eqnSystems) femImaging.ProjectImagingToFEMMesh("StateSystem" ,0.0,imageDataVec,eqnSystems) # create dirichlet nodes from this mask numNodes = pennesSystem.PetscFEMSystemCreateNodeSetFromMask(config.getfloat("labels","vessel"),dirichletID) print "# of dirichlet nodes %d" %numNodes # get image label as numpy array imageLabel = maskElemSystem.GetSolutionVector()[...] #imageLabel = numpy.floor(10.0*imageLabel.copy())+1 k_0Label = imageLabel.copy() w_0Label = imageLabel.copy() mu_aLabel = imageLabel.copy() mu_sLabel = imageLabel.copy() for (idpos,label) in enumerate(imageLabel): try: tissueType = labelTable["%d"%int(label)] except KeyError: tissueType = "default" labelCount[tissueType] = labelCount[tissueType] + 1 k_0Label[ idpos] = k_0Table[ tissueType] w_0Label[ idpos] = w_0Table[ tissueType] mu_aLabel[idpos] = mu_aTable[tissueType] mu_sLabel[idpos] = mu_sTable[tissueType] # create array of imaging data as petsc vec k_0Vec = PETSc.Vec().createWithArray(k_0Label , comm=PETSc.COMM_SELF) w_0Vec = PETSc.Vec().createWithArray(w_0Label , comm=PETSc.COMM_SELF) mu_aVec = PETSc.Vec().createWithArray(mu_aLabel, comm=PETSc.COMM_SELF) mu_sVec = PETSc.Vec().createWithArray(mu_sLabel, comm=PETSc.COMM_SELF) # copy material properties to the system eqnSystems.GetSystem("k_0").SetSolutionVector( k_0Vec ) eqnSystems.GetSystem("w_0").SetSolutionVector( w_0Vec ) eqnSystems.GetSystem("mu_a").SetSolutionVector(mu_aVec) eqnSystems.GetSystem("mu_s").SetSolutionVector(mu_sVec) # write IC exodusII_IO = femLibrary.PylibMeshExodusII_IO(femMesh) exodusII_IO.WriteTimeStep(MeshOutputFile,eqnSystems, 1, 0.0 ) exodusII_IO.WriteParameterSystems(eqnSystems) # setup IC pennesSystem.PetscFEMSystemSetupInitialConditions( ) # create list of laser positions laserPositionList = [ ((.015,.015,2*spacing[2]+quadratureOffset), (.018,.018,2*spacing[2]+quadratureOffset) ), ((.015,.015,2*spacing[2]+quadratureOffset), (.016,.018,2*spacing[2]+quadratureOffset) ), ((.015,.015,1*spacing[2]+quadratureOffset), (.014,.014,1*spacing[2]+quadratureOffset) ), ((.015,.015,1*spacing[2]+quadratureOffset), (.015,.018,3*spacing[2]+quadratureOffset) )] # time stamp import pickle,time timeStamp =0 # set power id to turn laser on pennesSystem.PetscFEMSystemUpdateTimeStep( 1 ) # loop over laser position and solve steady state equations for each position #for (idpos,(pos0,pos1)) in enumerate(laserPositionList): # loop and read new laser parameters while(True): if(os.path.getmtime(fem_params['ini_filename']) > timeStamp): timeStamp = os.path.getmtime(fem_params['ini_filename'] ) newIni = ConfigParser.SafeConfigParser({}) newIni.read(fem_params['ini_filename']) laserParams = {} laserParams['position1'] = [newIni.getfloat("probe",varID ) for varID in ["x_0","y_0","z_0"] ] laserParams['position2'] = [newIni.getfloat("probe",varID ) for varID in ["x_1","y_1","z_1"] ] print "laser position = ", newIni.getfloat("timestep","power") , laserParams pennesSystem.PennesSDASystemUpdateLaserPower(newIni.getfloat("timestep","power"),1) pennesSystem.PennesSDASystemUpdateLaserPosition(laserParams['position1'],laserParams['position2']) pennesSystem.SystemSolve( ) #fem.StoreTransientSystemTimeStep("StateSystem",timeID ) #exodusII_IO.WriteTimeStep(MeshOutputFile ,eqnSystems, idpos+2, idpos*kwargs['deltat']) exodusII_IO.WriteTimeStep(MeshOutputFile ,eqnSystems, 2, 1.0) exodusII_IO.WriteParameterSystems(eqnSystems) # write to txt file if( petscRank ==0 ): time.sleep(1) vtkExodusIIReader = vtk.vtkExodusIIReader() print "opening %s " % MeshOutputFile vtkExodusIIReader.SetFileName( MeshOutputFile ) vtkExodusIIReader.Update() ntime = vtkExodusIIReader.GetNumberOfTimeSteps() variableID = "u0" print "ntime %d %s " % (ntime,variableID) vtkExodusIIReader.SetTimeStep(1) vtkExodusIIReader.SetPointResultArrayStatus(variableID,1) vtkExodusIIReader.Update() curInput = None # multi block if vtkExodusIIReader.GetOutput().IsA("vtkMultiBlockDataSet"): iter = vtkExodusIIReader.GetOutput().NewIterator() iter.UnRegister(None) iter.InitTraversal() curInput = iter.GetCurrentDataObject() else: curInput = vtkExodusIIReader.GetOutput() #fem_point_data= curInput.GetPointData().GetArray('u0') #Soln=vtkNumPy.vtk_to_numpy(fem_point_data) #numpy.savetxt( "temperature.txt" ,Soln) # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview # scale back to millimeter # TODO verify that the data sets are registered in the native slicer coordinate system # TODO segmented data MUST be read in with: # TODO add data -> volume -> show options -> ignore orientation # TODO add data -> volume -> show options -> ignore orientation # TODO add data -> volume -> show options -> ignore orientation AffineTransform = vtk.vtkTransform() AffineTransform.Translate([ 0.0,0.0,0.0]) AffineTransform.RotateZ( 0.0 ) AffineTransform.RotateY( 0.0 ) AffineTransform.RotateX( 0.0 ) AffineTransform.Scale([1000.,1000.,1000.]) # scale to millimeter transformFilter = vtk.vtkTransformFilter() transformFilter.SetInput(curInput) transformFilter.SetTransform(AffineTransform) transformFilter.Update() # setup contour filter vtkContour = vtk.vtkContourFilter() vtkContour.SetInput( transformFilter.GetOutput() ) # TODO: not sure why this works... # set the array to process at the temperature == u0 vtkContour.SetInputArrayToProcess(0,0,0,0,'u0') contourValuesList = eval(newIni.get('exec','contours')) vtkContour.SetNumberOfContours( len(contourValuesList ) ) print "plotting array:", vtkContour.GetArrayComponent( ) for idContour,contourValue in enumerate(contourValuesList): print "plotting contour:",idContour,contourValue vtkContour.SetValue( idContour,contourValue ) vtkContour.Update( ) # setup threshold filter vtkThreshold = vtk.vtkThreshold() vtkThreshold.SetInput( transformFilter.GetOutput() ) vtkThreshold.ThresholdByLower( contourValuesList[0] ) #vtkThreshold.SetSelectedComponent( 0 ) vtkThreshold.SetComponentModeToUseAny( ) vtkThreshold.Update() # resample onto image vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput( vtkImageMask ) vtkResample.SetSource( vtkThreshold.GetOutput() ) vtkResample.Update() # write output print "writing fem.vtk " vtkImageWriter = vtk.vtkDataSetWriter() vtkImageWriter.SetFileTypeToBinary() vtkImageWriter.SetFileName("fem.vtk") vtkImageWriter.SetInput(vtkResample.GetOutput()) vtkImageWriter.Update() # write stl file stlWriter = vtk.vtkSTLWriter() stlWriter.SetInput(vtkContour.GetOutput( )) stlWriter.SetFileName("fem.stl") stlWriter.SetFileTypeToBinary() stlWriter.Write() # write support file to signal full stl file is written # Slicer module will wait for this file to be written # before trying to open stl file to avoid incomplete reads with open('./fem.finish', 'w') as signalFile: signalFile.write("the stl file has been written\n") else: print "waiting on user input.." # echo lookup table if( petscRank ==0 ): print "lookup tables" print "labeled %d voxels" % len(imageLabel) print "labels" , labelTable print "counts" , labelCount print "conductivity", k_0Table print "perfusion" , w_0Table print "absorption" , mu_aTable print "scattering" , mu_sTable time.sleep(2)
def deltapModeling(**kwargs): """ treatment planning model """ # import petsc and numpy import petsc4py, numpy # init petsc PetscOptions = sys.argv PetscOptions.append("-ksp_monitor") PetscOptions.append("-ksp_rtol") PetscOptions.append("1.0e-15") #PetscOptions.append("-help") #PetscOptions.append("-idb") petsc4py.init(PetscOptions) # # break processors into separate communicators from petsc4py import PETSc petscRank = PETSc.COMM_WORLD.getRank() petscSize = PETSc.COMM_WORLD.Get_size() sys.stdout.write("petsc rank %d petsc nproc %d\n" % (petscRank, petscSize)) # set shell context # TODO import vtk should be called after femLibrary ???? # FIXME WHY IS THIS???? import femLibrary # initialize libMesh data structures libMeshInit = femLibrary.PyLibMeshInit(PetscOptions,PETSc.COMM_WORLD) # store control variables getpot = femLibrary.PylibMeshGetPot(PetscOptions) # from Duck table 2.11 pig dermis getpot.SetIniValue( "material/specific_heat","3280.0" ) # set ambient temperature getpot.SetIniValue( "initial_condition/u_init","0.0" ) # from Duck 2.7 Rat tumor measured in vivo getpot.SetIniValue( "thermal_conductivity/k_0_tumor","0.32" ) getpot.SetIniValue( "thermal_conductivity/k_0_healthy",kwargs['cv']['k_0_healthy'] ) # water properties at http://www.d-a-instruments.com/light_absorption.html getpot.SetIniValue( "optical/mu_a_healthy", kwargs['cv']['mu_a_healthy'] ) # FIXME large mu_s (> 30) in agar causing negative fluence to satisfy BC getpot.SetIniValue( "optical/mu_s_healthy", kwargs['cv']['mu_s_healthy'] ) # from AE paper #http://scitation.aip.org/journals/doc/MPHYA6-ft/vol_36/iss_4/1351_1.html#F3 #For SPIOs #getpot.SetIniValue( "optical/guass_radius","0.0035" ) #For NR/NS getpot.SetIniValue( "optical/guass_radius",".003" ) # cauchy BC getpot.SetIniValue( "bc/u_infty","0.0" ) getpot.SetIniValue( "bc/newton_coeff","1.0e5" ) # 1-300 getpot.SetIniValue( "optical/mu_a_tumor", kwargs['cv']['mu_a_tumor'] ) # 1-300 getpot.SetIniValue( "optical/mu_s_tumor", kwargs['cv']['mu_s_tumor'] ) #getpot.SetIniValue( "optical/mu_a_tumor","71.0" ) #getpot.SetIniValue( "optical/mu_s_tumor","89.0" ) # .9 - .99 getpot.SetIniValue( "optical/anfact",kwargs['cv']['anfact'] ) #agar length #for SPIOs #getpot.SetIniValue( "optical/agar_length","0.0206" ) #for NR/NS getpot.SetIniValue( "optical/agar_length","0.023" ) getpot.SetIniValue("optical/refractive_index","1.0") # # given the original orientation as two points along the centerline z = x2 -x1 # the transformed orienteation would be \hat{z} = A x2 + b - A x1 - b = A z # ie transformation w/o translation which is exactly w/ vtk has implemented w/ TransformVector # TransformVector = TransformPoint - the transation #Setup Affine Transformation for registration RotationMatrix = [[1.,0.,0.], [0.,1.,0.], [0.,0.,1.]] Translation = [0.,0.,0.] # original coordinate system laser input # For SPIOs 67_11 #laserTip = [0.,-.000625,.035] # For SPIOs 67_10 #laserTip = [0.,-.0001562,.035] # For SPIOs 335_11 #laserTip = [0.,-.0014062,.035] # For NR #laserTip = [0.,.0002,.035] # For NS laserTip = [0.00001,.000001,.000001] laserOrientation = [0.0,0.,-1.0] import vtk import vtk.util.numpy_support as vtkNumPy # echo vtk version info print "using vtk version", vtk.vtkVersion.GetVTKVersion() # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview AffineTransform = vtk.vtkTransform() # should be in meters # For NS #AffineTransform.Translate([ .01320,-.0037,0.00000010]) #AffineTransform.Translate([ .005,-.0035,0.0]) AffineTransform.Translate([-.006,-.0022,0.0]) AffineTransform.RotateZ( 0.0 ) AffineTransform.RotateY( -90.0 ) AffineTransform.RotateX( 0.0 ) AffineTransform.Scale([1.,1.,1.]) # get homogenius 4x4 matrix of the form # A | b # matrix = ----- # 0 | 1 # matrix = AffineTransform.GetConcatenatedTransform(0).GetMatrix() #print matrix RotationMatrix = [[matrix.GetElement(0,0),matrix.GetElement(0,1),matrix.GetElement(0,2)], [matrix.GetElement(1,0),matrix.GetElement(1,1),matrix.GetElement(1,2)], [matrix.GetElement(2,0),matrix.GetElement(2,1),matrix.GetElement(2,2)]] Translation = [matrix.GetElement(0,3),matrix.GetElement(1,3),matrix.GetElement(2,3)] #print RotationMatrix ,Translation laserTip = AffineTransform.TransformPoint( laserTip ) laserOrientation = AffineTransform.TransformVector( laserOrientation ) # set laser orientation values getpot.SetIniValue( "probe/x_0","%f" % laserTip[0]) getpot.SetIniValue( "probe/y_0","%f" % laserTip[1]) getpot.SetIniValue( "probe/z_0","%f" % laserTip[2]) getpot.SetIniValue( "probe/x_orientation","%f" % laserOrientation[0] ) getpot.SetIniValue( "probe/y_orientation","%f" % laserOrientation[1] ) getpot.SetIniValue( "probe/z_orientation","%f" % laserOrientation[2] ) # initialize FEM Mesh femMesh = femLibrary.PylibMeshMesh() # must setup Ini File first #For SPIOs #femMesh.SetupUnStructuredGrid( "/work/01741/cmaclell/data/mdacc/deltap_phantom_oct10/phantomMeshFullTess.e",0,RotationMatrix, Translation ) #For NS/NR RotationMatrix = [[1,0,0], [0,1,0], [0,0,1]] Translation = [.0000001,.00000001,.000001] # femMesh.SetupUnStructuredGrid( "./sphereMesh.e",0,RotationMatrix, Translation ) #femMesh.SetupUnStructuredGrid( "phantomMesh.e",0,RotationMatrix, Translation ) MeshOutputFile = "fem_data.%04d.e" % kwargs['fileID'] #femMes.SetupStructuredGrid( (10,10,4) ,[0.0,1.0],[0.0,2.0],[0.0,1.0]) # add the data structures for the background system solve # set deltat, number of time steps, power profile, and add system nsubstep = 1 #for SPIOs #acquisitionTime = 4.9305 #for NS/NR acquisitionTime = 5.09 deltat = acquisitionTime / nsubstep ntime = 60 eqnSystems = femLibrary.PylibMeshEquationSystems(femMesh,getpot) #For SPIOs #getpot.SetIniPower(nsubstep, [ [1,6,30,ntime],[1.0,0.0,4.5,0.0] ]) #For NS/NR getpot.SetIniPower(nsubstep, [ [1,6,42,ntime],[1.0,0.0,1.13,0.0] ]) deltapSystem = eqnSystems.AddPennesDeltaPSystem("StateSystem",deltat) deltapSystem.AddStorageVectors(ntime) # hold imaging mrtiSystem = eqnSystems.AddExplicitSystem( "MRTI" ) mrtiSystem.AddFirstLagrangeVariable( "u0*" ) mrtiSystem.AddStorageVectors(ntime) maskSystem = eqnSystems.AddExplicitSystem( "ImageMask" ) maskSystem.AddFirstLagrangeVariable( "mask" ) # initialize libMesh data structures eqnSystems.init( ) # print info eqnSystems.PrintSelf() # write IC exodusII_IO = femLibrary.PylibMeshExodusII_IO(femMesh) exodusII_IO.WriteTimeStep(MeshOutputFile,eqnSystems, 1, 0.0 ) # read imaging data geometry that will be used to project FEM data onto #For 67_11 #vtkReader.SetFileName('/work/01741/cmaclell/data/mdacc/deltap_phantom_oct10/spio/spioVTK/67_11/tmap_67_11.0000.vtk') #For 67_10 #vtkReader.SetFileName('/work/01741/cmaclell/data/mdacc/deltap_phantom_oct10/spio/spioVTK/67_10/tmap_67_10.0000.vtk') #For 335_11 #vtkReader.SetFileName('/work/01741/cmaclell/data/mdacc/deltap_phantom_oct10/spio/spioVTK/335_11/tmap_335_11.0000.vtk') #For NS #vtkReader.SetFileName('/work/01741/cmaclell/data/mdacc/deltap_phantom_oct10/nrtmapsVTK/S695/S695.0000.vtk') #For NR imageFileNameTemplate = '/work/01741/cmaclell/data/mdacc/NanoMouseJune12/matlab_VTK/control_1_tmap.%04d.vtk' imageFileNameTemplate = '/FUS4/data2/CJM/SPIO_mice/matlab_VTK/control_1_tmap.%04d.vtk' #imageFileNameTemplate = "/share/work/fuentes/deltap_phantom_oct10/nrtmapsVTK/R695/R695.%04d.vtk" #imageFileNameTemplate = "/data/fuentes/mdacc/deltap_phantom_oct10/nrtmapsVTK/R695/R695.%04d.vtk" #vtkReader = vtk.vtkXMLImageDataReader() vtkReader = vtk.vtkDataSetReader() vtkReader.SetFileName( imageFileNameTemplate % 0 ) vtkReader.Update() templateImage = vtkReader.GetOutput() dimensions = templateImage.GetDimensions() spacing = templateImage.GetSpacing() origin = templateImage.GetOrigin() print spacing, origin, dimensions femImaging = femLibrary.PytttkImaging(getpot, dimensions ,origin,spacing) ObjectiveFunction = 0.0 # loop over time steps and solve for timeID in range(1,ntime*nsubstep): #for timeID in range(1,10): # project imaging onto fem mesh vtkImageReader = vtk.vtkDataSetReader() vtkImageReader.SetFileName( imageFileNameTemplate % timeID ) vtkImageReader.Update() image_cells = vtkImageReader.GetOutput().GetPointData() data_array = vtkNumPy.vtk_to_numpy(image_cells.GetArray('scalars')) v1 = PETSc.Vec().createWithArray(data_array, comm=PETSc.COMM_SELF) femImaging.ProjectImagingToFEMMesh("MRTI",0.0,v1,eqnSystems) mrtiSystem.StoreSystemTimeStep(timeID ) # create image mask # The = operator for numpy arrays just copies by reference # .copy() provides a deep copy (ie physical memory copy) image_mask = data_array.copy().reshape(dimensions,order='F') # Set all image pixels to large value largeValue = 1.e6 image_mask[:,:] = 1 # RMS error will be computed within this ROI/VOI imagemask[xcoords/column,ycoords/row] #image_mask[93:153,52:112] = 1.0 #image_mask[98:158,46:106] = 1.0 v2 = PETSc.Vec().createWithArray(image_mask, comm=PETSc.COMM_SELF) femImaging.ProjectImagingToFEMMesh("ImageMask",largeValue,v2,eqnSystems) #print mrti_array #print type(mrti_array) print "time step = " ,timeID eqnSystems.UpdatePetscFEMSystemTimeStep("StateSystem",timeID ) deltapSystem.SystemSolve() #eqnSystems.StoreTransientSystemTimeStep("StateSystem",timeID ) # accumulate objective function # # qoi = ( (FEM - MRTI) / ImageMask)^2 # qoi = femLibrary.WeightedL2Norm( deltapSystem,"u0", mrtiSystem,"u0*", maskSystem,"mask" ) ObjectiveFunction =( ObjectiveFunction + qoi) # control write output writeControl = True if ( timeID%nsubstep == 0 and writeControl ): # write exodus file exodusII_IO.WriteTimeStep(MeshOutputFile,eqnSystems, timeID+1, timeID*deltat ) # Interpolate FEM onto imaging data structures if (vtk != None): vtkExodusIIReader = vtk.vtkExodusIIReader() vtkExodusIIReader.SetFileName(MeshOutputFile ) vtkExodusIIReader.SetPointResultArrayStatus("u0",1) vtkExodusIIReader.SetTimeStep(timeID-1) vtkExodusIIReader.Update() # reflect vtkReflect = vtk.vtkReflectionFilter() vtkReflect.SetPlaneToYMax() vtkReflect.SetInput( vtkExodusIIReader.GetOutput() ) vtkReflect.Update() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput( vtkImageReader.GetOutput() ) vtkResample.SetSource( vtkReflect.GetOutput() ) vtkResample.Update() fem_point_data= vtkResample.GetOutput().GetPointData() fem_array = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('u0')) #print fem_array #print type(fem_array ) # only rank 0 should write #if ( petscRank == 0 ): # print "writing ", timeID # vtkTemperatureWriter = vtk.vtkDataSetWriter() # vtkTemperatureWriter.SetFileTypeToBinary() # vtkTemperatureWriter.SetFileName("invspio_67_11.%04d.vtk" % timeID ) # vtkTemperatureWriter.SetInput(vtkResample.GetOutput()) # vtkTemperatureWriter.Update() print 'Objective Fn' print ObjectiveFunction retval = dict([]) retval['fns'] = [ObjectiveFunction *10000000.] retval['rank'] = petscRank return(retval)
def ComputeObjective(SEMDataDirectory,MRTIDirectory): import vtk import vtk.util.numpy_support as vtkNumPy print "using vtk version", vtk.vtkVersion.GetVTKVersion() ObjectiveFunction = 0.0 # loop over time points of interest for (SEMtimeID,MRTItimeID) in [(1,58)]: # read SEM data vtkSEMReader = vtk.vtkXMLUnstructuredGridReader() vtufileName = "%s/%d.vtu" % (SEMDataDirectory,SEMtimeID) vtkSEMReader.SetFileName( vtufileName ) vtkSEMReader.SetPointArrayStatus("Temperature",1) vtkSEMReader.Update() # get registration parameters variableDictionary = kwargs['cv'] # register the SEM data to MRTI AffineTransform = vtk.vtkTransform() AffineTransform.Translate([ variableDictionary['x_displace'],variableDictionary['y_displace'],variableDictionary['z_displace'] ]) # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview AffineTransform.RotateZ(variableDictionary['z_rotate' ] ) AffineTransform.RotateY(variableDictionary['y_rotate' ] ) AffineTransform.RotateX(variableDictionary['x_rotate' ] ) AffineTransform.Scale([1.e3,1.e3,1.e3]) SEMRegister = vtk.vtkTransformFilter() SEMRegister.SetInput(vtkSEMReader.GetOutput()) SEMRegister.SetTransform(AffineTransform) SEMRegister.Update() # write output DebugObjective = True if ( DebugObjective ): vtkSEMWriter = vtk.vtkDataSetWriter() vtkSEMWriter.SetFileTypeToBinary() semfileName = "%s/semtransform%04d.vtk" % (SEMDataDirectory,SEMtimeID) print "writing ", semfileName vtkSEMWriter.SetFileName( semfileName ) vtkSEMWriter.SetInput(SEMRegister.GetOutput()) vtkSEMWriter.Update() # load image vtkImageReader = vtk.vtkDataSetReader() vtkImageReader.SetFileName('%s/temperature.%04d.vtk' % (MRTIDirectory, MRTItimeID) ) vtkImageReader.Update() ## image_cells = vtkImageReader.GetOutput().GetPointData() ## data_array = vtkNumPy.vtk_to_numpy(image_cells.GetArray('scalars')) # extract voi for QOI vtkVOIExtract = vtk.vtkExtractVOI() vtkVOIExtract.SetInput( vtkImageReader.GetOutput() ) VOI = [110,170,70,120,0,0] vtkVOIExtract.SetVOI( VOI ) vtkVOIExtract.Update() mrti_point_data= vtkVOIExtract.GetOutput().GetPointData() mrti_array = vtkNumPy.vtk_to_numpy(mrti_point_data.GetArray('image_data')) #print mrti_array #print type(mrti_array) # project SEM onto MRTI for comparison vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetSource( SEMRegister.GetOutput() ) vtkResample.SetInput( vtkVOIExtract.GetOutput() ) vtkResample.Update() # write output if ( DebugObjective ): vtkTemperatureWriter = vtk.vtkDataSetWriter() vtkTemperatureWriter.SetFileTypeToBinary() roifileName = "%s/roi%04d.vtk" % (SEMDataDirectory,SEMtimeID) print "writing ", roifileName vtkTemperatureWriter.SetFileName( roifileName ) vtkTemperatureWriter.SetInput(vtkResample.GetOutput()) vtkTemperatureWriter.Update() fem_point_data= vtkResample.GetOutput().GetPointData() fem_array = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Temperature')) #print fem_array #print type(fem_array ) # accumulate objective function diff = mrti_array-fem_array diffsq = diff**2 ObjectiveFunction = ObjectiveFunction + diffsq.sum() return ObjectiveFunction
def ProjectImagingMesh(work_dir,data_set): import vtk import vtk.util.numpy_support as vtkNumPy import numpy import scipy.io as scipyio # echo vtk version info print "using vtk version", vtk.vtkVersion.GetVTKVersion() # FIXME notice that order of operations is IMPORTANT # FIXME translation followed by rotation will give different results # FIXME than rotation followed by translation # FIXME Translate -> RotateZ -> RotateY -> RotateX -> Scale seems to be the order of paraview vtkReader = vtk.vtkDataSetReader() # offset averaging +/- in both directions about center listoffset = [-2,-1,0,1,2] if (data_set == "dog1"): # should be in meters #AffineTransform.Translate(0.206,0.289,-0.0215) #AffineTransform.RotateZ( 0.0 ) #AffineTransform.RotateY( 0.0 ) #AffineTransform.RotateX( 90.0 ) Translate = (0.293,0.0634,0.12345) RotateZ = -90.0 RotateY = 0.0 RotateX = 90.0 Scale = [1.,1.,1.] ImageFileTemplate = '/FUS4/data2/BioTex/Brain_PhaseII/060626_BrainDog1_Treat/ProcessedTMAPData/BioTexCanines/dog1dtmap.0000.vtk' elif (data_set == "dog2"): # should be in meters Translate = (0.2335,0.235,-0.0335) RotateZ = 6.0 RotateY = 0.0 RotateX = 90.0 Scale = [1.,1.,1.] ImageFileTemplate = '/data/sjfahrenholtz/mdacc/Dog/dog2_98000/mrivis/temperature.0000.vtk' ImageFileTemplate = '/FUS4/data2/BioTex/Brain_PhaseII/060626_BrainDog1_Treat/ProcessedTMAPData/BioTexCanines/dog2dtmap.0000.vtk' elif (data_set == "dog3"): # should be in meters Translate = (0.209,0.2625,-0.0247) RotateZ = -8.0 RotateY = 0.0 RotateX = 90.0 Scale = [1.,1.,1.] ImageFileTemplate = '/data/sjfahrenholtz/mdacc/Dog/dog3_98000/mrivis/temperature.0000.vtk' ImageFileTemplate = '/FUS4/data2/BioTex/Brain_PhaseII/060626_BrainDog1_Treat/ProcessedTMAPData/BioTexCanines/dog3dtmap.0000.vtk' elif (data_set == "dog4"): # should be in meters Translate = (0.195,0.245,-0.0715) RotateZ = -15.0 RotateY = 0.0 RotateX = 90.0 Scale = [1.,1.,1.] ImageFileTemplate = '/FUS4/data2/BioTex/Brain_PhaseII/060626_BrainDog1_Treat/ProcessedTMAPData/BioTexCanines/dog4dtmap.0000.vtk' elif (data_set == "human0"): # should be in meters vtkReader = vtk.vtkXMLImageDataReader() Translate = (0.051,0.080,0.0509) RotateZ = 29.0 RotateY = 86.0 RotateX = 0.0 Scale = [1.,1.,1.] ImageFileTemplate = '/data/fuentes/biotex/090318_751642_treat/Processed/imaging/temperature.0000.vti' elif (data_set == "agar0"): # should be in meters Translate = (0.0,0.13,-0.095) RotateZ = 0.0 RotateY = 180.0 RotateX = 0.0 Scale = [1.,1.,1.] ImageFileTemplate = '/data/jyung/MotionCorrection/motion_phantom_sept11/tmap.0000.vtk' else: raise RuntimeError("\n\n unknown case... ") # read imaging data geometry that will be used to project FEM data onto vtkReader.SetFileName( ImageFileTemplate ) vtkReader.Update() templateImage = vtkReader.GetOutput() dimensions = templateImage.GetDimensions() spacing = templateImage.GetSpacing() origin = templateImage.GetOrigin() print spacing, origin, dimensions #fem.SetImagingDimensions( dimensions ,origin,spacing) #setup to interpolate at 5 points across axial dimension TransformList = [] naverage = len(listoffset) subdistance = spacing[2] / (naverage-1) print "subspacing distance = ", subdistance for idtransform in listoffset: AffineTransform = vtk.vtkTransform() AffineTransform.Translate( Translate[0],Translate[1], Translate[2] + subdistance*idtransform ) AffineTransform.RotateZ( RotateZ ) AffineTransform.RotateY( RotateY ) AffineTransform.RotateX( RotateX ) AffineTransform.Scale( Scale ) TransformList.append( AffineTransform ) #laserTip = AffineTransform.TransformPoint( laserTip ) #laserOrientation = AffineTransform.TransformVector( laserOrientation ) # Interpolate FEM onto imaging data structures vtkExodusIIReader = vtk.vtkExodusIIReader() #vtkExodusIIReader.SetFileName( "%s/fem_stats.e" % work_dir ) #vtkExodusIIReader.SetPointResultArrayStatus("Mean0",1) #vtkExodusIIReader.SetPointResultArrayStatus("StdDev0",1) #Timesteps = 120 for ii in range(0,120): vtkExodusIIReader.SetFileName( "%s/fem_stats.%04d.e" % (work_dir,ii) ) #vtkExodusIIReader.SetPointResultArrayStatus("Vard0Mean",1) #vtkExodusIIReader.SetPointResultArrayStatus("Vard0Kurt",1) vtkExodusIIReader.Update() numberofresultarrays = vtkExodusIIReader.GetNumberOfPointResultArrays() print numberofresultarrays for resultarrayindex in range(numberofresultarrays): resultarrayname = vtkExodusIIReader.GetPointResultArrayName(resultarrayindex) vtkExodusIIReader.SetPointResultArrayStatus( "%s" % (resultarrayname),1) print resultarrayname vtkExodusIIReader.Update() ntime = vtkExodusIIReader.GetNumberOfTimeSteps() #for timeID in range(69,70): for timeID in range(ntime): vtkExodusIIReader.SetTimeStep(timeID) vtkExodusIIReader.Update() # reflect vtkReflectX = vtk.vtkReflectionFilter() vtkReflectX.SetPlaneToXMin() vtkReflectX.SetInput( vtkExodusIIReader.GetOutput() ) vtkReflectX.Update() # reflect vtkReflectY = vtk.vtkReflectionFilter() vtkReflectY.SetPlaneToYMax() vtkReflectY.SetInput( vtkReflectX.GetOutput() ) vtkReflectY.Update() # apply the average of the transform mean_array = numpy.zeros(dimensions[0]*dimensions[1]*dimensions[2]) std_array = numpy.zeros(dimensions[0]*dimensions[1]*dimensions[2]) for affineFEMTranform in TransformList: # get homogenius 4x4 matrix of the form # A | b # matrix = ----- # 0 | 1 # matrix = affineFEMTranform.GetConcatenatedTransform(0).GetMatrix() #print matrix RotationMatrix = [[matrix.GetElement(0,0),matrix.GetElement(0,1),matrix.GetElement(0,2)], [matrix.GetElement(1,0),matrix.GetElement(1,1),matrix.GetElement(1,2)], [matrix.GetElement(2,0),matrix.GetElement(2,1),matrix.GetElement(2,2)]] Translation = [matrix.GetElement(0,3),matrix.GetElement(1,3),matrix.GetElement(2,3)] #print RotationMatrix print Translation TransformedFEMMesh = None if vtkReflectY.GetOutput().IsA("vtkMultiBlockDataSet"): AppendBlocks = vtk.vtkAppendFilter() iter = vtkReflectY.GetOutput().NewIterator() iter.UnRegister(None) iter.InitTraversal() # loop over blocks... while not iter.IsDoneWithTraversal(): curInput = iter.GetCurrentDataObject() vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform( affineFEMTranform ) vtkTransformFEMMesh.SetInput( curInput ) vtkTransformFEMMesh.Update() AppendBlocks.AddInput( vtkTransformFEMMesh.GetOutput() ) AppendBlocks.Update( ) iter.GoToNextItem(); TransformedFEMMesh = AppendBlocks.GetOutput() else: vtkTransformFEMMesh = vtk.vtkTransformFilter() vtkTransformFEMMesh.SetTransform( affineFEMTranform ) vtkTransformFEMMesh.SetInput( vtkReflectY.GetOutput() ) vtkTransformFEMMesh.Update() TransformedFEMMesh = vtkTransformFEMMesh.GetOutput() # reuse ShiftScale Geometry vtkResample = vtk.vtkCompositeDataProbeFilter() vtkResample.SetInput( templateImage ) vtkResample.SetSource( TransformedFEMMesh ) vtkResample.Update() fem_point_data= vtkResample.GetOutput().GetPointData() #meantmp = vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Mean')) #print meantmp.max() #mean_array = mean_array + vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Mean')) #std_array = std_array + vtkNumPy.vtk_to_numpy(fem_point_data.GetArray('Vard0Kurt')) #print fem_array #print type(fem_array ) # average #mean_array = mean_array/naverage #print mean_array.max() #std_array = std_array /naverage # write numpy to disk in matlab #scipyio.savemat("%s/modelstats.navg%d.%04d.mat" % (work_dir,naverage,timeID), {'spacing':spacing, 'origin':origin,'Vard0Mean':mean_array,'Vard0Kurt':std_array }) # write output print "writing ", timeID, ii, work_dir vtkStatsWriter = vtk.vtkDataSetWriter() vtkStatsWriter.SetFileTypeToBinary() vtkStatsWriter.SetFileName("%s/modelstats.navg%d.%04d.vtk" % ( work_dir,naverage,ii )) vtkStatsWriter.SetInput(vtkResample.GetOutput()) vtkStatsWriter.Update()