from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
from scipy.spatial import distance as dist
import glob
import re
import os
from PyQt5 import QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
import cv2
import pandas as pd
from PyQt5.Qt import *
import pyqtgraph as pg
#from PyQt4.Qt import *
#%%
class eggUI(QDialog):
    '''
    createOpenCVEggROI : take eggID defined ROIs and visualise
    
    '''
    sliderUpdate = QtCore.pyqtSignal()
    embryoUpdate = QtCore.pyqtSignal()
    keyPressed = QtCore.pyqtSignal()
    
    def __init__(self, parent=None):
        super(eggUI, self).__init__(parent)
        # Make QDialog
        self.diag = QtGui.QDialog()
        global parentPath, vidTime
        self.diag.setWindowTitle('Identify eggs')
        self.diag.imv = pg.ImageView()
        self.btn_save = QPushButton('Save', self)

#==============================================================================
# 
#==============================================================================
    def showUI(self,ims,eggRotBBox, eggBoxPoints, embryoLabels, eggInt):
        self.eggInt = eggInt
        self.embryoLabels = embryoLabels
        self.diag.setWindowTitle('Identify eggs')
        # Make ImageView
        self.diag.imv = pg.ImageView()
        self.diag.resize(1000,600)
        # Make ROI
        self.importOpenCVROIs(eggRotBBox, eggBoxPoints)
        if (eggRotBBox[0][0][0] != 'nan'): 
            self.createOpenCVEggROI()
            self.diag.imv.addItem(self.roi)
        # Remove buttons from ImageView widget
        self.diag.imv.ui.roiBtn.hide()
        self.diag.imv.ui.menuBtn.hide()
        # Make tableview
        self.diag.table = QtGui.QTableWidget()
        self.diag.table.setShowGrid(True)
        self.diag.table.setHorizontalHeaderLabels(['Embryo', 'Sorted'])
        # Sets different alignment data just on the first column
        self.diag.table.setRowCount(int(len(self.embryoLabels)))
        self.diag.table.setColumnCount(2)
        # Highlight first row
        self.diag.table.selectRow(0)
        # Make layout
        checkLayout = QGridLayout()
        # Deal with stretching for approrpraite formatting.
        checkLayout.setColumnStretch(0, 3)
        checkLayout.setColumnStretch(1, 1)
        checkLayout.setRowStretch(0, 1)
        checkLayout.setRowStretch(1, 3)
        # Add to layout
        checkLayout.addWidget(self.diag.imv,0,0,2,2)
        checkLayout.addWidget(self.diag.table,1,5)
        # Apply layout
        self.diag.setLayout(checkLayout)
        # Make buttons
        self.cpROI_btn = QtGui.QPushButton('&Copy ROI')
        self.cpROI_btn.setMinimumHeight(40);
        self.useCpROI_btn = QtGui.QPushButton('&Use Copied ROI')
        self.useCpROI_btn.setMinimumHeight(40);
        self.noEgg_btn = QtGui.QPushButton('&No Egg')
        self.noEgg_btn.setMinimumHeight(40);
        self.approveROI_btn = QtGui.QPushButton('&Approve ROIs')
        self.approveROI_btn.setMinimumHeight(40);
        self.exit_btn = QtGui.QPushButton('Exit')
        self.exit_btn.setMinimumHeight(40);
        # Make button layout
        self.btnLayout = QGridLayout()
        self.btnLayout.addWidget(self.cpROI_btn,0,0)
        self.btnLayout.addWidget(self.useCpROI_btn,0,1)
        self.btnLayout.addWidget(self.noEgg_btn,1,1)
        self.btnLayout.addWidget(self.approveROI_btn,1,0)
        # Exit button not implemented, just use window x (topRight).
        # self.btnLayout.addWidget(self.exit_btn,2,1)
        # Add button layout to GridLayout.
        checkLayout.addLayout(self.btnLayout,0,5)
        # Format images for pyqtgraph and put in ImageView
        # self.formatSequence(ims)
        self.imImport()
        self.diag.imv.setImage(self.compSeq)
        # Add the ROI to ImageItem        
        self.diag.show()
        # Call function to add data
        self.dataForTable()
        # Function for modifying the table when ROI is approved.
        self.approveROI_btn.clicked.connect(self.updateTable)
        # Copy current ROI
        self.cpROI_btn.clicked.connect(self.cpROI)
        # Apply copied ROI
        self.useCpROI_btn.clicked.connect(self.applyCopiedROI)
        # Assign nan to frames not containing egg
        self.noEgg_btn.clicked.connect(self.recordNoEgg)
        # Exit - prompt user to confirm
        #self.exit_btn.clicked.connect(self.closeEvent)
        # Connect changes in timeline so correct ROI is created and displayed.
        self.diag.imv.timeLine.sigPositionChanged.connect(self.updateOpenCVEggROICurrEmbryo)
        #self.diag.keyPressEvent(self.keyPressEvent)
#==============================================================================
#   Generate data for populating the embryo/approveROI table.
#==============================================================================
    def dataForTable(self):
        self.tableData = {'Embryo':list(self.embryoLabels),
        'ROI approved':['No'] * len(list(self.embryoLabels))}
        self.tableCols = [QtGui.QColor(0,0,100,120)]* len(list(self.embryoLabels))
        # Enter data onto Table
        horHeaders = []
        for n, key in enumerate(sorted(self.tableData.keys())):
            horHeaders.append(key)
            for m, item in enumerate(self.tableData[key]):
                newitem = QtGui.QTableWidgetItem(item)
                newitem.setBackground(QtGui.QColor(0,0,100,120))
                self.diag.table.setItem(m, n, newitem)
        # Add Header
        self.diag.table.setHorizontalHeaderLabels(horHeaders)  
        # Adjust size of Table
        self.diag.table.resizeRowsToContents()
        # self.diag.table.resizeColumnsToContents()

#==============================================================================
#   Update table when approve ROI button clicked.
#==============================================================================
    def updateTable(self):   
        self.tableData['ROI approved'][self.diag.table.currentRow()] = 'Approved'
        self.tableCols[self.diag.table.currentRow()] = QtGui.QColor(0,100,0,120)
        horHeaders = []
        for n, key in enumerate(sorted(self.tableData.keys())):
            horHeaders.append(key)
            for m, item in enumerate(self.tableData[key]):
                newitem = QtGui.QTableWidgetItem(item) 
                self.diag.table.setItem(m, n, newitem)
                newitem.setBackground(self.tableCols[m])
        #Add Header
        self.diag.table.setHorizontalHeaderLabels(horHeaders)  
        #Adjust size of Table
        self.diag.table.resizeRowsToContents()

#==============================================================================
#   Update the user interface        
#==============================================================================
    def updateUI(self,ims,eggRotBBox, eggBoxPoints):
        self.imImport()
        self.diag.imv.setImage(self.compSeq)
        self.importOpenCVROIs(eggRotBBox, eggBoxPoints)
        self.getSeqValsAndCurrROI()  
        self.updateOpenCVEggROINewEmbryo()
        # Add the ROI to ImageItem
        #self.diag.imv.addItem(self.roi)

#==============================================================================
#   Deal with data from the dataHandling class        
#==============================================================================
    def formatSequence(self,ims):
        # Format seq appropriately for pyqtgraph ROIs
        self.tSeqd = np.zeros_like(ims)
        for l in range(len(self.tSeqd)):
            self.tSeqd[l] = ims[l].T
 
#==============================================================================
#   Get folders for a particular embryo
#==============================================================================
    def getEmbryoFolders(self, parentPath, embryo):
        self.parentPath = parentPath
        self.embryo = embryo
        self.embryoFolders = glob.glob(parentPath + "*/" + embryo +"/")
        self.embryoFolders.sort(key=os.path.getctime) 
        
#==============================================================================
#   Get image
#==============================================================================
    def imImport(self):
        for f in range(len(self.eggUIimPaths)):
            im = cv2.imread(self.eggUIimPaths[f],cv2.IMREAD_ANYDEPTH)
            ran = (im.max()-im.min())/255.
            out = (im/ran)
            out = out-out.min()
            self.compSeq[int(f)] = out.astype(np.uint8)
            self.compSeq[f] = self.compSeq[f].T
#==============================================================================
#   Update image iteratively when slider moved
#==============================================================================
#==============================================================================
#     def updateImage(self):
#         self.getSeqValsAndCurrROI()
#         #self.UI.compSeq[e*len(self.eggIDIms):(e*len(self.eggIDIms)+len(self.eggIDIms))] = self.seq
#         #self.UI.comp(self.imImport(self.diag.imv.currentIndex()))
#         im = cv2.imread(self.eggUIimPaths[self.diag.imv.currentIndex],cv2.IMREAD_ANYDEPTH)
#         ran = (im.max()-im.min())/255.
#         out = (im/ran)
#         out = out-out.min()
#         self.compSeq[self.diag.imv.currentIndex] = out.astype(np.uint8)
#         self.diag.imv.setImage(self.compSeq.T)
#         self.diag.imv.show()
# #========
#==============================================================================
#==============================================================================
# ROI functions
#==============================================================================         
#==============================================================================
#   Import OpenCV determined ROIs from dataHandling instance. Called from showUI and updateUI.
#==============================================================================
    def importOpenCVROIs(self,eggRotBBox, eggBoxPoints):
        self.eggRotBBox = eggRotBBox
        self.eggBoxPoints = eggBoxPoints
        self.originalEggRotBBox = eggRotBBox.copy()
        self.originalEggBoxPoints = eggBoxPoints.copy()

#==============================================================================
#   Get index values for ROI data.     
#==============================================================================
    def getSeqValsAndCurrROI(self):
        # Calculate the indices for current frame
        if self.eggInt != 1234:
            self.divVal = self.diag.imv.currentIndex/float(len(self.eggRotBBox[1]))
            self.intDivVal = int(self.divVal)
            self.withinSeqVal = int((self.divVal - self.intDivVal)*len(self.eggRotBBox[self.intDivVal]))
            self.currROI_eggRotBBox = self.eggRotBBox[self.intDivVal,self.withinSeqVal]
            self.currROI_eggBoxPoints = self.eggBoxPoints[self.intDivVal,self.withinSeqVal]
        else:
            self.divVal = self.diag.imv.currentIndex
            self.intDivVal = int(self.divVal)
            self.currROI_eggRotBBox = self.eggRotBBox[0,self.intDivVal] 
            self.currROI_eggBoxPoints = self.eggBoxPoints[0,self.intDivVal] 
