Commit 3aa03487ce9ce8290b8270beba82ef41eb27d4c9
1 parent
76b791fa
Exists in
workdir
saving and opening in the new way
Showing
4 changed files
with
155 additions
and
80 deletions
Show diff stats
invesalius/data/imagedata_utils.py
| ... | ... | @@ -32,6 +32,7 @@ from vtk.util import numpy_support |
| 32 | 32 | |
| 33 | 33 | import constants as const |
| 34 | 34 | from data import vtk_utils |
| 35 | + | |
| 35 | 36 | import utils |
| 36 | 37 | |
| 37 | 38 | # TODO: Test cases which are originally in sagittal/coronal orientation |
| ... | ... | @@ -421,10 +422,12 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): |
| 421 | 422 | From a list of dicom files it creates memmap file in the temp folder and |
| 422 | 423 | returns it and its related filename. |
| 423 | 424 | """ |
| 425 | + from project import Project | |
| 424 | 426 | message = _("Generating multiplanar visualization...") |
| 425 | 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 | 432 | if orientation == 'SAGITTAL': |
| 430 | 433 | if resolution_percentage == 1.0: |
| ... | ... | @@ -496,7 +499,9 @@ def dcm2memmap(files, slice_size, orientation, resolution_percentage): |
| 496 | 499 | def analyze2mmap(analyze): |
| 497 | 500 | data = analyze.get_data() |
| 498 | 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 | 506 | # Sagital |
| 502 | 507 | if header['orient'] == 2: | ... | ... |
invesalius/data/mask.py
| ... | ... | @@ -33,6 +33,7 @@ import session as ses |
| 33 | 33 | from wx.lib.pubsub import pub as Publisher |
| 34 | 34 | |
| 35 | 35 | |
| 36 | + | |
| 36 | 37 | class EditionHistoryNode(object): |
| 37 | 38 | def __init__(self, index, orientation, array, clean=False): |
| 38 | 39 | self.index = index |
| ... | ... | @@ -259,6 +260,26 @@ class Mask(): |
| 259 | 260 | path = os.path.join(dirpath, mask_file) |
| 260 | 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 | 283 | def OnFlipVolume(self, pubsub_evt): |
| 263 | 284 | axis = pubsub_evt.data |
| 264 | 285 | submatrix = self.matrix[1:, 1:, 1:] |
| ... | ... | @@ -289,10 +310,14 @@ class Mask(): |
| 289 | 310 | Mask.general_index = index |
| 290 | 311 | |
| 291 | 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 | 318 | shape = shape[0] + 1, shape[1] + 1, shape[2] + 1 |
| 295 | 319 | self.matrix = numpy.memmap(self.temp_file, mode='w+', dtype='uint8', shape=shape) |
| 320 | + proj.save_workdir() | |
| 296 | 321 | |
| 297 | 322 | def clean(self): |
| 298 | 323 | self.matrix[1:, 1:, 1:] = 0 | ... | ... |
invesalius/data/surface.py
| ... | ... | @@ -59,6 +59,7 @@ class Surface(): |
| 59 | 59 | self.transparency = const.SURFACE_TRANSPARENCY |
| 60 | 60 | self.volume = 0 |
| 61 | 61 | self.is_shown = 1 |
| 62 | + self.temp_file = '' | |
| 62 | 63 | if not name: |
| 63 | 64 | self.name = const.SURFACE_NAME_PATTERN %(self.index+1) |
| 64 | 65 | else: |
| ... | ... | @@ -101,6 +102,19 @@ class Surface(): |
| 101 | 102 | self.polydata = pu.Import(os.path.join(dirpath, sp['polydata'])) |
| 102 | 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 | 118 | def _set_class_index(self, index): |
| 105 | 119 | Surface.general_index = index |
| 106 | 120 | |
| ... | ... | @@ -278,6 +292,17 @@ class SurfaceManager(): |
| 278 | 292 | surface.index = index |
| 279 | 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 | 306 | # Set actor colour and transparency |
| 282 | 307 | actor.GetProperty().SetColor(surface.colour) |
| 283 | 308 | actor.GetProperty().SetOpacity(1-surface.transparency) |
| ... | ... | @@ -307,6 +332,7 @@ class SurfaceManager(): |
| 307 | 332 | (surface.index, surface.name, |
| 308 | 333 | surface.colour, surface.volume, |
| 309 | 334 | surface.transparency)) |
| 335 | + | |
| 310 | 336 | return surface.index |
| 311 | 337 | |
| 312 | 338 | def OnCloseProject(self, pubsub_evt): |
| ... | ... | @@ -644,6 +670,8 @@ class SurfaceManager(): |
| 644 | 670 | polydata.DebugOn() |
| 645 | 671 | del filled_polydata |
| 646 | 672 | |
| 673 | + proj = prj.Project() | |
| 674 | + | |
| 647 | 675 | normals = vtk.vtkPolyDataNormals() |
| 648 | 676 | normals.ReleaseDataFlagOn() |
| 649 | 677 | normals_ref = weakref.ref(normals) |
| ... | ... | @@ -693,6 +721,17 @@ class SurfaceManager(): |
| 693 | 721 | surface = Surface(index = self.last_surface_index) |
| 694 | 722 | else: |
| 695 | 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 | 735 | surface.colour = colour |
| 697 | 736 | surface.polydata = polydata |
| 698 | 737 | del polydata |
| ... | ... | @@ -707,7 +746,6 @@ class SurfaceManager(): |
| 707 | 746 | |
| 708 | 747 | prop.SetInterpolation(interpolation) |
| 709 | 748 | |
| 710 | - proj = prj.Project() | |
| 711 | 749 | if overwrite: |
| 712 | 750 | proj.ChangeSurface(surface) |
| 713 | 751 | else: | ... | ... |
invesalius/project.py
| ... | ... | @@ -74,6 +74,7 @@ class Project(object): |
| 74 | 74 | |
| 75 | 75 | self.raycasting_preset = '' |
| 76 | 76 | |
| 77 | + self.working_dir = tempfile.mkdtemp() | |
| 77 | 78 | |
| 78 | 79 | #self.surface_quality_list = ["Low", "Medium", "High", "Optimal *", |
| 79 | 80 | # "Custom"i] |
| ... | ... | @@ -84,6 +85,13 @@ class Project(object): |
| 84 | 85 | # Allow insertion of new surface quality modes |
| 85 | 86 | |
| 86 | 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 | 95 | for name in self.__dict__: |
| 88 | 96 | attr = getattr(self, name) |
| 89 | 97 | del attr |
| ... | ... | @@ -195,77 +203,10 @@ class Project(object): |
| 195 | 203 | return measures |
| 196 | 204 | |
| 197 | 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 | 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 | 211 | def OpenPlistProject(self, filename): |
| 271 | 212 | import data.measures as ms |
| ... | ... | @@ -278,7 +219,9 @@ class Project(object): |
| 278 | 219 | ow.SetInstance(fow) |
| 279 | 220 | |
| 280 | 221 | filelist = Extract(filename, tempfile.mkdtemp()) |
| 222 | + print "@@@@", os.path.split(filelist[0])[0] | |
| 281 | 223 | dirpath = os.path.abspath(os.path.split(filelist[0])[0]) |
| 224 | + self.working_dir = dirpath | |
| 282 | 225 | |
| 283 | 226 | # Opening the main file from invesalius 3 project |
| 284 | 227 | main_plist = os.path.join(dirpath ,'main.plist') |
| ... | ... | @@ -326,15 +269,77 @@ class Project(object): |
| 326 | 269 | measure.Load(measurements[index]) |
| 327 | 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 | 335 | def Compress(folder, filename, filelist): |
| 330 | 336 | tmpdir, tmpdir_ = os.path.split(folder) |
| 331 | 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 | 338 | tar = tarfile.open(filename.encode(wx.GetDefaultPyEncoding()), "w:gz") |
| 336 | 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 | 343 | tar.close() |
| 339 | 344 | #shutil.move(tmpdir_+ ".inv3", filename) |
| 340 | 345 | #os.chdir(current_dir) |
| ... | ... | @@ -350,6 +355,8 @@ def Extract(filename, folder): |
| 350 | 355 | fname = os.path.join(folder, t.name.decode('utf-8')) |
| 351 | 356 | fdst = file(fname, 'wb') |
| 352 | 357 | |
| 358 | + print fsrc, fdst | |
| 359 | + | |
| 353 | 360 | shutil.copyfileobj(fsrc, fdst) |
| 354 | 361 | |
| 355 | 362 | filelist.append(fname) |
| ... | ... | @@ -361,7 +368,7 @@ def Extract(filename, folder): |
| 361 | 368 | print filelist |
| 362 | 369 | return filelist |
| 363 | 370 | |
| 364 | - | |
| 371 | + | |
| 365 | 372 | def Extract_(filename, folder): |
| 366 | 373 | tar = tarfile.open(filename, "r:gz") |
| 367 | 374 | #tar.list(verbose=True) | ... | ... |