Commit 3aa03487ce9ce8290b8270beba82ef41eb27d4c9

Authored by Thiago Franco de Moraes
1 parent 76b791fa
Exists in workdir

saving and opening in the new way

invesalius/data/imagedata_utils.py
@@ -32,6 +32,7 @@ from vtk.util import numpy_support @@ -32,6 +32,7 @@ from vtk.util import numpy_support
32 32
33 import constants as const 33 import constants as const
34 from data import vtk_utils 34 from data import vtk_utils
  35 +
35 import utils 36 import utils
36 37
37 # TODO: Test cases which are originally in sagittal/coronal orientation 38 # TODO: Test cases which are originally in sagittal/coronal orientation
@@ -421,10 +422,12 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): @@ -421,10 +422,12 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage):
421 From a list of dicom files it creates memmap file in the temp folder and 422 From a list of dicom files it creates memmap file in the temp folder and
422 returns it and its related filename. 423 returns it and its related filename.
423 """ 424 """
  425 + from project import Project
424 message = _("Generating multiplanar visualization...") 426 message = _("Generating multiplanar visualization...")
425 update_progress= vtk_utils.ShowProgress(len(files) - 1, dialog_type = "ProgressDialog") 427 update_progress= vtk_utils.ShowProgress(len(files) - 1, dialog_type = "ProgressDialog")
426 -  
427 - temp_file = tempfile.mktemp() 428 + proj = Project()
  429 + wdir = proj.working_dir
  430 + temp_file = os.path.join(wdir, 'matrix.dat')
428 431
429 if orientation == 'SAGITTAL': 432 if orientation == 'SAGITTAL':
430 if resolution_percentage == 1.0: 433 if resolution_percentage == 1.0:
@@ -496,7 +499,9 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): @@ -496,7 +499,9 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage):
496 def analyze2mmap(analyze): 499 def analyze2mmap(analyze):
497 data = analyze.get_data() 500 data = analyze.get_data()
498 header = analyze.get_header() 501 header = analyze.get_header()
499 - temp_file = tempfile.mktemp() 502 + proj = Project()
  503 + wdir = proj.working_dir
  504 + temp_file = os.path.join(wdir, 'matrix.dat')
500 505
501 # Sagital 506 # Sagital
502 if header['orient'] == 2: 507 if header['orient'] == 2:
invesalius/data/mask.py
@@ -33,6 +33,7 @@ import session as ses @@ -33,6 +33,7 @@ import session as ses
33 from wx.lib.pubsub import pub as Publisher 33 from wx.lib.pubsub import pub as Publisher
34 34
35 35
  36 +
36 class EditionHistoryNode(object): 37 class EditionHistoryNode(object):
37 def __init__(self, index, orientation, array, clean=False): 38 def __init__(self, index, orientation, array, clean=False):
38 self.index = index 39 self.index = index
@@ -259,6 +260,26 @@ class Mask(): @@ -259,6 +260,26 @@ class Mask():
259 path = os.path.join(dirpath, mask_file) 260 path = os.path.join(dirpath, mask_file)
260 self._open_mask(path, tuple(shape)) 261 self._open_mask(path, tuple(shape))
261 262
  263 + def save_workdir(self):
  264 + mask = {}
  265 + filename = os.path.split(self.temp_file)[-1]
  266 +
  267 + mask['index'] = self.index
  268 + mask['name'] = self.name
  269 + mask['colour'] = self.colour
  270 + mask['opacity'] = self.opacity
  271 + mask['threshold_range'] = self.threshold_range
  272 + mask['edition_threshold_range'] = self.edition_threshold_range
  273 + mask['visible'] = self.is_shown
  274 + mask['mask_file'] = filename
  275 + mask['mask_shape'] = self.matrix.shape
  276 + mask['edited'] = self.was_edited
  277 +
  278 + plist_filename = os.path.splitext(self.temp_file)[0]+ '.plist'
  279 + plistlib.writePlist(mask, plist_filename)
  280 +
  281 + return os.path.split(plist_filename)[-1]
  282 +
262 def OnFlipVolume(self, pubsub_evt): 283 def OnFlipVolume(self, pubsub_evt):
263 axis = pubsub_evt.data 284 axis = pubsub_evt.data
264 submatrix = self.matrix[1:, 1:, 1:] 285 submatrix = self.matrix[1:, 1:, 1:]
@@ -289,10 +310,14 @@ class Mask(): @@ -289,10 +310,14 @@ class Mask():
289 Mask.general_index = index 310 Mask.general_index = index
290 311
291 def create_mask(self, shape): 312 def create_mask(self, shape):
292 - print "Creating a mask"  
293 - self.temp_file = tempfile.mktemp() 313 + from project import Project
  314 + proj = Project()
  315 + wdir = proj.working_dir
  316 + self.temp_file = tempfile.mktemp(prefix='mask%d_' % self.index, dir=wdir)
  317 + print "Creating mask at", self.temp_file
294 shape = shape[0] + 1, shape[1] + 1, shape[2] + 1 318 shape = shape[0] + 1, shape[1] + 1, shape[2] + 1
295 self.matrix = numpy.memmap(self.temp_file, mode='w+', dtype='uint8', shape=shape) 319 self.matrix = numpy.memmap(self.temp_file, mode='w+', dtype='uint8', shape=shape)
  320 + proj.save_workdir()
296 321
297 def clean(self): 322 def clean(self):
298 self.matrix[1:, 1:, 1:] = 0 323 self.matrix[1:, 1:, 1:] = 0
invesalius/data/surface.py
@@ -59,6 +59,7 @@ class Surface(): @@ -59,6 +59,7 @@ class Surface():
59 self.transparency = const.SURFACE_TRANSPARENCY 59 self.transparency = const.SURFACE_TRANSPARENCY
60 self.volume = 0 60 self.volume = 0
61 self.is_shown = 1 61 self.is_shown = 1
  62 + self.temp_file = ''
62 if not name: 63 if not name:
63 self.name = const.SURFACE_NAME_PATTERN %(self.index+1) 64 self.name = const.SURFACE_NAME_PATTERN %(self.index+1)
64 else: 65 else:
@@ -101,6 +102,19 @@ class Surface(): @@ -101,6 +102,19 @@ class Surface():
101 self.polydata = pu.Import(os.path.join(dirpath, sp['polydata'])) 102 self.polydata = pu.Import(os.path.join(dirpath, sp['polydata']))
102 Surface.general_index = max(Surface.general_index, self.index) 103 Surface.general_index = max(Surface.general_index, self.index)
103 104
  105 + def save_workdir(self):
  106 + surface = {'colour': self.colour,
  107 + 'index': self.index,
  108 + 'name': self.name,
  109 + 'polydata': self.temp_file,
  110 + 'transparency': self.transparency,
  111 + 'visible': bool(self.is_shown),
  112 + 'volume': self.volume,
  113 + }
  114 + plist_filename = os.path.splitext(self.temp_file)[0] + '.plist'
  115 + plistlib.writePlist(surface, plist_filename)
  116 + return os.path.split(plist_filename)[-1]
  117 +
104 def _set_class_index(self, index): 118 def _set_class_index(self, index):
105 Surface.general_index = index 119 Surface.general_index = index
106 120
@@ -278,6 +292,17 @@ class SurfaceManager(): @@ -278,6 +292,17 @@ class SurfaceManager():
278 surface.index = index 292 surface.index = index
279 self.last_surface_index = index 293 self.last_surface_index = index
280 294
  295 + wdir = proj.working_dir
  296 + temp_file = tempfile.mktemp(prefix='surface%d_' % surface.index, suffix='.vtp', dir=wdir)
  297 +
  298 + writer = vtk.vtkXMLPolyDataWriter()
  299 + writer.SetInput(polydata)
  300 + writer.SetFileName(temp_file)
  301 + writer.Write()
  302 + del writer
  303 +
  304 + surface.temp_file = temp_file
  305 +
281 # Set actor colour and transparency 306 # Set actor colour and transparency
282 actor.GetProperty().SetColor(surface.colour) 307 actor.GetProperty().SetColor(surface.colour)
283 actor.GetProperty().SetOpacity(1-surface.transparency) 308 actor.GetProperty().SetOpacity(1-surface.transparency)
@@ -307,6 +332,7 @@ class SurfaceManager(): @@ -307,6 +332,7 @@ class SurfaceManager():
307 (surface.index, surface.name, 332 (surface.index, surface.name,
308 surface.colour, surface.volume, 333 surface.colour, surface.volume,
309 surface.transparency)) 334 surface.transparency))
  335 +
