From 199eed724379cb783efcd9348991c5362530a66b Mon Sep 17 00:00:00 2001 From: thorstenkranz Date: Sun, 31 Aug 2025 12:37:09 +0200 Subject: [PATCH] Port to Python 3 and add Poetry config --- bin/pylocator | 6 +-- doc/src/conf.py | 8 ++-- doc/src/sphinxext/autosummary.py | 6 +-- doc/src/sphinxext/autosummary_generate.py | 14 +++--- doc/src/sphinxext/comment_eater.py | 6 +-- doc/src/sphinxext/compiler_unparse.py | 8 ++-- doc/src/sphinxext/docscrape.py | 20 ++++----- doc/src/sphinxext/docscrape_sphinx.py | 4 +- doc/src/sphinxext/numpydoc.py | 6 +-- doc/src/sphinxext/phantom_import.py | 4 +- doc/src/sphinxext/plot_directive.py | 14 +++--- doc/src/sphinxext/traitsdoc.py | 10 ++--- .../GtkGLExtVTKRenderWindowInteractor.py | 8 ++-- pylocator/colors.py | 8 ++-- pylocator/connect_filter.py | 6 +-- pylocator/controller.py | 34 +++++++------- pylocator/decimate_filter.py | 4 +- pylocator/dialogs.py | 18 ++++---- pylocator/events.py | 28 ++++++------ pylocator/gtkutils.py | 30 ++++++------- pylocator/main.py | 4 +- pylocator/marker_list.py | 18 ++++---- pylocator/marker_window_interactor.py | 42 +++++++++--------- pylocator/markers.py | 6 +-- pylocator/misc/markers_io.py | 4 +- pylocator/plane_widgets_observer.py | 30 ++++++------- pylocator/plane_widgets_observer_toolbar.py | 4 +- pylocator/plane_widgets_xyz.py | 44 +++++++++---------- pylocator/render_window.py | 18 ++++---- pylocator/roi_renderer_props.py | 26 +++++------ pylocator/rois.py | 6 +-- pylocator/screenshot_props.py | 6 +-- pylocator/surf_params.py | 12 ++--- pylocator/surf_renderer.py | 24 +++++----- pylocator/surf_renderer_props.py | 28 ++++++------ pylocator/vtkNifti.py | 26 +++++------ pylocator/vtksurface.py | 10 ++--- pyproject.toml | 20 +++++++++ setupegg.py | 4 +- 39 files changed, 297 insertions(+), 277 deletions(-) create mode 100644 pyproject.toml diff --git a/bin/pylocator b/bin/pylocator index fa8f0c7..972a7a6 100644 --- a/bin/pylocator +++ b/bin/pylocator @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/env python3 """Run pylocator""" import getopt @@ -17,8 +17,8 @@ def main(): def info_exit(option = None, value = None): """Print usage information and abort execution""" if not (option in ["-h", "--help"] or option == None): - print "Wrong argument:", option, ",", value - print USAGE + print("Wrong argument:", option, ",", value) + print(USAGE) sys.exit(0) try: options, args = getopt.getopt( diff --git a/doc/src/conf.py b/doc/src/conf.py index c567eba..2dd26a0 100644 --- a/doc/src/conf.py +++ b/doc/src/conf.py @@ -41,8 +41,8 @@ master_doc = 'index' # General information about the project. -project = u'PyLocator' -copyright = u'2011-2012, Thorsten Kranz' +project = 'PyLocator' +copyright = '2011-2012, Thorsten Kranz' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -168,8 +168,8 @@ # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). latex_documents = [ - ('index', 'pylocator.tex', ur'PyLocator Documentation', - ur'Thorsten Kranz', 'manual'), + ('index', 'pylocator.tex', r'PyLocator Documentation', + r'Thorsten Kranz', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of diff --git a/doc/src/sphinxext/autosummary.py b/doc/src/sphinxext/autosummary.py index 6feddba..944aa5b 100644 --- a/doc/src/sphinxext/autosummary.py +++ b/doc/src/sphinxext/autosummary.py @@ -59,7 +59,7 @@ import sphinx.addnodes, sphinx.roles from sphinx.util import patfilter -from docscrape_sphinx import get_doc_object +from .docscrape_sphinx import get_doc_object def setup(app): @@ -288,7 +288,7 @@ def _import_by_name(name): # ... then as MODNAME, MODNAME.OBJ1, MODNAME.OBJ1.OBJ2, ... last_j = 0 modname = None - for j in reversed(range(1, len(name_parts)+1)): + for j in reversed(list(range(1, len(name_parts)+1))): last_j = j modname = '.'.join(name_parts[:j]) try: @@ -305,7 +305,7 @@ def _import_by_name(name): return obj else: return sys.modules[modname] - except (ValueError, ImportError, AttributeError, KeyError), e: + except (ValueError, ImportError, AttributeError, KeyError) as e: raise ImportError(e) #------------------------------------------------------------------------------ diff --git a/doc/src/sphinxext/autosummary_generate.py b/doc/src/sphinxext/autosummary_generate.py index 2c65097..73641e2 100755 --- a/doc/src/sphinxext/autosummary_generate.py +++ b/doc/src/sphinxext/autosummary_generate.py @@ -15,10 +15,10 @@ """ import glob, re, inspect, os, optparse, pydoc -from autosummary import import_by_name +from .autosummary import import_by_name try: - from phantom_import import import_phantom_module + from .phantom_import import import_phantom_module except ImportError: import_phantom_module = lambda x: x @@ -42,7 +42,7 @@ def main(): # read names = {} - for name, loc in get_documented(args).items(): + for name, loc in list(get_documented(args).items()): for (filename, sec_title, keyword, toctree) in loc: if toctree is not None: path = os.path.join(os.path.dirname(filename), toctree) @@ -58,8 +58,8 @@ def main(): try: obj, name = import_by_name(name) - except ImportError, e: - print "Failed to import '%s': %s" % (name, e) + except ImportError as e: + print("Failed to import '%s': %s" % (name, e)) continue fn = os.path.join(path, '%s.rst' % name) @@ -127,8 +127,8 @@ def get_documented_in_docstring(name, module=None, filename=None): return get_documented_in_lines(lines, module=name, filename=filename) except AttributeError: pass - except ImportError, e: - print "Failed to import '%s': %s" % (name, e) + except ImportError as e: + print("Failed to import '%s': %s" % (name, e)) return {} def get_documented_in_lines(lines, module=None, filename=None): diff --git a/doc/src/sphinxext/comment_eater.py b/doc/src/sphinxext/comment_eater.py index e11eea9..9c660e5 100644 --- a/doc/src/sphinxext/comment_eater.py +++ b/doc/src/sphinxext/comment_eater.py @@ -1,10 +1,10 @@ -from cStringIO import StringIO +from io import StringIO import compiler import inspect import textwrap import tokenize -from compiler_unparse import unparse +from .compiler_unparse import unparse class Comment(object): @@ -68,7 +68,7 @@ def __init__(self): def process_file(self, file): """ Process a file object. """ - for token in tokenize.generate_tokens(file.next): + for token in tokenize.generate_tokens(file.__next__): self.process_token(*token) self.make_index() diff --git a/doc/src/sphinxext/compiler_unparse.py b/doc/src/sphinxext/compiler_unparse.py index ffcf51b..bbd028d 100644 --- a/doc/src/sphinxext/compiler_unparse.py +++ b/doc/src/sphinxext/compiler_unparse.py @@ -12,11 +12,11 @@ """ import sys -import cStringIO +import io from compiler.ast import Const, Name, Tuple, Div, Mul, Sub, Add def unparse(ast, single_line_functions=False): - s = cStringIO.StringIO() + s = io.StringIO() UnparseCompilerAst(ast, s, single_line_functions) return s.getvalue().lstrip() @@ -504,7 +504,7 @@ def __binary_op(self, t, symbol): # Check if parenthesis are needed on left side and then dispatch has_paren = False left_class = str(t.left.__class__) - if (left_class in op_precedence.keys() and + if (left_class in list(op_precedence.keys()) and op_precedence[left_class] < op_precedence[str(t.__class__)]): has_paren = True if has_paren: @@ -517,7 +517,7 @@ def __binary_op(self, t, symbol): # Check if parenthesis are needed on the right side and then dispatch has_paren = False right_class = str(t.right.__class__) - if (right_class in op_precedence.keys() and + if (right_class in list(op_precedence.keys()) and op_precedence[right_class] < op_precedence[str(t.__class__)]): has_paren = True if has_paren: diff --git a/doc/src/sphinxext/docscrape.py b/doc/src/sphinxext/docscrape.py index 904270a..7cec14e 100644 --- a/doc/src/sphinxext/docscrape.py +++ b/doc/src/sphinxext/docscrape.py @@ -6,7 +6,7 @@ import textwrap import re import pydoc -from StringIO import StringIO +from io import StringIO from warnings import warn 4 class Reader(object): @@ -113,7 +113,7 @@ def __getitem__(self,key): return self._parsed_data[key] def __setitem__(self,key,val): - if not self._parsed_data.has_key(key): + if key not in self._parsed_data: warn("Unknown section %s" % key) else: self._parsed_data[key] = val @@ -369,7 +369,7 @@ def _str_index(self): idx = self['index'] out = [] out += ['.. index:: %s' % idx.get('default','')] - for section, references in idx.iteritems(): + for section, references in idx.items(): if section == 'default': continue out += [' :%s: %s' % (section, ', '.join(references))] @@ -411,10 +411,10 @@ def __init__(self, func, role='func'): self._role = role # e.g. "func" or "meth" try: NumpyDocString.__init__(self,inspect.getdoc(func) or '') - except ValueError, e: - print '*'*78 - print "ERROR: '%s' while parsing `%s`" % (e, self._f) - print '*'*78 + except ValueError as e: + print('*'*78) + print("ERROR: '%s' while parsing `%s`" % (e, self._f)) + print('*'*78) #print "Docstring follows:" #print doclines #print '='*78 @@ -427,7 +427,7 @@ def __init__(self, func, role='func'): argspec = inspect.formatargspec(*argspec) argspec = argspec.replace('*','\*') signature = '%s%s' % (func_name, argspec) - except TypeError, e: + except TypeError as e: signature = '%s()' % func_name self['Signature'] = signature @@ -449,8 +449,8 @@ def __str__(self): 'meth': 'method'} if self._role: - if not roles.has_key(self._role): - print "Warning: invalid role %s" % self._role + if self._role not in roles: + print("Warning: invalid role %s" % self._role) out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''), func_name) diff --git a/doc/src/sphinxext/docscrape_sphinx.py b/doc/src/sphinxext/docscrape_sphinx.py index d431ecd..d47f98d 100644 --- a/doc/src/sphinxext/docscrape_sphinx.py +++ b/doc/src/sphinxext/docscrape_sphinx.py @@ -1,5 +1,5 @@ import re, inspect, textwrap, pydoc -from docscrape import NumpyDocString, FunctionDoc, ClassDoc +from .docscrape import NumpyDocString, FunctionDoc, ClassDoc class SphinxDocString(NumpyDocString): # string conversion routines @@ -73,7 +73,7 @@ def _str_index(self): return out out += ['.. index:: %s' % idx.get('default','')] - for section, references in idx.iteritems(): + for section, references in idx.items(): if section == 'default': continue elif section == 'refguide': diff --git a/doc/src/sphinxext/numpydoc.py b/doc/src/sphinxext/numpydoc.py index 2ea41fb..f178299 100644 --- a/doc/src/sphinxext/numpydoc.py +++ b/doc/src/sphinxext/numpydoc.py @@ -17,7 +17,7 @@ """ import os, re, pydoc -from docscrape_sphinx import get_doc_object, SphinxDocString +from .docscrape_sphinx import get_doc_object, SphinxDocString import inspect def mangle_docstrings(app, what, name, obj, options, lines, @@ -44,7 +44,7 @@ def mangle_docstrings(app, what, name, obj, options, lines, try: references.append(int(l[len('.. ['):l.index(']')])) except ValueError: - print "WARNING: invalid reference in %s docstring" % name + print("WARNING: invalid reference in %s docstring" % name) # Start renaming from the biggest number, otherwise we may # overwrite references. @@ -99,7 +99,7 @@ def monkeypatch_sphinx_ext_autodoc(): if sphinx.ext.autodoc.format_signature is our_format_signature: return - print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..." + print("[numpydoc] Monkeypatching sphinx.ext.autodoc ...") _original_format_signature = sphinx.ext.autodoc.format_signature sphinx.ext.autodoc.format_signature = our_format_signature diff --git a/doc/src/sphinxext/phantom_import.py b/doc/src/sphinxext/phantom_import.py index c77eeb5..7170a80 100644 --- a/doc/src/sphinxext/phantom_import.py +++ b/doc/src/sphinxext/phantom_import.py @@ -23,7 +23,7 @@ def setup(app): def initialize(app): fn = app.config.phantom_import_file if (fn and os.path.isfile(fn)): - print "[numpydoc] Phantom importing modules from", fn, "..." + print("[numpydoc] Phantom importing modules from", fn, "...") import_phantom_module(fn) #------------------------------------------------------------------------------ @@ -129,7 +129,7 @@ def base_cmp(a, b): doc = "%s%s\n\n%s" % (funcname, argspec, doc) obj = lambda: 0 obj.__argspec_is_invalid_ = True - obj.func_name = funcname + obj.__name__ = funcname obj.__name__ = name obj.__doc__ = doc if inspect.isclass(object_cache[parent]): diff --git a/doc/src/sphinxext/plot_directive.py b/doc/src/sphinxext/plot_directive.py index 6a94188..6d250c2 100644 --- a/doc/src/sphinxext/plot_directive.py +++ b/doc/src/sphinxext/plot_directive.py @@ -69,7 +69,7 @@ """ -import sys, os, glob, shutil, imp, warnings, cStringIO, re, textwrap +import sys, os, glob, shutil, imp, warnings, io, re, textwrap def setup(app): setup.app = app @@ -137,12 +137,12 @@ def run_code(code, code_path): if code_path is not None: os.chdir(os.path.dirname(code_path)) stdout = sys.stdout - sys.stdout = cStringIO.StringIO() + sys.stdout = io.StringIO() try: code = unescape_doctest(code) ns = {} - exec setup.config.plot_pre_code in ns - exec code in ns + exec(setup.config.plot_pre_code, ns) + exec(code, ns) finally: os.chdir(pwd) sys.stdout = stdout @@ -203,7 +203,7 @@ def makefig(code, code_path, output_dir, output_base, config): return i # We didn't find the files, so build them - print "-- Plotting figures %s" % output_base + print("-- Plotting figures %s" % output_base) # Clear between runs plt.close('all') @@ -311,7 +311,7 @@ def run(arguments, content, options, state_machine, state, lineno): # is it in doctest format? is_doctest = contains_doctest(code) - if options.has_key('format'): + if 'format' in options: if options['format'] == 'python': is_doctest = False else: @@ -367,7 +367,7 @@ def run(arguments, content, options, state_machine, state, lineno): return [sm] - opts = [':%s: %s' % (key, val) for key, val in options.items() + opts = [':%s: %s' % (key, val) for key, val in list(options.items()) if key in ('alt', 'height', 'width', 'scale', 'align', 'class')] result = jinja.from_string(TEMPLATE).render( diff --git a/doc/src/sphinxext/traitsdoc.py b/doc/src/sphinxext/traitsdoc.py index e0a2d3b..298896a 100644 --- a/doc/src/sphinxext/traitsdoc.py +++ b/doc/src/sphinxext/traitsdoc.py @@ -18,13 +18,13 @@ import os import pydoc -import docscrape -import docscrape_sphinx -from docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString +from . import docscrape +from . import docscrape_sphinx +from .docscrape_sphinx import SphinxClassDoc, SphinxFunctionDoc, SphinxDocString -import numpydoc +from . import numpydoc -import comment_eater +from . import comment_eater class SphinxTraitsDoc(SphinxClassDoc): def __init__(self, cls, modulename='', func_doc=SphinxFunctionDoc): diff --git a/pylocator/GtkGLExtVTKRenderWindowInteractor.py b/pylocator/GtkGLExtVTKRenderWindowInteractor.py index 01f73dd..04f62bc 100644 --- a/pylocator/GtkGLExtVTKRenderWindowInteractor.py +++ b/pylocator/GtkGLExtVTKRenderWindowInteractor.py @@ -14,7 +14,7 @@ import gtk.gtkgl import vtk -from shared import shared +from .shared import shared class GtkGLExtVTKRenderWindowInteractor(gtk.gtkgl.DrawingArea): """ @@ -86,8 +86,8 @@ def __getattr__(self, attr): elif hasattr(self._Iren, attr): return getattr(self._Iren, attr) else: - raise AttributeError, self.__class__.__name__ + \ - " has no attribute named " + attr + raise AttributeError(self.__class__.__name__ + \ + " has no attribute named " + attr) def CreateTimer(self, obj, event): gtk.timeout_add(10, self._Iren.TimerEvent) @@ -143,7 +143,7 @@ def _GetCtrlShift(self, event): return ctrl, shift def OnButtonDown(self, wid, event): - if shared.debug: print "GtkGLExtVTKRenderWindowInteractor.OnButtonDown()" + if shared.debug: print("GtkGLExtVTKRenderWindowInteractor.OnButtonDown()") """Mouse button pressed.""" m = self.get_pointer() ctrl, shift = self._GetCtrlShift(event) diff --git a/pylocator/colors.py b/pylocator/colors.py index 4ba03c2..0ee6b5e 100644 --- a/pylocator/colors.py +++ b/pylocator/colors.py @@ -1,9 +1,9 @@ -from __future__ import division + import gobject import gtk -from gtkutils import make_option_menu +from .gtkutils import make_option_menu colorSeq = ( ( 'light skin' , (0.953, 0.875, 0.765) ), @@ -74,7 +74,7 @@ def choose_color(self, *args): class ColorChooserWithPredefinedColors(gtk.HBox): custom_str = "custom..." def __init__(self, colorSeq=colorSeq): - names, self.colors= zip(*colorSeq) + names, self.colors= list(zip(*colorSeq)) self.colorDict = dict(colorSeq) self.colorNames = list(names) @@ -181,7 +181,7 @@ def gdkColor2tuple(color): if __name__=="__main__": def func(cc): - print "Color changed", cc.get_color() + print("Color changed", cc.get_color()) win = gtk.Window() box = gtk.VBox() diff --git a/pylocator/connect_filter.py b/pylocator/connect_filter.py index 47a1ba2..87eaf3d 100644 --- a/pylocator/connect_filter.py +++ b/pylocator/connect_filter.py @@ -1,7 +1,7 @@ -from __future__ import division + import vtk import gtk -from gtkutils import ProgressBarDialog +from .gtkutils import ProgressBarDialog class ConnectFilter(vtk.vtkPolyDataConnectivityFilter): """ @@ -18,7 +18,7 @@ class ConnectFilter(vtk.vtkPolyDataConnectivityFilter): 'All Regions' : 5, 'Closest Point Region' : 6, } - num2mode = dict([ (v,k) for k,v in mode2num.items()]) + num2mode = dict([ (v,k) for k,v in list(mode2num.items())]) mode = 5 def __init__(self): diff --git a/pylocator/controller.py b/pylocator/controller.py index aead074..42d87a5 100644 --- a/pylocator/controller.py +++ b/pylocator/controller.py @@ -1,26 +1,26 @@ import os import gtk -from shared import shared -from events import EventHandler -from vtkNifti import vtkNiftiImageReader +from .shared import shared +from .events import EventHandler +from .vtkNifti import vtkNiftiImageReader -from surf_renderer import SurfRenderWindow -from plane_widgets_xyz import PlaneWidgetsXYZ, move_pw_to_point -from plane_widgets_observer import PlaneWidgetObserver -from plane_widgets_observer_toolbar import ObserverToolbar +from .surf_renderer import SurfRenderWindow +from .plane_widgets_xyz import PlaneWidgetsXYZ, move_pw_to_point +from .plane_widgets_observer import PlaneWidgetObserver +from .plane_widgets_observer_toolbar import ObserverToolbar -from surf_renderer_props import SurfRendererProps -from roi_renderer_props import RoiRendererProps -from screenshot_props import ScreenshotProps +from .surf_renderer_props import SurfRendererProps +from .roi_renderer_props import RoiRendererProps +from .screenshot_props import ScreenshotProps -from marker_list import MarkerList -from gtkutils import simple_msg +from .marker_list import MarkerList +from .gtkutils import simple_msg import pylocator -from resources import main_window -from dialogs import SettingsController, about +from .resources import main_window +from .dialogs import SettingsController, about -from colors import gdkColor2tuple +from .colors import gdkColor2tuple class PyLocatorController(object): def __init__(self): @@ -81,7 +81,7 @@ def __fill_notebook_pages(self, window, vboxes): def __add_observer_widgets_to_window(self,win,hbox): win.observers = [] - for orientation, pw in zip(range(3),win.pwxyz.get_plane_widgets_xyz()): + for orientation, pw in zip(list(range(3)),win.pwxyz.get_plane_widgets_xyz()): vboxObs = gtk.VBox() vboxObs.show() observer = PlaneWidgetObserver(pw, owner=win, orientation=orientation) @@ -176,7 +176,7 @@ def load_nifti(self, filename): filename = dialog.get_filename() dialog.destroy() if response == gtk.RESPONSE_OK: - print "Loading:", filename + print("Loading:", filename) else: return False diff --git a/pylocator/decimate_filter.py b/pylocator/decimate_filter.py index 75e1209..16b2e59 100644 --- a/pylocator/decimate_filter.py +++ b/pylocator/decimate_filter.py @@ -1,10 +1,10 @@ -from __future__ import division + import sys, os import vtk import gtk -from gtkutils import ProgressBarDialog, str2posnum_or_err +from .gtkutils import ProgressBarDialog, str2posnum_or_err # vtkDecimate is patented and no longer in VTK5. we will try vtkDecimatePro (argh) diff --git a/pylocator/dialogs.py b/pylocator/dialogs.py index 5e0342b..8b405f2 100644 --- a/pylocator/dialogs.py +++ b/pylocator/dialogs.py @@ -1,10 +1,10 @@ import gtk import re -from resources import edit_label_dialog, edit_coordinates_dialog, edit_settings_dialog, about_dialog -from gtkutils import str2num_or_err -from colors import gdkColor2tuple, tuple2gdkColor -from events import EventHandler -from shared import shared +from .resources import edit_label_dialog, edit_coordinates_dialog, edit_settings_dialog, about_dialog +from .gtkutils import str2num_or_err +from .colors import gdkColor2tuple, tuple2gdkColor +from .events import EventHandler +from .shared import shared def edit_label(oldLabel="", description=None): @@ -30,16 +30,16 @@ def edit_label(oldLabel="", description=None): def edit_label_of_marker(marker): label = marker.get_label() defaultLabel = label - print defaultLabel, shared.lastLabel + print(defaultLabel, shared.lastLabel) if defaultLabel=='' and shared.lastLabel is not None: m = re.match('(.+?)(\d+)', shared.lastLabel) if m: num = str(int(m.group(2))+1).zfill(len(m.group(2))) defaultLabel = m.group(1) + num - print defaultLabel + print(defaultLabel) new_label = edit_label(defaultLabel) - if shared.debug: print new_label, label + if shared.debug: print(new_label, label) if new_label==None or new_label==label: return EventHandler().notify('label marker', marker, new_label) @@ -147,7 +147,7 @@ def set_default_color(self, *args): EventHandler().set_default_color(gdkColor2tuple(color)) def close_dialog(self, *args): - print "close dialog" + print("close dialog") self.dialog.hide() self.dialog.destroy() diff --git a/pylocator/events.py b/pylocator/events.py index bfe7744..1d53597 100644 --- a/pylocator/events.py +++ b/pylocator/events.py @@ -1,8 +1,8 @@ import vtk -from markers import Marker +from .markers import Marker import pickle -from shared import shared -from vtkutils import vtkmatrix4x4_to_array +from .shared import shared +from .vtkutils import vtkmatrix4x4_to_array class UndoRegistry: __sharedState = {} @@ -50,12 +50,12 @@ def add_selection(self, marker): self.notify('select marker', marker) def remove_selection(self, marker): - if self.selected.has_key(marker): + if marker in self.selected: del self.selected[marker] self.notify('unselect marker', marker) def clear_selection(self): - for oldMarker in self.selected.keys(): + for oldMarker in list(self.selected.keys()): self.remove_selection(oldMarker) def select_new(self, marker): @@ -130,11 +130,11 @@ def get_nifti_stats(self): self.__NiftiMax) def set_vtkactor(self, vtkactor): - if shared.debug: print "EventHandler.set_vtkactor()" + if shared.debug: print("EventHandler.set_vtkactor()") self.vtkactor = vtkactor def save_registration_as(self, fname): - if shared.debug: print "EventHandler.save_registration_as(", fname,")" + if shared.debug: print("EventHandler.save_registration_as(", fname,")") fh = file(fname, 'w') # XXX mcc: somehow get the transform for the VTK actor. aiieeee @@ -145,7 +145,7 @@ def save_registration_as(self, fname): mat = self.vtkactor.GetMatrix() orient = self.vtkactor.GetOrientation() - if shared.debug: print "EventHandler.save_registration_as(): vtkactor has origin, pos, scale, mat, orient=", loc, pos, scale, mat, orient, "!!" + if shared.debug: print("EventHandler.save_registration_as(): vtkactor has origin, pos, scale, mat, orient=", loc, pos, scale, mat, orient, "!!") scipy_mat = vtkmatrix4x4_to_array(mat) @@ -170,13 +170,13 @@ def detach(self, observer): except KeyError: pass def notify(self, event, *args): - for observer in self.observers.keys(): + for observer in list(self.observers.keys()): if shared.debug: - print "EventHandler.notify(", event, "): calling update_viewer for ", observer + print("EventHandler.notify(", event, "): calling update_viewer for ", observer) try: observer.update_viewer(event, *args) - except Exception, e: - print "Error while updating observer", observer, type(e), e + except Exception as e: + print("Error while updating observer", observer, type(e), e) def get_labels_on(self): return self.labelsOn @@ -190,10 +190,10 @@ def set_labels_off(self): self.notify('labels off') def is_selected(self, marker): - return self.selected.has_key(marker) + return marker in self.selected def get_selected(self): - return self.selected.keys() + return list(self.selected.keys()) def get_num_selected(self): return len(self.selected) diff --git a/pylocator/gtkutils.py b/pylocator/gtkutils.py index 27ed038..1b36494 100644 --- a/pylocator/gtkutils.py +++ b/pylocator/gtkutils.py @@ -1,9 +1,9 @@ import os, sys -import StringIO, traceback +import io, traceback import gobject, gtk from gtk import gdk -from shared import shared +from .shared import shared import datetime def is_string_like(obj): @@ -15,8 +15,8 @@ def is_string_like(obj): def exception_to_str(s = None): - sh = StringIO.StringIO() - if s is not None: print >>sh, s + sh = io.StringIO() + if s is not None: print(s, file=sh) traceback.print_exc(file=sh) return sh.getvalue() @@ -153,7 +153,7 @@ def __init__(self, defaultDir, okCallback, title='Select file', """wrap some of the file selection boilerplate. okCallback is a function that takes a Dialog_FileSelection instance as a single arg.""" - if shared.debug: print "Dialog_FileSelection.__init__" + if shared.debug: print("Dialog_FileSelection.__init__") self.defaultDir = defaultDir self.okCallback = okCallback gtk.FileSelection.__init__(self, title=title) @@ -391,22 +391,22 @@ def get_num_range(minLabel='Min', maxLabel='Max', if response==gtk.RESPONSE_OK: if (as_times): # mcc XXX: what's the magic code word to unfurl an array into a tuple or untupled comma-separated variables? - x= map(int, (entryMin.get_text()).split(':')) + x= list(map(int, (entryMin.get_text()).split(':'))) try: minVal = datetime.time(x[0], x[1], x[2]) except ValueError: msg = exception_to_str('ValueError: minVal not in HH:MM:SS format') - if shared.debug: print "get_num_range (as_times=True): minVal = " , str(minVal) + if shared.debug: print("get_num_range (as_times=True): minVal = " , str(minVal)) else: minVal = str2num_or_err(entryMin.get_text(), labelMin, parent) if minVal is None: continue if (as_times): - x= map(int, (entryMax.get_text()).split(':')) + x= list(map(int, (entryMax.get_text()).split(':'))) try: maxVal = datetime.time(x[0], x[1], x[2]) except ValueError: msg = exception_to_str('ValueError: maxVal not in HH:MM:SS format') - if shared.debug: print "get_num_range (as_times=True): maxVal = " , str(maxVal) + if shared.debug: print("get_num_range (as_times=True): maxVal = " , str(maxVal)) else: maxVal = str2num_or_err(entryMax.get_text(), labelMax, parent) if maxVal is None: continue @@ -454,7 +454,7 @@ def select_name(names, title='Select Name'): response = dlg.run() if response == gtk.RESPONSE_OK: - for button, name in buttond.items(): + for button, name in list(buttond.items()): if button.get_active(): dlg.destroy() return name @@ -616,12 +616,12 @@ def make_float_string(value): try: rv = "%.2f"%float(value) return rv - except Exception, e: + except Exception as e: return str(value) dlg = gtk.Dialog(title) if parent is not None: - print "parent not None:", parent + print("parent not None:", parent) dlg.set_transient_for(parent) vbox = dlg.vbox @@ -764,7 +764,7 @@ def open(self, button): filename = self.fmanager.get_filename(title='Select input file') if filename is not None: try: infile = file(filename, 'r') - except IOError, msg: + except IOError as msg: msg = exception_to_str('Could not open %s' % filename) error_msg(msg, parent=self.parentWin) else: @@ -789,7 +789,7 @@ def save(self, button, **kwargs): try: outfile = file(filename, 'w') - except IOError, msg: + except IOError as msg: msg = exception_to_str('Could not write markers to %s' % filename) error_msg(msg, parent=self.parentWin) return @@ -919,7 +919,7 @@ def save(self, *args): # todo: add csv extension fh = file(filename, 'w', False) for row in self.rows: - print >>fh, ','.join(row) + print(','.join(row), file=fh) fh.close() diff --git a/pylocator/main.py b/pylocator/main.py index a5bddc9..3c43645 100644 --- a/pylocator/main.py +++ b/pylocator/main.py @@ -2,8 +2,8 @@ import gtk import os.path -from controller import PyLocatorController -from shared import shared +from .controller import PyLocatorController +from .shared import shared def run_pylocator(filename=None, surface=None): """main method to run when PyLocator is started""" diff --git a/pylocator/marker_list.py b/pylocator/marker_list.py index 0e02a3a..c1835d2 100644 --- a/pylocator/marker_list.py +++ b/pylocator/marker_list.py @@ -1,14 +1,14 @@ -from __future__ import division + import gobject import gtk -from dialogs import edit_coordinates, edit_label_of_marker +from .dialogs import edit_coordinates, edit_label_of_marker -from events import EventHandler -from colors import choose_one_color, tuple2gdkColor, gdkColor2tuple -from markers import Marker -from list_toolbar import ListToolbar -from shared import shared +from .events import EventHandler +from .colors import choose_one_color, tuple2gdkColor, gdkColor2tuple +from .markers import Marker +from .list_toolbar import ListToolbar +from .shared import shared class MarkerList(gtk.VBox): @@ -238,8 +238,8 @@ def remove_marker(self,marker): self.tree_mrk.remove(treeiter) del self._markers[id_] del self._marker_ids[marker.uuid] - except Exception, e: - print "Exception in MarkerList.remove_marker" + except Exception as e: + print("Exception in MarkerList.remove_marker") finally: self.__update_treeview_visibility() diff --git a/pylocator/marker_window_interactor.py b/pylocator/marker_window_interactor.py index 37fef62..ac343b2 100644 --- a/pylocator/marker_window_interactor.py +++ b/pylocator/marker_window_interactor.py @@ -1,9 +1,9 @@ import gtk import vtk -from render_window import PyLocatorRenderWindow -from events import EventHandler, UndoRegistry -from shared import shared -from dialogs import edit_label_of_marker +from .render_window import PyLocatorRenderWindow +from .events import EventHandler, UndoRegistry +from .shared import shared +from .dialogs import edit_label_of_marker INTERACT_CURSOR, MOVE_CURSOR, COLOR_CURSOR, SELECT_CURSOR, DELETE_CURSOR, LABEL_CURSOR, SCREENSHOT_CURSOR = gtk.gdk.ARROW, gtk.gdk.HAND2, gtk.gdk.SPRAYCAN, gtk.gdk.TCROSS, gtk.gdk.X_CURSOR, gtk.gdk.PENCIL, gtk.gdk.ICON @@ -42,25 +42,25 @@ def update_viewer(self, event, *args): if event.find('mouse1')==0: self.mouse1_mode_change(event) if event=='mouse1 interact': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_interact()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_interact()") self.set_mouse1_to_interact() elif event=='vtk interact': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_vtkinteract()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_vtkinteract()") self.set_mouse1_to_vtkinteract() elif event=='mouse1 color': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_color()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_color()") self.set_mouse1_to_color() elif event=='mouse1 delete': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_delete()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_delete()") self.set_mouse1_to_delete() elif event=='mouse1 label': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_label()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_label()") self.set_mouse1_to_label() elif event=='mouse1 select': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_select()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_select()") self.set_mouse1_to_select() elif event=='mouse1 move': - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_move()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_move()") self.set_mouse1_to_move() def get_marker_at_point(self): @@ -73,11 +73,11 @@ def set_select_mode(self): pass def set_interact_mode(self): - if shared.debug: print "set_interact_mode()!!!!" + if shared.debug: print("set_interact_mode()!!!!") self.vtk_interact_mode = False def set_vtkinteract_mode(self): - if shared.debug: print "set_vtkinteract_mode()!!!!" + if shared.debug: print("set_vtkinteract_mode()!!!!") if (self.vtk_interact_mode == False): # mcc XXX: ignore this @@ -87,7 +87,7 @@ def set_vtkinteract_mode(self): def set_mouse1_to_interact(self): - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_interact()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_interact()") self.vtk_interact_mode = False @@ -105,12 +105,12 @@ def set_mouse1_to_interact(self): self.window.set_cursor (cursor) def vtkinteraction_event(self, *args): - if shared.debug: print "vtkinteraction_event!!!" + if shared.debug: print("vtkinteraction_event!!!") self.Render() def set_mouse1_to_vtkinteract(self): - if shared.debug: print "MarkerWindowInteractor.set_mouse1_to_vtkinteract()" + if shared.debug: print("MarkerWindowInteractor.set_mouse1_to_vtkinteract()") self.set_vtkinteract_mode() @@ -228,14 +228,14 @@ def OnButtonDown(self, wid, event): self.lastCamera = self.get_camera_fpu() m = self.get_pointer() ctrl, shift = self._GetCtrlShift(event) - if shared.debug: print "MarkerWindowInteractor.OnButtonDown(): ctrl=", ctrl,"shift=",shift,"button=",event.button + if shared.debug: print("MarkerWindowInteractor.OnButtonDown(): ctrl=", ctrl,"shift=",shift,"button=",event.button) self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift, chr(0), 0, None) - if shared.debug: print "MarkerWindowInteractor.OnButtonDown(): pressFuncs=", self.pressFuncs, "pressHooks=", self.pressHooks + if shared.debug: print("MarkerWindowInteractor.OnButtonDown(): pressFuncs=", self.pressFuncs, "pressHooks=", self.pressHooks) if event.button in self.interactButtons: - if shared.debug: print "self.vtk_interact_mode =", self.vtk_interact_mode + if shared.debug: print("self.vtk_interact_mode =", self.vtk_interact_mode) if (self.vtk_interact_mode == False): self.pressFuncs[event.button]() @@ -246,13 +246,13 @@ def OnButtonUp(self, wid, event): """Mouse button released.""" m = self.get_pointer() ctrl, shift = self._GetCtrlShift(event) - if shared.debug: print "MarkerWindowInteractor.OnButtonUp(): ctrl=", ctrl,"shift=",shift, "button=",event.button + if shared.debug: print("MarkerWindowInteractor.OnButtonUp(): ctrl=", ctrl,"shift=",shift, "button=",event.button) self._Iren.SetEventInformationFlipY(m[0], m[1], ctrl, shift, chr(0), 0, None) if event.button in self.interactButtons: - if shared.debug: print "self.vtk_interact_mode =", self.vtk_interact_mode + if shared.debug: print("self.vtk_interact_mode =", self.vtk_interact_mode) if (self.vtk_interact_mode == False): self.releaseFuncs[event.button]() diff --git a/pylocator/markers.py b/pylocator/markers.py index 9de6baa..630c9f7 100644 --- a/pylocator/markers.py +++ b/pylocator/markers.py @@ -6,7 +6,7 @@ import numpy as n -from shared import shared +from .shared import shared class Marker(vtk.vtkActor): """ @@ -86,7 +86,7 @@ def set_size(self, s): return self.sphere.SetRadius(s) def set_color(self, color): - if shared.debug: print "Marker.GetProperty().SetColor(", color, ")" + if shared.debug: print("Marker.GetProperty().SetColor(", color, ")") self.GetProperty().SetColor( color ) def get_color(self): @@ -112,7 +112,7 @@ def from_string(s): #todo; use csv module vals = s.replace('"', '').split(',') label = vals[0] - x,y,z,radius,r,g,b = map(float, vals[1:]) + x,y,z,radius,r,g,b = list(map(float, vals[1:])) marker = Marker(xyz=(x,y,z), radius=radius, rgb=(r,g,b)) marker.set_label(label) return marker diff --git a/pylocator/misc/markers_io.py b/pylocator/misc/markers_io.py index 6b42ac9..7b533d6 100644 --- a/pylocator/misc/markers_io.py +++ b/pylocator/misc/markers_io.py @@ -25,7 +25,7 @@ def load_markers_to_dict(fh): if __name__=="__main__": fn = "/media/Extern/public/Experimente/AudioStroop/kombinierte_analyse/elec_pos/443.txt" - print load_markers(fn) + print(load_markers(fn)) fh = open(fn,"r") - print load_markers(fh) + print(load_markers(fh)) diff --git a/pylocator/plane_widgets_observer.py b/pylocator/plane_widgets_observer.py index b6491b2..c32810a 100644 --- a/pylocator/plane_widgets_observer.py +++ b/pylocator/plane_widgets_observer.py @@ -2,14 +2,14 @@ import gtk import vtk import time -from markers import Marker, RingActor -from events import EventHandler, UndoRegistry +from .markers import Marker, RingActor +from .events import EventHandler, UndoRegistry import numpy as np -from marker_window_interactor import MarkerWindowInteractor -from shared import shared -from rois import RoiEdgeActor +from .marker_window_interactor import MarkerWindowInteractor +from .shared import shared +from .rois import RoiEdgeActor INTERACT_CURSOR, MOVE_CURSOR, COLOR_CURSOR, SELECT_CURSOR, DELETE_CURSOR, LABEL_CURSOR, SCREENSHOT_CURSOR = gtk.gdk.ARROW, gtk.gdk.HAND2, gtk.gdk.SPRAYCAN, gtk.gdk.TCROSS, gtk.gdk.X_CURSOR, gtk.gdk.PENCIL, gtk.gdk.ICON @@ -21,7 +21,7 @@ class PlaneWidgetObserver(MarkerWindowInteractor): axes_labels_color = (0.,0.82,1.) def __init__(self, planeWidget, owner, orientation, imageData=None): - if shared.debug: print "PlaneWidgetObserver.__init__(): orientation=",orientation + if shared.debug: print("PlaneWidgetObserver.__init__(): orientation=",orientation) MarkerWindowInteractor.__init__(self) self.interactButtons = (1,2,3) self.pw = planeWidget @@ -44,9 +44,9 @@ def set_image_data(self, imageData): if imageData is None: return self.imageData = imageData if not self.hasData: - if shared.debug: print "PlaneWidgetObserver(", self.orientation,").. AddObserver(self.interaction_event)" + if shared.debug: print("PlaneWidgetObserver(", self.orientation,").. AddObserver(self.interaction_event)") foo = self.pw.AddObserver('InteractionEvent', self.interaction_event) - if shared.debug: print "PlaneWidgetObserver.set_image_data(): AddObserver call returns ", foo + if shared.debug: print("PlaneWidgetObserver.set_image_data(): AddObserver call returns ", foo) self.connect("scroll_event", self.scroll_widget_slice) self.hasData = 1 @@ -88,7 +88,7 @@ def add_axes_labels(self): coords[i/2] = b*1.12 idx_label = 1*i #historical reasons for using this label = labels[idx_label] - if shared.debug: print i,b, coords, label + if shared.debug: print(i,b, coords, label) if self.orientation == 0: if label in ["R","L"]: continue @@ -118,7 +118,7 @@ def add_axes_labels(self): center = self.imageData.GetCenter() spacing = self.imageData.GetSpacing() bounds = np.array(self.imageData.GetBounds()) - if shared.debug: print "***center,spacing,bounds", center,spacing,bounds + if shared.debug: print("***center,spacing,bounds", center,spacing,bounds) pos = [center[0], center[1], center[2]] camera_up = [0,0,0] if self.orientation == 0: @@ -130,9 +130,9 @@ def add_axes_labels(self): elif self.orientation == 2: pos[2] += max((bounds[1::2]-bounds[0::2]))*2 camera_up[0] = -1 - if shared.debug: print camera_up + if shared.debug: print(camera_up) fpu = center, pos, tuple(camera_up) - if shared.debug: print "***fpu2:", fpu + if shared.debug: print("***fpu2:", fpu) self.set_camera(fpu) self.scroll_depth(self.sliceIncrement) @@ -357,7 +357,7 @@ def update_rings(self): textActor.VisibilityOff() def update_rois(self): - for actor in self.roi_actors.values(): + for actor in list(self.roi_actors.values()): actor.update() def interaction_event(self, *args): @@ -486,12 +486,12 @@ def label_ring_actor(self, marker, label): textActor.SetMapper(textMapper) def get_actor_for_marker(self, marker): - if self.ringActors.has_key(marker.uuid): + if marker.uuid in self.ringActors: return self.ringActors[marker.uuid] return None def get_ring_actors_as_list(self): - return self.ringActors.values() + return list(self.ringActors.values()) def get_cursor_position_world(self): x, y = self.GetEventPosition() diff --git a/pylocator/plane_widgets_observer_toolbar.py b/pylocator/plane_widgets_observer_toolbar.py index 381ce2f..b2db323 100644 --- a/pylocator/plane_widgets_observer_toolbar.py +++ b/pylocator/plane_widgets_observer_toolbar.py @@ -1,7 +1,7 @@ import gtk -from gtkutils import error_msg +from .gtkutils import error_msg import vtk -from events import EventHandler +from .events import EventHandler def move_pw_to_point(pw, xyz): diff --git a/pylocator/plane_widgets_xyz.py b/pylocator/plane_widgets_xyz.py index 2718764..71930ea 100644 --- a/pylocator/plane_widgets_xyz.py +++ b/pylocator/plane_widgets_xyz.py @@ -1,11 +1,11 @@ import vtk -from events import EventHandler, UndoRegistry -from render_window import ThreeDimRenderWindow -from marker_window_interactor import MarkerWindowInteractor +from .events import EventHandler, UndoRegistry +from .render_window import ThreeDimRenderWindow +from .marker_window_interactor import MarkerWindowInteractor import numpy as np -from shared import shared +from .shared import shared def move_pw_to_point(pw, xyz): @@ -38,7 +38,7 @@ def __init__(self, imageData=None): MarkerWindowInteractor.__init__(self) ThreeDimRenderWindow.__init__(self) - if shared.debug: print "PlaneWidgetsXYZ.__init__()" + if shared.debug: print("PlaneWidgetsXYZ.__init__()") self.vtksurface = None @@ -86,11 +86,11 @@ def rotate_vtk(self, axis, value): self.Render() def set_image_data(self, imageData): - if shared.debug: print "PlaneWidgetsXYZ.set_image_data()!!" + if shared.debug: print("PlaneWidgetsXYZ.set_image_data()!!") if imageData is None: return self.imageData = imageData extent = self.imageData.GetBounds()#Extent() - if shared.debug: print "***Extent:", extent + if shared.debug: print("***Extent:", extent) frac = 0.3 self._plane_widget_boilerplate( @@ -133,7 +133,7 @@ def add_axes_labels(self): #Correction for negative spacings idx_label = 1*i label = labels[idx_label] - if shared.debug: print i,b, coords, label + if shared.debug: print(i,b, coords, label) #Orientation should be correct due to reading affine in vtkNifti text = vtk.vtkVectorText() text.SetText(label) @@ -153,16 +153,16 @@ def add_axes_labels(self): center = self.imageData.GetCenter() spacing = self.imageData.GetSpacing() bounds = np.array(self.imageData.GetBounds()) - if shared.debug: print "***center,spacing,bounds", center,spacing,bounds + if shared.debug: print("***center,spacing,bounds", center,spacing,bounds) #idx_left = labels.index("L") pos = [center[0], center[1], center[2]] pos[0] += max((bounds[1::2]-bounds[0::2]))*2 #idx_sup = labels.index("S") camera_up = [0,0,0] camera_up[2] = 1 - if shared.debug: print camera_up + if shared.debug: print(camera_up) fpu = center, pos, tuple(camera_up) - if shared.debug: print "***fpu2:", fpu + if shared.debug: print("***fpu2:", fpu) self.set_camera(fpu) def get_marker_at_point(self): @@ -182,7 +182,7 @@ def update_viewer(self, event, *args): marker, label = args marker.set_label(label) - if shared.debug: print "Create VTK-Text", marker.get_label() + if shared.debug: print("Create VTK-Text", marker.get_label()) text = vtk.vtkVectorText() text.SetText(marker.get_label()) textMapper = vtk.vtkPolyDataMapper() @@ -200,7 +200,7 @@ def update_viewer(self, event, *args): x,y,z = marker.get_center() textActor.SetPosition(x+size, y+size, z+size) - if self.boxes.has_key(marker): + if marker in self.boxes: selectActor = self.boxes[marker] boxSource = vtk.vtkCubeSource() boxSource.SetBounds(marker.GetBounds()) @@ -209,11 +209,11 @@ def update_viewer(self, event, *args): selectActor.SetMapper(mapper) elif event=='labels on': - actors = self.textActors.values() + actors = list(self.textActors.values()) for actor in actors: actor.VisibilityOn() elif event=='labels off': - actors = self.textActors.values() + actors = list(self.textActors.values()) for actor in actors: actor.VisibilityOff() #elif event=='select marker': @@ -238,18 +238,18 @@ def update_viewer(self, event, *args): def _plane_widget_boilerplate(self, pw, key, color, index, orientation): - if shared.debug: print "PlaneWidgetsXYZ._plane_widget_boilerplate(", index , orientation,")" + if shared.debug: print("PlaneWidgetsXYZ._plane_widget_boilerplate(", index , orientation,")") pw.TextureInterpolateOn() #pw.SetResliceInterpolateToCubic() pw.SetKeyPressActivationValue(key) - if shared.debug: print "pw " , orientation, ".SetPicker(self.sharedPicker)" + if shared.debug: print("pw " , orientation, ".SetPicker(self.sharedPicker)") pw.SetPicker(self.sharedPicker) pw.GetPlaneProperty().SetColor(color) pw.DisplayTextOn() pw.SetInput(self.imageData) pw.SetPlaneOrientation(orientation) pw.SetSliceIndex(int(index)) - if shared.debug: print "pw " , orientation, ".SetInteractor(self.interactor)" + if shared.debug: print("pw " , orientation, ".SetInteractor(self.interactor)") pw.SetInteractor(self.interactor) pw.On() pw.UpdatePlacement() @@ -299,22 +299,22 @@ def set_interact_mode(self): def OnButtonDown(self, wid, event): """Mouse button pressed.""" - if shared.debug: print "PlaneWidgetsXYZ.OnButtonDown(): event=", event + if shared.debug: print("PlaneWidgetsXYZ.OnButtonDown(): event=", event) self.lastPntsXYZ = ( self.get_plane_points(self.pwX), self.get_plane_points(self.pwY), self.get_plane_points(self.pwZ)) - if shared.debug: print "PlaneWidgetsXYZ.OnButtonDown(): self.lastPntsXYZ=", self.lastPntsXYZ + if shared.debug: print("PlaneWidgetsXYZ.OnButtonDown(): self.lastPntsXYZ=", self.lastPntsXYZ) MarkerWindowInteractor.OnButtonDown(self, wid, event) - if shared.debug: print self.axes_labels + if shared.debug: print(self.axes_labels) return True def OnButtonUp(self, wid, event): """Mouse button released.""" - if shared.debug: print "PlaneWidgetsXYZ.OnButtonUp(): event=", event + if shared.debug: print("PlaneWidgetsXYZ.OnButtonUp(): event=", event) if not hasattr(self, 'lastPntsXYZ'): return MarkerWindowInteractor.OnButtonUp(self, wid, event) diff --git a/pylocator/render_window.py b/pylocator/render_window.py index b9ba9f7..123e983 100644 --- a/pylocator/render_window.py +++ b/pylocator/render_window.py @@ -1,11 +1,11 @@ import gtk import vtk -from GtkGLExtVTKRenderWindowInteractor import GtkGLExtVTKRenderWindowInteractor -from events import EventHandler -from gtkutils import error_msg -from vtkutils import create_box_actor_around_marker +from .GtkGLExtVTKRenderWindowInteractor import GtkGLExtVTKRenderWindowInteractor +from .events import EventHandler +from .gtkutils import error_msg +from .vtkutils import create_box_actor_around_marker -from shared import shared +from .shared import shared INTERACT_CURSOR, MOVE_CURSOR, COLOR_CURSOR, SELECT_CURSOR, DELETE_CURSOR, LABEL_CURSOR, SCREENSHOT_CURSOR = gtk.gdk.ARROW, gtk.gdk.HAND2, gtk.gdk.SPRAYCAN, gtk.gdk.TCROSS, gtk.gdk.X_CURSOR, gtk.gdk.PENCIL, gtk.gdk.ICON @@ -127,7 +127,7 @@ def change_roi_opacity(self, uuid, opactiy): pass def _get_roi_actor(self, uuid): - if not self.roi_actors.has_key(uuid): + if uuid not in self.roi_actors: return return self.roi_actors[uuid] @@ -208,10 +208,10 @@ def add_marker(self, marker): textActor.SetCamera(self.camera) textActor.GetProperty().SetColor(marker.get_label_color()) if EventHandler().get_labels_on(): - if shared.debug: print "VisibilityOn" + if shared.debug: print("VisibilityOn") textActor.VisibilityOn() else: - if shared.debug: print "VisibilityOff" + if shared.debug: print("VisibilityOff") textActor.VisibilityOff() self.textActors[marker] = textActor self.renderer.AddActor(textActor) @@ -227,7 +227,7 @@ def remove_marker(self, marker): def set_marker_selection(self, marker, select=True): if select: actor = create_box_actor_around_marker(marker) - if shared.debug: print "PlaneWidgetsXYZ.update_viewer(): self.renderer.AddActor(actor)" + if shared.debug: print("PlaneWidgetsXYZ.update_viewer(): self.renderer.AddActor(actor)") self.renderer.AddActor(actor) self.boxes[marker] = actor else: diff --git a/pylocator/roi_renderer_props.py b/pylocator/roi_renderer_props.py index 0f1d666..96c204d 100644 --- a/pylocator/roi_renderer_props.py +++ b/pylocator/roi_renderer_props.py @@ -1,18 +1,18 @@ -from __future__ import division + import os.path import gobject import gtk -from gtkutils import error_msg, ButtonAltLabel +from .gtkutils import error_msg, ButtonAltLabel -from events import EventHandler -from shared import shared +from .events import EventHandler +from .shared import shared -from surf_params import SurfParams +from .surf_params import SurfParams -from list_toolbar import ListToolbar -from colors import ColorChooser -from vtkNifti import vtkNiftiImageReader -from rois import RoiParams +from .list_toolbar import ListToolbar +from .colors import ColorChooser +from .vtkNifti import vtkNiftiImageReader +from .rois import RoiParams class RoiRendererProps(gtk.VBox): SCROLLBARSIZE = 150,20 @@ -180,12 +180,12 @@ def treev_sel_changed(self,selection): roi_id = self.tree_roi.get(treeiter,0) try: self.color_chooser._set_color(self.paramd[roi_id].color) - except Exception, e: - print "During setting color of color chooser:", type(e),e + except Exception as e: + print("During setting color of color chooser:", type(e),e) try: self.scrollbar_opacity.set_value(self.paramd[roi_id].opacity) - except Exception, e: - print "During setting value of opacity scrollbar:", type(e),e + except Exception as e: + print("During setting value of opacity scrollbar:", type(e),e) else: self.props_frame.hide() diff --git a/pylocator/rois.py b/pylocator/rois.py index cb2726f..3178ee1 100644 --- a/pylocator/rois.py +++ b/pylocator/rois.py @@ -1,7 +1,7 @@ -from __future__ import division + import vtk -from events import EventHandler -from surf_params import SurfParams +from .events import EventHandler +from .surf_params import SurfParams class RoiParams(SurfParams): diff --git a/pylocator/screenshot_props.py b/pylocator/screenshot_props.py index b22bf76..60d87bc 100644 --- a/pylocator/screenshot_props.py +++ b/pylocator/screenshot_props.py @@ -1,7 +1,7 @@ import gtk -from gtkutils import error_msg -from resources import camera_small_fn -from shared import shared +from .gtkutils import error_msg +from .resources import camera_small_fn +from .shared import shared INTERACT_CURSOR, MOVE_CURSOR, COLOR_CURSOR, SELECT_CURSOR, DELETE_CURSOR, LABEL_CURSOR, SCREENSHOT_CURSOR = gtk.gdk.ARROW, gtk.gdk.HAND2, gtk.gdk.SPRAYCAN, gtk.gdk.TCROSS, gtk.gdk.X_CURSOR, gtk.gdk.PENCIL, gtk.gdk.ICON diff --git a/pylocator/surf_params.py b/pylocator/surf_params.py index 6bc9bfa..4b45d98 100644 --- a/pylocator/surf_params.py +++ b/pylocator/surf_params.py @@ -1,12 +1,12 @@ -from __future__ import division + import uuid import vtk import gtk -from gtkutils import ProgressBarDialog -from events import EventHandler -from connect_filter import ConnectFilter -from decimate_filter import DecimateFilter -from colors import colorSeq, gdkColor2tuple +from .gtkutils import ProgressBarDialog +from .events import EventHandler +from .connect_filter import ConnectFilter +from .decimate_filter import DecimateFilter +from .colors import colorSeq, gdkColor2tuple class SurfParams(object): label = "Surface" diff --git a/pylocator/surf_renderer.py b/pylocator/surf_renderer.py index 16bb06b..2c33f05 100644 --- a/pylocator/surf_renderer.py +++ b/pylocator/surf_renderer.py @@ -1,12 +1,12 @@ -from __future__ import division + import vtk import gtk -from gtkutils import error_msg +from .gtkutils import error_msg -from events import EventHandler -from markers import Marker -from shared import shared -from render_window import PyLocatorRenderWindow, ThreeDimRenderWindow +from .events import EventHandler +from .markers import Marker +from .shared import shared +from .render_window import PyLocatorRenderWindow, ThreeDimRenderWindow class SurfRenderWindow(ThreeDimRenderWindow, PyLocatorRenderWindow): picker_id = None @@ -30,11 +30,11 @@ def set_image_data(self, imageData): def set_labels_visibility(self, visible=True): if visible: - actors = self.textActors.values() + actors = list(self.textActors.values()) for actor in actors: actor.VisibilityOn() else: - actors = self.textActors.values() + actors = list(self.textActors.values()) for actor in actors: actor.VisibilityOff() @@ -66,7 +66,7 @@ def change_surface_opacity(self, uuid, opacity): actor.GetProperty().SetOpacity(opacity) def __get_surface_actor(self, uuid): - if not self.surface_actors.has_key(uuid): + if uuid not in self.surface_actors: return return self.surface_actors[uuid] @@ -77,7 +77,7 @@ def update_viewer(self, event, *args): self.Render() def key_press(self, interactor, event): - if shared.debug: print "key press event in SurfRenderWindow" + if shared.debug: print("key press event in SurfRenderWindow") key = interactor.GetKeySym() sas = self.surface_actors @@ -92,7 +92,7 @@ def checkPickerId(): if key.lower()=='i': if not checkPickerId(): return - if shared.debug: print "Inserting Marker" + if shared.debug: print("Inserting Marker") x,y = interactor.GetEventPosition() picker = vtk.vtkCellPicker() picker.PickFromListOn() @@ -124,6 +124,6 @@ def checkPickerId(): if cellId==-1: pass else: - o = self.paramd.values()[0] + o = list(self.paramd.values())[0] o.remove.RemoveCell(cellId) interactor.Render() diff --git a/pylocator/surf_renderer_props.py b/pylocator/surf_renderer_props.py index 265c81b..8a29660 100644 --- a/pylocator/surf_renderer_props.py +++ b/pylocator/surf_renderer_props.py @@ -1,20 +1,20 @@ -from __future__ import division + import gobject import gtk -from gtkutils import error_msg, ButtonAltLabel -from dialogs import edit_label +from .gtkutils import error_msg, ButtonAltLabel +from .dialogs import edit_label -from events import EventHandler +from .events import EventHandler -from colors import ColorChooserWithPredefinedColors, colorSeq +from .colors import ColorChooserWithPredefinedColors, colorSeq -from list_toolbar import ListToolbar -from surf_params import SurfParams +from .list_toolbar import ListToolbar +from .surf_params import SurfParams -from decimate_filter import DecimateFilter -from connect_filter import ConnectFilter +from .decimate_filter import DecimateFilter +from .connect_filter import ConnectFilter class SurfRendererProps(gtk.VBox): SCROLLBARSIZE = 150,20 @@ -198,7 +198,7 @@ def connect_toggled(button): def set_connect_mode(id_): if self.paramd[id_].useConnect: - for num in self.connectExtractButtons.keys(): + for num in list(self.connectExtractButtons.keys()): bt = self.connectExtractButtons[num] if bt.get_active(): self.paramd[id_].connect.mode = num @@ -234,11 +234,11 @@ def apply_(*args): self.vboxPipeline = vbox - decattrs = DecimateFilter.labels.keys() + decattrs = list(DecimateFilter.labels.keys()) decattrs.sort() self.decattrs = decattrs - names = self.paramd.keys() + names = list(self.paramd.keys()) names.sort() # Filter selection @@ -265,7 +265,7 @@ def apply_(*args): vboxFrame = gtk.VBox() vboxFrame.set_spacing(3) frameConnectFilter.add(vboxFrame) - extractModes = ConnectFilter.num2mode.items() + extractModes = list(ConnectFilter.num2mode.items()) extractModes.sort() lastButton = None self.connectExtractButtons = {} @@ -410,7 +410,7 @@ def treev_sel_changed(self, selection): is_picker_surface = param.uuid==self.picker_surface_id self.pickerButton.set_active(is_picker_surface) self.pickerButton.set_sensitive(not is_picker_surface) - except Exception, e: + except Exception as e: "During reacting to treeview selection change:", type(e), e finally: self.ignore_settings_updates = False diff --git a/pylocator/vtkNifti.py b/pylocator/vtkNifti.py index 478fae2..43549c3 100644 --- a/pylocator/vtkNifti.py +++ b/pylocator/vtkNifti.py @@ -2,8 +2,8 @@ #from numpy import oldnumeric as Numeric import numpy as np import vtk -from shared import shared -from vtkutils import array_to_vtkmatrix4x4 +from .shared import shared +from .vtkutils import array_to_vtkmatrix4x4 #from vtk.util.vtkImageImportFromArray import vtkImageImportFromArray @@ -22,9 +22,9 @@ def SetFileName(self, filename): self.__filename=filename def Update(self): - if shared.debug: print "Loading ", self.__filename + if shared.debug: print("Loading ", self.__filename) self.__nim=load(self.__filename) - if shared.debug: print self.__nim + if shared.debug: print(self.__nim) self.__data=self.__nim.get_data().astype("f").swapaxes(0,2) #self.__vtkimport.SetDataExtent(0,self.__data.shape[2]-1,0,self.__data.shape[1]-1,0,self.__data.shape[0]-1) self.__vtkimport.SetWholeExtent(0,self.__data.shape[2]-1,0,self.__data.shape[1]-1,0,self.__data.shape[0]-1) @@ -32,7 +32,7 @@ def Update(self): voxdim = self.__nim.get_header()['pixdim'][:3].copy() #Export data as string self.__data_string = self.__data.tostring() - if shared.debug: print voxdim + if shared.debug: print(voxdim) self.__vtkimport.SetDataSpacing((1.,1.,1.))#to reverse: [::-1] self.__vtkimport.CopyImportVoidPointer(self.__data_string,len(self.__data_string)) self.__vtkimport.UpdateWholeExtent() @@ -51,9 +51,9 @@ def Update(self): affine = array_to_vtkmatrix4x4(self.__nim.get_affine()) - if shared.debug: print self._irs.GetResliceAxesOrigin() + if shared.debug: print(self._irs.GetResliceAxesOrigin()) self._irs.SetResliceAxes(affine) - if shared.debug: print self._irs.GetResliceAxesOrigin() + if shared.debug: print(self._irs.GetResliceAxesOrigin()) m2t = vtk.vtkMatrixToLinearTransform() m2t.SetInput(affine.Invert()) self._irs.TransformInputSamplingOff() @@ -62,9 +62,9 @@ def Update(self): #print self.__vtkimport.GetOutput().GetBounds() #print self._irs.GetOutput().GetBounds() - if shared.debug: print voxdim, self._irs.GetOutputSpacing() + if shared.debug: print(voxdim, self._irs.GetOutputSpacing()) self._irs.SetOutputSpacing(abs(voxdim)) - if shared.debug: print self._irs.GetOutputSpacing() + if shared.debug: print(self._irs.GetOutputSpacing()) #print self._irs.GetOutputOrigin() #self._irs.SetOutputOrigin((0,0,0)) # print self._irs.GetOutputOrigin() @@ -90,7 +90,7 @@ def GetDepth(self): return self._irs.GetOutput().GetBouds()[4:] def GetDataSpacing(self): - if shared.debug: print self.__spacing, "*******************" + if shared.debug: print(self.__spacing, "*******************") return self._irs.GetOutput().GetSpacing() def GetOutput(self): @@ -100,7 +100,7 @@ def GetOutput(self): return self._irs.GetOutput() def GetFilename(self): - if shared.debug: print self.__filename + if shared.debug: print(self.__filename) return self.__filename def GetDataExtent(self): @@ -140,5 +140,5 @@ def median(self): reader = vtkNiftiImageReader() reader.SetFileName("/home/thorsten/Dokumente/pylocator-examples/Can7/mri/post2std_brain.nii.gz") reader.Update() - print reader._irs - print reader.GetOutput() + print(reader._irs) + print(reader.GetOutput()) diff --git a/pylocator/vtksurface.py b/pylocator/vtksurface.py index 0019100..85c7c18 100644 --- a/pylocator/vtksurface.py +++ b/pylocator/vtksurface.py @@ -1,6 +1,6 @@ import vtk -from events import EventHandler -from vtkutils import vtkmatrix4x4_to_array, array_to_vtkmatrix4x4 +from .events import EventHandler +from .vtkutils import vtkmatrix4x4_to_array, array_to_vtkmatrix4x4 class VTKSurface(vtk.vtkActor): """ @@ -9,7 +9,7 @@ class VTKSurface(vtk.vtkActor): """ def set_matrix(self, registration_mat): - print "VTKSurface.set_matrix(", registration_mat, ")!!" + print("VTKSurface.set_matrix(", registration_mat, ")!!") #print "calling SetUserMatrix(", array_to_vtkmatrix4x4(registration_mat) , ")" mat = array_to_vtkmatrix4x4(registration_mat) @@ -18,7 +18,7 @@ def set_matrix(self, registration_mat): mat2xform = vtk.vtkMatrixToLinearTransform() mat2xform.SetInput(mat) - print "calling SetUserTransform(", mat2xform, ")" + print("calling SetUserTransform(", mat2xform, ")") self.SetUserTransform(mat2xform) # see vtk Prop3d docs self.Modified() # how do we like update the render tree or somethin.. @@ -126,7 +126,7 @@ def __init__(self, filename, renderer): renderer.AddActor(self.contours) # XXX: mcc will this work?!? - print "PlaneWidgetsXYZ.set_image_data: setting EventHandler.set_vtkactor(self.contours)!" + print("PlaneWidgetsXYZ.set_image_data: setting EventHandler.set_vtkactor(self.contours)!") EventHandler().set_vtkactor(self.contours) #writer = vtk.vtkSTLWriter() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e5209be --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[tool.poetry] +name = "pylocator" +version = "1.0.0" +description = "EEG electrode localisation in MRI/CT volumes" +authors = ["Thorsten Kranz"] +license = "BSD-2-Clause" + +[tool.poetry.dependencies] +python = "^3.11" +numpy = "^1.26" +nibabel = "^5.2" +vtk = "^9.3" +PySide6 = "^6.6" + +[tool.poetry.group.dev.dependencies] +pytest = "^8.1" + +[build-system] +requires = ["poetry-core>=1.7.0"] +build-backend = "poetry.core.masonry.api" diff --git a/setupegg.py b/setupegg.py index 201cf75..9bbb75e 100755 --- a/setupegg.py +++ b/setupegg.py @@ -28,7 +28,7 @@ class ZipHelp(Command): def run(self): if not os.path.exists(DOC_BUILD_DIR): - raise OSError, 'Doc directory does not exist.' + raise OSError('Doc directory does not exist.') target_file = os.path.join('doc', 'documentation.zip') # ZIP_DEFLATED actually compresses the archive. However, there # will be a RuntimeError if zlib is not installed, so we check @@ -67,7 +67,7 @@ def finalize_options(self): if __name__ == '__main__': - execfile('setup.py', dict(__name__='__main__', + exec(compile(open('setup.py', "rb").read(), 'setup.py', 'exec'), dict(__name__='__main__', extra_setuptools_args=extra_setuptools_args))