<commit_before>import math
import os
import sys
import time

from PyQt4 import QtGui, QtCore

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.ticker import ScalarFormatter

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from pptx import Presentation
from pptx.util import Inches

from config import *
from dat_file import DatFile
from operations import Operations

"""
TODO:
- Config file with defaults
- Cropping operation

Open file:
- Fill ui
-
"""

class FixedOrderFormatter(ScalarFormatter):
    def __init__(self, significance=0):
        ScalarFormatter.__init__(self, useOffset=None, useMathText=None)
        self.format = '%.' + str(significance) + 'f'

    def __call__(self, x, pos=None):
        if x == 0:
            return '0'

        exp = self.orderOfMagnitude

        return self.format % (x / (10 ** exp))

    def _set_orderOfMagnitude(self, range):
        exp = math.floor(math.log10(range))
        self.orderOfMagnitude = exp - (exp % 3)

class Window(QtGui.QMainWindow):
    def __init__(self, lc_window, op_window, filename=None):
        QtGui.QMainWindow.__init__(self)

        self.linecut = lc_window
        self.operations = op_window

        self.fig, self.ax = plt.subplots()
        self.cb = None

        self.linecut_type = None
        self.linecut_coord = None

        self.ppt = None
        self.slide = None

        self.data = None
        self.data_file = None

        self.init_ui()

        if filename is not None:
            self.load_file(filename)
            self.update_ui()

    def init_ui(self):
        self.setWindowTitle('qtplot')

        self.main_widget = QtGui.QWidget(self)

        self.canvas = FigureCanvasQTAgg(self.fig)
        self.canvas.mpl_connect('button_press_event', self.on_mouse_click)
        self.canvas.mpl_connect('motion_notify_event', self.on_mouse_motion)
        self.toolbar = NavigationToolbar2QT(self.canvas, self)

        self.b_load = QtGui.QPushButton('Load DAT')
        self.b_load.clicked.connect(self.on_load_dat)
        self.c_swap = QtGui.QCheckBox('Swap columns', self)
        self.c_swap.stateChanged.connect(self.change_data)

        self.lbl_x = QtGui.QLabel("X", self)
        self.cb_x = QtGui.QComboBox(self)
        self.cb_x.activated.connect(self.change_data)

        self.lbl_y = QtGui.QLabel("Y", self)
        self.cb_y = QtGui.QComboBox(self)
        self.cb_y.activated.connect(self.change_data)

        self.lbl_d = QtGui.QLabel("Data", self)
        self.cb_z = QtGui.QComboBox(self)
        self.cb_z.activated.connect(self.change_data)

        self.s_gamma = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.s_gamma.setMinimum(0)
        self.s_gamma.setMaximum(100)
        self.s_gamma.setValue(50)
        self.s_gamma.valueChanged.connect(self.on_gamma_changed)

        self.lbl_ppt = QtGui.QLabel("PPT File", self)
        self.b_ppt = QtGui.QPushButton("Browse", self)
        self.b_ppt.clicked.connect(self.browse_ppt)
        self.le_ppt = QtGui.QLineEdit(cfg_ppt_file, self)

        self.b_slide = QtGui.QPushButton('Add slide')
        self.b_slide.setEnabled(False)
        self.b_slide.clicked.connect(self.add_slide)

        self.b_ppt1 = QtGui.QPushButton('Add 2D data Figure')
        self.b_ppt1.setEnabled(False)
        self.b_ppt1.clicked.connect(self.add_2d_data)

        self.b_ppt2 = QtGui.QPushButton('Add linecut figure')
        self.b_ppt2.setEnabled(False)
        self.b_ppt2.clicked.connect(self.add_linecut)

        self.b_refresh = QtGui.QPushButton('Save PPT')
        self.b_refresh.clicked.connect(self.save_ppt)

        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(self.b_load)
        hbox.addWidget(self.c_swap)

        hbox1 = QtGui.QHBoxLayout()
        hbox1.addWidget(self.lbl_x)
        hbox1.addWidget(self.cb_x)

        hbox2 = QtGui.QHBoxLayout()
        hbox2.addWidget(self.lbl_y)
        hbox2.addWidget(self.cb_y)

        hbox3 = QtGui.QHBoxLayout()
        hbox3.addWidget(self.lbl_d)
        hbox3.addWidget(self.cb_z)

        hbox4 = QtGui.QHBoxLayout()
        hbox4.addWidget(self.lbl_ppt)
        hbox4.addWidget(self.b_ppt)
        hbox4.addWidget(self.le_ppt)

        hbox5 = QtGui.QHBoxLayout()
        hbox5.addWidget(self.b_slide)
        hbox5.addWidget(self.b_ppt1)
        hbox5.addWidget(self.b_ppt2)
        hbox5.addWidget(self.b_refresh)

        vbox = QtGui.QVBoxLayout(self.main_widget)
        vbox.addWidget(self.toolbar)
        vbox.addWidget(self.canvas)
        vbox.addLayout(hbox)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        vbox.addLayout(hbox3)
        vbox.addWidget(self.s_gamma)
        vbox.addLayout(hbox4)
        vbox.addLayout(hbox5)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.move(100, 100)

    def update_ui(self):
        self.setWindowTitle(self.name)

        self.cb_x.addItems(self.data_file.columns)
        self.cb_x.setCurrentIndex(5)

        self.cb_y.addItems(self.data_file.columns)
        self.cb_y.setCurrentIndex(9)

        self.cb_z.addItems(self.data_file.columns)
        self.cb_z.setCurrentIndex(7)

        self.b_slide.setEnabled(True)
        self.b_ppt1.setEnabled(True)
        self.b_ppt2.setEnabled(True)

    def load_file(self, filename):
        if filename != "":
            self.data_file = DatFile(filename)

            path, self.name = os.path.split(self.data_file.filename)

            self.update_ui()
            self.change_data()

    def on_load_dat(self, event):
        self.filename = str(QtGui.QFileDialog.getOpenFileName(filter='*.dat'))

        self.load_file(self.filename)

    def change_data(self):
        if self.data_file is not None:
            self.manipulate_data()
            self.plot_2d_data()

    def manipulate_data(self):
        data = self.data_file.df.copy()
        columns = self.data_file.columns

        # Get the column names to use for the x, y and data
        self.lbl_x = str(self.cb_x.currentText())
        self.lbl_y = str(self.cb_y.currentText())
        self.data_lbl = str(self.cb_z.currentText())

        # Average the measurement columns which are related to the DAC values
        for col in columns:
            if self.lbl_x == col or self.lbl_y == col:
                one, two = 1, 0

                if self.c_swap.isChecked():
                    one, two = two, one

                if col in columns[3:7]:
                    data[col] = data.groupby(columns[one])[col].transform(np.average)

                if col in columns[7:11]:
                    data[col] = data.groupby(columns[two])[col].transform(np.average)

        # Pivot the data into an x and y axis, and values
        data = data.pivot(self.lbl_y, self.lbl_x, self.data_lbl)

        self.data = self.operations.apply_operations(data)

        self.data_changed = False

    def plot_2d_data(self):
        # Clear the figure
        self.ax.clear()

        x = np.array(self.data.columns)
        y = np.array(self.data.index)

        # Calculate the centers of the data bins to use as coordinates
        xc = x[:-1] + np.diff(x) / 2.0
        yc = y[:-1] + np.diff(y) / 2.0

        # Add a first and last coordinate so all datapoints get plotted
        xc = np.append(xc[0] - (x[1] - x[0]), xc)
        xc = np.append(xc, xc[-1] + (x[-1] - x[-2]))

        yc = np.append(yc[0] - (y[1] - y[0]), yc)
        yc = np.append(yc, yc[-1] + (y[-1] - y[-2]))

        cmap = mpl.cm.get_cmap('seismic')
        cmap.set_gamma((self.s_gamma.value() / 50.0)**4)

        # Mask NaN values so they will not be plotted
        masked = np.ma.masked_where(np.isnan(self.data.values), self.data.values)
        quadmesh = self.ax.pcolormesh(xc, yc, masked, cmap=cmap)

        self.ax.axis('tight')

        # Create a colorbar, if there is already one draw it in the existing place
        if self.cb:
            self.cb.ax.clear()
            self.cb = self.fig.colorbar(quadmesh, cax=self.cb.ax)
        else:
            self.cb = self.fig.colorbar(quadmesh)

        self.cb.set_label(self.data_lbl)
        self.cb.formatter = FixedOrderFormatter(1)
        self.cb.update_ticks()

        # Set the various labels
        self.ax.set_title(self.name)
        self.ax.set_xlabel(self.lbl_x)
        self.ax.set_ylabel(self.lbl_y)
        self.ax.xaxis.set_major_formatter(FixedOrderFormatter())
        self.ax.yaxis.set_major_formatter(FixedOrderFormatter())
        self.ax.set_aspect('auto')

        self.fig.tight_layout()

        self.canvas.draw()

    def on_gamma_changed(self, value):
        self.plot_2d_data()

    def on_mouse_motion(self, event):
        if event.button != None:
            self.on_mouse_click(event)

    def on_mouse_click(self, event):
        # Don't do anything if we are not within the axes of the figure
        if not event.inaxes:
            return

        lc = self.linecut

        # If there is already a line in the figure, remove it for the new one
        if len(self.ax.lines) > 0:
            self.ax.lines.pop(0)

        if len(lc.ax.lines) > 0:
            lc.ax.lines.pop(0)

        if event.button == 1:
            # Get the row closest to the mouse Y
            self.linecut_coord = min(self.data.index, key=lambda x:abs(x - event.ydata))
            self.linecut_type = 'horizontal'

            # Draw a horizontal line
            self.ax.axhline(y=self.linecut_coord, color='red')

            lc.ax.plot(self.data.columns, self.data.loc[self.linecut_coord], color='red', linewidth=0.5)
            lc.ax.set_xlabel(self.lbl_x)
        elif event.button == 2:
            # Get the column closest to the mouse X
            self.linecut_coord = min(self.data.columns, key=lambda x:abs(x - event.xdata))
            self.linecut_type = 'vertical'

            # Draw a vertical line
            self.ax.axvline(x=self.linecut_coord, color='red')

            lc.ax.plot(self.data.index, self.data[self.linecut_coord], color='red', linewidth=0.5)
            lc.ax.set_xlabel(self.lbl_y)

        lc.ax.set_title(self.name)
        lc.ax.set_ylabel(self.data_lbl)
        lc.ax.xaxis.set_major_formatter(FixedOrderFormatter())
        lc.ax.yaxis.set_major_formatter(FixedOrderFormatter())

        # Make the figure fit the data
        lc.ax.relim()
        lc.ax.autoscale_view()
        lc.fig.tight_layout()

        # Redraw both plots to update them
        self.canvas.draw()
        lc.canvas.draw()

    def add_slide(self, event):
        if self.ppt is not None:
            title_slide_layout = self.ppt.slide_layouts[6]
            self.slide = self.ppt.slides.add_slide(title_slide_layout)

    def add_2d_data(self, event):
        if self.slide is not None:
            path = os.path.dirname(os.path.realpath(__file__))
            path = os.path.join(path, 'test.png')
            self.fig.savefig(path)
            self.slide.shapes.add_picture(path, Inches(1), Inches(1))

    def add_linecut(self, event):
        if self.slide is not None:
            path = os.path.dirname(os.path.realpath(__file__))
            path = os.path.join(path, 'test.png')
            self.linecut.fig.savefig(path)
            self.slide.shapes.add_picture(path, Inches(1), Inches(1))

    def browse_ppt(self, event):
        filename = str(QtGui.QFileDialog.getOpenFileName(self))
        self.le_ppt.setText(filename)

        try:
            self.ppt_file = open(filename, 'rb')
            self.ppt = Presentation(self.ppt_file)
        except IOError:
            print 'Could not open PowerPoint file: ' + filename
            self.ppt = None

    def save_ppt(self, event):
        if self.ppt:
            try:
                self.ppt.save(str(self.le_ppt.text()))
            except IOError as e:
                print 'Could not save PowerPoint file: '

    def closeEvent(self, event):
        if self.ppt:
            try:
                self.ppt.save(str(self.le_ppt.text()))
            except IOError as e:
                path, filename = os.path.split(str(self.le_ppt.text()))
                name, ext = os.path.splitext(filename)
                new = os.path.join(path, (name + time.asctime()) + ext)
                print new
                self.ppt.save(new)

        self.linecut.close()
        self.operations.close()

class Linecut(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Linecut, self).__init__(parent)

        self.fig, self.ax = plt.subplots()

        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("Linecut")

        self.canvas = FigureCanvasQTAgg(self.fig)
        self.toolbar = NavigationToolbar2QT(self.canvas, self)

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)

        self.move(800, 100)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    linecut = Linecut()
    operations = Operations()
    main = Window(linecut, operations)

    if len(sys.argv) > 1:
        main = Window(linecut, operations, filename=sys.argv[1])

    linecut.main = main
    operations.main = main

    linecut.show()
    main.show()

    operations.show()

    sys.exit(app.exec_())<commit_msg>better gamma adjustment<commit_after>import math
import os
import sys
import time

from PyQt4 import QtGui, QtCore

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg, NavigationToolbar2QT
from matplotlib.ticker import ScalarFormatter

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from pptx import Presentation
from pptx.util import Inches

from config import *
from dat_file import DatFile
from operations import Operations

"""
TODO:
- Config file with defaults
- Cropping operation

Open file:
- Fill ui
-
"""

class FixedOrderFormatter(ScalarFormatter):
    def __init__(self, significance=0):
        ScalarFormatter.__init__(self, useOffset=None, useMathText=None)
        self.format = '%.' + str(significance) + 'f'

    def __call__(self, x, pos=None):
        if x == 0:
            return '0'

        exp = self.orderOfMagnitude

        return self.format % (x / (10 ** exp))

    def _set_orderOfMagnitude(self, range):
        exp = math.floor(math.log10(range))
        self.orderOfMagnitude = exp - (exp % 3)

class Window(QtGui.QMainWindow):
    def __init__(self, lc_window, op_window, filename=None):
        QtGui.QMainWindow.__init__(self)

        self.linecut = lc_window
        self.operations = op_window

        self.fig, self.ax = plt.subplots()
        self.cb = None

        self.linecut_type = None
        self.linecut_coord = None

        self.ppt = None
        self.slide = None

        self.data = None
        self.data_file = None

        self.init_ui()

        if filename is not None:
            self.load_file(filename)
            self.update_ui()

    def init_ui(self):
        self.setWindowTitle('qtplot')

        self.main_widget = QtGui.QWidget(self)

        self.canvas = FigureCanvasQTAgg(self.fig)
        self.canvas.mpl_connect('button_press_event', self.on_mouse_click)
        self.canvas.mpl_connect('motion_notify_event', self.on_mouse_motion)
        self.toolbar = NavigationToolbar2QT(self.canvas, self)

        self.b_load = QtGui.QPushButton('Load DAT')
        self.b_load.clicked.connect(self.on_load_dat)
        self.c_swap = QtGui.QCheckBox('Swap columns', self)
        self.c_swap.stateChanged.connect(self.change_data)

        self.lbl_x = QtGui.QLabel("X", self)
        self.cb_x = QtGui.QComboBox(self)
        self.cb_x.activated.connect(self.change_data)

        self.lbl_y = QtGui.QLabel("Y", self)
        self.cb_y = QtGui.QComboBox(self)
        self.cb_y.activated.connect(self.change_data)

        self.lbl_d = QtGui.QLabel("Data", self)
        self.cb_z = QtGui.QComboBox(self)
        self.cb_z.activated.connect(self.change_data)

        self.s_gamma = QtGui.QSlider(QtCore.Qt.Horizontal)
        self.s_gamma.setMinimum(0)
        self.s_gamma.setMaximum(100)
        self.s_gamma.setValue(50)
        self.s_gamma.valueChanged.connect(self.on_gamma_changed)

        self.lbl_ppt = QtGui.QLabel("PPT File", self)
        self.b_ppt = QtGui.QPushButton("Browse", self)
        self.b_ppt.clicked.connect(self.browse_ppt)
        self.le_ppt = QtGui.QLineEdit(cfg_ppt_file, self)

        self.b_slide = QtGui.QPushButton('Add slide')
        self.b_slide.setEnabled(False)
        self.b_slide.clicked.connect(self.add_slide)

        self.b_ppt1 = QtGui.QPushButton('Add 2D data Figure')
        self.b_ppt1.setEnabled(False)
        self.b_ppt1.clicked.connect(self.add_2d_data)

        self.b_ppt2 = QtGui.QPushButton('Add linecut figure')
        self.b_ppt2.setEnabled(False)
        self.b_ppt2.clicked.connect(self.add_linecut)

        self.b_refresh = QtGui.QPushButton('Save PPT')
        self.b_refresh.clicked.connect(self.save_ppt)

        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(self.b_load)
        hbox.addWidget(self.c_swap)

        hbox1 = QtGui.QHBoxLayout()
        hbox1.addWidget(self.lbl_x)
        hbox1.addWidget(self.cb_x)

        hbox2 = QtGui.QHBoxLayout()
        hbox2.addWidget(self.lbl_y)
        hbox2.addWidget(self.cb_y)

        hbox3 = QtGui.QHBoxLayout()
        hbox3.addWidget(self.lbl_d)
        hbox3.addWidget(self.cb_z)

        hbox4 = QtGui.QHBoxLayout()
        hbox4.addWidget(self.lbl_ppt)
        hbox4.addWidget(self.b_ppt)
        hbox4.addWidget(self.le_ppt)

        hbox5 = QtGui.QHBoxLayout()
        hbox5.addWidget(self.b_slide)
        hbox5.addWidget(self.b_ppt1)
        hbox5.addWidget(self.b_ppt2)
        hbox5.addWidget(self.b_refresh)

        vbox = QtGui.QVBoxLayout(self.main_widget)
        vbox.addWidget(self.toolbar)
        vbox.addWidget(self.canvas)
        vbox.addLayout(hbox)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        vbox.addLayout(hbox3)
        vbox.addWidget(self.s_gamma)
        vbox.addLayout(hbox4)
        vbox.addLayout(hbox5)

        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)

        self.move(100, 100)

    def update_ui(self):
        self.setWindowTitle(self.name)

        self.cb_x.addItems(self.data_file.columns)
        self.cb_x.setCurrentIndex(5)

        self.cb_y.addItems(self.data_file.columns)
        self.cb_y.setCurrentIndex(9)

        self.cb_z.addItems(self.data_file.columns)
        self.cb_z.setCurrentIndex(7)

        self.b_slide.setEnabled(True)
        self.b_ppt1.setEnabled(True)
        self.b_ppt2.setEnabled(True)

    def load_file(self, filename):
        if filename != "":
            self.data_file = DatFile(filename)

            path, self.name = os.path.split(self.data_file.filename)

            self.update_ui()
            self.change_data()

    def on_load_dat(self, event):
        self.filename = str(QtGui.QFileDialog.getOpenFileName(filter='*.dat'))

        self.load_file(self.filename)

    def change_data(self):
        if self.data_file is not None:
            self.manipulate_data()
            self.plot_2d_data()

    def manipulate_data(self):
        data = self.data_file.df.copy()
        columns = self.data_file.columns

        # Get the column names to use for the x, y and data
        self.lbl_x = str(self.cb_x.currentText())
        self.lbl_y = str(self.cb_y.currentText())
        self.data_lbl = str(self.cb_z.currentText())

        # Average the measurement columns which are related to the DAC values
        for col in columns:
            if self.lbl_x == col or self.lbl_y == col:
                one, two = 1, 0

                if self.c_swap.isChecked():
                    one, two = two, one

                if col in columns[3:7]:
                    data[col] = data.groupby(columns[one])[col].transform(np.average)

                if col in columns[7:11]:
                    data[col] = data.groupby(columns[two])[col].transform(np.average)

        # Pivot the data into an x and y axis, and values
        data = data.pivot(self.lbl_y, self.lbl_x, self.data_lbl)

        self.data = self.operations.apply_operations(data)

        self.data_changed = False

    def plot_2d_data(self):
        if self.data is None:
            return

        # Clear the figure
        self.ax.clear()

        x = np.array(self.data.columns)
        y = np.array(self.data.index)

        # Calculate the centers of the data bins to use as coordinates
        xc = x[:-1] + np.diff(x) / 2.0
        yc = y[:-1] + np.diff(y) / 2.0

        # Add a first and last coordinate so all datapoints get plotted
        xc = np.append(xc[0] - (x[1] - x[0]), xc)
        xc = np.append(xc, xc[-1] + (x[-1] - x[-2]))

        yc = np.append(yc[0] - (y[1] - y[0]), yc)
        yc = np.append(yc, yc[-1] + (y[-1] - y[-2]))

        cmap = mpl.cm.get_cmap('seismic')
        value = (self.s_gamma.value() / 100.0)
        cmap.set_gamma(math.exp(value * 5) / 10.0)

        # Mask NaN values so they will not be plotted
        masked = np.ma.masked_where(np.isnan(self.data.values), self.data.values)
        quadmesh = self.ax.pcolormesh(xc, yc, masked, cmap=cmap)

        self.ax.axis('tight')

        # Create a colorbar, if there is already one draw it in the existing place
        if self.cb:
            self.cb.ax.clear()
            self.cb = self.fig.colorbar(quadmesh, cax=self.cb.ax)
        else:
            self.cb = self.fig.colorbar(quadmesh)

        self.cb.set_label(self.data_lbl)
        self.cb.formatter = FixedOrderFormatter(1)
        self.cb.update_ticks()

        # Set the various labels
        self.ax.set_title(self.name)
        self.ax.set_xlabel(self.lbl_x)
        self.ax.set_ylabel(self.lbl_y)
        self.ax.xaxis.set_major_formatter(FixedOrderFormatter())
        self.ax.yaxis.set_major_formatter(FixedOrderFormatter())
        self.ax.set_aspect('auto')

        self.fig.tight_layout()

        self.canvas.draw()

    def on_gamma_changed(self, value):
        self.plot_2d_data()

    def on_mouse_motion(self, event):
        if event.button != None:
            self.on_mouse_click(event)

    def on_mouse_click(self, event):
        # Don't do anything if we are not within the axes of the figure
        if not event.inaxes:
            return

        lc = self.linecut

        # If there is already a line in the figure, remove it for the new one
        if len(self.ax.lines) > 0:
            self.ax.lines.pop(0)

        if len(lc.ax.lines) > 0:
            lc.ax.lines.pop(0)

        if event.button == 1:
            # Get the row closest to the mouse Y
            self.linecut_coord = min(self.data.index, key=lambda x:abs(x - event.ydata))
            self.linecut_type = 'horizontal'

            # Draw a horizontal line
            self.ax.axhline(y=self.linecut_coord, color='red')

            lc.ax.plot(self.data.columns, self.data.loc[self.linecut_coord], color='red', linewidth=0.5)
            lc.ax.set_xlabel(self.lbl_x)
        elif event.button == 2:
            # Get the column closest to the mouse X
            self.linecut_coord = min(self.data.columns, key=lambda x:abs(x - event.xdata))
            self.linecut_type = 'vertical'

            # Draw a vertical line
            self.ax.axvline(x=self.linecut_coord, color='red')

            lc.ax.plot(self.data.index, self.data[self.linecut_coord], color='red', linewidth=0.5)
            lc.ax.set_xlabel(self.lbl_y)

        lc.ax.set_title(self.name)
        lc.ax.set_ylabel(self.data_lbl)
        lc.ax.xaxis.set_major_formatter(FixedOrderFormatter())
        lc.ax.yaxis.set_major_formatter(FixedOrderFormatter())

        # Make the figure fit the data
        lc.ax.relim()
        lc.ax.autoscale_view()
        lc.fig.tight_layout()

        # Redraw both plots to update them
        self.canvas.draw()
        lc.canvas.draw()

    def add_slide(self, event):
        if self.ppt is not None:
            title_slide_layout = self.ppt.slide_layouts[6]
            self.slide = self.ppt.slides.add_slide(title_slide_layout)

    def add_2d_data(self, event):
        if self.slide is not None:
            path = os.path.dirname(os.path.realpath(__file__))
            path = os.path.join(path, 'test.png')
            self.fig.savefig(path)
            self.slide.shapes.add_picture(path, Inches(1), Inches(1))

    def add_linecut(self, event):
        if self.slide is not None:
            path = os.path.dirname(os.path.realpath(__file__))
            path = os.path.join(path, 'test.png')
            self.linecut.fig.savefig(path)
            self.slide.shapes.add_picture(path, Inches(1), Inches(1))

    def browse_ppt(self, event):
        filename = str(QtGui.QFileDialog.getOpenFileName(self))
        self.le_ppt.setText(filename)

        try:
            self.ppt_file = open(filename, 'rb')
            self.ppt = Presentation(self.ppt_file)
        except IOError:
            print 'Could not open PowerPoint file: ' + filename
            self.ppt = None

    def save_ppt(self, event):
        if self.ppt:
            try:
                self.ppt.save(str(self.le_ppt.text()))
            except IOError as e:
                print 'Could not save PowerPoint file: '

    def closeEvent(self, event):
        if self.ppt:
            try:
                self.ppt.save(str(self.le_ppt.text()))
            except IOError as e:
                path, filename = os.path.split(str(self.le_ppt.text()))
                name, ext = os.path.splitext(filename)
                new = os.path.join(path, (name + time.asctime()) + ext)
                print new
                self.ppt.save(new)

        self.linecut.close()
        self.operations.close()

