.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/volumeMeasures.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_volumeMeasures.py: Measurements on a volume ------------------------ Complete example with a specific graphical interface that embeds an Anatomist window and a matplotlib widget. Shows a 4D volume and a curve of the values in a selected voxel or the mean of values in a selected region. .. GENERATED FROM PYTHON SOURCE LINES 41-268 .. code-block:: default from __future__ import absolute_import import sys import os import weakref import gc import operator import anatomist.direct.api as anatomist from soma.qt_gui.qt_backend.QtCore import Qt, QPoint from soma.qt_gui.qt_backend.QtGui import QSplitter, QListWidget, QTextEdit, \ QApplication from soma import aims from soma.qt_gui import qt_backend import six from six.moves import zip from functools import reduce qt_backend.init_matplotlib_backend() import matplotlib import numpy import pylab FigureCanvas = qt_backend.FigureCanvas from matplotlib.figure import Figure class MeasuresWindow(QSplitter): def __init__(self, fileName, roiIterator=None, parent=None, anatomistInstance=None): QSplitter.__init__(self, Qt.Horizontal, parent) if anatomistInstance is None: # initialize Anatomist self.anatomist = anatomist.Anatomist() else: self.anatomist = anatomistInstance # open an axial window self.aWindow = self.anatomist.createWindow( 'Axial', no_decoration=True) self.aWindow.setParent(self) if roiIterator is not None: self.roiList = QListWidget(self) self.maskIterators = [] # Iterate on each region while roiIterator.isValid(): self.roiList.addItem(roiIterator.regionName()) maskIterator = roiIterator.maskIterator().get() maskIterator.bucket = None self.maskIterators.append(maskIterator) next(roiIterator) self.selectedBucket = None self.roiList.currentRowChanged.connect(self.regionSelected) else: self.roiList = None self.infoSplitter = QSplitter(Qt.Vertical, self) self.info = QTextEdit(self.infoSplitter) self.info.setReadOnly(True) self.matplotFigure = Figure() self.matplotAxes = self.matplotFigure.add_subplot(111) # We want the axes cleared every time plot() is called self.matplotAxes.hold(False) self.matplotCanvas = FigureCanvas(self.matplotFigure) self.matplotCanvas.setParent(self.infoSplitter) self.matplotCanvas.updateGeometry() self.anatomist.onCursorNotifier.add(self.clicked2) self.resize(800, 600) # Read the image dir, base = os.path.split(fileName) if dir: self.setWindowTitle(base + ' (' + dir + ')') else: self.setWindowTitle(base) # load any volume as a aims.Volume_* object self.volume = aims.read(fileName) self.interpolator = aims.aims.getLinearInterpolator(self.volume).get() # convert the carto volume to Anatomist API avol = self.anatomist.toAObject(self.volume) avol.releaseAppRef() # put volume in window self.aWindow.addObjects(avol) self._ignoreClicked = False voxelSize = self.volume.header()['voxel_size'] tmp = self.volume.header()['volume_dimension'] volumeSize = [int(i) for i in tmp] volumeCenter = [v * s / 2 for v, s in zip(volumeSize, voxelSize)] self.clicked(volumeCenter) infoHeight = self.info.sizeHint().height() self.infoSplitter.setSizes([infoHeight, self.height() - infoHeight]) def clicked2(self, eventName, eventParameters): self.clicked(eventParameters['position'], eventParameters['window']) def clicked(self, posMM, aWindow=None): posMM = [float(i) for i in posMM] if self._ignoreClicked: return text = '\n' text += 'Coordinate millimeters: %.2f, %.2f, %.2f, %.2f' % tuple( posMM) + '
\n' voxelSize = self.volume.header()['voxel_size'] posVoxel = [int(round(i / j)) for i, j in zip(posMM, voxelSize)] text += 'Coordinate voxels: %d, %d, %d, %d' % tuple( posVoxel) + '
\n' tmp = self.volume.header()['volume_dimension'] volumeSize = [int(i) for i in tmp] if not [None for i in posVoxel if i < 0] and \ not [None for i, j in zip(posVoxel, volumeSize) if i >= j]: text += 'Voxel value: ' + \ str(self.volume.value(*posVoxel)) + '
\n' if volumeSize[3] > 1: indices = numpy.arange(volumeSize[3]) # Extract values as numarray structure values = self.interpolator.values(posVoxel[0] * voxelSize[0], posVoxel[1] * voxelSize[1], posVoxel[2] * voxelSize[2]) self.matplotAxes.plot(indices, numpy.array(values)) self.matplotCanvas.draw() text += '' self.info.setText(text) def regionSelected(self): index = self.roiList.currentRow() if index >= 0: text = '\n' text += '

' + \ six.text_type(self.roiList.item(index).text()) + '

\n' maskIterator = self.maskIterators[index] if maskIterator.bucket is None: roiCenter = aims.Point3df(0, 0, 0) bucket = aims.BucketMap_VOID() bucket.setSizeXYZT( *list(maskIterator.voxelSize().items()) + (1,)) maskIterator.restart() valid = 0 invalid = 0 sum = None # Iterate on each point of a region while maskIterator.isValid(): bucket[0][maskIterator.value()] = 1 p = maskIterator.valueMillimeters() roiCenter += p # Check if the point is in the image limit if self.interpolator.isValid(p): values = self.interpolator.values(p) if sum is None: sum = values else: sum = [s + v for s, v in zip(sum, values)] valid += 1 else: invalid += 1 next(maskIterator) text += 'valid points: ' + str(valid) + '
\n' text += 'invalid points: ' + str(invalid) + '
\n' if valid: means = [s / float(valid) for s in sum] mean = reduce(operator.add, means) / len(means) else: means = [] mean = 'N/A' text += 'mean: ' + str(mean) + '
\n' text += '' maskIterator.text = text # convert the BucketMap to Anatomist API maskIterator.bucket = self.anatomist.toAObject(bucket) maskIterator.bucket.releaseAppRef() maskIterator.bucket.setName( str(self.roiList.item(index).text())) maskIterator.bucket.setChanged() count = valid + invalid if count: maskIterator.roiCenter = [ c / count for c in roiCenter.items()] else: maskIterator.roiCenter = None maskIterator.means = means # put bucket in window self.info.setText(maskIterator.text) self.aWindow.addObjects([maskIterator.bucket]) # Set selected color to bucket maskIterator.bucket.setMaterial(self.anatomist.Material( diffuse=[1, 0, 0, 0.5], lighting=0, face_culling=1, )) # Set unselected color to previously selected bucket if self.selectedBucket is not None: self.selectedBucket.setMaterial( self.anatomist.Material(diffuse=[0, 0.8, 0.8, 0.8])) self.selectedBucket = maskIterator.bucket if maskIterator.roiCenter is not None: self._ignoreClicked = True self.aWindow.moveLinkedCursor(maskIterator.roiCenter) self._ignoreClicked = False if len(maskIterator.means) > 1: indices = numpy.arange(len(maskIterator.means)) self.matplotAxes.plot( indices, numpy.array(maskIterator.means)) self.matplotCanvas.draw() if __name__ == '__main__': qApp = QApplication(sys.argv) if len(sys.argv) == 3: roiIterator = aims.aims.getRoiIterator(sys.argv[2]).get() w = MeasuresWindow(sys.argv[1], roiIterator=roiIterator) else: w = MeasuresWindow(sys.argv[1]) w.show() anatomist.Anatomist().getControlWindow().hide() qApp.exec_() del w .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.000 seconds) .. _sphx_glr_download_auto_examples_volumeMeasures.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: volumeMeasures.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: volumeMeasures.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_