310 return surface.index 336 return surface.index
311 337
312 def OnCloseProject(self, pubsub_evt): 338 def OnCloseProject(self, pubsub_evt):
@@ -644,6 +670,8 @@ class SurfaceManager(): @@ -644,6 +670,8 @@ class SurfaceManager():
644 polydata.DebugOn() 670 polydata.DebugOn()
645 del filled_polydata 671 del filled_polydata
646 672
  673 + proj = prj.Project()
  674 +
647 normals = vtk.vtkPolyDataNormals() 675 normals = vtk.vtkPolyDataNormals()
648 normals.ReleaseDataFlagOn() 676 normals.ReleaseDataFlagOn()
649 normals_ref = weakref.ref(normals) 677 normals_ref = weakref.ref(normals)
@@ -693,6 +721,17 @@ class SurfaceManager(): @@ -693,6 +721,17 @@ class SurfaceManager():
693 surface = Surface(index = self.last_surface_index) 721 surface = Surface(index = self.last_surface_index)
694 else: 722 else:
695 surface = Surface(name=surface_name) 723 surface = Surface(name=surface_name)
  724 +
  725 + wdir = proj.working_dir
  726 + temp_file = tempfile.mktemp(prefix='surface%d_' % surface.index, suffix='.vtp', dir=wdir)
  727 +
  728 + writer = vtk.vtkXMLPolyDataWriter()
  729 + writer.SetInput(polydata)
  730 + writer.SetFileName(temp_file)
  731 + writer.Write()
  732 + del writer
  733 +
  734 + surface.temp_file = temp_file
696 surface.colour = colour 735 surface.colour = colour
697 surface.polydata = polydata 736 surface.polydata = polydata
698 del polydata 737 del polydata
@@ -707,7 +746,6 @@ class SurfaceManager(): @@ -707,7 +746,6 @@ class SurfaceManager():
707 746
708 prop.SetInterpolation(interpolation) 747 prop.SetInterpolation(interpolation)
709 748
710 - proj = prj.Project()  
711 if overwrite: 749 if overwrite:
712 proj.ChangeSurface(surface) 750 proj.ChangeSurface(surface)
713 else: 751 else:
invesalius/project.py
@@ -74,6 +74,7 @@ class Project(object): @@ -74,6 +74,7 @@ class Project(object):
74 74
75 self.raycasting_preset = '' 75 self.raycasting_preset = ''
76 76
  77 + self.working_dir = tempfile.mkdtemp()
77 78
78 #self.surface_quality_list = ["Low", "Medium", "High", "Optimal *", 79 #self.surface_quality_list = ["Low", "Medium", "High", "Optimal *",
79 # "Custom"i] 80 # "Custom"i]
@@ -84,6 +85,13 @@ class Project(object): @@ -84,6 +85,13 @@ class Project(object):
84 # Allow insertion of new surface quality modes 85 # Allow insertion of new surface quality modes
85 86
86 def Close(self): 87 def Close(self):
  88 + try:
  89 + print ">>>>> Trying to remove", self.working_dir
  90 + os.rmdir(self.working_dir)
  91 + print ">>>> done"
  92 + except OSError:
  93 + print ">>>> It was not possible"
  94 +