class Linecut(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Linecut, self).__init__(parent)

        self.fig, self.ax = plt.subplots()

        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("Linecut")

        self.canvas = FigureCanvasQTAgg(self.fig)
        self.toolbar = NavigationToolbar2QT(self.canvas, self)

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)

        self.move(800, 100)

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    linecut = Linecut()
    operations = Operations()
    main = Window(linecut, operations)

    if len(sys.argv) > 1:
        main = Window(linecut, operations, filename=sys.argv[1])

    linecut.main = main
    operations.main = main

    linecut.show()
    main.show()

    operations.show()

    sys.exit(app.exec_())<|endoftext|>


<commit_before>import os

from mopidy import config, ext
from mopidy.exceptions import ExtensionError

__version__ = "2.1.0"

class Extension(ext.Extension):

    dist_name = "Mopidy-SoundCloud"
    ext_name = "soundcloud"
    version = __version__

    def get_default_config(self):
        conf_file = os.path.join(os.path.dirname(__file__), "ext.conf")
        return config.read(conf_file)

    def get_config_schema(self):
        schema = super().get_config_schema()
        schema["explore_songs"] = config.Integer(optional=True)
        schema["auth_token"] = config.Secret()
        schema["explore"] = config.Deprecated()
        schema["explore_pages"] = config.Deprecated()
        return schema

    def validate_config(self, config):  # no_coverage
        if not config.getboolean("soundcloud", "enabled"):
            return
        if not config.get("soundcloud", "auth_token"):
            raise ExtensionError(
                "In order to use SoundCloud extension you must provide an "
                "auth token. For more information refer to "
                "https://github.com/mopidy/mopidy-soundcloud/"
            )

    def setup(self, registry):
        from .actor import SoundCloudBackend

        registry.add("backend", SoundCloudBackend)
<commit_msg>Use pathlib to read ext.conf<commit_after>import pathlib

from mopidy import config, ext
from mopidy.exceptions import ExtensionError

__version__ = "2.1.0"

class Extension(ext.Extension):

    dist_name = "Mopidy-SoundCloud"
    ext_name = "soundcloud"
    version = __version__

    def get_default_config(self):
        return config.read(pathlib.Path(__file__).parent / "ext.conf")

    def get_config_schema(self):
        schema = super().get_config_schema()
        schema["explore_songs"] = config.Integer(optional=True)
        schema["auth_token"] = config.Secret()
        schema["explore"] = config.Deprecated()
        schema["explore_pages"] = config.Deprecated()
        return schema

    def validate_config(self, config):  # no_coverage
        if not config.getboolean("soundcloud", "enabled"):
            return
        if not config.get("soundcloud", "auth_token"):
            raise ExtensionError(
                "In order to use SoundCloud extension you must provide an "
                "auth token. For more information refer to "
                "https://github.com/mopidy/mopidy-soundcloud/"
            )

    def setup(self, registry):
        from .actor import SoundCloudBackend

        registry.add("backend", SoundCloudBackend)
<|endoftext|>


<commit_before>from __future__ import absolute_import

import ast
import logging
import os.path
from pathlib import Path

import pytest
import pretend

from pip_check_reqs import common

@pytest.mark.parametrize(
    ["path", "result"],
    [
        ('/', ''),
        ('__init__.py', ''),  # a top-level file like this has no package name
        ('/__init__.py', ''),  # no package name
        ('spam/__init__.py', 'spam'),
        ('spam/__init__.pyc', 'spam'),
        ('spam/__init__.pyo', 'spam'),
        ('ham/spam/__init__.py', 'ham/spam'),
        ('/ham/spam/__init__.py', '/ham/spam'),
    ])
def test_is_package_file(path, result):
    assert common.is_package_file(path) == result

def test_FoundModule():
    fm = common.FoundModule('spam', 'ham')
    assert fm.modname == 'spam'
    assert fm.filename == os.path.realpath('ham')
    assert fm.locations == []
    assert str(fm) == 'FoundModule("spam")'

@pytest.mark.parametrize(
    ["stmt", "result"],
    [
        ('import ast', ['ast']),
        ('import ast, sys', ['ast', 'sys']),
        ('from sys import version', ['sys']),
        ('from os import path', ['os']),
        ('import distutils.command.check', ['distutils']),
        ('import spam', []),  # don't break because bad programmer
    ])
def test_ImportVisitor(stmt, result):
    class options:
        def ignore_mods(self, modname):
            return False

    vis = common.ImportVisitor(options())
    vis.set_location('spam.py')
    vis.visit(ast.parse(stmt))
    result = vis.finalise()
    assert set(result.keys()) == set(result)

def test_pyfiles_file(monkeypatch):
    monkeypatch.setattr(os.path, 'abspath',
                        pretend.call_recorder(lambda x: '/spam/ham.py'))

    assert list(common.pyfiles('spam')) == ['/spam/ham.py']

def test_pyfiles_file_no_dice(monkeypatch):
    monkeypatch.setattr(os.path, 'abspath',
                        pretend.call_recorder(lambda x: '/spam/ham'))

    with pytest.raises(ValueError):
        list(common.pyfiles('spam'))

def test_pyfiles_package(monkeypatch):
    monkeypatch.setattr(os.path, 'abspath',
                        pretend.call_recorder(lambda x: '/spam'))
    monkeypatch.setattr(os.path, 'isdir',
                        pretend.call_recorder(lambda x: True))
    walk_results = [
        ('spam', [], ['__init__.py', 'spam', 'ham.py']),
        ('spam/dub', [], ['bass.py', 'dropped']),
    ]
    monkeypatch.setattr(os, 'walk',
                        pretend.call_recorder(lambda x: walk_results))

    assert list(common.pyfiles('spam')) == \
        ['spam/__init__.py', 'spam/ham.py', 'spam/dub/bass.py']

@pytest.mark.parametrize(["ignore_ham", "ignore_hashlib", "expect", "locs"], [
    (False, False, ['ast', 'os', 'hashlib'], [('spam.py', 2), ('ham.py', 2)]),
    (False, True, ['ast', 'os'], [('spam.py', 2), ('ham.py', 2)]),
    (True, False, ['ast'], [('spam.py', 2)]),
    (True, True, ['ast'], [('spam.py', 2)]),
])
def test_find_imported_modules(monkeypatch, caplog, ignore_ham, ignore_hashlib,
                               expect, locs):
    monkeypatch.setattr(common, 'pyfiles',
                        pretend.call_recorder(lambda x: ['spam.py', 'ham.py']))

    class FakeFile():
        contents = [
            'from os import path\nimport ast, hashlib',
            'from __future__ import braces\nimport ast, sys\n'
            'from . import friend',
        ]

        def __init__(self, filename, encoding=None):
            pass

        def read(self):
            return self.contents.pop()

        def __enter__(self):
            return self

        def __exit__(self, *args):
            pass

    monkeypatch.setattr(common, 'open', FakeFile, raising=False)

    caplog.set_level(logging.INFO)

    class options:
        paths = ['dummy']
        verbose = True

        @staticmethod
        def ignore_files(path):
            if path == 'ham.py' and ignore_ham:
                return True
            return False

        @staticmethod
        def ignore_mods(module):
            if module == 'hashlib' and ignore_hashlib:
                return True
            return False

    result = common.find_imported_modules(options)
    assert set(result) == set(expect)
    assert result['ast'].locations == locs

    if ignore_ham:
        assert caplog.records[0].message == 'ignoring: ham.py'