#==============================================================================
#   Generate a pyqtgraph ROI, using data from OpenCV.
#==============================================================================
    def createOpenCVEggROI(self):
        # Get relevant sequence position and ROI.
        self.getSeqValsAndCurrROI()   
        if (self.currROI_eggRotBBox[0] != 'nan'):
            # 0 or 90 degree angles seem very buggy. Shift to 1 and 89 as a bodge fix.
            if self.currROI_eggRotBBox[4] == -90:
                #self.currROI_eggRotBBox[4] = -89
                # Get rotated bounding box points
                ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
                # Get bottom most, and top most sorted corner points
                bottomMost = ySorted[:2, :]
                topMost = ySorted[2:, :]
                # Get bottom most
                bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
                (bl, br) = bottomMost
                # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
                # The point with the largest distance will be our bottom-right point
                D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
                (tl, tr) = topMost[np.argsort(D)[::-1], :]
                self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
            elif self.currROI_eggRotBBox[4] == -0:
                #self.currROI_eggRotBBox[4] = -1  
                ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
                # Get bottom most, and top most sorted corner points
                bottomMost = ySorted[:2, :]
                topMost = ySorted[2:, :]
                # Get bottom most
                bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
                (bl, br) = bottomMost
                # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
                # The point with the largest distance will be our bottom-right point
                D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
                (tl, tr) = topMost[np.argsort(D)[::-1], :]
                self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
            elif self.currROI_eggRotBBox[4] == -180:
                #self.currROI_eggRotBBox[4] = -179
                ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
                # Get bottom most, and top most sorted corner points
                bottomMost = ySorted[:2, :]
                topMost = ySorted[2:, :]
                # Get bottom most
                bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
                (bl, br) = bottomMost
                # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
                # The point with the largest distance will be our bottom-right point
                D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
                (tl, tr) = topMost[np.argsort(D)[::-1], :]
                self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
            
            else:
                # Get rotated bounding box points
                ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
                # Get bottom most, and top most sorted corner points
                bottomMost = ySorted[:2, :]
                topMost = ySorted[2:, :]
                # Get bottom most
                bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
                (bl, br) = bottomMost
                # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
                # The point with the largest distance will be our bottom-right point
                D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
                (tl, tr) = topMost[np.argsort(D)[::-1], :]
        
                # Make ROI - note non 0,or 90 degree angles, require different of the X size
                # Rectangular ROI used to enable more easy handling of corner handles for tracking user chagnges.
                if (self.currROI_eggRotBBox[4] == -90.0) | (self.currROI_eggRotBBox[4] == -0.0)| (self.currROI_eggRotBBox[4] == 0.0):
                    self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
                    # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
                    # Debug
                    # print 'no angle'    
                else:
                    # Random angle ROIs
                    self.roi = pg.ROI([bottomMost[0][0], bottomMost[0][1]], [-self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
                    self.roi.setAngle(self.currROI_eggRotBBox[4], update=True)
                    # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [-eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
            # Add handles
            self.roi.addRotateHandle([1, 0],[0.5,0.5])
            self.roi.addRotateHandle([0, 1], [0.5,0.5])
            self.roi.addScaleHandle([1, 1], [0, 0])
            self.roi.addScaleHandle([0, 0], [1, 1])
            self.roi.setPen('y',width=3)
            self.roi.removable
            self.roi.invertible = 'True'
            # Make var for dealing with modifications to roi
            self.updatedEggROI=[]
            self.roi.sigRegionChangeFinished.connect(self.updateROI)
        #else:
#==============================================================================
#   Update the ROI for current embryo.
#==============================================================================    
    def updateOpenCVEggROICurrEmbryo(self):
        # Remove previous
        if (hasattr(self, 'roi')):
            self.diag.imv.removeItem(self.roi)
        # Get relevant video position and ROI.
        self.getSeqValsAndCurrROI()      
        # 0 or 90 degree angles seem very buggy. Shift to 1 and 89 as a bodge fix.
        if self.currROI_eggRotBBox[4] == -90:
            #self.currROI_eggRotBBox[4] = -89
            # Get rotated bounding box points
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
            self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
        elif self.currROI_eggRotBBox[4] == -0:
            #self.currROI_eggRotBBox[4] = -1  
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
            self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
        elif self.currROI_eggRotBBox[4] == -180:
            #self.currROI_eggRotBBox[4] = -179
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
            self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
        
        else:
            # Get rotated bounding box points
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
    
            # Make ROI - note non 0,or 90 degree angles, require different of the X size
            # Rectangular ROI used to enable more easy handling of corner handles for tracking user chagnges.
            if (self.currROI_eggRotBBox[4] == -90.0) | (self.currROI_eggRotBBox[4] == -0.0)| (self.currROI_eggRotBBox[4] == 0.0):
                self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
                # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
                # Debug
                # print 'no angle'    
            else:
                # Random angle ROIs
                self.roi = pg.ROI([bottomMost[0][0], bottomMost[0][1]], [-self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
                self.roi.setAngle(self.currROI_eggRotBBox[4], update=True)
                # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [-eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
 
            # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [-eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
        # Add handles
        self.roi.addRotateHandle([1, 0],[0.5,0.5])
        self.roi.addRotateHandle([0, 1], [0.5,0.5])
        self.roi.addScaleHandle([1, 1], [0, 0])
        self.roi.addScaleHandle([0, 0], [1, 1])
        self.roi.setPen('y',width=3)
        self.roi.removable
        self.roi.invertible = 'True'
        # Make var for dealing with modifications to roi
        self.updatedEggROI=[]
        ### Still to do...
        self.diag.imv.addItem(self.roi)
        self.roi.sigRegionChangeFinished.connect(self.updateROI)

#==============================================================================
#   Update ROI for new embryo.        
#==============================================================================
    def updateOpenCVEggROINewEmbryo(self):
        # Remove old ROI
        if (hasattr(self, 'roi')):
            self.diag.imv.removeItem(self.roi)
        # Get relevant video position and ROI
        self.getSeqValsAndCurrROI()    
        # 0 or 90 degree angles seem very buggy. Shift to 1 and 89 as a bodge fix.        
        if self.currROI_eggRotBBox[4] == -90:
            #self.currROI_eggRotBBox[4] = -89
            # Get rotated bounding box points
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
            self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
        elif self.currROI_eggRotBBox[4] == -0:
            #self.currROI_eggRotBBox[4] = -1  
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
            self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
        elif self.currROI_eggRotBBox[4] == -180:
            #self.currROI_eggRotBBox[4] = -179
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
            self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
        
        else:
            # Get rotated bounding box points
            ySorted = self.currROI_eggBoxPoints[np.argsort(self.currROI_eggBoxPoints[:, 1]), :]
            # Get bottom most, and top most sorted corner points
            bottomMost = ySorted[:2, :]
            topMost = ySorted[2:, :]
            # Get bottom most
            bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
            (bl, br) = bottomMost
            # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
            # The point with the largest distance will be our bottom-right point
            D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
            (tl, tr) = topMost[np.argsort(D)[::-1], :]
    
            # Make ROI - note non 0,or 90 degree angles, require different of the X size
            # Rectangular ROI used to enable more easy handling of corner handles for tracking user chagnges.
            if (self.currROI_eggRotBBox[4] == -90.0) | (self.currROI_eggRotBBox[4] == -0.0)| (self.currROI_eggRotBBox[4] == 0.0):
                self.roi = pg.ROI([bl[0], bl[1]], [self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
                # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
                # Debug
                # print 'no angle'    
            else:
                # Random angle ROIs
                self.roi = pg.ROI([bottomMost[0][0], bottomMost[0][1]], [-self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]])
                self.roi.setAngle(self.currROI_eggRotBBox[4], update=True)
        # Add handles
        self.roi.addRotateHandle([1, 0],[0.5,0.5])
        self.roi.addRotateHandle([0, 1], [0.5,0.5])
        self.roi.addScaleHandle([1, 1], [0, 0])
        self.roi.addScaleHandle([0, 0], [1, 1])
        self.roi.setPen('y',width=3)
        self.roi.removable
        self.roi.invertible = 'True'
        # Make var for dealing with modifications to roi
        self.updatedEggROI=[]
        ### Still to do...
        self.diag.imv.addItem(self.roi)
        self.roi.sigRegionChangeFinished.connect(self.updateROI)

#==============================================================================
#   Update ROI.        
#==============================================================================
    def updateROI(self):
        #global vidTime, xyPosHandles, ellipse, changeAngle, roiChanges,updatedEggROI, changeX, changeY, changeScaleX, changeScaleY, changeAngle
        # Get changes to ROI scale, angle and position
        roiChanges = self.roi.getGlobalTransform()    
        changeX = -roiChanges.getTranslation()[0]
        changeY = roiChanges.getTranslation()[1]
        changeScaleX = roiChanges.getScale()[0]
        changeScaleY = roiChanges.getScale()[1]
        changeAngle = roiChanges.getAngle()
        # Update ROI, either updating the previously updated or taking the unaltered ROI from OpenCV as a starting point.
        #if len(self.updatedEggROI) == 0:
        self.updatedEggROI = (((self.currROI_eggRotBBox[0]-changeX),(self.currROI_eggRotBBox[1]+changeY)),((max((self.currROI_eggRotBBox[3]*changeScaleX),(self.currROI_eggRotBBox[2]*changeScaleY))),(min((self.currROI_eggRotBBox[3]*changeScaleX),(self.currROI_eggRotBBox[2]*changeScaleY)))),self.currROI_eggRotBBox[4]+changeAngle)
        #else:
            #self.updatedEggROI = (((self.updatedEggROI[0][0]-changeX),(self.updatedEggROI[0][1]+changeY)),((max((self.updatedEggROI[1][0]*changeScaleX),(self.updatedEggROI[1][1]*changeScaleY))),(min((self.updatedEggROI[1][0]*changeScaleX),(self.updatedEggROI[1][1]*changeScaleY)))),self.updatedEggROI[2]+changeAngle)
        hh = self.roi.getHandles()
        hh = [self.roi.mapToItem(self.diag.imv.getImageItem(), h.pos()) for h in hh]
        # Handle on each corner. Get handle positions
        self.xyPosHandles =[]  
        for h in hh:
            self.xyPosHandles.append([h.x(),h.y()]) 
        (eggBBX, eggBBY), (eggBBW, eggBBH), eggBBAng = cv2.minAreaRect(np.array(self.xyPosHandles, dtype=np.int32) )
        if eggBBAng == -90:
            eggBBAng = -89
        elif eggBBAng == -180:
            eggBBAng = -179
        elif eggBBAng == -0:
            eggBBAng = -1  
            # Save updated 
        # If more than one frame eggID per sequence..
        if self.eggInt != 1234:
            self.eggRotBBox[self.intDivVal,self.withinSeqVal] = [eggBBX, eggBBY, eggBBW, eggBBH, eggBBAng]
            self.eggBoxPoints[self.intDivVal,self.withinSeqVal] = cv2.boxPoints(((eggBBX, eggBBY), (eggBBW, eggBBH), eggBBAng))
        # Otherwise just save simply
        else:
            self.eggRotBBox[0,self.intDivVal] = [eggBBX, eggBBY, eggBBW, eggBBH, eggBBAng]
            self.eggBoxPoints[0,self.intDivVal] = cv2.boxPoints(((eggBBX, eggBBY), (eggBBW, eggBBH), eggBBAng))

#==============================================================================
#   Copy ROI on button click.
#==============================================================================
    def cpROI(self):
        self.originalEggRotBBox = self.currROI_eggRotBBox
        self.originalEggBoxPoints = self.currROI_eggBoxPoints

#==============================================================================
#   Assign nan to current ROI if 'No Egg' button clicked
#==============================================================================
    def recordNoEgg(self):
        # Remove ROI
        self.diag.imv.removeItem(self.roi)
        # Store nans in place of ROI
        if self.eggInt != 1234:
            self.eggRotBBox[self.intDivVal,self.withinSeqVal] = [np.nan, np.nan, np.nan, np.nan, np.nan]
            self.eggBoxPoints[0,self.intDivVal] = [np.nan,np.nan,np.nan,np.nan]
        else:
            self.eggBoxPoints[0,self.intDivVal] = [np.nan,np.nan,np.nan,np.nan]
            self.eggRotBBox[0,self.intDivVal] = [np.nan, np.nan, np.nan, np.nan, np.nan]
        
#==============================================================================
#   Copy ROI on button click.
#==============================================================================
    def applyCopiedROI(self):
        self.getSeqValsAndCurrROI()
        # Store copied ROI to embryo sequence ROIs
        if self.eggInt != 1234:
            self.divVal = self.diag.imv.currentIndex/float(len(self.eggRotBBox[1]))
            self.intDivVal = int(self.divVal)
            self.withinSeqVal = int((self.divVal - self.intDivVal)*len(self.eggRotBBox[self.intDivVal]))
            self.eggRotBBox[self.intDivVal,self.withinSeqVal] = self.originalEggRotBBox
            self.eggBoxPoints[self.intDivVal,self.withinSeqVal] = self.originalEggBoxPoints
        else:
            self.divVal = self.diag.imv.currentIndex
            self.intDivVal = int(self.divVal)
            self.eggRotBBox[0,self.intDivVal] = self.originalEggRotBBox
            self.eggBoxPoints[0,self.intDivVal] = self.originalEggBoxPoints 
        self.updateOpenCVEggROICurrEmbryo()
        
        
 
#==============================================================================
#        
#==============================================================================

#==============================================================================
#   Close button - not implemented (hidden)
#==============================================================================
#==============================================================================
#     def closeEvent(self, event):
#     
#         quit_msg = "Are you sure you want to exit the program?"
#         reply = QtGui.QMessageBox.question(self, 'Message', 
#                          quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
#     
#         if reply == QtGui.QMessageBox.Yes:
#             #event.accept()
#             app.quit()
#         else:
#             event.ignore()
#         
#==============================================================================
#==============================================================================
#         #self.originalEggRotBBox = eggRotBBox.copy()
#         #self.originalEggBoxPoints = eggBoxPoints.copy()
#         #self.currROI_eggRotBBox = self.eggRotBBox[self.intDivVal,self.withinSeqVal]
#         #self.currROI_eggBoxPoints = self.eggBoxPoints[self.intDivVal,self.withinSeqVal]
# 
#         # Modified version of updateOpenCVEggROICurrEmbryo
#         # Remove previous
#         self.diag.imv.removeItem(self.roi)
#         # Get relevant video position and ROI.
#         self.getSeqValsAndCurrROI()      
#         # Get rotated bounding box points
#         ySorted = self.originalEggBoxPoints[np.argsort(self.originalEggBoxPoints[:, 1]), :]
#         # Get bottom most, and top most sorted corner points
#         bottomMost = ySorted[:2, :]
#         topMost = ySorted[2:, :]
#         # Get bottom most
#         bottomMost = bottomMost[np.argsort(bottomMost[:, 1]), :]
#         (bl, br) = bottomMost
#         # Use bottom-left coordinate as anchor to calculate the Euclidean distance between the
#         # The point with the largest distance will be our bottom-right point
#         D = dist.cdist(bl[np.newaxis], topMost, "euclidean")[0]
#         (tl, tr) = topMost[np.argsort(D)[::-1], :]
#         # Make ROI - note non 0,or 90 degree angles, require different of the X size
#         # Rectangular ROI used to enable more easy handling of corner handles for tracking user chagnges.
#         if (self.originalEggRotBBox[4] == -90.0) | (self.originalEggRotBBox[4] == -0.0)| (self.originalEggRotBBox[4] == 0.0):
#             self.roi = pg.ROI([bottomMost[0][0], bottomMost[0][1]], [self.originalEggRotBBox[2], self.originalEggRotBBox[3]])
#             # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
#         else:
#             # Random angle ROIs
#             self.roi = pg.ROI([bottomMost[0][0], bottomMost[0][1]], [-self.originalEggRotBBox[2], self.originalEggRotBBox[3]])
#             self.roi.setAngle(self.originalEggRotBBox[4], update=True)
#             # roi = pg.EllipseROI([bottomMost[0][0], bottomMost[0][1]], [-eggRotBBox[vidTime][2], eggRotBBox[vidTime][3]])
#         # Add handles
#         self.roi.addRotateHandle([1, 0],[0.5,0.5])
#         self.roi.addRotateHandle([0, 1], [0.5,0.5])
#         self.roi.addScaleHandle([1, 1], [0, 0])
#         self.roi.addScaleHandle([0, 0], [1, 1])
#         self.roi.setPen('y',width=3)
#         self.roi.removable
#         self.roi.invertible = 'True'
#         # Make var for dealing with modifications to roi
#         self.updatedEggROI=[]
#         ### Still to do...
#         self.diag.imv.addItem(self.roi)
#         self.roi.sigRegionChangeFinished.connect(self.updateROI)
#==============================================================================
        
#===============
[(22, 'pyqtgraph.Qt.QtCore.pyqtSignal', 'QtCore.pyqtSignal', ([], {}), False, 'from pyqtgraph.Qt import QtCore, QtGui\n'), (23, 'pyqtgraph.Qt.QtCore.pyqtSignal', 'QtCore.pyqtSignal', ([], {}), False, 'from pyqtgraph.Qt import QtCore, QtGui\n'), (24, 'pyqtgraph.Qt.QtCore.pyqtSignal', 'QtCore.pyqtSignal', ([], {}), False, 'from pyqtgraph.Qt import QtCore, QtGui\n'), (29, 'PyQt5.QtGui.QDialog', 'QtGui.QDialog', ([], {}), False, 'from PyQt5 import QtGui\n'), (32, 'pyqtgraph.ImageView', 'pg.ImageView', ([], {}), True, 'import pyqtgraph as pg\n'), (43, 'pyqtgraph.ImageView', 'pg.ImageView', ([], {}), True, 'import pyqtgraph as pg\n'), (54, 'PyQt5.QtGui.QTableWidget', 'QtGui.QTableWidget', ([], {}), False, 'from PyQt5 import QtGui\n'), (75, 'PyQt5.QtGui.QPushButton', 'QtGui.QPushButton', (['"""&Copy ROI"""'], {}), False, 'from PyQt5 import QtGui\n'), (77, 'PyQt5.QtGui.QPushButton', 'QtGui.QPushButton', (['"""&Use Copied ROI"""'], {}), False, 'from PyQt5 import QtGui\n'), (79, 'PyQt5.QtGui.QPushButton', 'QtGui.QPushButton', (['"""&No Egg"""'], {}), False, 'from PyQt5 import QtGui\n'), (81, 'PyQt5.QtGui.QPushButton', 'QtGui.QPushButton', (['"""&Approve ROIs"""'], {}), False, 'from PyQt5 import QtGui\n'), (83, 'PyQt5.QtGui.QPushButton', 'QtGui.QPushButton', (['"""Exit"""'], {}), False, 'from PyQt5 import QtGui\n'), (142, 'PyQt5.QtGui.QColor', 'QtGui.QColor', (['(0)', '(100)', '(0)', '(120)'], {}), False, 'from PyQt5 import QtGui\n'), (172, 'numpy.zeros_like', 'np.zeros_like', (['ims'], {}), True, 'import numpy as np\n'), (182, 'glob.glob', 'glob.glob', (["(parentPath + '*/' + embryo + '/')"], {}), False, 'import glob\n'), (190, 'cv2.imread', 'cv2.imread', (['self.eggUIimPaths[f]', 'cv2.IMREAD_ANYDEPTH'], {}), False, 'import cv2\n'), (355, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (451, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (543, 'numpy.array', 'np.array', (['self.xyPosHandles'], {'dtype': 'np.int32'}), True, 'import numpy as np\n'), (554, 'cv2.boxPoints', 'cv2.boxPoints', (['((eggBBX, eggBBY), (eggBBW, eggBBH), eggBBAng)'], {}), False, 'import cv2\n'), (558, 'cv2.boxPoints', 'cv2.boxPoints', (['((eggBBX, eggBBY), (eggBBW, eggBBH), eggBBAng)'], {}), False, 'import cv2\n'), (122, 'PyQt5.QtGui.QColor', 'QtGui.QColor', (['(0)', '(0)', '(100)', '(120)'], {}), False, 'from PyQt5 import QtGui\n'), (128, 'PyQt5.QtGui.QTableWidgetItem', 'QtGui.QTableWidgetItem', (['item'], {}), False, 'from PyQt5 import QtGui\n'), (147, 'PyQt5.QtGui.QTableWidgetItem', 'QtGui.QTableWidgetItem', (['item'], {}), False, 'from PyQt5 import QtGui\n'), (263, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (353, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (369, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (449, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (465, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (129, 'PyQt5.QtGui.QColor', 'QtGui.QColor', (['(0)', '(0)', '(100)', '(120)'], {}), False, 'from PyQt5 import QtGui\n'), (261, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (277, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (367, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (383, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (463, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (479, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (275, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (291, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (344, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (349, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (381, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (396, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (402, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (408, 'pyqtgraph.ROI', 'pg.ROI', (['[bottomMost[0][0], bottomMost[0][1]]', '[-self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (440, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (445, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (477, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (492, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (498, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (504, 'pyqtgraph.ROI', 'pg.ROI', (['[bottomMost[0][0], bottomMost[0][1]]', '[-self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (252, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (257, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (289, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (304, 'scipy.spatial.distance.cdist', 'dist.cdist', (['bl[np.newaxis]', 'topMost', '"""euclidean"""'], {}), True, 'from scipy.spatial import distance as dist\n'), (310, 'pyqtgraph.ROI', 'pg.ROI', (['[bl[0], bl[1]]', '[self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (316, 'pyqtgraph.ROI', 'pg.ROI', (['[bottomMost[0][0], bottomMost[0][1]]', '[-self.currROI_eggRotBBox[2], self.currROI_eggRotBBox[3]]'], {}), True, 'import pyqtgraph as pg\n'), (354, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (358, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (363, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (450, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (454, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (459, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (262, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (266, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (271, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (368, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (372, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (377, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (387, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (392, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (464, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (468, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (473, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (483, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (488, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (276, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (280, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (285, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (295, 'numpy.argsort', 'np.argsort', (['self.currROI_eggBoxPoints[:, (1)]'], {}), True, 'import numpy as np\n'), (300, 'numpy.argsort', 'np.argsort', (['bottomMost[:, (1)]'], {}), True, 'import numpy as np\n'), (382, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (397, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (478, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (493, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (290, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n'), (305, 'numpy.argsort', 'np.argsort', (['D'], {}), True, 'import numpy as np\n')]