87 for name in self.__dict__: 95 for name in self.__dict__:
88 attr = getattr(self, name) 96 attr = getattr(self, name)
89 del attr 97 del attr
@@ -195,77 +203,10 @@ class Project(object): @@ -195,77 +203,10 @@ class Project(object):
195 return measures 203 return measures
196 204
197 def SavePlistProject(self, dir_, filename): 205 def SavePlistProject(self, dir_, filename):
198 - dir_temp = tempfile.mkdtemp()  
199 - filename_tmp = os.path.join(dir_temp, 'matrix.dat')  
200 - filelist = {}  
201 -  
202 - project = {  
203 - # Format info  
204 - "format_version": 1,  
205 - "invesalius_version": const.INVESALIUS_VERSION,  
206 - "date": datetime.datetime.now().isoformat(),  
207 -  
208 - # case info  
209 - "name": self.name, # patient's name  
210 - "modality": self.modality, # CT, RMI, ...  
211 - "orientation": self.original_orientation,  
212 - "window_width": self.window,  
213 - "window_level": self.level,  
214 - "scalar_range": self.threshold_range,  
215 - "spacing": self.spacing,  
216 - }  
217 -  
218 - # Saving the matrix containing the slices  
219 - matrix = {'filename': u'matrix.dat',  
220 - 'shape': self.matrix_shape,  
221 - 'dtype': self.matrix_dtype,  
222 - }  
223 - project['matrix'] = matrix  
224 - filelist[self.matrix_filename] = 'matrix.dat'  
225 - #shutil.copyfile(self.matrix_filename, filename_tmp)  
226 -  
227 - # Saving the masks  
228 - masks = {}  
229 - for index in self.mask_dict:  
230 - masks[str(index)] = self.mask_dict[index].SavePlist(dir_temp,  
231 - filelist)  
232 - project['masks'] = masks  
233 -  
234 - # Saving the surfaces  
235 - surfaces = {}  
236 - for index in self.surface_dict:  
237 - surfaces[str(index)] = self.surface_dict[index].SavePlist(dir_temp,  
238 - filelist)  
239 - project['surfaces'] = surfaces  
240 -  
241 - # Saving the measurements  
242 - measurements = self.GetMeasuresDict()  
243 - measurements_filename = 'measurements.plist'  
244 - temp_mplist = tempfile.mktemp()  
245 - plistlib.writePlist(measurements,  
246 - temp_mplist)  
247 - filelist[temp_mplist] = measurements_filename  
248 - project['measurements'] = measurements_filename  
249 -  
250 - # Saving the annotations (empty in this version)  
251 - project['annotations'] = {}  
252 -  
253 - # Saving the main plist  
254 - temp_plist = tempfile.mktemp()  
255 - plistlib.writePlist(project, temp_plist)  
256 - filelist[temp_plist] = 'main.plist'  
257 -  
258 - # Compressing and generating the .inv3 file  
259 path = os.path.join(dir_,filename) 206 path = os.path.join(dir_,filename)
260 - Compress(dir_temp, path, filelist) 207 + filelist = self.save_workdir()
  208 + Compress(self.working_dir, path, filelist)
261 209
262 - # Removing the temp folder.  
263 - shutil.rmtree(dir_temp)  
264 -  
265 - for f in filelist:  
266 - if filelist[f].endswith('.plist'):  
267 - print f  
268 - os.remove(f)  
269 210
270 def OpenPlistProject(self, filename): 211 def OpenPlistProject(self, filename):
271 import data.measures as ms 212 import data.measures as ms
@@ -278,7 +219,9 @@ class Project(object): @@ -278,7 +219,9 @@ class Project(object):
278 ow.SetInstance(fow) 219 ow.SetInstance(fow)
279 220
280 filelist = Extract(filename, tempfile.mkdtemp()) 221 filelist = Extract(filename, tempfile.mkdtemp())
  222 + print "@@@@", os.path.split(filelist[0])[0]
281 dirpath = os.path.abspath(os.path.split(filelist[0])[0]) 223 dirpath = os.path.abspath(os.path.split(filelist[0])[0])
  224 + self.working_dir = dirpath