@pytest.mark.parametrize(["ignore_cfg", "candidate", "result"], [
    ([], 'spam', False),
    ([], 'ham', False),
    (['spam'], 'spam', True),
    (['spam'], 'spam.ham', False),
    (['spam'], 'eggs', False),
    (['spam*'], 'spam', True),
    (['spam*'], 'spam.ham', True),
    (['spam*'], 'eggs', False),
    (['spam'], '/spam', True),
])
def test_ignorer(monkeypatch, tmp_path: Path, ignore_cfg, candidate, result):
    monkeypatch.setattr(os.path, 'relpath', lambda s: s.lstrip('/'))
    ignorer = common.ignorer(ignore_cfg)
    assert ignorer(candidate) == result

def test_find_required_modules(monkeypatch, tmp_path: Path):
    class options:
        skip_incompatible = False

    options.ignore_reqs = common.ignorer(ignore_cfg=['barfoo'])

    fake_requirements_file = tmp_path / 'requirements.txt'
    fake_requirements_file.write_text('foobar==1\nbarfoo==2')

    reqs = common.find_required_modules(
        options=options,
        requirements_filename=str(fake_requirements_file),
    )
    assert reqs == set(['foobar'])

def test_find_required_modules_env_markers(monkeypatch, tmp_path):
    class options:
        skip_incompatible = True

        def ignore_reqs(self, modname):
            return False

    fake_requirements_file = tmp_path / 'requirements.txt'
    fake_requirements_file.write_text('spam==1; python_version<"2.0"\n'
                                      'ham==2;\n'
                                      'eggs==3\n')

    reqs = common.find_required_modules(
        options=options(),
        requirements_filename=str(fake_requirements_file),
    )
    assert reqs == {'ham', 'eggs'}

def test_find_imported_modules_sets_encoding_to_utf8_when_reading(tmp_path):
    (tmp_path / 'module.py').touch()

    class options:
        paths = [tmp_path]

        def ignore_files(*_):
            return False

    expected_encoding = 'utf-8'
    used_encoding = None

    original_open = common.__builtins__['open']

    def mocked_open(*args, **kwargs):
        # As of Python 3.9, the args to open() are as follows:
        # file, mode, buffering, encoding, erorrs, newline, closedf, opener
        nonlocal used_encoding
        if 'encoding' in kwargs:
            used_encoding = kwargs['encoding']
        return original_open(*args, **kwargs)

    common.__builtins__['open'] = mocked_open
    common.find_imported_modules(options)
    common.__builtins__['open'] = original_open

    assert used_encoding == expected_encoding
<commit_msg>Test version_info for inclusion of __version__<commit_after>from __future__ import absolute_import

import ast
import logging
import os.path
from pathlib import Path

import pytest
import pretend

from pip_check_reqs import common, __version__

@pytest.mark.parametrize(
    ["path", "result"],
    [
        ('/', ''),
        ('__init__.py', ''),  # a top-level file like this has no package name
        ('/__init__.py', ''),  # no package name
        ('spam/__init__.py', 'spam'),
        ('spam/__init__.pyc', 'spam'),
        ('spam/__init__.pyo', 'spam'),
        ('ham/spam/__init__.py', 'ham/spam'),
        ('/ham/spam/__init__.py', '/ham/spam'),
    ])
def test_is_package_file(path, result):
    assert common.is_package_file(path) == result

def test_FoundModule():
    fm = common.FoundModule('spam', 'ham')
    assert fm.modname == 'spam'
    assert fm.filename == os.path.realpath('ham')
    assert fm.locations == []
    assert str(fm) == 'FoundModule("spam")'

@pytest.mark.parametrize(
    ["stmt", "result"],
    [
        ('import ast', ['ast']),
        ('import ast, sys', ['ast', 'sys']),
        ('from sys import version', ['sys']),
        ('from os import path', ['os']),
        ('import distutils.command.check', ['distutils']),
        ('import spam', []),  # don't break because bad programmer
    ])
def test_ImportVisitor(stmt, result):
    class options:
        def ignore_mods(self, modname):
            return False

    vis = common.ImportVisitor(options())
    vis.set_location('spam.py')
    vis.visit(ast.parse(stmt))
    result = vis.finalise()
    assert set(result.keys()) == set(result)

def test_pyfiles_file(monkeypatch):
    monkeypatch.setattr(os.path, 'abspath',
                        pretend.call_recorder(lambda x: '/spam/ham.py'))

    assert list(common.pyfiles('spam')) == ['/spam/ham.py']

def test_pyfiles_file_no_dice(monkeypatch):
    monkeypatch.setattr(os.path, 'abspath',
                        pretend.call_recorder(lambda x: '/spam/ham'))

    with pytest.raises(ValueError):
        list(common.pyfiles('spam'))

def test_pyfiles_package(monkeypatch):
    monkeypatch.setattr(os.path, 'abspath',
                        pretend.call_recorder(lambda x: '/spam'))
    monkeypatch.setattr(os.path, 'isdir',
                        pretend.call_recorder(lambda x: True))
    walk_results = [
        ('spam', [], ['__init__.py', 'spam', 'ham.py']),
        ('spam/dub', [], ['bass.py', 'dropped']),
    ]
    monkeypatch.setattr(os, 'walk',
                        pretend.call_recorder(lambda x: walk_results))

    assert list(common.pyfiles('spam')) == \
        ['spam/__init__.py', 'spam/ham.py', 'spam/dub/bass.py']

@pytest.mark.parametrize(["ignore_ham", "ignore_hashlib", "expect", "locs"], [
    (False, False, ['ast', 'os', 'hashlib'], [('spam.py', 2), ('ham.py', 2)]),
    (False, True, ['ast', 'os'], [('spam.py', 2), ('ham.py', 2)]),
    (True, False, ['ast'], [('spam.py', 2)]),
    (True, True, ['ast'], [('spam.py', 2)]),
])
def test_find_imported_modules(monkeypatch, caplog, ignore_ham, ignore_hashlib,
                               expect, locs):
    monkeypatch.setattr(common, 'pyfiles',
                        pretend.call_recorder(lambda x: ['spam.py', 'ham.py']))

    class FakeFile():
        contents = [
            'from os import path\nimport ast, hashlib',
            'from __future__ import braces\nimport ast, sys\n'
            'from . import friend',
        ]

        def __init__(self, filename, encoding=None):
            pass

        def read(self):
            return self.contents.pop()

        def __enter__(self):
            return self

        def __exit__(self, *args):
            pass

    monkeypatch.setattr(common, 'open', FakeFile, raising=False)

    caplog.set_level(logging.INFO)

    class options:
        paths = ['dummy']
        verbose = True

        @staticmethod
        def ignore_files(path):
            if path == 'ham.py' and ignore_ham:
                return True
            return False

        @staticmethod
        def ignore_mods(module):
            if module == 'hashlib' and ignore_hashlib:
                return True
            return False

    result = common.find_imported_modules(options)
    assert set(result) == set(expect)
    assert result['ast'].locations == locs

    if ignore_ham:
        assert caplog.records[0].message == 'ignoring: ham.py'

@pytest.mark.parametrize(["ignore_cfg", "candidate", "result"], [
    ([], 'spam', False),
    ([], 'ham', False),
    (['spam'], 'spam', True),
    (['spam'], 'spam.ham', False),
    (['spam'], 'eggs', False),
    (['spam*'], 'spam', True),
    (['spam*'], 'spam.ham', True),
    (['spam*'], 'eggs', False),
    (['spam'], '/spam', True),
])
def test_ignorer(monkeypatch, tmp_path: Path, ignore_cfg, candidate, result):
    monkeypatch.setattr(os.path, 'relpath', lambda s: s.lstrip('/'))
    ignorer = common.ignorer(ignore_cfg)
    assert ignorer(candidate) == result

def test_find_required_modules(monkeypatch, tmp_path: Path):
    class options:
        skip_incompatible = False

    options.ignore_reqs = common.ignorer(ignore_cfg=['barfoo'])

    fake_requirements_file = tmp_path / 'requirements.txt'
    fake_requirements_file.write_text('foobar==1\nbarfoo==2')

    reqs = common.find_required_modules(
        options=options,
        requirements_filename=str(fake_requirements_file),
    )
    assert reqs == set(['foobar'])

def test_find_required_modules_env_markers(monkeypatch, tmp_path):
    class options:
        skip_incompatible = True

        def ignore_reqs(self, modname):
            return False

    fake_requirements_file = tmp_path / 'requirements.txt'
    fake_requirements_file.write_text('spam==1; python_version<"2.0"\n'
                                      'ham==2;\n'
                                      'eggs==3\n')

    reqs = common.find_required_modules(
        options=options(),
        requirements_filename=str(fake_requirements_file),
    )
    assert reqs == {'ham', 'eggs'}

def test_find_imported_modules_sets_encoding_to_utf8_when_reading(tmp_path):
    (tmp_path / 'module.py').touch()

    class options:
        paths = [tmp_path]

        def ignore_files(*_):
            return False

    expected_encoding = 'utf-8'
    used_encoding = None

    original_open = common.__builtins__['open']

    def mocked_open(*args, **kwargs):
        # As of Python 3.9, the args to open() are as follows:
        # file, mode, buffering, encoding, erorrs, newline, closedf, opener
        nonlocal used_encoding
        if 'encoding' in kwargs:
            used_encoding = kwargs['encoding']
        return original_open(*args, **kwargs)

    common.__builtins__['open'] = mocked_open
    common.find_imported_modules(options)
    common.__builtins__['open'] = original_open

    assert used_encoding == expected_encoding

def test_version_info_shows_version_number():
    assert __version__ in common.version_info()
<|endoftext|>


<commit_before>"""Facilities for grouping distributed hardware and search spaces.

Classes
-------
ComputeClass
    Group hardware by a common property.
"""
import uuid
import sys

from pyrameter.optimizer import FMin

class ComputeClass(object):
    """Group hardware by a common property.

    When working with heterogeneous distributed hardware (e.g., multiple
    clusters, multiple cloud services), it is often useful to group machines by
    a common resource. ComputeClass allows SHADHO to target specific hardware
    for running specific tasks. Hardware may be grouped by:

        * CPU count
        * Available RAM
        * GPU model
        * GPU count
        * Other accelerators
        * and by arbitrary, user-defined values.

    Parameters
    ----------
    name : str
        User-level name for the compute class (e.g. "8-core", "1080ti", etc.).
    resource : str
        The name of the resource common to this group.
    value
        The value of the resource common to this group.
    max_queued_tasks : int
        The maximum number of tasks to queue. Recommended to be 1.5-2x the
        number of expected nodes with this resource.

    Attributes
    ----------
    id : str
        Internal id of this ComputeClass.
    name : str
        User-level name for the compute class (e.g. "8-core", "1080ti", etc.).
    resource : str
        The name of the resource common to this group.
    value
        The value of the resource common to this group.
    max_queued_tasks : int
        The maximum number of tasks to queue. Recommended to be 1.5-2x the
        number of expected nodes with this resource.
    current_tasks : int
        The current number of queued tasks.

    See Also
    --------
    `pyrameter.ModelGroup`
    """
    def __init__(self, name, resource, value, max_queued_tasks):
        self.id = str(uuid.uuid4())
        self.name = name
        self.resource = resource
        self.value = value
        self.max_queued_tasks = max_queued_tasks
        self.current_tasks = 0
        self.searchspaces = []

    def __hash__(self):
        return hash((self.id, self.name, self.resource, self.value))

    def add_searchspace(self, searchspace):
        """Add a search space to this compute class.

        Parameters
        ----------
        searchspace : `pyrameter.searchspace.SearchSpace` or list
            The search space(s) to add to this compute class.
        """
        if isinstance(searchspace, list):
            self.searchspaces.extend(searchspace)
        else:
            self.searchspaces.append(searchspace)

    def remove_searchspace(self, ssid):
        """Remove a search space from this compute class.

        Parameters
        ----------
        model_id : str
        """
        idx = None
        for i, ss in enumerate(self.searchspaces):
            if ss.id == ssid:
                idx = i
                break
        if idx is not None:
            self.searchspaces.pop(idx)

    def clear(self):
        """Remove all models from this compute class."""
        self.searchspaces = []

