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) | ... | ... |