def OnImportFolder(self, folder): Publisher.sendMessage('Begin busy cursor') folder = os.path.abspath(folder) proj = prj.Project() proj.load_from_folder(folder) self.Slice = sl.Slice() self.Slice._open_image_matrix(proj.matrix_filename, tuple(proj.matrix_shape), proj.matrix_dtype) self.Slice.window_level = proj.level self.Slice.window_width = proj.window Publisher.sendMessage('Update threshold limits list', threshold_range=proj.threshold_range) session = ses.Session() filename = proj.name + ".inv3" filename = filename.replace("/", "") #Fix problem case other/Skull_DICOM dirpath = session.CreateProject(filename) self.LoadProject() Publisher.sendMessage("Enable state project", state=True) Publisher.sendMessage('End busy cursor')
def on_show(self): self.history._config_undo_redo(self.is_shown) if ses.Session().mask_3d_preview: Publisher.sendMessage('Show mask preview', index=self.index, flag=bool(self.is_shown)) Publisher.sendMessage("Render volume viewer")
def CreateDicomProject(self, dicom, matrix, matrix_filename): name_to_const = { "AXIAL": const.AXIAL, "CORONAL": const.CORONAL, "SAGITTAL": const.SAGITAL } proj = prj.Project() proj.name = dicom.patient.name proj.modality = dicom.acquisition.modality proj.SetAcquisitionModality(dicom.acquisition.modality) proj.matrix_shape = matrix.shape proj.matrix_dtype = matrix.dtype.name proj.matrix_filename = matrix_filename #proj.imagedata = imagedata proj.dicom_sample = dicom proj.original_orientation =\ name_to_const[dicom.image.orientation_label] # Forcing to Axial # proj.original_orientation = const.AXIAL proj.window = float(dicom.image.window) proj.level = float(dicom.image.level) proj.threshold_range = int(matrix.min()), int(matrix.max()) proj.spacing = self.Slice.spacing ###### session = ses.Session() filename = proj.name + ".inv3" filename = filename.replace("/", "") #Fix problem case other/Skull_DICOM dirpath = session.CreateProject(filename)
def OpenProject(self, filepath): Publisher.sendMessage('Begin busy cursor') path = os.path.abspath(filepath) proj = prj.Project() proj.OpenPlistProject(path) proj.SetAcquisitionModality(proj.modality) self.Slice = sl.Slice() self.Slice._open_image_matrix(proj.matrix_filename, tuple(proj.matrix_shape), proj.matrix_dtype) self.Slice.window_level = proj.level self.Slice.window_width = proj.window if proj.affine: self.Slice.affine = np.asarray(proj.affine).reshape(4, 4) else: self.Slice.affine = None Publisher.sendMessage('Update threshold limits list', threshold_range=proj.threshold_range) self.LoadProject() session = ses.Session() session.OpenProject(filepath) Publisher.sendMessage("Enable state project", state=True)
def disable_mask_preview(self): ses.Session().mask_3d_preview = False mask = self.Slice.current_mask if mask is not None: Publisher.sendMessage("Remove mask preview", mask_3d_actor=mask.volume._actor) Publisher.sendMessage("Render volume viewer")
def OnSlideChanging(self, evt): thresh_min = self.gradient.GetMinValue() thresh_max = self.gradient.GetMaxValue() Publisher.sendMessage('Changing threshold values', threshold_range=(thresh_min, thresh_max)) session = ses.Session() session.ChangeProject()
def CreateOtherProject(self, name, matrix, matrix_filename): name_to_const = {"AXIAL": const.AXIAL, "CORONAL": const.CORONAL, "SAGITTAL": const.SAGITAL} proj = prj.Project() proj.name = name proj.modality = 'MRI' proj.SetAcquisitionModality('MRI') proj.matrix_shape = matrix.shape proj.matrix_dtype = matrix.dtype.name proj.matrix_filename = matrix_filename # Orientation must be CORONAL in order to as_closes_canonical and # swap axis in img2memmap to work in a standardized way. # TODO: Create standard import image for all acquisition orientations orientation = 'CORONAL' proj.original_orientation =\ name_to_const[orientation] proj.window = self.Slice.window_width proj.level = self.Slice.window_level proj.threshold_range = int(matrix.min()), int(matrix.max()) proj.spacing = self.Slice.spacing proj.affine = self.affine.tolist() ###### session = ses.Session() filename = proj.name + ".inv3" filename = filename.replace("/", "") # Fix problem case other/Skull_DICOM dirpath = session.CreateProject(filename)
def ShowDialogImportOtherFiles(self, id_type): # Offer to save current project if necessary session = ses.Session() st = session.project_status if (st == const.PROJ_NEW) or (st == const.PROJ_CHANGE): filename = session.project_path[1] answer = dialog.SaveChangesDialog2(filename) if answer: self.ShowDialogSaveProject() self.CloseProject() # Publisher.sendMessage("Enable state project", False) Publisher.sendMessage('Set project name') Publisher.sendMessage("Stop Config Recording") Publisher.sendMessage("Set slice interaction style", const.STATE_DEFAULT) # Warning for limited support to Analyze format if id_type == const.ID_ANALYZE_IMPORT: dialog.ImportAnalyzeWarning() # Import project treating compressed nifti exception suptype = ('hdr', 'nii', 'nii.gz', 'par') filepath = dialog.ShowImportOtherFilesDialog(id_type) if filepath is not None: name = filepath.rpartition('\\')[-1].split('.') if name[-1] == 'gz': name[1] = 'nii.gz' filetype = name[1].lower() if filetype in suptype: Publisher.sendMessage("Open other files", filepath) else: dialog.ImportInvalidFiles()
def parse_comand_line(): """ Handle command line arguments. """ session = ses.Session() # Parse command line arguments parser = op.OptionParser() # -d or --debug: print all pubsub messagessent parser.add_option("-d", "--debug", action="store_true", dest="debug") parser.add_option('--no-gui', action='store_true', dest='no_gui') # -i or --import: import DICOM directory # chooses largest series parser.add_option("-i", "--import", action="store", dest="dicom_dir") parser.add_option("--import-all", action="store") parser.add_option("-s", "--save", help="Save the project after an import.") parser.add_option( "-t", "--threshold", help="Define the threshold for the export (e.g. 100-780).") parser.add_option("-e", "--export", help="Export to STL.") parser.add_option("-a", "--export-to-all", help="Export to STL for all mask presets.") options, args = parser.parse_args() return options, args
def SaveProject(self, path=None, compress=False): Publisher.sendMessage('Begin busy cursor') session = ses.Session() if path: dirpath, filename = os.path.split(path) else: dirpath, filename = session.project_path if isinstance(filename, str): filename = utils.decode(filename, const.FS_ENCODE) proj = prj.Project() try: prj.Project().SavePlistProject(dirpath, filename, compress) except PermissionError as err: if wx.GetApp() is None: print( "Error: Permission denied, you don't have permission to write at {}" .format(dirpath)) else: dlg = dialogs.ErrorMessageBox( None, "Save project error", "It was not possible to save because you don't have permission to write at {}\n{}" .format(dirpath, err)) dlg.ShowModal() dlg.Destroy() else: session.SaveProject((dirpath, filename)) Publisher.sendMessage('End busy cursor')
def UpdateSurfaceInterpolation(self): interpolation = int(ses.Session().surface_interpolation) key_actors = self.actors_dict.keys() for key in self.actors_dict: self.actors_dict[key].GetProperty().SetInterpolation(interpolation) Publisher.sendMessage('Render volume viewer')
def redo_history(self, actual_slices): self.history.redo(self.matrix, actual_slices) self.modified() # Marking the project as changed session = ses.Session() session.ChangeProject()
def UpdateCheck(): import urllib import urllib2 import wx import invesalius.session as ses def _show_update_info(): from invesalius.gui import dialogs msg = _( "A new version of InVesalius is available. Do you want to open the download website now?" ) title = _("Invesalius Update") msgdlg = dialogs.UpdateMessageDialog(url) #if (msgdlg.Show()==wx.ID_YES): #wx.LaunchDefaultBrowser(url) msgdlg.Show() #msgdlg.Destroy() print "Checking updates..." # Check if there is a language set #import invesalius.i18n as i18n import invesalius.session as ses session = ses.Session() install_lang = 0 if session.ReadLanguage(): lang = session.GetLanguage() #if (lang != "False"): #_ = i18n.InstallLanguage(lang) #install_lang = 1 #if (install_lang==0): #return if session.ReadRandomId(): random_id = session.GetRandomId() # Fetch update data from server import invesalius.constants as const url = "http://www.cti.gov.br/dt3d/invesalius/update/checkupdate.php" headers = { 'User-Agent': 'Mozilla/5.0 (compatible; MSIE 5.5; Windows NT)' } data = { 'update_protocol_version': '1', 'invesalius_version': const.INVESALIUS_VERSION, 'platform': sys.platform, 'architecture': platform.architecture()[0], 'language': lang, 'random_id': random_id } data = urllib.urlencode(data) req = urllib2.Request(url, data, headers) try: response = urllib2.urlopen(req, timeout=10) except: return last = response.readline().rstrip() url = response.readline().rstrip() if (last != const.INVESALIUS_VERSION): print " ...New update found!!! -> version:", last #, ", url=",url wx.CallAfter(wx.CallLater, 1000, _show_update_info)
def TestLoadProjects2(self): import invesalius.session as ses session = ses.Session() projects = session.recent_projects for tuple in projects: filename = tuple[1] path = tuple[0] self.LoadProject(filename, path)
def CloseProject(self): proj = prj.Project() proj.Close() Publisher.sendMessage('Hide content panel') Publisher.sendMessage('Close project data') session = ses.Session() session.CloseProject()
def _load_user_parameters(self): session = ses.Session() if 'surface' in session: self._default_parameters.update(session['surface']) else: session['surface'] = self._default_parameters session.WriteSessionFile()
def OnLinkExportSurface(self, evt=None): "OnLinkExportSurface" project = proj.Project() n_surface = 0 for index in project.surface_dict: if project.surface_dict[index].is_shown: n_surface += 1 if n_surface: if sys.platform == 'win32': project_name = project.name else: project_name = project.name+".stl" session = ses.Session() last_directory = session.get('paths', 'last_directory_3d_surface', '') dlg = wx.FileDialog(None, _("Save 3D surface as..."), # title last_directory, # last used directory project_name, # filename WILDCARD_SAVE_3D, wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) dlg.SetFilterIndex(3) # default is STL if dlg.ShowModal() == wx.ID_OK: filetype_index = dlg.GetFilterIndex() filetype = INDEX_TO_TYPE_3D[filetype_index] filename = dlg.GetPath() extension = INDEX_TO_EXTENSION[filetype_index] if sys.platform != 'win32': if filename.split(".")[-1] != extension: filename = filename + "."+ extension if filename: session['paths']['last_directory_3d_surface'] = os.path.split(filename)[0] session.WriteSessionFile() Publisher.sendMessage('Export surface to file', filename=filename, filetype=filetype) if not os.path.exists(filename): dlg = wx.MessageDialog(None, _("It was not possible to save the surface."), _("Error saving surface"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() else: dlg = wx.MessageDialog(None, _("You need to create a surface and make it ") + _("visible before exporting it."), 'InVesalius 3', wx.OK | wx.ICON_INFORMATION) try: dlg.ShowModal() finally: dlg.Destroy()
def UpdateCheck(): try: from urllib.parse import urlencode from urllib.request import urlopen, Request from urllib.error import HTTPError except ImportError: from urllib import urlencode from urllib2 import urlopen, Request, HTTPError import wx import invesalius.session as ses def _show_update_info(): from invesalius.gui import dialogs msg=_("A new version of InVesalius is available. Do you want to open the download website now?") title=_("Invesalius Update") msgdlg = dialogs.UpdateMessageDialog(url) #if (msgdlg.Show()==wx.ID_YES): #wx.LaunchDefaultBrowser(url) msgdlg.Show() #msgdlg.Destroy() print("Checking updates...") # Check if there is a language set #import invesalius.i18n as i18n import invesalius.session as ses session = ses.Session() install_lang = 0 lang = session.GetLanguage() random_id = session.GetRandomId() if lang: # Fetch update data from server import invesalius.constants as const url = "https://www.cti.gov.br/dt3d/invesalius/update/checkupdate.php" headers = { 'User-Agent' : 'Mozilla/5.0 (compatible; MSIE 5.5; Windows NT)' } data = {'update_protocol_version' : '1', 'invesalius_version' : const.INVESALIUS_VERSION, 'platform' : sys.platform, 'architecture' : platform.architecture()[0], 'language' : lang, 'random_id' : random_id } data = urlencode(data).encode('utf8') req = Request(url, data, headers) try: response = urlopen(req, timeout=10) except: return last = response.readline().rstrip().decode('utf8') url = response.readline().rstrip().decode('utf8') try: last_ver = LooseVersion(last) actual_ver = LooseVersion(const.INVESALIUS_VERSION) except (ValueError, AttributeError): return if last_ver > actual_ver: print(" ...New update found!!! -> version:", last) #, ", url=",url wx.CallAfter(wx.CallLater, 1000, _show_update_info)
def use_cmd_optargs(options, args): # If debug argument... if options.debug: Publisher.subscribe(print_events, Publisher.ALL_TOPICS) session = ses.Session() session.debug = 1 # If import DICOM argument... if options.dicom_dir: import_dir = options.dicom_dir Publisher.sendMessage('Import directory', { 'directory': import_dir, 'gui': not options.no_gui }) if options.save: Publisher.sendMessage('Save project', os.path.abspath(options.save)) exit(0) check_for_export(options) return True elif options.import_all: import invesalius.reader.dicom_reader as dcm for patient in dcm.GetDicomGroups(options.import_all): for group in patient.GetGroups(): Publisher.sendMessage('Import group', { 'group': group, 'gui': not options.no_gui }) check_for_export(options, suffix=group.title, remove_surfaces=False) Publisher.sendMessage('Remove masks', [0]) return True # Check if there is a file path somewhere in what the user wrote # In case there is, try opening as it was a inv3 else: for arg in reversed(args): file = utils.decode(arg, FS_ENCODE) if os.path.isfile(file): path = os.path.abspath(file) Publisher.sendMessage('Open project', path) check_for_export(options) return True file = utils.decode(arg, sys.stdin.encoding) if os.path.isfile(file): path = os.path.abspath(file) Publisher.sendMessage('Open project', path) check_for_export(options) return True return False
def CloseProject(self): proj = prj.Project() proj.Close() Publisher.sendMessage('Set slice interaction style', const.STATE_DEFAULT) Publisher.sendMessage('Hide content panel') Publisher.sendMessage('Close project data') session = ses.Session() session.CloseProject()
def enable_mask_preview(self): ses.Session().mask_3d_preview = True mask = self.Slice.current_mask if mask is not None: self.Slice.do_threshold_to_all_slices(mask) mask.create_3d_preview() Publisher.sendMessage("Load mask preview", mask_3d_actor=mask.volume._actor, flag=True) Publisher.sendMessage("Render volume viewer")
def parse_comand_line(): """ Handle command line arguments. """ session = ses.Session() # Parse command line arguments parser = op.OptionParser() # -d or --debug: print all pubsub messagessent parser.add_option("-d", "--debug", action="store_true", dest="debug") parser.add_option('--no-gui', action='store_true', dest='no_gui') # -i or --import: import DICOM directory # chooses largest series parser.add_option("-i", "--import", action="store", dest="dicom_dir") parser.add_option("--import-all", action="store") parser.add_option("--import-folder", action="store", dest="import_folder") parser.add_option("--remote-host", action="store", dest="remote_host") parser.add_option("-s", "--save", help="Save the project after an import.") parser.add_option( "-t", "--threshold", help="Define the threshold for the export (e.g. 100-780).") parser.add_option("-e", "--export", help="Export to STL.") parser.add_option("-a", "--export-to-all", help="Export to STL for all mask presets.") parser.add_option("--export-project", help="Export slices and mask to HDF5 or Nifti file.") parser.add_option( "--no-masks", action="store_false", dest="save_masks", default=True, help="Make InVesalius not export mask when exporting project.") parser.add_option("--use-pedal", action="store_true", dest="use_pedal", help="Use an external trigger pedal") options, args = parser.parse_args() return options, args
def LoadPreferences(self): se = ses.Session() values = {const.RENDERING:se.rendering, const.SURFACE_INTERPOLATION:se.surface_interpolation, const.LANGUAGE:se.language, const.SLICE_INTERPOLATION: se.slice_interpolation, } self.pnl_viewer2d.LoadSelection(values) self.pnl_viewer3d.LoadSelection(values) self.pnl_language.LoadSelection(values)
def __init__(self, frame): self.surface_manager = srf.SurfaceManager() self.volume = volume.Volume() self.__bind_events() self.frame = frame self.progress_dialog = None self.cancel_import = False #Init session session = ses.Session() self.measure_manager = measures.MeasurementManager() Publisher.sendMessage('Load Preferences')
def OnOpenRecentProject(self, filepath): if os.path.exists(filepath): session = ses.Session() st = session.project_status if (st == const.PROJ_NEW) or (st == const.PROJ_CHANGE): filename = session.project_path[1] answer = dialog.SaveChangesDialog2(filename) if answer: self.ShowDialogSaveProject() if session.IsOpen(): self.CloseProject() self.OpenProject(filepath) else: dialog.InexistentPath(filepath)
def SaveProject(self, path=None): Publisher.sendMessage('Begin busy cursor') session = ses.Session() if path: dirpath, filename = os.path.split(path) session.SaveProject((dirpath, filename)) else: dirpath, filename = session.project_path proj = prj.Project() prj.Project().SavePlistProject(dirpath, filename) session.SaveProject() Publisher.sendMessage('End busy cursor')
def ReadDicomGroup(dir_): patient_group = GetDicomGroups(dir_) if len(patient_group) > 0: filelist, dicom, zspacing = SelectLargerDicomGroup(patient_group) filelist = SortFiles(filelist, dicom) size = dicom.image.size bits = dicom.image.bits_allocad imagedata = CreateImageData(filelist, zspacing, size, bits) session.Session().project_status = const.NEW_PROJECT return imagedata, dicom else: return False
def ShowDialogSaveProject(self, saveas=False): session = ses.Session() if saveas or session.temp_item: proj = prj.Project() filepath, compress = dialog.ShowSaveAsProjectDialog(proj.name) if not filepath: return else: proj = prj.Project() compress = proj.compress dirpath, filename = session.project_path filepath = os.path.join(dirpath, filename) self.SaveProject(filepath, compress)
def modified(self, all_volume=False): if all_volume: self.matrix[0] = 1 self.matrix[:, 0, :] = 1 self.matrix[:, :, 0] = 1 if ses.Session().auto_reload_preview: self._update_imagedata() self.modified_time = time.monotonic() callbacks = [] print(self._modified_callbacks) for callback in self._modified_callbacks: if callback() is not None: callback()() callbacks.append(callback) self._modified_callbacks = callbacks
def ShowDialogSaveProject(self, saveas=False): session = ses.Session() if saveas or session.temp_item: proj = prj.Project() filepath = dialog.ShowSaveAsProjectDialog(proj.name) if filepath: #session.RemoveTemp() session.OpenProject(filepath) else: return else: dirpath, filename = session.project_path filepath = os.path.join(dirpath, filename) self.SaveProject(filepath)