<commit_msg>documentation<commit_after>"""Facilities for grouping distributed hardware and search spaces.

Classes
-------
ComputeClass
    Group hardware by a common property.
"""
import uuid
import sys

from pyrameter.optimizer import FMin

class ComputeClass(object):
    """Group hardware by a common property.

    When working with heterogeneous distributed hardware (e.g., multiple
    clusters, multiple cloud services), it is often useful to group machines by
    a common resource. ComputeClass allows SHADHO to target specific hardware
    for running specific tasks. Hardware may be grouped by:

        * CPU count
        * Available RAM
        * GPU model
        * GPU count
        * Other accelerators
        * and by arbitrary, user-defined values.

    Parameters
    ----------
    name : str
        User-level name for the compute class (e.g. "8-core", "1080ti", etc.).
    resource : str
        The name of the resource common to this group.
    value
        The value of the resource common to this group.
    max_queued_tasks : int
        The maximum number of tasks to queue. Recommended to be 1.5-2x the
        number of expected nodes with this resource.

    Attributes
    ----------
    id : str
        Internal id of this ComputeClass.
    name : str
        User-level name for the compute class (e.g. "8-core", "1080ti", etc.).
    resource : str
        The name of the resource common to this group.
    value
        The value of the resource common to this group.
    max_queued_tasks : int
        The maximum number of tasks to queue. Recommended to be 1.5-2x the
        number of expected nodes with this resource.
    current_tasks : int
        The current number of queued tasks.
    searchspaces : list of `pyrameter.searchspace.SearchSpace`
        The search spaces assigned to this compute class.
    """
    def __init__(self, name, resource, value, max_queued_tasks):
        self.id = str(uuid.uuid4())
        self.name = name
        self.resource = resource
        self.value = value
        self.max_queued_tasks = max_queued_tasks
        self.current_tasks = 0
        self.searchspaces = []

    def __hash__(self):
        return hash((self.id, self.name, self.resource, self.value))

    def add_searchspace(self, searchspace):
        """Add a search space to this compute class.

        Parameters
        ----------
        searchspace : `pyrameter.searchspace.SearchSpace` or list
            The search space(s) to add to this compute class.
        """
        if isinstance(searchspace, list):
            self.searchspaces.extend(searchspace)
        else:
            self.searchspaces.append(searchspace)

    @property
    def hungry(self):
        """Determine if the compute class has room for more tasks.

        Returns
        -------
        hungry : bool
            True if more tasks may be submitted to this compute class,
            False if it is full.
        """
        return self.current_tasks < self.max_queued_tasks

    def remove_searchspace(self, ssid):
        """Remove a search space from this compute class.

        Parameters
        ----------
        model_id : str
        """
        idx = None
        for i, ss in enumerate(self.searchspaces):
            if ss.id == ssid:
                idx = i
                break
        if idx is not None:
            self.searchspaces.pop(idx)

    def clear(self):
        """Remove all models from this compute class."""
        self.searchspaces = []

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from logging.config import fileConfig

from alembic import context
from sqlalchemy import engine_from_config, pool

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)

# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
from flask import current_app
config.set_main_option(
    'sqlalchemy.url', current_app.config.get('SQLALCHEMY_DATABASE_URI')
)
target_metadata = current_app.extensions['migrate'].db.metadata

# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.

def run_migrations_offline():
    """
    Run migrations in 'offline' mode.

    This configures the context with just a URL
    and not an Engine, though an Engine is acceptable
    here as well.  By skipping the Engine creation
    we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.

    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(url=url, compare_type=True)

    with context.begin_transaction():
        context.run_migrations()

def run_migrations_online():
    """
    Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    engine = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix='sqlalchemy.', poolclass=pool.NullPool
    )

    connection = engine.connect()
    context.configure(
        connection=connection, target_metadata=target_metadata,
        compare_type=True)

    try:
        with context.begin_transaction():
            context.run_migrations()
    finally:
        connection.close()

if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()
<commit_msg>Touched up formatting and PEP8 compliance of Alembic env.py<commit_after># -*- coding: utf-8 -*-
from logging.config import fileConfig

from alembic import context
from flask import current_app
from sqlalchemy import engine_from_config, pool

# This is the Alembic Config object, which provides access to the values
# within the .ini file in use.
config = context.config

# Interpret the config file for Python logging. This line sets up loggers
# basically.
fileConfig(config.config_file_name)

# Adding the model's MetaData object here for 'autogenerate' support.
config.set_main_option(
    'sqlalchemy.url', current_app.config.get('SQLALCHEMY_DATABASE_URI')
)
target_metadata = current_app.extensions['migrate'].db.metadata

# Other values from the config, defined by the needs of env.py,
# can be acquired:
#
# my_important_option = config.get_main_option("my_important_option")
# ... etc.

def run_migrations_offline():
    """
    Run migrations in 'offline' mode.

    This configures the context with just a URL and not an Engine,
    though an Engine is acceptable here as well.  By skipping the
    Engine creation we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the
    script output.
    """
    url = config.get_main_option("sqlalchemy.url")
    context.configure(url=url, compare_type=True)

    with context.begin_transaction():
        context.run_migrations()

def run_migrations_online():
    """
    Run migrations in 'online' mode.

    In this scenario we need to create an Engine and associate a
    connection with the context.
    """
    engine = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix='sqlalchemy.', poolclass=pool.NullPool
    )

    connection = engine.connect()
    context.configure(
        connection=connection, target_metadata=target_metadata,
        compare_type=True)

    try:
        with context.begin_transaction():
            context.run_migrations()
    finally:
        connection.close()

if context.is_offline_mode():
    run_migrations_offline()
else:
    run_migrations_online()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# Created By: Virgil Dupras
# Created On: 2010-02-06
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "HS" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/hs_license

# Interfaces for proxies in cocoalib

import logging

import objc

from ..reg import InvalidCodeError
from .objcmin import NSObject

if objc.__version__ == '1.4':
    # we're 32 bit and the _C_NSInteger and _C_CGFloat consts aint there.
    signature = objc.signature
else:
    def signature(signature):
        """Returns an objc.signature with 'i' and 'f' letters changed to correct NSInteger and
        CGFloat values.
        """
        signature = signature.replace('i', objc._C_NSInteger)
        signature = signature.replace('I', objc._C_NSUInteger)
        signature = signature.replace('f', objc._C_CGFloat)
        return objc.signature(signature)

class PyGUIObject(NSObject):
    def initWithCocoa_pyParent_(self, cocoa, pyparent):
        super(PyGUIObject, self).init()
        self.cocoa = cocoa
        self.py = self.py_class(self, pyparent.py)
        return self

    def connect(self):
        if hasattr(self.py, 'connect'):
            self.py.connect()

    def disconnect(self):
        if hasattr(self.py, 'disconnect'):
            self.py.disconnect()

    def free(self):
        # call this method only when you don't need to use this proxy anymore. you need to call this
        # if you want to release the cocoa side (self.cocoa is holding a refcount)
        # We don't delete py, it might be called after the free. It will be garbage collected anyway.
        # The if is because there is something happening giving a new ref to cocoa right after
        # the free, and then the ref gets to 1 again, free is called again.
        self.disconnect()
        if hasattr(self, 'cocoa'):
            del self.cocoa

    #--- Python -> Cocoa
    def refresh(self):
        self.cocoa.refresh()

class PyOutline(PyGUIObject):
    def cancelEdits(self):
        self.py.cancel_edits()

    @signature('c@:@@')
    def canEditProperty_atPath_(self, property, path):
        node = self.py.get_node(path)
        assert node is self.py.selected
        return getattr(node, 'can_edit_' + property, False)

    def saveEdits(self):
        self.py.save_edits()

    def selectedPath(self):
        return self.py.get_path(self.py.selected)

    def setSelectedPath_(self, path):
        self.py.selected_path = path

    def property_valueAtPath_(self, property, path):
        try:
            return getattr(self.py.get_node(path), property)
        except IndexError:
            logging.warning(u"%r doesn't have a node at path %r", self.py, path)
            return u''

    def setProperty_value_atPath_(self, property, value, path):
        setattr(self.py.get_node(path), property, value)

    #--- Python -> Cocoa
    def start_editing(self):
        self.cocoa.startEditing()

    def stop_editing(self):
        self.cocoa.stopEditing()

    def update_selection(self):
        self.cocoa.updateSelection()

class PyRegistrable(NSObject):
    def appName(self):
        return ""

    def demoLimitDescription(self):
        return self.py.DEMO_LIMIT_DESC

    @signature('c@:')
    def isRegistered(self):
        return self.py.registered

    def isCodeValid_withEmail_(self, code, email):
        try:
            self.py.validate_code(code, email)
            return None
        except InvalidCodeError as e:
            return unicode(e)

    def setRegisteredCode_andEmail_(self, code, email):
        self.py.set_registration(code, email)

<commit_msg>Added multiple selection support to PyOutline interface.<commit_after># -*- coding: utf-8 -*-
# Created By: Virgil Dupras
# Created On: 2010-02-06
# Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
#
# This software is licensed under the "HS" License as described in the "LICENSE" file,
# which should be included with this package. The terms are also available at
# http://www.hardcoded.net/licenses/hs_license

# Interfaces for proxies in cocoalib

import logging

import objc

from ..reg import InvalidCodeError
from .objcmin import NSObject

if objc.__version__ == '1.4':
    # we're 32 bit and the _C_NSInteger and _C_CGFloat consts aint there.
    signature = objc.signature
else:
    def signature(signature):
        """Returns an objc.signature with 'i' and 'f' letters changed to correct NSInteger and
        CGFloat values.
        """
        signature = signature.replace('i', objc._C_NSInteger)
        signature = signature.replace('I', objc._C_NSUInteger)
        signature = signature.replace('f', objc._C_CGFloat)
        return objc.signature(signature)

