<commit_before>#!/usr/bin/env python

"""Tune the free parameters, debug, and characterize analysis performed by
RegisterImageToTubesUsingRigidTransform."""

import argparse
import json
import os
import subprocess
import sys

import numpy as np
import pyqtgraph as pg
import pyqtgraph.console
import pyqtgraph.dockarea
import pyqtgraph.opengl as gl
from pyqtgraph.Qt import QtCore, QtGui
import SimpleITK as sitk
import tables
import matplotlib.cm

from tubetk.pyqtgraph import tubes_as_circles
from tubetk.numpy import tubes_from_file


class RegistrationTuner(QtGui.QMainWindow):

    def __init__(self, config):
        super(RegistrationTuner, self).__init__()

        self.config = config

        self.iteration = 0
        self.number_of_iterations = 0

        self.image_planes = {}
        self.subsampled_tubes = None
        self.input_image = None
        self.image_content = None
        self.tubes_circles = {}
        self.dock_area = None
        self.iteration_slider = None
        self.iteration_spinbox = None
        self.progression = None
        self.tubes_center = [0.0, 0.0, 0.0]
        self.translations = None
        self.progression_colors = None
        self.metric_values_plot = None
        self.image_controls = {}
        self.ultrasound_probe_origin = None

        self.initializeUI()

    def initializeUI(self):
        self.resize(1024, 768)
        self.setWindowTitle('Registration Tuner')

        exit_action = QtGui.QAction('&Exit', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Exit application')
        exit_action.triggered.connect(QtGui.QApplication.instance().quit)
        self.addAction(exit_action)

        iteration_dock_area_layout = QtGui.QVBoxLayout()
        iteration_dock_area = QtGui.QWidget()
        iteration_dock_area.setLayout(iteration_dock_area_layout)
        self.dock_area = pg.dockarea.DockArea()
        iteration_dock_area_layout.addWidget(self.dock_area, stretch=1)
        iteration_layout = QtGui.QHBoxLayout()
        iteration_widget = QtGui.QWidget()
        iteration_widget.setLayout(iteration_layout)
        iteration_dock_area_layout.addWidget(iteration_widget)
        iteration_layout.addWidget(QtGui.QLabel('Iteration:'))
        iteration_layout.addSpacing(1)
        self.iteration_spinbox = QtGui.QSpinBox()
        self.iteration_spinbox.setMinimum(0)
        self.iteration_spinbox.setMaximum(self.number_of_iterations)
        QtCore.QObject.connect(self.iteration_spinbox,
                               QtCore.SIGNAL('valueChanged(int)'),
                               self._iteration_spinbox_changed)
        iteration_layout.addWidget(self.iteration_spinbox)
        self.iteration_slider = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.iteration_slider.setMinimum(0)
        self.iteration_slider.setMaximum(self.number_of_iterations)
        self.iteration_slider.setTickPosition(QtGui.QSlider.TicksBelow)
        QtCore.QObject.connect(self.iteration_slider,
                               QtCore.SIGNAL('valueChanged(int)'),
                               self._iteration_slider_changed)
        QtCore.QObject.connect(self.iteration_slider,
                               QtCore.SIGNAL('sliderReleased()'),
                               self._iteration_slider_changed)
        iteration_layout.addWidget(self.iteration_slider, stretch=1)

        Dock = pyqtgraph.dockarea.Dock

        run_button = QtGui.QPushButton('Run Analysis')
        run_button.setToolTip('Run the analysis with ' +
                              'current parameter settings.')
        run_button.resize(run_button.sizeHint())
        QtCore.QObject.connect(run_button, QtCore.SIGNAL('clicked()'),
                               self.run_analysis)
        run_action = QtGui.QAction('&Run Analysis', self)
        run_action.setShortcut('Ctrl+R')
        run_action.setStatusTip('Run Analysis')
        QtCore.QObject.connect(run_action, QtCore.SIGNAL('triggered()'),
                               self.run_analysis)
        self.addAction(run_action)

        video_button = QtGui.QPushButton('Make Video Frames')
        video_button.resize(video_button.sizeHint())
        QtCore.QObject.connect(video_button, QtCore.SIGNAL('clicked()'),
                               self.make_video)
        # todo do properly
        self.video_frame_dir = '/tmp/registration_tuner'
        if not os.path.exists(self.video_frame_dir):
            os.makedirs(self.video_frame_dir)

        import pprint
        console_namespace = {'pg': pg,
                             'np': np,
                             'config': self.config,
                             'tuner': self,
                             'pp': pprint.pprint}
        console_text = """
This is an interactive Python console.  The numpy and pyqtgraph modules have
already been imported as 'np' and 'pg'.  The parameter configuration is
available as 'config'.  The RegistrationTuner instance is available as 'tuner'.
"""
        self.console = pyqtgraph.console.ConsoleWidget(
            namespace=console_namespace,
            text=console_text)

        run_console_layout = QtGui.QVBoxLayout()
        run_console_layout.addWidget(run_button)
        run_console_layout.addWidget(video_button)
        run_console_layout.addWidget(self.console)
        run_console = QtGui.QWidget()
        run_console.setLayout(run_console_layout)
        run_console_dock = Dock("Console", size=(400, 300))
        run_console_dock.addWidget(run_console)
        self.dock_area.addDock(run_console_dock, 'right')

        self.image_tubes = gl.GLViewWidget()
        if 'Visualization' in self.config:
            visualization = self.config['Visualization']
            if 'ImageTubes' in visualization:
                imageTubes = visualization['ImageTubes']
                if 'CameraPosition' in imageTubes:
                    # The current position can be obtained with
                    # tuner.image_tubes.opts
                    cameraPosition = imageTubes['CameraPosition']
                    it = self.image_tubes
                    it.setCameraPosition(distance=cameraPosition['distance'],
                                         elevation=cameraPosition['elevation'],
                                         azimuth=cameraPosition['azimuth'])
        x_grid = gl.GLGridItem()
        grid_scale = 20
        x_grid.rotate(90, 0, 1, 0)
        x_grid.translate(-10 * grid_scale, 0, 0)
        y_grid = gl.GLGridItem()
        y_grid.rotate(90, 1, 0, 0)
        y_grid.translate(0, -10 * grid_scale, 0)
        z_grid = gl.GLGridItem()
        z_grid.translate(0, 0, -10 * grid_scale)
        for grid in x_grid, y_grid, z_grid:
            grid.scale(grid_scale, grid_scale, grid_scale)<commit_msg>ENH: Reg Tuner: set initial camera center.<commit_after>#!/usr/bin/env python

"""Tune the free parameters, debug, and characterize analysis performed by
RegisterImageToTubesUsingRigidTransform."""

import argparse
import json
import os
import subprocess
import sys

import numpy as np
import pyqtgraph as pg
import pyqtgraph.console
import pyqtgraph.dockarea
import pyqtgraph.opengl as gl
from pyqtgraph.Qt import QtCore, QtGui
import SimpleITK as sitk
import tables
import matplotlib.cm

from tubetk.pyqtgraph import tubes_as_circles
from tubetk.numpy import tubes_from_file


class RegistrationTuner(QtGui.QMainWindow):

    def __init__(self, config):
        super(RegistrationTuner, self).__init__()

        self.config = config

        self.iteration = 0
        self.number_of_iterations = 0

        self.image_planes = {}
        self.subsampled_tubes = None
        self.input_image = None
        self.image_content = None
        self.tubes_circles = {}
        self.dock_area = None
        self.iteration_slider = None
        self.iteration_spinbox = None
        self.progression = None
        self.tubes_center = [0.0, 0.0, 0.0]
        self.translations = None
        self.progression_colors = None
        self.metric_values_plot = None
        self.image_controls = {}
        self.ultrasound_probe_origin = None

        self.initializeUI()

    def initializeUI(self):
        self.resize(1024, 768)
        self.setWindowTitle('Registration Tuner')

        exit_action = QtGui.QAction('&Exit', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Exit application')
        exit_action.triggered.connect(QtGui.QApplication.instance().quit)
        self.addAction(exit_action)

        iteration_dock_area_layout = QtGui.QVBoxLayout()
        iteration_dock_area = QtGui.QWidget()
        iteration_dock_area.setLayout(iteration_dock_area_layout)
        self.dock_area = pg.dockarea.DockArea()
        iteration_dock_area_layout.addWidget(self.dock_area, stretch=1)
        iteration_layout = QtGui.QHBoxLayout()
        iteration_widget = QtGui.QWidget()
        iteration_widget.setLayout(iteration_layout)
        iteration_dock_area_layout.addWidget(iteration_widget)
        iteration_layout.addWidget(QtGui.QLabel('Iteration:'))
        iteration_layout.addSpacing(1)
        self.iteration_spinbox = QtGui.QSpinBox()
        self.iteration_spinbox.setMinimum(0)
        self.iteration_spinbox.setMaximum(self.number_of_iterations)
        QtCore.QObject.connect(self.iteration_spinbox,
                               QtCore.SIGNAL('valueChanged(int)'),
                               self._iteration_spinbox_changed)
        iteration_layout.addWidget(self.iteration_spinbox)
        self.iteration_slider = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.iteration_slider.setMinimum(0)
        self.iteration_slider.setMaximum(self.number_of_iterations)
        self.iteration_slider.setTickPosition(QtGui.QSlider.TicksBelow)
        QtCore.QObject.connect(self.iteration_slider,
                               QtCore.SIGNAL('valueChanged(int)'),
                               self._iteration_slider_changed)
        QtCore.QObject.connect(self.iteration_slider,
                               QtCore.SIGNAL('sliderReleased()'),
                               self._iteration_slider_changed)
        iteration_layout.addWidget(self.iteration_slider, stretch=1)

        Dock = pyqtgraph.dockarea.Dock

        run_button = QtGui.QPushButton('Run Analysis')
        run_button.setToolTip('Run the analysis with ' +
                              'current parameter settings.')
        run_button.resize(run_button.sizeHint())
        QtCore.QObject.connect(run_button, QtCore.SIGNAL('clicked()'),
                               self.run_analysis)
        run_action = QtGui.QAction('&Run Analysis', self)
        run_action.setShortcut('Ctrl+R')
        run_action.setStatusTip('Run Analysis')
        QtCore.QObject.connect(run_action, QtCore.SIGNAL('triggered()'),
                               self.run_analysis)
        self.addAction(run_action)

        video_button = QtGui.QPushButton('Make Video Frames')
        video_button.resize(video_button.sizeHint())
        QtCore.QObject.connect(video_button, QtCore.SIGNAL('clicked()'),
                               self.make_video)
        # todo do properly
        self.video_frame_dir = '/tmp/registration_tuner'
        if not os.path.exists(self.video_frame_dir):
            os.makedirs(self.video_frame_dir)

        import pprint
        console_namespace = {'pg': pg,
                             'np': np,
                             'config': self.config,
                             'tuner': self,
                             'pp': pprint.pprint}
        console_text = """
This is an interactive Python console.  The numpy and pyqtgraph modules have
already been imported as 'np' and 'pg'.  The parameter configuration is
available as 'config'.  The RegistrationTuner instance is available as 'tuner'.
"""
        self.console = pyqtgraph.console.ConsoleWidget(
            namespace=console_namespace,
            text=console_text)

        run_console_layout = QtGui.QVBoxLayout()
        run_console_layout.addWidget(run_button)
        run_console_layout.addWidget(video_button)
        run_console_layout.addWidget(self.console)
        run_console = QtGui.QWidget()
        run_console.setLayout(run_console_layout)
        run_console_dock = Dock("Console", size=(400, 300))
        run_console_dock.addWidget(run_console)
        self.dock_area.addDock(run_console_dock, 'right')

        self.image_tubes = gl.GLViewWidget()
        if 'Visualization' in self.config:
            visualization = self.config['Visualization']
            if 'ImageTubes' in visualization:
                imageTubes = visualization['ImageTubes']
                if 'CameraPosition' in imageTubes:
                    # The current position can be obtained with
                    # tuner.image_tubes.opts
                    cameraPosition = imageTubes['CameraPosition']
                    it = self.image_tubes
                    it.setCameraPosition(distance=cameraPosition['distance'],
                                         elevation=cameraPosition['elevation'],
                                         azimuth=cameraPosition['azimuth'])
                    # HACK: pyqtgraph needs to fix its api so this can be set
                    # with setCameraPosition
                    if 'center' in cameraPosition:
                        center = cameraPosition['center']
                        it.opts['center'] = QtGui.QVector3D(center[0],
                                                            center[1],
                                                            center[2])
        x_grid = gl.GLGridItem()
        grid_scale = 20
        x_grid.rotate(90, 0, 1, 0)
        x_grid.translate(-10 * grid_scale, 0, 0)
        y_grid = gl.GLGridItem()
        y_grid.rotate(90, 1, 0, 0)
        y_grid.translate(0, -10 * grid_scale, 0)
        z_grid = gl.GLGridItem()
        z_grid.translate(0, 0, -10 * grid_scale)
        for grid in x_grid, y_grid, z_grid:
            grid.scale(grid_scale, grid_scale, grid_scale)
{'fraction_non_alphanumeric': 0.08685446009389672, 'fraction_numerical': 0.007397922890880637, 'mean_word_length': 2.2408944213923467, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '23122', 'n_tokens_mistral': 4138, 'n_tokens_neox': 3945, 'n_words': 699}