From 1aaf2ccb100d3fcc4fee87eb4f0f9bc58f8d78ef Mon Sep 17 00:00:00 2001 From: tfmoraes Date: Wed, 12 Sep 2012 19:50:21 +0000 Subject: [PATCH] ENH: Saving InVesalius3 using the proposed file format --- invesalius/data/mask.py | 39 +++++++++++++++++++++------------------ invesalius/data/measures.py | 2 +- invesalius/data/polydata_utils.py | 8 ++++++-- invesalius/data/surface.py | 50 +++++++++++++++++++++++++++----------------------- invesalius/project.py | 189 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------- 5 files changed, 152 insertions(+), 136 deletions(-) diff --git a/invesalius/data/mask.py b/invesalius/data/mask.py index c5c5169..40c691b 100644 --- a/invesalius/data/mask.py +++ b/invesalius/data/mask.py @@ -51,37 +51,40 @@ class Mask(): Publisher.subscribe(self.OnFlipVolume, 'Flip volume') Publisher.subscribe(self.OnSwapVolumeAxes, 'Swap volume axes') - def SavePlist(self, filename): + def SavePlist(self, dir_temp): mask = {} - filename = u'%s_%s_%d_%s' % (filename, 'mask', self.index, self.name) - img_name = u'%s.dat' % filename - self._save_mask(img_name) + filename = u'mask%d_%s' % (self.index, self.name) + mask_filename = u'%s.dat' % filename + mask_filepath = os.path.join(dir_temp, mask_filename) + self._save_mask(mask_filepath) mask['index'] = self.index + mask['name'] = self.name mask['colour'] = self.colour mask['opacity'] = self.opacity - mask['threshold range'] = self.threshold_range - mask['name'] = self.name - mask['edition threshold range'] = self.edition_threshold_range - mask['show'] = self.is_shown - mask['mask file'] = os.path.split(img_name)[1] - mask['mask shape'] = self.matrix.shape + mask['threshold_range'] = self.threshold_range + mask['edition_threshold_range'] = self.edition_threshold_range + mask['visible'] = self.is_shown + mask['mask_file'] = mask_filename + mask['mask_shape'] = self.matrix.shape - plistlib.writePlist(mask, filename + '.plist') - return os.path.split(filename)[1] + '.plist' + plist_filename = filename + '.plist' + plist_filepath = os.path.join(dir_temp, plist_filename) + plistlib.writePlist(mask, plist_filepath) + return plist_filename def OpenPList(self, filename): mask = plistlib.readPlist(filename) self.index = mask['index'] + self.name = mask['name'] self.colour = mask['colour'] self.opacity = mask['opacity'] - self.threshold_range = mask['threshold range'] - self.name = mask['name'] - self.edition_threshold_range = mask['edition threshold range'] - self.is_shown = mask['show'] - mask_file = mask['mask file'] - shape = mask['mask shape'] + self.threshold_range = mask['threshold_range'] + self.edition_threshold_range = mask['edition_threshold_range'] + self.is_shown = mask['visible'] + mask_file = mask['mask_file'] + shape = mask['mask_shape'] dirpath = os.path.abspath(os.path.split(filename)[0]) path = os.path.join(dirpath, mask_file) self._open_mask(path, tuple(shape)) diff --git a/invesalius/data/measures.py b/invesalius/data/measures.py index a389f6f..e1e0d09 100644 --- a/invesalius/data/measures.py +++ b/invesalius/data/measures.py @@ -198,7 +198,7 @@ class Measurement(): self.type = info["type"] self.slice_number = info["slice_number"] self.points = info["points"] - self.is_shown = info["is_shown"] + self.is_shown = info["visible"] class CirclePointRepresentation(object): """ diff --git a/invesalius/data/polydata_utils.py b/invesalius/data/polydata_utils.py index 825dd8f..0dcb7a6 100644 --- a/invesalius/data/polydata_utils.py +++ b/invesalius/data/polydata_utils.py @@ -17,7 +17,10 @@ # detalhes. #-------------------------------------------------------------------------- +import sys + import vtk +import wx from wx.lib.pubsub import pub as Publisher import vtk_utils as vu @@ -103,7 +106,8 @@ def Merge(polydata_list): def Export(polydata, filename, bin=False): writer = vtk.vtkXMLPolyDataWriter() - writer.SetFileName(filename) + print filename, type(filename) + writer.SetFileName(filename.encode('utf-8')) if bin: writer.SetDataModeToBinary() else: @@ -113,7 +117,7 @@ def Export(polydata, filename, bin=False): def Import(filename): reader = vtk.vtkXMLPolyDataReader() - reader.SetFileName(filename) + reader.SetFileName(filename.encode('utf-8')) reader.Update() return reader.GetOutput() diff --git a/invesalius/data/surface.py b/invesalius/data/surface.py index cfb7498..97380a5 100644 --- a/invesalius/data/surface.py +++ b/invesalius/data/surface.py @@ -62,32 +62,35 @@ class Surface(): else: self.name = name - def SavePlist(self, filename): - surface = {} - filename = '%s$%s$%d' % (filename, 'surface', self.index) - d = self.__dict__ - for key in d: - if isinstance(d[key], vtk.vtkPolyData): - img_name = '%s_%s.vtp' % (filename, key) - pu.Export(d[key], img_name, bin=True) - surface[key] = {'$vtp': os.path.split(img_name)[1]} - else: - surface[key] = d[key] - - - plistlib.writePlist(surface, filename + '.plist') - return os.path.split(filename)[1] + '.plist' + def SavePlist(self, dir_temp): + filename = 'surface_%d_%s' % (self.index, self.name) + vtp_filename = filename + '.vtp' + vtp_filepath = os.path.join(dir_temp, vtp_filename) + pu.Export(self.polydata, vtp_filepath, bin=True) + surface = {'colour': self.colour, + 'index': self.index, + 'name': self.name, + 'polydata': vtp_filename, + 'transparency': self.transparency, + 'visible': bool(self.is_shown), + 'volume': self.volume, + } + plist_filename = filename + '.plist' + plist_filepath = os.path.join(dir_temp, filename + '.plist') + plistlib.writePlist(surface, plist_filepath) + return plist_filename def OpenPList(self, filename): - surface = plistlib.readPlist(filename) + sp = plistlib.readPlist(filename) dirpath = os.path.abspath(os.path.split(filename)[0]) - for key in surface: - if key == 'polydata': - filepath = os.path.split(surface[key]["$vtp"])[-1] - path = os.path.join(dirpath, filepath) - self.polydata = pu.Import(path) - else: - setattr(self, key, surface[key]) + self.index = sp['index'] + self.name = sp['name'] + self.colour = sp['colour'] + self.transparency = sp['transparency'] + self.is_shown = sp['visible'] + self.volume = sp['volume'] + self.polydata = pu.Import(os.path.join(dirpath, sp['polydata'])) + Surface.general_index = max(Surface.general_index, self.index) def _set_class_index(self, index): Surface.general_index = index @@ -319,6 +322,7 @@ class SurfaceManager(): self.last_surface_index = index self.ShowActor(index, True) + def OnLoadSurfaceDict(self, pubsub_evt): surface_dict = pubsub_evt.data for key in surface_dict: diff --git a/invesalius/project.py b/invesalius/project.py index bb420c7..fd16ec2 100755 --- a/invesalius/project.py +++ b/invesalius/project.py @@ -17,6 +17,7 @@ # detalhes. #-------------------------------------------------------------------------- +import datetime import glob import os import plistlib @@ -49,8 +50,6 @@ class Project(object): self.dicom_sample = '' self.modality = '' self.original_orientation = '' - self.min_threshold = '' - self.max_threshold = '' self.window = '' self.level = '' @@ -199,61 +198,71 @@ class Project(object): item["type"] = m.type item["slice_number"] = m.slice_number item["points"] = m.points - item["is_shown"] = m.is_shown + item["visible"] = m.is_shown measures[str(m.index)] = item return measures - - def SavePlistProject(self, dir_, filename): - # Some filenames have non-ascii characters and encoded in a strange - # encoding, in that cases a UnicodeEncodeError is raised. To avoid - # that we encode in utf-8. - filename = filename.encode('utf-8') + def SavePlistProject(self, dir_, filename): dir_temp = tempfile.mkdtemp(filename) filename_tmp = os.path.join(dir_temp, 'matrix.dat') - project = {} - - for key in self.__dict__: - if getattr(self.__dict__[key], 'SavePlist', None): - project[key] = {'#plist': - self.__dict__[key].SavePlist(filename_tmp).decode('utf-8')} - elif key == 'dicom_sample': - #sample_path = os.path.join(dir_temp, 'sample.dcm') - #shutil.copy(self.dicom_sample.parser.filename,sample_path) - #os.chmod(sample_path, stat.S_IREAD|stat.S_IWRITE) - - #project[key] = 'sample.dcm' - pass - elif key.startswith('matrix'): - continue - else: - project[key] = self.__dict__[key] + project = { + # Format info + "format_version": 1, + "invesalius_version": "invesalius3b3", + "date": datetime.datetime.now().isoformat(), + + # case info + "name": self.name, # patient's name + "modality": self.modality, # CT, RMI, ... + "orientation": self.original_orientation, + "window_width": self.window, + "window_level": self.level, + "scalar_range": self.threshold_range, + "spacing": self.spacing, + } + + # Saving the matrix containing the slices + matrix = {'filename': u'matrix.dat', + 'shape': self.matrix_shape, + 'dtype': self.matrix_dtype, + } + project['matrix'] = matrix + shutil.copyfile(self.matrix_filename, filename_tmp) + # Saving the masks masks = {} for index in self.mask_dict: - masks[str(index)] = {'#mask':\ - self.mask_dict[index].SavePlist(filename_tmp)} + masks[str(index)] = self.mask_dict[index].SavePlist(dir_temp) + project['masks'] = masks + # Saving the surfaces surfaces = {} for index in self.surface_dict: - surfaces[str(index)] = {'#surface':\ - self.surface_dict[index].SavePlist(filename_tmp)} - - project['surface_dict'] = surfaces - project['mask_dict'] = masks - project['measurement_dict'] = self.GetMeasuresDict() - shutil.copyfile(self.matrix_filename, filename_tmp) - project['matrix'] = {'filename':os.path.split(filename_tmp)[1].decode('utf-8'), - 'shape': self.matrix_shape, - 'dtype': self.matrix_dtype} + surfaces[str(index)] = self.surface_dict[index].SavePlist(dir_temp) + project['surfaces'] = surfaces + + # Saving the measurements + measurements = self.GetMeasuresDict() + measurements_filename = 'measurements.plist' + plistlib.writePlist(measurements, + os.path.join(dir_temp, measurements_filename)) + project['measurements'] = measurements_filename + + # Saving the annotations (empty in this version) + project['annotations'] = {} - plistlib.writePlist(project, filename_tmp + '.plist') + # Saving the main plist + plistlib.writePlist(project, os.path.join(dir_temp, 'main.plist')) + # Compressing and generating the .inv3 file path = os.path.join(dir_,filename) - Compress(dir_temp, path)#os.path.join("~/Desktop/","teste.inv3")) + Compress(dir_temp, path) + + # Removing the temp folder. shutil.rmtree(dir_temp) + def OpenPlistProject(self, filename): import data.measures as ms @@ -265,57 +274,53 @@ class Project(object): ow.SetInstance(fow) filelist = Extract(filename, tempfile.mkdtemp()) - main_plist = min(filter(lambda x: x.endswith('.plist'), filelist), - key=lambda x: len(x)) + dirpath = os.path.abspath(os.path.split(filelist[0])[0]).decode(wx.GetDefaultPyEncoding()) + + # Opening the main file from invesalius 3 project + main_plist = os.path.join(dirpath ,'main.plist') project = plistlib.readPlist(main_plist) - dirpath = os.path.abspath(os.path.split(filelist[0])[0]) - - for key in project: - if key == 'matrix': - filepath = os.path.split(project[key]["filename"])[-1] - path = os.path.join(dirpath, filepath) - self.matrix_filename = path - self.matrix_shape = project[key]['shape'] - self.matrix_dtype = project[key]['dtype'] - elif key == 'presets': - filepath = os.path.split(project[key]["#plist"])[-1] - path = os.path.join(dirpath, filepath) - p = Presets() - p.OpenPlist(path) - self.presets = p - #elif key == 'dicom_sample': - #path = os.path.join(dirpath, project[key]) - #p = dicom.Parser() - #p.SetFileName(path) - #d = dicom.Dicom() - #d.SetParser(p) - #self.dicom_sample = d - - elif key == 'mask_dict': - self.mask_dict = {} - for mask in project[key]: - filepath = os.path.split(project[key][mask]["#mask"])[-1] - path = os.path.join(dirpath, filepath) - m = msk.Mask() - m.OpenPList(path) - self.mask_dict[m.index] = m - elif key == 'surface_dict': - self.surface_dict = {} - for surface in project[key]: - filepath = os.path.split(project[key][surface]["#surface"])[-1] - path = os.path.join(dirpath, filepath) - s = srf.Surface() - s.OpenPList(path) - self.surface_dict[s.index] = s - elif key == 'measurement_dict': - self.measurement_dict = {} - d = project['measurement_dict'] - for index in d: - measure = ms.Measurement() - measure.Load(d[index]) - self.measurement_dict[int(index)] = measure - else: - setattr(self, key, project[key]) + + # case info + self.name = project["name"] + self.modality = project["modality"] + self.original_orientation = project["orientation"] + self.window = project["window_width"] + self.level = project["window_level"] + self.threshold_range = project["scalar_range"] + self.spacing = project["spacing"] + + # Opening the matrix containing the slices + filepath = os.path.join(dirpath, project["matrix"]["filename"]) + self.matrix_filename = filepath + self.matrix_shape = project["matrix"]['shape'] + self.matrix_dtype = project["matrix"]['dtype'] + + # Opening the masks + self.mask_dict = {} + for index in project["masks"]: + filename = project["masks"][index] + filepath = os.path.join(dirpath, filename) + m = msk.Mask() + m.OpenPList(filepath) + self.mask_dict[m.index] = m + self.surface_dict = {} + + # Opening the surfaces + for index in project["surfaces"]: + filename = project["surfaces"][index] + filepath = os.path.join(dirpath, filename) + s = srf.Surface() + s.OpenPList(filepath) + self.surface_dict[s.index] = s + + # Opening the measurements + self.measurement_dict = {} + measurements = plistlib.readPlist(os.path.join(dirpath, + project["measurements"])) + for index in measurements: + measure = ms.Measurement() + measure.Load(measurements[index]) + self.measurement_dict[int(index)] = measure def Compress(folder, filename): @@ -323,8 +328,8 @@ def Compress(folder, filename): current_dir = os.path.abspath(".") os.chdir(tmpdir) file_list = glob.glob(os.path.join(tmpdir_,"*")) - - tar = tarfile.open(tmpdir_ + ".inv3", "w:gz") + tar_filename = tmpdir_ + ".inv3" + tar = tarfile.open(tar_filename.encode(wx.GetDefaultPyEncoding()), "w:gz") for name in file_list: tar.add(name) tar.close() -- libgit2 0.21.2