282 225
283 # Opening the main file from invesalius 3 project 226 # Opening the main file from invesalius 3 project
284 main_plist = os.path.join(dirpath ,'main.plist') 227 main_plist = os.path.join(dirpath ,'main.plist')
@@ -326,15 +269,77 @@ class Project(object): @@ -326,15 +269,77 @@ class Project(object):
326 measure.Load(measurements[index]) 269 measure.Load(measurements[index])
327 self.measurement_dict[int(index)] = measure 270 self.measurement_dict[int(index)] = measure
328 271
  272 + def save_workdir(self):
  273 + filelist = []
  274 + project = {
  275 + # Format info
  276 + "format_version": 1,
  277 + "invesalius_version": const.INVESALIUS_VERSION,
  278 + "date": datetime.datetime.now().isoformat(),
  279 +
  280 + # case info
  281 + "name": self.name, # patient's name
  282 + "modality": self.modality, # CT, RMI, ...
  283 + "orientation": self.original_orientation,
  284 + "window_width": self.window,
  285 + "window_level": self.level,
  286 + "scalar_range": self.threshold_range,
  287 + "spacing": self.spacing,
  288 + }
  289 +
  290 + # Saving the matrix containing the slices
  291 + matrix = {'filename': u'matrix.dat',
  292 + 'shape': self.matrix_shape,
  293 + 'dtype': self.matrix_dtype,
  294 + }
  295 +
  296 + project['matrix'] = matrix
  297 + filelist.append(os.path.join(self.working_dir, 'matrix.dat'))
  298 + #shutil.copyfile(self.matrix_filename, filename_tmp)
  299 +
  300 + # Saving the masks
  301 + masks = {}
  302 + for index in self.mask_dict:
  303 + masks[str(index)] = self.mask_dict[index].save_workdir()
  304 + filelist.append(os.path.join(self.working_dir, masks[str(index)]))
  305 + filelist.append(os.path.join(self.working_dir, os.path.splitext(masks[str(index)])[0]))
  306 + project['masks'] = masks
  307 +
  308 + # # Saving the surfaces
  309 + surfaces = {}
  310 + for index in self.surface_dict:
  311 + surfaces[str(index)] = self.surface_dict[index].save_workdir()
  312 + filelist.append(os.path.join(self.working_dir, surfaces[str(index)]))
  313 + filelist.append(os.path.join(self.working_dir, os.path.splitext(surfaces[str(index)])[0]))
  314 + project['surfaces'] = surfaces
  315 +
  316 + # Saving the measurements
  317 + measurements = self.GetMeasuresDict()
  318 + measurements_filename = 'measurements.plist'
  319 + temp_mplist = os.path.join(self.working_dir, measurements_filename)
  320 + plistlib.writePlist(measurements, temp_mplist)
  321 + project['measurements'] = measurements_filename
  322 + filelist.append(os.path.join(self.working_dir, 'measurements.plist'))
  323 +
  324 + # Saving the annotations (empty in this version)
  325 + project['annotations'] = {}
  326 +
  327 + # Saving the main plist
  328 + pfname = os.path.join(self.working_dir, 'main.plist')
  329 + plistlib.writePlist(project, pfname)
  330 + filelist.append(os.path.join(self.working_dir, 'main.plist'))
  331 +
  332 + return filelist
  333 +
  334 +
329 def Compress(folder, filename, filelist): 335 def Compress(folder, filename, filelist):
330 tmpdir, tmpdir_ = os.path.split(folder) 336 tmpdir, tmpdir_ = os.path.split(folder)
331 current_dir = os.path.abspath(".") 337 current_dir = os.path.abspath(".")
332 - #os.chdir(tmpdir)  
333 - #file_list = glob.glob(os.path.join(tmpdir_,"*"))  
334 - tar_filename = tmpdir_ + ".inv3"  
335 tar = tarfile.open(filename.encode(wx.GetDefaultPyEncoding()), "w:gz") 338 tar = tarfile.open(filename.encode(wx.GetDefaultPyEncoding()), "w:gz")
336 for name in filelist: 339 for name in filelist:
337 - tar.add(name, arcname=os.path.join(tmpdir_, filelist[name])) 340 + sname = name.split(os.path.sep)
  341 + print ">>>>", sname
  342 + tar.add(name, arcname=os.path.join(sname[-2], sname[-1]))
338 tar.close() 343 tar.close()
339 #shutil.move(tmpdir_+ ".inv3", filename) 344 #shutil.move(tmpdir_+ ".inv3", filename)
340 #os.chdir(current_dir) 345 #os.chdir(current_dir)
@@ -350,6 +355,8 @@ def Extract(filename, folder): @@ -350,6 +355,8 @@ def Extract(filename, folder):
350 fname = os.path.join(folder, t.name.decode('utf-8')) 355 fname = os.path.join(folder, t.name.decode('utf-8'))
351 fdst = file(fname, 'wb') 356 fdst = file(fname, 'wb')
352 357
  358 + print fsrc, fdst
  359 +
353 shutil.copyfileobj(fsrc, fdst) 360 shutil.copyfileobj(fsrc, fdst)
354 361
355 filelist.append(fname) 362 filelist.append(fname)
@@ -361,7 +368,7 @@ def Extract(filename, folder): @@ -361,7 +368,7 @@ def Extract(filename, folder):
361 print filelist 368 print filelist
362 return filelist 369 return filelist
363 370
364 - 371 +
365 def Extract_(filename, folder): 372 def Extract_(filename, folder):
366 tar = tarfile.open(filename, "r:gz") 373 tar = tarfile.open(filename, "r:gz")
367 #tar.list(verbose=True) 374 #tar.list(verbose=True)