class PyGUIObject(NSObject):
    def initWithCocoa_pyParent_(self, cocoa, pyparent):
        super(PyGUIObject, self).init()
        self.cocoa = cocoa
        self.py = self.py_class(self, pyparent.py)
        return self

    def connect(self):
        if hasattr(self.py, 'connect'):
            self.py.connect()

    def disconnect(self):
        if hasattr(self.py, 'disconnect'):
            self.py.disconnect()

    def free(self):
        # call this method only when you don't need to use this proxy anymore. you need to call this
        # if you want to release the cocoa side (self.cocoa is holding a refcount)
        # We don't delete py, it might be called after the free. It will be garbage collected anyway.
        # The if is because there is something happening giving a new ref to cocoa right after
        # the free, and then the ref gets to 1 again, free is called again.
        self.disconnect()
        if hasattr(self, 'cocoa'):
            del self.cocoa

    #--- Python -> Cocoa
    def refresh(self):
        self.cocoa.refresh()

class PyOutline(PyGUIObject):
    def cancelEdits(self):
        self.py.cancel_edits()

    @signature('c@:@@')
    def canEditProperty_atPath_(self, propname, path):
        node = self.py.get_node(path)
        assert node is self.py.selected_node
        return getattr(node, 'can_edit_' + propname, False)

    def saveEdits(self):
        self.py.save_edits()

    def selectedPath(self):
        return self.py.selected_path

    def setSelectedPath_(self, path):
        self.py.selected_path = path

    def selectedPaths(self):
        return self.py.selected_paths

    def setSelectedPaths_(self, paths):
        self.py.selected_paths = paths

    def property_valueAtPath_(self, property, path):
        try:
            return getattr(self.py.get_node(path), property)
        except IndexError:
            logging.warning(u"%r doesn't have a node at path %r", self.py, path)
            return u''

    def setProperty_value_atPath_(self, property, value, path):
        setattr(self.py.get_node(path), property, value)

    #--- Python -> Cocoa
    def start_editing(self):
        self.cocoa.startEditing()

    def stop_editing(self):
        self.cocoa.stopEditing()

    def update_selection(self):
        self.cocoa.updateSelection()

class PyRegistrable(NSObject):
    def appName(self):
        return ""

    def demoLimitDescription(self):
        return self.py.DEMO_LIMIT_DESC

    @signature('c@:')
    def isRegistered(self):
        return self.py.registered

    def isCodeValid_withEmail_(self, code, email):
        try:
            self.py.validate_code(code, email)
            return None
        except InvalidCodeError as e:
            return unicode(e)

    def setRegisteredCode_andEmail_(self, code, email):
        self.py.set_registration(code, email)

<|endoftext|>


<commit_before>import abc
from typing import Any, List, Callable

class Compilable(abc.ABC):
    """
    A base class for all compileables
    """
    @abc.abstractmethod
    def compile(self) -> str:
        """
        :return: Compiled string
        """

    def __repr__(self):
        return self.compile()

    def __eq__(self, other: str) -> bool:
        return self.compile() == other

class Variable(Compilable):
    """
    A base for variables
    """
    def __init__(self, value: Any):
        self.value = value

    def compile(self) -> str:
        return ""

class Provider(object):
    """
    A dynamic class which itself is not compilable, but its methods - are
    """
    def __init__(self, name):
        self.name = name
        self.assignments = []

    def __getattr__(self, item: str) -> Callable:
        if item in self.__dict__:
            return self[item]

        def caller(*args: List[str]) -> str:
            content = "{0}.{1}({2})".format(self.name, item, ",".join(args))
            return Promise(content)

        return caller

    def __setattr__(self, key: str, value: str):
        special = {"name", "assignments"}
        if key in special:
            super().__setattr__(key, value)
        else:
            self.assignments.append(SimpleDeclare("{0}.{1}".format(self.name, key), value))

    def __setitem__(self, key: str, value: str):
        return self.__setattr__(key, value)

    def __getitem__(self, key: str):
        return self.__getattr__(key)

class Expression(Variable):
    """
    For cases when expression is needed as a variable
    """
    def compile(self) -> str:
        return "{0}".format(self.value)

class String(Variable):
    """
    A string variable representation
    """
    def compile(self) -> str:
        return "\"{0}\"".format(self.value)

class Number(Variable):
    """
    A number variable representation
    """
    def compile(self) -> str:
        return "{0}".format(self.value)

class SimpleDeclare(Compilable):
    """
    Builder for variable declaration
    """
    def __init__(self, name: str, value: Compilable, private: bool=False):
        self.name = name
        self.value = value
        self.private = private

    def compile(self):
        return "{0} {1} = {2};".format("var" if self.private else "", self.name, self.value).strip()

class Object(Compilable):
    """
    Class builder
    """
    def __init__(self):
        self.members = []

    def compile(self):
        body = ",\n".join(["\"{0}\": {1}".format(key, val.compile()) for key, val in self.members])
        content = "{{\n {0} \n}}".format(body)

        return content

    def add_member(self, name: str, content: Compilable):
        self.members.append((name, content))

class Function(Compilable):
    """
    Function builder
    """
    def __init__(self, params: List=None, body: List=None, returns: Compilable=None):
        self.params = params if params else []
        self.body = body if body else []
        self.returns = returns

    def compile(self):
        def create_params():
            return ",".join(self.params)

        def create_body():
            return "\n\t".join([comp.compile() for comp in self.body])

        def create_return():
            if self.returns:
                return "\treturn {0};".format(self.returns.compile())
            else:
                return ""

        return "function({0}){{\n {1} \n{2}\n}}".format(create_params(), create_body(), create_return())

class Promise(Compilable):
    def __init__(self, content):
        self.content = content

    def compile(self) -> str:
        return self.content

    def resolve(self, body: Function) -> str:
        return "{0}.then({1});".format(self.compile(), body.compile())

def unwraps(promise: Promise=None, parent: str=None) -> tuple:
    """
    A helper function which unwraps promise by executing and returning result inline.
    :param promise: promise function to unwrap
    :param parent: provide parent parameter name if desired to fill existing variable
    :returns: 'body', 'returns'. To be used as Function object parameter
    """
    body = []
    if parent:
        result_val = parent
    else:
        body.append(SimpleDeclare("result", "[]", private=True))
        result_val = "result"

    body.append(Expression(promise.resolve(Function(["response"],
                                                    body=[
                                                        Expression("""
                                                        angular.forEach(response.data, function(val){
                                                            {0}.push(val);
                                                            })
                                                        """.format(result_val))]))))
    returns = Expression(result_val)
    return body, returns
<commit_msg>Ability to get variables, not just method calls, from Provider<commit_after>import abc
from typing import Any, List, Callable

class Compilable(abc.ABC):
    """
    A base class for all compileables
    """
    @abc.abstractmethod
    def compile(self) -> str:
        """
        :return: Compiled string
        """

    def __repr__(self):
        return self.compile()

    def __eq__(self, other: str) -> bool:
        return self.compile() == other

class Variable(Compilable):
    """
    A base for variables
    """
    def __init__(self, value: Any):
        self.value = value

    def compile(self) -> str:
        return ""

class Arg(object):
    def __init__(self, onstr: str, oncall: Callable):
        self.onstr = onstr
        self.oncall = oncall

    def compile(self):
        return self.onstr

    def __call__(self, *args, **kwargs):
        return self.oncall(*args, **kwargs)

class Provider(object):
    """
    A dynamic class which itself is not compilable, but its methods - are
    """
    def __init__(self, name):
        self.name = name
        self.assignments = []

    def __getattr__(self, item: str) -> Callable:
        if item in self.__dict__:
            return self[item]

        def caller(*args: List[str]) -> Compilable:
            content = "{0}.{1}({2})".format(self.name, item, ",".join(args))
            return Promise(content)

        return Arg(Expression("{0}.{1}".format(self.name, item)).compile(), caller)

    def __setattr__(self, key: str, value: str):
        special = {"name", "assignments"}
        if key in special:
            super().__setattr__(key, value)
        else:
            self.assignments.append(SimpleDeclare("{0}.{1}".format(self.name, key), value))

    def __setitem__(self, key: str, value: str):
        return self.__setattr__(key, value)

    def __getitem__(self, key: str):
        return self.__getattr__(key)

class Expression(Variable):
    """
    For cases when expression is needed as a variable
    """
    def compile(self) -> str:
        return "{0}".format(self.value)

class String(Variable):
    """
    A string variable representation
    """
    def compile(self) -> str:
        return "\"{0}\"".format(self.value)

class Number(Variable):
    """
    A number variable representation
    """
    def compile(self) -> str:
        return "{0}".format(self.value)

class SimpleDeclare(Compilable):
    """
    Builder for variable declaration
    """
    def __init__(self, name: str, value: Compilable, private: bool=False):
        self.name = name
        self.value = value
        self.private = private

    def compile(self):
        return "{0} {1} = {2};".format("var" if self.private else "", self.name, self.value).strip()

class Object(Compilable):
    """
    Class builder
    """
    def __init__(self):
        self.members = []

    def compile(self):
        body = ",\n".join(["\"{0}\": {1}".format(key, val.compile()) for key, val in self.members])
        content = "{{\n {0} \n}}".format(body)

        return content

    def add_member(self, name: str, content: Compilable):
        self.members.append((name, content))

class Function(Compilable):
    """
    Function builder
    """
    def __init__(self, params: List=None, body: List=None, returns: Compilable=None):
        self.params = params if params else []
        self.body = body if body else []
        self.returns = returns

    def compile(self):
        def create_params():
            return ",".join(self.params)

        def create_body():
            return "\n\t".join([comp.compile() for comp in self.body])

        def create_return():
            if self.returns:
                return "\treturn {0};".format(self.returns.compile())
            else:
                return ""

        return "function({0}){{\n {1} \n{2}\n}}".format(create_params(), create_body(), create_return())

class Promise(Compilable):
    def __init__(self, content):
        self.content = content

    def compile(self) -> str:
        return self.content

    def resolve(self, body: Function) -> str:
        return "{0}.then({1});".format(self.compile(), body.compile())

def unwraps(promise: Promise=None, parent: str=None) -> tuple:
    """
    A helper function which unwraps promise by executing and returning result inline.
    :param promise: promise function to unwrap
    :param parent: provide parent parameter name if desired to fill existing variable
    :returns: 'body', 'returns'. To be used as Function object parameter
    """
    body = []
    if parent:
        result_val = parent
    else:
        body.append(SimpleDeclare("result", "[]", private=True))
        result_val = "result"

    body.append(Expression(promise.resolve(Function(["response"],
                                                    body=[
                                                        Expression("""
                                                        angular.forEach(response.data, function(val){{
                                                            {0}.push(val);
                                                            }})
                                                        """.format(result_val))]))))
    returns = Expression(result_val)
    return body, returns
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
Created on Tue Oct 20 17:40:07 2015

@author: casimp
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
from edi12.peak_fitting import cos_
from edi12.plotting import plot_complex

class XRD_plotting():
    """
    Takes post-processed .nxs file from the I12 EDXD detector. File should have
    been created with the XRD_analysis tool and contain detector specific peaks
    and associated strain.
    """
    def __init__(self):
        pass

    def plot_intensity(self, detector = 0, point = ()):
        """
        Plots q v intensity. *Not implemented for merged files.*

        # detector:   0 based indexing - 0 (default) to 23 - detector 23 empty.
        # point:      Define point (index) from which to extract q v I plot.
                      First point in array chosen if not (default) specified.
        """
        try:
            group = self.f['entry1']['EDXD_elements']
            q = group['edxd_q'][detector]
            if point == ():
                point = (0, ) * len(self.dims)
            assert len(self.dims) == len(point), 'must define point with correct '\
                                     'number of dimensions.'
            I = group['data'][point][detector]

            plt.plot(q, I)
        except (NameError, AttributeError):
            print("Can't plot spectrum on merged data.")

    def plot_fitted(self, point = (), q_idx = 0, figsize = (7, 5)):
        """
        Plots fitted in-plane strain field for given data point.
        *Not implemented for merged files.*

        # point:      Define point (index) from which to plot fitted in-plane
                      strain field.
        # q_idx:      0 based indexing - 0 (default) to 23 - detector 23 empty.
        # figsize:    Figure dimensions
        """
        if point == ():
            point = (0, ) * len(self.dims)

        assert len(self.dims) == len(point), 'must define point with correct '\
                                             'number of dimensions.'

        plt.figure(figsize = figsize)
        p = self.strain_param[point][q_idx]
        theta = np.linspace(0, np.pi, 23)
        plt.plot(theta, self.strain[point][..., q_idx][:-1], 'k*')
        theta_2 = np.linspace(0, np.pi, 1000)
        plt.plot(theta_2, cos_(theta_2, *p), 'k-')
        plt.xlabel('Detector angle (rad)')
        plt.ylabel('Strain')

    def plot_mohrs(self, point = (0), q_idx = 0, angle = 0, figsize = (7, 5)):
        """
        Use fitted in-plane styrain tensor to plot Mohr's circle.
        *Not implemented for merged files.*

        # point:      Define point (index) from which to plot fitted in-plane
                      strain field.
        # q_idx:      0 based indexing - 0 (default) to 23 - detector 23 empty.
        # angle:      Angle to highlight on circle (inc + 90deg).
        # figsize:    Figure dimensions
        """
        p = self.strain_param[point][q_idx][0] ### test change
        R = p[0]
        theta = p[1] + angle

        e_xx, e_yy = cos_(angle, *p), cos_(angle + np.pi/2, *p)
        e_1, e_2 = (p[2] + abs(p[0])), (p[2] - abs(p[0]))
        tau_xy = -np.sin(2 * theta) * ((p[2] + p[0]) - (p[2] - p[0]))/2

        fig = plt.figure(figsize = figsize)
        plt.axis('equal')
        ax = fig.add_subplot(1, 1, 1)
        circ = plt.Circle((p[2], 0), radius=R, color='k', fill = False)

        ax.add_patch(circ)

        plt.xlim([p[2] - abs(2 * R), p[2] + abs(2 * R)])
        plt.plot([e_1, e_2], [0, 0], 'ko', markersize = 3)

        plt.plot(e_xx, tau_xy, 'ko', label = r'$(\epsilon_{xx}$, $\tau_{xy})$')
        plt.plot(e_yy, -tau_xy, 'wo', label = r'$(\epsilon_{yy}$, $-\tau_{xy})$')

        plt.legend(numpoints=1, frameon = False, handletextpad = 0.2)
        plt.plot([e_xx, e_yy], [tau_xy, -tau_xy], 'k-.')
        ax.annotate('  %s' % r'$\epsilon_{1}$', xy=(e_1, 0), textcoords='offset points')
        ax.annotate('  %s' % r'$\epsilon_{2}$', xy=(e_2, 0), textcoords='offset points')

    def plot_line(self, detector = 0, q0_index = 0, axis = 'scalar',
                  pnt = (0, 0), angle = 0, npnts = 100, method = 'linear'):
        """
        Plots a line profile through a 2D strain field - extract_line method
        must be run first. *Not yet implemented in 3D.*

        # detector:   0 based indexing - 0 (default) to 23 - detector 23 empty.
        # q0_index:   Specify lattice parameter/peak to display.
        # axis:       Plot strain against the 'x', 'y' or 'scalar' (default)
                      position. 'scalar' co-ordinates re-zeroed/centred against
                      point specified in the extract_line command.
        """
        A = self.extract_line()
        plt.plot(A[0], A[2][..., 0, 0], '-*')

    def plot_detector(self, detector = 0, q_idx = 0, cmap = 'RdBu_r', res = 10,
                 lvls = 11, figsize = (10, 10), plotting = plot_complex,
                 line = False, line_props = 'w--', mark = None):
        """
        Plot a 2D heat map of the strain field. *Not yet implemented in 3D.*

        # detector:   0 based indexing - 0 (default) to 23 - detector 23 empty.
        # q0_index:   Specify lattice parameter/peak to display.
        # res:        Resolution in points per unit length (of raw data)
                      - only implemented for merged data
        # cmap:       The colormap (default - 'RdBu_r') to use for plotting
        # lvls:       Number of contours to overlay on map. Can also explicitly
                      define levels.
        # figsize:    Tuple containing the fig size (x, y) - default (10, 10).
                      Constrained by axis being equal.

        Additional functionality allows for the overlaying of a line on top of
        the map - to be used in conjunction with the line plotting.

        # line:       Plot line (default = False)
        # line_props: Define line properties (default = 'w-')
        # mark:       Mark properties for centre point of line (default = None)
        """
        assert len(self.dims) == 2, 'plotting method only compatible with \
                                     2d data sets'

        d1, d2 = [self.co_ords[x] for x in self.dims]

        if self.strain[..., 0, 0].ndim != 2:
            # Data point spacing based on resolution
            d1_points = np.ceil(res * (np.max(d1) - np.min(d1)))
            d2_points = np.ceil(res * (np.max(d2) - np.min(d2)))
            # Data point location
            d1_ = np.linspace(np.min(d1), np.max(d1), d1_points)
            d2_ = np.linspace(np.min(d2), np.max(d2), d2_points)
            D1, D2 = np.meshgrid(d1_, d2_)
            Z = griddata((d1.flatten(), d2.flatten()),
                          self.strain[..., detector, q_idx].flatten(), (D1, D2))
        else:
            D1, D2 = d1, d2
            Z = self.strain[..., detector, q_idx]
        f, ax = plotting(d1, d2, D1, D2, Z, cmap, lvls, figsize)

############ UNFINISHED ###############

        if line == True:
            A = self.extract_line(pnt = (0, 0), angle = 0, npnts = 100, method = 'linear')
            ax.plot(A[0], A[1], line_props, linewidth = 2)
            plt.figure()
            self.plot_line(detector, q_idx, axis = 'scalar', pnt = (0, 0), angle = 0, npnts = 100, method = 'linear')
            #if mark != None:
             #   ax.plot(self.line_centre[0], self.line_centre[1], mark)

    def plot_angle(self, angle = 0, shear = False, q_idx = 0, cmap = 'RdBu_r',
                 res = 10, lvls = 11, figsize = (10, 10), plotting = plot_complex,
                 line = False, line_props = 'w--', mark = None):
        """
        Plot a 2D heat map of the strain field. *Not yet implemented in 3D.*

        # angle:      Angle in radians - default (0).
        # q0_index:   Specify lattice parameter/peak to display.
        # res:        Resolution in points per unit length (of raw data)
                      - only implemented for merged data
        # cmap:       The colormap (default - 'RdBu_r') to use for plotting
        # lvls:       Number of contours to overlay on map. Can also explicitly
                      define levels.
        # figsize:    Tuple containing the fig size (x, y) - default (10, 10).
                      Constrained by axis being equal.

        Additional functionality allows for the overlaying of a line on top of
        the map - to be used in conjunction with the line plotting.

        # line:       Plot line (default = False)
        # line_props: Define line properties (default = 'w-')
        # mark:       Mark properties for centre point of line (default = None)
        """

        assert len(self.dims) == 2, 'plotting method only compatible with \
                                     2d data sets'

        d1, d2 = [self.co_ords[x] for x in self.dims]
        strain_field = np.nan * self.strain[..., 0, 0]
        for idx in np.ndindex(strain_field.shape):
            p = self.strain_param[idx][0]
            if shear == True:
                e_1, e_2 = (p[2] + p[0]), (p[2] - p[0])
                theta = p[1]
                tau_xy = -np.sin(2 * theta + angle) * (e_1 - e_2)/2
                strain_field[idx] = tau_xy
            else:
                strain_field[idx] = cos_(angle, *p)

        # Testing whether it is merged (and therefore flattened) data
        if self.strain[..., 0, 0].ndim != 2:
            # Data point spacing based on resolution
            d1_points = np.ceil(res * (np.max(d1) - np.min(d1)))
            d2_points = np.ceil(res * (np.max(d2) - np.min(d2)))
            # Data point location
            d1_ = np.linspace(np.min(d1), np.max(d1), d1_points)
            d2_ = np.linspace(np.min(d2), np.max(d2), d2_points)
            D1, D2 = np.meshgrid(d1_, d2_)
            Z = griddata((d1.flatten(), d2.flatten()),
                         strain_field.flatten(), (D1, D2))
        else:
            D1, D2 = d1, d2
            Z = strain_field

        f, ax = plotting(d1, d2, D1, D2, Z, cmap, lvls, figsize)

