Skip to content
Snippets Groups Projects
Commit 3564b562 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

Important object _inits_ and _dels_ are logged to a custom log

level.
parent 1bf2b385
No related branches found
No related tags found
No related merge requests found
......@@ -59,28 +59,41 @@ import argparse
import subprocess
log = logging.getLogger(__name__)
# make matplotlib quiet
warnings.filterwarnings('ignore', module='matplotlib')
warnings.filterwarnings('ignore', module='mpl_toolkits')
# My own custom logging level for tracing memory related events
logging.MEMORY = 15
def logmemory(self, message, *args, **kwargs):
if self.isEnabledFor(logging.MEMORY):
self._log(logging.MEMORY, message, args, **kwargs)
logging.Logger.memory = logmemory
logging.addLevelName(logging.MEMORY, 'MEMORY')
# There's a bug in OpenGL.GL.shaders (which has been fixed in
# the latest version) - it calls logging.basicConfig(), and
# thus screws up our own logging. We overcome this by configuring
# the root logger before OpenGL.GL.shaders is imported (which
# occurs when fsl.fslview.gl.slicecanvas.SliceCanvas is imported).
logging.basicConfig(
format='%(levelname)8.8s '
'%(filename)20.20s '
'%(lineno)4d: '
'%(funcName)-15.15s - '
'%(message)s')
logFormatter = logging.Formatter('%(levelname)8.8s '
'%(filename)20.20s '
'%(lineno)4d: '
'%(funcName)-15.15s - '
'%(message)s')
logHandler = logging.StreamHandler()
logHandler.setFormatter(logFormatter)
log = logging.getLogger('fsl')
log.addHandler(logHandler)
import fsl.tools as tools
......@@ -176,6 +189,10 @@ def parseArgs(argv, allTools):
parser.add_argument(
'-n', '--noisy', metavar='MODULE', action='append',
help='Make the specified module noisy')
parser.add_argument(
'-m', '--memory', action='store_true',
help='Output memory events (implied if -v is set)')
parser.add_argument(
'-w', '--wxinspect', action='store_true',
......@@ -242,12 +259,23 @@ def parseArgs(argv, allTools):
# Configure any logging verbosity
# settings specified by the user
if namespace.verbose is None:
if namespace.memory:
class MemFilter(object):
def filter(self, record):
if record.levelno == logging.MEMORY: return 1
else: return 0
log.setLevel(logging.MEMORY)
log.handlers[0].addFilter(MemFilter())
log.memory('Added filter for MEMORY messages')
if namespace.verbose == 1:
log.setLevel(logging.DEBUG)
# make some noisy things quiet
logging.getLogger('fsl.fslview.gl') .setLevel(logging.WARNING)
logging.getLogger('fsl.fslview.views').setLevel(logging.WARNING)
logging.getLogger('fsl.fslview.gl') .setLevel(logging.MEMORY)
logging.getLogger('fsl.fslview.views').setLevel(logging.MEMORY)
logging.getLogger('props') .setLevel(logging.WARNING)
logging.getLogger('pwidgets') .setLevel(logging.WARNING)
elif namespace.verbose == 2:
......
......@@ -168,6 +168,12 @@ class Image(props.HasProperties):
if len(self.shape) < 3 or len(self.shape) > 4:
raise RuntimeError('Only 3D or 4D images are supported')
log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
def __del__(self):
log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
def loadData(self):
"""Loads the image data from the file. This method only needs to
......
......@@ -5,9 +5,15 @@
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
import logging
import os.path as op
import numpy as np
log = logging.getLogger(__name__)
ALLOWED_EXTENSIONS = ['.vtk']
EXTENSION_DESCRIPTIONS = ['VTK polygon model file']
......@@ -78,6 +84,12 @@ class Model(object):
self.vertices = np.array(data, dtype=np.float32)
self.indices = indices
log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
def __del__(self):
log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
def __repr__(self):
return '{}({}, {})'.format(type(self).__name__,
......
......@@ -47,6 +47,12 @@ class DisplayOpts(props.SyncableHasProperties):
self.overlayType = display.overlayType
self.name = '{}_{}'.format(type(self).__name__, id(self))
log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
def __del__(self):
log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
def destroy(self):
"""If overridden, this method should be called by the subclass
......@@ -200,7 +206,12 @@ class Display(props.SyncableHasProperties):
self.__displayOpts = None
self.__overlayTypeChanged()
log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
def __del__(self):
log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
def destroy(self):
"""This method should be called when this ``Display`` instance
......
......@@ -12,6 +12,7 @@ mappings between overlay objects and their corresponding OpenGL
representation.
"""
import logging
import numpy as np
......@@ -19,6 +20,9 @@ import routines as glroutines
import fsl.utils.transform as transform
log = logging.getLogger(__name__)
def createGLObject(overlay, display):
"""Create :class:`GLObject` instance for the given overlay, as specified
by the :attr:`.Display.overlayType` property.
......@@ -73,7 +77,7 @@ class GLObject(object):
self.zax = 2
self.__updateListeners = {}
def addUpdateListener(self, name, listener):
"""Adds a listener function which will be called whenever this
......@@ -225,6 +229,12 @@ class GLImageObject(GLObject):
self.display = display
self.displayOpts = display.getDisplayOpts()
log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
def __del__(self):
log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
def destroy(self):
"""If this method is overridden, it should be called by the subclass
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment