def set_evol_analysis(self, leak_evol):
     if not self.has_leakage_ivs:
         self.my_leak_analysis = LeakageAnalysis([])
         self.my_leak_analysis.set_leak_array_from_leak_evol(leak_evol)
         self.has_leakage_evolution = True
class TLPAnalysis(object):
    """Utils to analyse leakage data
    """
    def __init__(self, tlp_data):
        self.tlp_data = tlp_data
        self.volt = np.array(tlp_data[0])
        self.curr = np.array(tlp_data[1])
        self.is_snapback = False
        self.is_multi = False
        self.start_region = []
        self.end_region = []
        self.trig_inf = []
        self.my_leak_analysis = None
        self.has_leakage_ivs = False
        self.has_leakage_evolution = False

    def get_voltage_array(self):
        return self.volt

    def get_current_array(self):
        return self.curr

    def data_smoothing(self, arr):
        smoothD = []
        for val in range(len(arr) - 3):
            point1 = arr[val]
            point2 = arr[val + 1]
            point3 = arr[val + 2]
            smoothD.append((point1 + point2 + point3) / 3.0)
        return smoothD

    def extract_triggering_point(self, threshold):
        if threshold == 0.0:
            threshold = -0.5
        volt = self.volt
        smoothV = self.data_smoothing(volt)
        #smoothI=self.data_smoothing(curr)
        dV = np.diff(smoothV)
        #dI=np.diff(smoothI)
        #der=np.divide(dI,dV)
        mytrip = np.where(dV <= threshold)
        self.dV = dV
        #TODO
### line commented to be placed somewhere else to manage the plot
###        if len(mytrip[0])==0 or True:
###            derivative=pl.figure()
###            pl.plot(dV)
            #pl.hold(True)
            #pl.plot(der)
###            pl.axhline(threshold,color='m', linestyle='-.', linewidth=2)
        kInd = -1
        if len(mytrip[0]) > 0:
            #print mytrip
            self.is_snapback = True
            if len(mytrip[0]) > 1:
                self.is_multi = True
                prev_elem = -1
                for elem in mytrip[0]:
                    if prev_elem != -1:
                        if (elem - prev_elem) != 1:
                            self.start_region.append(elem)
                            self.end_region.append(elem - 1)
                    if elem == mytrip[0][0]:
                        self.start_region.append(elem)
                    prev_elem = elem

            ##### adjusting the index found on the smoothed matrix

            kInd = self.adjust_index(mytrip[0][0])
            if len(self.start_region) <= 1:
                self.is_multi = False

#            if mytrip[0][0] >=2:
#                sInd=mytrip[0][0]-2
#            else:
#                sInd=0
#            kInd=sInd
#            for item in range(1,5):
#                if volt[kInd] < volt[sInd+item]:
#                    kInd=sInd+item
            self.ext_table = mytrip
        self.kInd = kInd
        return self.kInd

    def adjust_index(self, valIndex):
        volt = self.volt

        if valIndex >= 2:
            sInd = valIndex - 2
        else:
            sInd = 0
        kInd = sInd
        for item in range(1, 5):
            if volt[kInd] < volt[sInd + item]:
                kInd = sInd + item

        return kInd

    def get_snapback_index(self, fromI):
        volt = self.volt
        prev_volt = volt[fromI]
        for elem in range(fromI + 1, len(volt)):
            if volt[elem] > prev_volt:
                return elem
            prev_volt = volt[elem]
        return -1

    def get_start_index(self, currRef):
        if currRef == 0.0:
            currRef = 0.01
        mytab = np.where(self.curr >= currRef)
        if len(mytab[0]) > 0:
            return mytab[0][0]
        return -1

    def set_threshold(self, value):
        self.seuil = value

    def set_spot(self, value):
        if self.has_leakage_ivs:
            self.my_leak_analysis.set_spot(value)

    def set_base_dir(self, str_dir):
        self.baseDir = str_dir
        if self.has_leakage_ivs or self.has_leakage_evolution:
            self.my_leak_analysis.set_base_dir(str_dir)

    def set_fail(self, value):
        if self.has_leakage_ivs or self.has_leakage_evolution:
            self.my_leak_analysis.set_fail(value)

    def set_triggering_str(self):
        if self.is_snapback:
            self.trig_reg = 1
            if self.is_multi:
                for item in self.start_region:
                    affInd = self.adjust_index(item)
                    inf_str = "|{2}|{0:.3}|{1:.3}|".format(self.volt[affInd],
                                                           self.curr[affInd],
                                                           self.trig_reg)
                    self.trig_inf.append(inf_str)

                    self.trig_reg += 1
            else:
                inf_str = "|{2}|{0:.3}|{1:.3}|".format(self.volt[self.kInd],
                                                       self.curr[self.kInd], 1)
                self.trig_inf.append(inf_str)
        return self.trig_inf

    def make_derivative_plot(self, file_name):
        derivative_fig = Figure()
        FigureCanvas(derivative_fig)
        derivative_plot = derivative_fig.add_subplot(111)
        derivative_plot.plot(self.dV)
        derivative_plot.axhline(self.seuil, color='m',
                                linestyle='-.', linewidth=2)
        derivative_fig.savefig(file_name)

    def set_leak_analysis(self, leak_table):
        self.my_leak_analysis = LeakageAnalysis(leak_table)
        if not len(leak_table) == 0:
            self.has_leakage_ivs = True

    def set_evol_analysis(self, leak_evol):
        if not self.has_leakage_ivs:
            self.my_leak_analysis = LeakageAnalysis([])
            self.my_leak_analysis.set_leak_array_from_leak_evol(leak_evol)
            self.has_leakage_evolution = True

    def set_device_name(self, str_name):
        self.devName = str_name
        if not (self.my_leak_analysis is None):
            self.my_leak_analysis.set_device_name(str_name)

    def get_fitting_data(self):
        x_val = []
        y_val = []
        x_val2 = []
        y_val2 = []
        p = []
        p2 = []
        self.fit_inf = []
        if self.is_snapback:
            sbIndex = self.get_snapback_index(self.kInd)
            #print kInd, sbIndex
            endPoint = len(self.volt) - 1
            if not (self.my_leak_analysis is None):
                if len(self.my_leak_analysis.rising) > 0:
                    endPoint = self.my_leak_analysis.rising[0] - 1
            if     self.is_multi:
                #### fit sur la derniere region non fail
                newTrigPoint = self.adjust_index(self.start_region[-1])
                newSbkIndex = self.get_snapback_index(newTrigPoint)
                newEndPoint = self.adjust_index(self.start_region[1])
                buff = endPoint
                endPoint = newEndPoint
                newEndPoint = buff
                if newEndPoint > newSbkIndex:
                    p2 = np.polyfit(self.curr[newSbkIndex:newEndPoint],
                                    self.volt[newSbkIndex:newEndPoint], 1)
                    x_val2 = np.linspace(0, np.max(self.curr), 50)
                    y_val2 = np.polyval(p2, x_val2)
                    #print "Last fitting snapback",p2[0],p2[1]
                    self.fit_inf.append("|{2}|{0:.3}|{1:.3}|".format(
                                        p2[1], p2[0], len(self.start_region)))
                    fittingLast = True
                else:
                    fittingLast = False

                self.fittingLast = fittingLast
                self.newSbkIndex = newSbkIndex
                self.newEndPoint = newEndPoint
                self.x_val2 = x_val2
                self.y_val2 = y_val2
                self.p2 = p2

            if endPoint > sbIndex:
                p = np.polyfit(self.curr[sbIndex:endPoint],
                               self.volt[sbIndex:endPoint], 1)
                x_val = np.linspace(0, np.max(self.curr), 50)
                y_val = np.polyval(p, x_val)
                #print "first fitting snapback",p[0],p[1]
                self.fit_inf.insert(0,
                                    "|{2}|{0:.3}|{1:.3}|".format(p[1],
                                                                 p[0], 1))
                self.fitting = True
            else:
                self.fitting = False

        else:
            endPoint = len(self.volt) - 1
            if not (self.my_leak_analysis is None):
                if len(self.my_leak_analysis.rising) > 0:
                    endPoint = self.my_leak_analysis.rising[0] - 1

            # get index for current above 20mA
            sbIndex = self.get_start_index(0.02)
            if sbIndex == -1:
                sbIndex = 0
            if endPoint > sbIndex:
                p = np.polyfit(self.curr[sbIndex:endPoint],
                               self.volt[sbIndex:endPoint], 2)
                if np.max(self.curr) > 0:
                    x_val = np.linspace(0, np.max(self.curr), 50)
                else:
                    x_val = np.linspace(0, np.min(self.curr), 50)

                y_val = np.polyval(p, x_val)
                #print "fitting non snapback",p[0],p[1],p[2]
                self.fit_inf.insert(0, "|{2}|{0:.3}|{1:.3}|".format(p[2],
                                                                    p[1], 1))
                self.fitting = True
            else:
                self.fitting = False

        self.sbIndex = sbIndex
        self.endPoint = endPoint
        self.x_val = x_val
        self.y_val = y_val
        self.p = p

    def make_tlp_plot(self, file_name):
        tlp_fig = Figure()
        FigureCanvas(tlp_fig)
        tlpA_plot = tlp_fig.add_subplot(111)

        tlpA_plot.plot(self.tlp_data[0],
                       self.tlp_data[1], 'ro', markersize=3)
        tlpA_plot.set_xlabel(r'Voltage [V]')
        tlpA_plot.set_ylabel(r'Current [A]')
        myaxis = tlpA_plot.axis()
        date_deb = datetime.now()
        self.make_zoom = False
        if myaxis[3] > 3.5:
            self.make_zoom = True
        tlpA_plot.text(myaxis[0], myaxis[3] * 0.95, " " + date_deb.ctime())
        tlpA_plot.text(myaxis[1] * 0.4, myaxis[3] * 0.95,
                       self.devName + " TLP Curve", color='r')
        tlpA_plot.text(myaxis[1] * 0.4, myaxis[3] * 0.9,
                       "Leakage Curve", color='b')
        tlpA_plot.grid(True)
        if np.max(self.tlp_data[0]) <= 0:
            tlpA_plot.set_xlim(myaxis[0], 0)
        else:
            tlpA_plot.set_xlim(0,)
        if np.max(self.tlp_data[1]) <= 0:
            tlpA_plot.set_ylim(myaxis[2], 0)
        else:
            tlpA_plot.set_ylim(0,)

        analysis = self.my_leak_analysis

        if not (analysis is None):
            if len(analysis.rising) > 0:
                fail_ind = analysis.fail_index
                tlpA_plot.axhspan(self.tlp_data[1][fail_ind - 1],
                                  myaxis[3], facecolor='r', alpha=0.5)
            if len(analysis.rising) > 1:
                for item in range(len(analysis.falling)):
                    data = self.tlp_data[1]
                    tlpA_plot.axhspan(data[analysis.rising[item]],
                                      data[analysis.falling[item]],
                                      facecolor='y', alpha=0.5)
            if not (analysis.leak_tab.shape[0]
                    < self.tlp_data[1].shape[0]):
                tlpA2 = tlpA_plot.twiny()
                if (analysis.leak_tab.shape[0]
                        > self.tlp_data[1].shape[0]):
                    leak_abs = np.array(analysis.leak_tab[1:])
                    tlpA2.semilogx(np.abs(leak_abs), self.tlp_data[1],
                                   'bs', markersize=3)
                else:
                    leak_abs = np.array(analysis.leak_tab)
                    tlpA2.semilogx(np.abs(leak_abs), self.tlp_data[1],
                                   'bs', markersize=3)
                    tlpA2.set_xlabel(r'Leakage Current [A]')

                tlpA2.set_ylim(0,)
        tlp_fig.savefig(file_name + "_A.png")

        textFile = ('[<img src="TLP_A.png" align="center" alt="TLPA"> ](../'
                    + self.devName + '_report.html)')
        text_output = md.markdown(textFile, extensions=['extra'])
        text_out = open(file_name + "_A.html", "w")
        text_out.write(text_output)
        text_out.close()

        if self.make_zoom:
            zoom_fig = Figure()
            FigureCanvas(zoom_fig)
            zoom_plot = zoom_fig.add_subplot(111)

            zoom_plot.plot(self.tlp_data[0], self.tlp_data[1],
                           'ro', markersize=3)

            zoom_plot.set_xlabel(r'Voltage [V]')
            zoom_plot.set_ylabel(r'Current [A]')
            if np.max(self.tlp_data[0]) <= 0:
                zoom_plot.set_xlim(myaxis[0], 0)
            else:
                zoom_plot.set_xlim(0,)
            if np.max(self.tlp_data[1]) <= 0:
                zoom_plot.set_ylim(-2, 0)
            else:
                zoom_plot.set_ylim(0, 2)

            myaxis = zoom_plot.axis()
            date_deb = datetime.now()
            zoom_plot.text(myaxis[0], myaxis[3] * 0.95,
                           " " + date_deb.ctime())
            zoom_plot.text(myaxis[1] * 0.4, myaxis[3] * 0.95,
                           "TLP Curve", color='r')
            zoom_plot.text(myaxis[1] * 0.4, myaxis[3] * 0.9,
                           "Leakage Curve", color='b')
            zoom_plot.grid(True)

            if not (analysis is None):
                if not (analysis.leak_tab.shape[0]
                        < self.tlp_data[1].shape[0]):
                    if len(analysis.rising) > 0:
                        data = self.tlp_data
                        analysis = analysis
                        zoom_plot.axhspan(data[1][analysis.fail_index - 1],
                                          myaxis[3], facecolor='r', alpha=0.5)
                        if len(analysis.rising) > 1:
                            zoom_plot.axhspan(data[1][analysis.rising[0]],
                                              data[1][analysis.falling[0]],
                                              facecolor='y', alpha=0.5)

                        zoomb_plot = zoom_plot.twiny()
                        zoomb_plot.set_ylim(0, 2)

                        if analysis.leak_tab.shape[0] > data[1].shape[0]:
                            leak_abs = np.array(analysis.leak_tab[1:])

                            zoomb_plot.semilogx(np.abs(leak_abs),
                                                self.tlp_data[1],
                                                'bs', markersize=3)
                        else:
                            leak_abs = np.array(analysis.leak_tab)

                            zoomb_plot.semilogx(np.abs(leak_abs),
                                                self.tlp_data[1],
                                                'bs', markersize=3)

                        zoomb_plot.set_xlabel(r'Leakage Current [A]')
            zoom_fig.savefig(file_name + "_B.png")

            textFile = ('[<img src="TLP_B.png"'
                        + ' align="center" alt="TLPB"> ](../'
                        + self.devName + '_report.html)')
            text_output = md.markdown(textFile, extensions=['extra'])
            text_out = open(file_name + "_B.html", "w")
            text_out.write(text_output)
            text_out.close()

    def make_extraction_plot(self, file_name):
        extract_fig = Figure()
        FigureCanvas(extract_fig)
        ext_plot = extract_fig.add_subplot(111)

        ext_plot.plot(self.tlp_data[0], self.tlp_data[1],
                      'ro', markersize=3)
        myaxis = ext_plot.axis()
        ext_plot.hold(True)

        if self.is_snapback and self.fitting:
            ext_plot.plot(self.y_val, self.x_val)
            ext_plot.axhspan(self.tlp_data[1][self.sbIndex],
                             self.tlp_data[1][self.endPoint],
                             facecolor='b', alpha=0.2)
            sb_str = " Vsb:{0:.2}V, Ron:{1:.3}".format(self.p[1], self.p[0])
            annotI = (self.endPoint - self.sbIndex) / 2 + self.sbIndex
            ext_plot.annotate(sb_str, xy=(self.volt[annotI],
                                          self.curr[annotI]),
                              xytext=(0, self.curr[annotI]),
                              arrowprops=dict(width=1, frac=0, headwidth=0,
                                              color='blue', shrink=0.05),
                              color='b')
        if self.is_multi and self.fittingLast:
            ext_plot.plot(self.y_val2, self.x_val2)
            ext_plot.axhspan(self.tlp_data[1][self.newSbkIndex],
                             self.tlp_data[1][self.newEndPoint],
                             facecolor='g', alpha=0.2)
            sb_str = " Vsb:{0:.2}V, Ron:{1:.3}".format(self.p2[1], self.p2[0])
            annotI = ((self.newEndPoint - self.newSbkIndex)
                      / 2 + self.newSbkIndex)
            ext_plot.annotate(sb_str, xy=(self.volt[annotI],
                                          self.curr[annotI]),
                              xytext=(0, self.curr[annotI]),
                              arrowprops=dict(width=1, frac=0, headwidth=0,
                                              color='green', shrink=0.05),
                              color='g')
        if not self.is_snapback and self.fitting:
            ext_plot.plot(self.y_val, self.x_val)
            pfit = np.poly1d([self.p[1], self.p[2]])
            #x_val=np.linspace(0,np.max(curr),50)
            y_fit = np.polyval(pfit, self.x_val)
            ext_plot.plot(y_fit, self.x_val, ':')
            ext_plot.axhspan(self.tlp_data[1][self.sbIndex],
                             self.tlp_data[1][self.endPoint],
                             facecolor='b', alpha=0.2)
            sb_str = " Vsb:{0:.4}V, Ron:{1:.4}".format(self.p[2], self.p[1])
            annotI = (self.endPoint - self.sbIndex) / 2 + self.sbIndex
            ext_plot.annotate(sb_str,
                              xy=(self.volt[annotI], self.curr[annotI]),
                              xytext=(0, self.curr[annotI]),
                              arrowprops=dict(width=1, frac=0, headwidth=0,
                                              color='blue', shrink=0.05),
                              color='b')

        ext_plot.set_xlabel(r'Voltage [V]')
        ext_plot.set_ylabel(r'Current [A]')

        if np.max(self.tlp_data[0]) <= 0:
            ext_plot.set_xlim(myaxis[0], 0)
        else:
            ext_plot.set_xlim(0, myaxis[1])
        if np.max(self.tlp_data[1]) <= 0:
            ext_plot.set_ylim(myaxis[2], 0)
        else:
            ext_plot.set_ylim(0, myaxis[3])

        date_deb = datetime.now()
        ext_plot.text(myaxis[0], myaxis[3] * 0.95, " " + date_deb.ctime())
        if self.is_snapback:
            if self.curr[self.kInd] > myaxis[2]:
                ext_plot.axhline(self.curr[self.kInd], color='m')
                ext_plot.text(myaxis[0], self.curr[self.kInd],
                              " {0:.3}A".format(self.curr[self.kInd]),
                              color='m')
            ext_plot.axvline(self.volt[self.kInd], color='m')
            ext_plot.text(self.volt[self.kInd], 0.95 * myaxis[3],
                          "{0:.4}V ".format(self.volt[self.kInd]),
                          color='m', rotation=270)
        ext_plot.grid(True)
        ext_plot.set_title(self.devName + " Extraction Data from TLP curve")
        extract_fig.savefig(file_name)

        textFile = ('[<img src="TLP_C.png"'
                    + ' align="center" alt="TLPC"> ](../'
                    + self.devName + '_report.html)')
        text_output = md.markdown(textFile, extensions=['extra'])
        text_out = open(file_name[:-4] + ".html", "w")
        text_out.write(text_output)
        text_out.close()

    def update_analysis(self):
        self.is_snapback = False
        self.is_multi = False
        self.start_region = []
        self.end_region = []
        self.trig_inf = []

        baseDir = self.baseDir
        if self.has_leakage_ivs:
            self.my_leak_analysis.update_leakage_analysis(self.tlp_data)

        if self.has_leakage_evolution:
            self.my_leak_analysis.update_evol_analysis(self.tlp_data)

        kInd = self.extract_triggering_point(self.seuil)
        trig_inf = self.set_triggering_str()
        #TODO Bad design above

        self.get_fitting_data()

        self.make_derivative_plot(baseDir + '/derivative.png')

        self.make_tlp_plot(baseDir + '/TLP')

        self.make_extraction_plot(baseDir + '/TLP_C.png')
 def set_leak_analysis(self, leak_table):
     self.my_leak_analysis = LeakageAnalysis(leak_table)
     if not len(leak_table) == 0:
         self.has_leakage_ivs = True