<commit_msg>Added shear stress plotting to plot_line, added line plotting to angle map. Bug fixes.<commit_after># -*- coding: utf-8 -*-
"""
Created on Tue Oct 20 17:40:07 2015

@author: casimp
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
from edi12.peak_fitting import cos_
from edi12.plotting import plot_complex

class XRD_plotting():
    """
    Takes post-processed .nxs file from the I12 EDXD detector. File should have
    been created with the XRD_analysis tool and contain detector specific peaks
    and associated strain.
    """
    def __init__(self):
        pass

    def plot_intensity(self, detector = 0, point = ()):
        """
        Plots q v intensity. *Not implemented for merged files.*

        # detector:   0 based indexing - 0 (default) to 23 - detector 23 empty.
        # point:      Define point (index) from which to extract q v I plot.
                      First point in array chosen if not (default) specified.
        """
        try:
            group = self.f['entry1']['EDXD_elements']
            q = group['edxd_q'][detector]
            if point == ():
                point = (0, ) * len(self.dims)
            assert len(self.dims) == len(point), 'must define point with correct '\
                                     'number of dimensions.'
            I = group['data'][point][detector]

            plt.plot(q, I)
        except (NameError, AttributeError):
            print("Can't plot spectrum on merged data.")

    def plot_fitted(self, point = (), q_idx = 0, figsize = (7, 5)):
        """
        Plots fitted in-plane strain field for given data point.
        *Not implemented for merged files.*

        # point:      Define point (index) from which to plot fitted in-plane
                      strain field.
        # q_idx:      0 based indexing - 0 (default) to 23 - detector 23 empty.
        # figsize:    Figure dimensions
        """
        if point == ():
            point = (0, ) * len(self.dims)

        assert len(self.dims) == len(point), 'must define point with correct '\
                                             'number of dimensions.'

        plt.figure(figsize = figsize)
        p = self.strain_param[point][q_idx]
        theta = np.linspace(0, np.pi, 23)
        plt.plot(theta, self.strain[point][..., q_idx][:-1], 'k*')
        theta_2 = np.linspace(0, np.pi, 1000)
        plt.plot(theta_2, cos_(theta_2, *p), 'k-')
        plt.xlabel('Detector angle (rad)')
        plt.ylabel('Strain')

    def plot_mohrs(self, point = (0), q_idx = 0, angle = 0, figsize = (7, 5)):
        """
        Use fitted in-plane styrain tensor to plot Mohr's circle.
        *Not implemented for merged files.*

        # point:      Define point (index) from which to plot fitted in-plane
                      strain field.
        # q_idx:      0 based indexing - 0 (default) to 23 - detector 23 empty.
        # angle:      Angle to highlight on circle (inc + 90deg).
        # figsize:    Figure dimensions
        """
        p = self.strain_param[point][q_idx][0] ### test change
        R = p[0]
        theta = p[1] + angle

        e_xx, e_yy = cos_(angle, *p), cos_(angle + np.pi/2, *p)
        e_1, e_2 = (p[2] + abs(p[0])), (p[2] - abs(p[0]))
        tau_xy = -np.sin(2 * theta) * ((p[2] + p[0]) - (p[2] - p[0]))/2

        fig = plt.figure(figsize = figsize)
        plt.axis('equal')
        ax = fig.add_subplot(1, 1, 1)
        circ = plt.Circle((p[2], 0), radius=R, color='k', fill = False)

        ax.add_patch(circ)

        plt.xlim([p[2] - abs(2 * R), p[2] + abs(2 * R)])
        plt.plot([e_1, e_2], [0, 0], 'ko', markersize = 3)

        plt.plot(e_xx, tau_xy, 'ko', label = r'$(\epsilon_{xx}$, $\tau_{xy})$')
        plt.plot(e_yy, -tau_xy, 'wo', label = r'$(\epsilon_{yy}$, $-\tau_{xy})$')

        plt.legend(numpoints=1, frameon = False, handletextpad = 0.2)
        plt.plot([e_xx, e_yy], [tau_xy, -tau_xy], 'k-.')
        ax.annotate('  %s' % r'$\epsilon_{1}$', xy=(e_1, 0), textcoords='offset points')
        ax.annotate('  %s' % r'$\epsilon_{2}$', xy=(e_2, 0), textcoords='offset points')

    def plot_line(self, az_angles = [0, np.pi/2], q_idx = 0, line_angle = 0,
                  pnt = (0, 0), npts = 100, axis = 'scalar', method = 'linear', detectors = [], e_xy = False):
        """
        Plots a line profile through a 2D strain field - extract_line method
        must be run first. *Not yet implemented in 3D.*

        # detector:   0 based indexing - 0 (default) to 23 - detector 23 empty.
        # q0_index:   Specify lattice parameter/peak to display.
        # axis:       Plot strain against the 'x', 'y' or 'scalar' (default)
                      position. 'scalar' co-ordinates re-zeroed/centred against
                      point specified in the extract_line command.
        """
        d1, d2, strain = self.extract_line(az_angles = az_angles, q_idx = q_idx,
                                line_angle = line_angle, pnt = pnt, npts = npts,
                                method = method, detectors = detectors, e_xy = e_xy)

        d1_min, d2_min = np.min(d1), np.min(d2)
        zero = ((pnt[0] - d1_min)**2 + (pnt[1] - d2_min)**2)**0.5
        scalar_ext = ((d1 - d1_min)**2 + (d2 - d2_min)**2)**0.5 - zero

        if axis == 'd1':
            plt.plot(d1, strain, '-*')
        elif axis == 'd2':
            plt.plot(d2, strain, '-*')
        else:
            plt.plot(scalar_ext, strain, '-*')

    def plot_detector(self, detector = 0, q_idx = 0, cmap = 'RdBu_r', res = 10,
                 lvls = 11, figsize = (10, 10), plotting = plot_complex,
                 line = False, pnt = (0,0), line_angle = 0, npts = 100,
                 method = 'linear', line_props = 'w--', mark = None):
        """
        Plot a 2D heat map of the strain field. *Not yet implemented in 3D.*

        # detector:   0 based indexing - 0 (default) to 23 - detector 23 empty.
        # q0_index:   Specify lattice parameter/peak to display.
        # res:        Resolution in points per unit length (of raw data)
                      - only implemented for merged data
        # cmap:       The colormap (default - 'RdBu_r') to use for plotting
        # lvls:       Number of contours to overlay on map. Can also explicitly
                      define levels.
        # figsize:    Tuple containing the fig size (x, y) - default (10, 10).
                      Constrained by axis being equal.

        Additional functionality allows for the overlaying of a line on top of
        the map - to be used in conjunction with the line plotting.

        # line:       Plot line (default = False)
        # line_props: Define line properties (default = 'w-')
        # mark:       Mark properties for centre point of line (default = None)
        """
        assert len(self.dims) == 2, 'plotting method only compatible with \
                                     2d data sets'

        d1, d2 = [self.co_ords[x] for x in self.dims]

        if self.strain[..., 0, 0].ndim != 2:
            # Data point spacing based on resolution
            d1_points = np.ceil(res * (np.max(d1) - np.min(d1)))
            d2_points = np.ceil(res * (np.max(d2) - np.min(d2)))
            # Data point location
            d1_ = np.linspace(np.min(d1), np.max(d1), d1_points)
            d2_ = np.linspace(np.min(d2), np.max(d2), d2_points)
            D1, D2 = np.meshgrid(d1_, d2_)
            Z = griddata((d1.flatten(), d2.flatten()),
                          self.strain[..., detector, q_idx].flatten(), (D1, D2))
        else:
            D1, D2 = d1, d2
            Z = self.strain[..., detector, q_idx]
        f, ax = plotting(d1, d2, D1, D2, Z, cmap, lvls, figsize)

        if line == True:
            d1, d2, strain = self.extract_line([], q_idx = q_idx, line_angle = line_angle, pnt = pnt,
                                    npts = npts,  method = method, detectors = [detector], save = False)

            print(d1, d2)

            ax.plot(d1, d2, line_props, linewidth = 2)
            plt.figure()
            self.plot_line(az_angles = [], q_idx = q_idx,
                           line_angle = line_angle, pnt = pnt, npts = npts,
                           method = method, detectors = [detector])
            #if mark != None:
             #   ax.plot(self.line_centre[0], self.line_centre[1], mark)

    def plot_angle(self, angle = 0, shear = False, q_idx = 0, cmap = 'RdBu_r',
                 res = 10, lvls = 11, figsize = (10, 10), plotting = plot_complex,
                 line = False, pnt = (0,0), line_angle = 0, npts = 100,
                 method = 'linear', line_props = 'w--', mark = None):
        """
        Plot a 2D heat map of the strain field. *Not yet implemented in 3D.*

        # angle:      Angle in radians - default (0).
        # q0_index:   Specify lattice parameter/peak to display.
        # res:        Resolution in points per unit length (of raw data)
                      - only implemented for merged data
        # cmap:       The colormap (default - 'RdBu_r') to use for plotting
        # lvls:       Number of contours to overlay on map. Can also explicitly
                      define levels.
        # figsize:    Tuple containing the fig size (x, y) - default (10, 10).
                      Constrained by axis being equal.

        Additional functionality allows for the overlaying of a line on top of
        the map - to be used in conjunction with the line plotting.

        # line:       Plot line (default = False)
        # line_props: Define line properties (default = 'w-')
        # mark:       Mark properties for centre point of line (default = None)
        """

        assert len(self.dims) == 2, 'plotting method only compatible with \
                                     2d data sets'

        d1, d2 = [self.co_ords[x] for x in self.dims]
        strain_field = np.nan * self.strain[..., 0, 0]
        for idx in np.ndindex(strain_field.shape):
            p = self.strain_param[idx][0]
            if shear == True:
                e_1, e_2 = (p[2] + p[0]), (p[2] - p[0])
                theta = p[1]
                tau_xy = -np.sin(2 * theta + angle) * (e_1 - e_2)/2
                strain_field[idx] = tau_xy
            else:
                strain_field[idx] = cos_(angle, *p)

        # Testing whether it is merged (and therefore flattened) data
        if self.strain[..., 0, 0].ndim != 2:
            # Data point spacing based on resolution
            d1_points = np.ceil(res * (np.max(d1) - np.min(d1)))
            d2_points = np.ceil(res * (np.max(d2) - np.min(d2)))
            # Data point location
            d1_ = np.linspace(np.min(d1), np.max(d1), d1_points)
            d2_ = np.linspace(np.min(d2), np.max(d2), d2_points)
            D1, D2 = np.meshgrid(d1_, d2_)
            Z = griddata((d1.flatten(), d2.flatten()),
                         strain_field.flatten(), (D1, D2))
        else:
            D1, D2 = d1, d2
            Z = strain_field

        f, ax = plotting(d1, d2, D1, D2, Z, cmap, lvls, figsize)

        if line == True:
            d1, d2, strain = self.extract_line([angle], q_idx = q_idx, line_angle = line_angle, pnt = pnt,
                                    npts = npts,  method = method, save = False)

            print(d1, d2)

            ax.plot(d1, d2, line_props, linewidth = 2)
            plt.figure()
            self.plot_line(az_angles = [angle], q_idx = q_idx,
                           line_angle = line_angle, pnt = pnt, npts = npts,
                           method = method)

<|endoftext|>


<commit_before>"""
sentry.tasks.base
~~~~~~~~~~~~~~~~~

:copyright: (c) 2010-2014 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import

from celery.task import current
from functools import wraps

from sentry.celery import app
from sentry.utils import metrics

def instrumented_task(name, stat_suffix=None, **kwargs):
    def wrapped(func):
        @wraps(func)
        def _wrapped(*args, **kwargs):
            key = 'jobs.duration'.format(name=name)
            if stat_suffix:
                instance = '{}.{}'.format(name, stat_suffix(*args, **kwargs))
            else:
                instance = name
            with metrics.timer(key, instance=instance):
                result = func(*args, **kwargs)
            return result
        return app.task(name=name, **kwargs)(_wrapped)
    return wrapped

def retry(func):
    @wraps(func)
    def wrapped(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as exc:
            current.retry(exc=exc)
    return wrapped
<commit_msg>Unused format call<commit_after>"""
sentry.tasks.base
~~~~~~~~~~~~~~~~~

:copyright: (c) 2010-2014 by the Sentry Team, see AUTHORS for more details.
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import

from celery.task import current
from functools import wraps

from sentry.celery import app
from sentry.utils import metrics

def instrumented_task(name, stat_suffix=None, **kwargs):
    def wrapped(func):
        @wraps(func)
        def _wrapped(*args, **kwargs):
            key = 'jobs.duration'
            if stat_suffix:
                instance = '{}.{}'.format(name, stat_suffix(*args, **kwargs))
            else:
                instance = name
            with metrics.timer(key, instance=instance):
                result = func(*args, **kwargs)
            return result
        return app.task(name=name, **kwargs)(_wrapped)
    return wrapped

def retry(func):
    @wraps(func)
    def wrapped(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as exc:
            current.retry(exc=exc)
    return wrapped
<|endoftext|>