def TafelSlopeVPerDec(rawd, interd, var='I(A)', vshift=-(.187-0.045), boolDevFrac=0.5, boolDevNOut=3,
                      dyDevFrac=0.2, dyDevNOut=5, dyDevAbs = 0.,
                      dx=1., maxFracOutliers=0.5, critSegVRange=0.04, critSegIEnd=3.e-5,
                      critSegVEnd=0.36, SavGolPts=10):
    # initialize the arrays to hold Tafel values (considered both
    #   intermediate data and figures of merit)
    interd['Tafel_slopeVperdec'] = []
    interd['Tafel_estart'] = []
    interd['Tafel_fitVrange'] = []
    interd['Tafel_logExCurrent'] = []
    booldn_segstart = 3 * boolDevNOut
    dn_segstart = 3 * dyDevNOut
    inter.calcsegind(rawd, interd, SGpts=SavGolPts) # breaks experiment into segments
    inter.calccurvregions(rawd, interd, SGpts=SavGolPts) # runs on all segments
    linsub =  inter.calcLinSub(rawd, interd, var=var) # returns 1 if successful, 0 if not
    if not linsub:
        interd['Tafel_slopeVperdec'] = float('nan')
        interd['Tafel_estart'] = float('nan')
        interd['Tafel_fitVrange'] = float('nan')
        interd['Tafel_logExCurrent'] = float('nan')
        return float('nan')
    inter.SegSG(rawd, interd, SGpts=SGpts, order=1, k=var+'_LinSub')
    for seg in range(len(interd['segprops_dlist'])):
        inds=interd['segprops_dlist'][seg]['inds']
        i=interd['I(A)_LinSub_SG'][inds]
        v=rawd['Ewe(V)'][inds]+vshift
        posinds=numpy.where(i>zero_thresh)
        invboolarr=numpy.float32(i<=zero_thresh)
        istart_segs, len_segs, fitdy_segs, fitinterc_segs=inter.findzerosegs(
            invboolarr, boolDevFrac,  boolDevNOut, booldn_segstart, SGnpts=SavGolPts,
            dx=dx, maxfracoutliers=maxFracOutliers)
        if len(istart_segs)==0:
            # no Tafel segments
            interd['Tafel_slopeVperdec'].append(float('nan'))
            interd['Tafel_estart'].append(float('nan'))
            interd['Tafel_fitVrange'].append(float('nan'))
            interd['Tafel_logExCurrent'].append(float('nan'))
            continue
        ind=numpy.argmax(len_segs)
        i0=istart_segs[ind]
        i1=i0+len_segs[ind]
        taffitinds=numpy.arange(i0, i1)
        interd['segprops_dlist'][seg]['TafelFitInds']=inds[taffitinds]
        i=i[i0:i1]
        i[i<zero_thresh]=zero_thresh #needed due to outliers
        v=v[i0:i1]
        il=numpy.log10(i)
        try:
            istart_segs, len_segs, fitdy_segs, fitinterc_segs, dy=inter.findlinearsegs(
                il, dyDevFrac, dyDevNOut, dn_segstart, dydev_abs=dyDevAbs, dx=dx, critdy_fracmaxdy=None)
        except:
            interd['Tafel_slopeVperdec'].append(float('nan'))
            interd['Tafel_estart'].append(float('nan'))
            interd['Tafel_fitVrange'].append(float('nan'))
            interd['Tafel_logExCurrent'].append(float('nan'))
            continue
        if len(istart_segs)==0:
            # no Tafel segments
            interd['Tafel_slopeVperdec'].append(float('nan'))
            interd['Tafel_estart'].append(float('nan'))
            interd['Tafel_fitVrange'].append(float('nan'))
            interd['Tafel_logExCurrent'].append(float('nan'))
            continue
        #only take those segments covering a certain V range and with a min current for the top 10th of the V range
        #   in the segment and positive slope for there on out and then take the steepest one.
        ind=None
        maxdy=0
        npts=critSegVRange/dx
        npts2=max(2, npts//10+1)
        for count2, (it0, slen, dyv) in enumerate(zip(istart_segs, len_segs, fitdy_segs)):
            if slen<npts:
                continue
            it1=it0+slen
            if numpy.mean(i[it1-npts2:it1])<critSegIEnd:
                continue
            if numpy.mean(v[it1-npts2:it1])<critSegVEnd:
                continue
            if numpy.any(dy[it1:]<0.):
                continue
            if dyv>maxdy:
                maxdy=dyv
                ind=count2
        if ind is None:
            # no Tafel segments
            interd['Tafel_slopeVperdec'].append(float('nan'))
            interd['Tafel_estart'].append(float('nan'))
            interd['Tafel_fitVrange'].append(float('nan'))
            interd['Tafel_logExCurrent'].append(float('nan'))
            continue
        
        i0=istart_segs[ind]
        i1=i0+len_segs[ind]
        tafinds=numpy.arange(i0, i1)
        it=il[tafinds]
        vt=v[tafinds]
        fitdy, fitint=numpy.polyfit(vt, it, 1)

        interd['Tafel_slopeVperdec'].append(1./fitdy)
        interd['Tafel_estart'].append(v[0])
        interd['Tafel_fitVrange'].append(vt.max()-vt.min())
        interd['Tafel_logExCurrent'].append(fitint)

        interd['segprops_dlist'][seg]['TafelInds']=inds[taffitinds][tafinds]
        
    #FOMs (the entire list):
    return interd['Tafel_slopeVperdec']
def TafelSlopeVPerDec(rawd, interd, var='I(A)', vk='Ewe(V)_E0', boolDevFrac=0.5, boolDevNOut=3,
                      dyDevFrac=0.2, dyDevNOut=5, dyDevAbs = 0.,
                      dx=1., maxFracOutliers=0.5, critSegVRange=0.04, critSegIEnd=3.e-5,
                      critSegVEnd=0.36, SavGolPts=10, inverty=False):
    # initialize the arrays to hold Tafel values (considered both
    #   intermediate data and figures of merit)
    interd['TafelSlope'] = []
    interd['TafelEstart'] = []
    interd['TafelFitErange'] = []
    interd['TafelLogIex'] = []
    booldn_segstart = 3 * boolDevNOut
    dn_segstart = 3 * dyDevNOut
    inter.calcsegind(rawd, interd, SGpts=SavGolPts) # breaks experiment into segments
    inter.calccurvregions(rawd, interd, SGpts=SavGolPts, inverty=inverty) # runs on all segments
    linsub =  inter.calcLinSub(rawd, interd, var=var, inverty=inverty) # returns 1 if successful, 0 if not
    if inverty:
        yinv=-1.
    else:
        yinv=1.
    if not linsub:
        nanlist=[float('nan')]*len(interd['segprops_dlist'])
        interd['TafelSlope'] = nanlist
        interd['TafelEstart'] = nanlist
        interd['TafelFitErange'] = nanlist
        interd['TafelLogIex'] = nanlist
        return float('nan')
    inter.SegSG(rawd, interd, SGpts=SGpts, order=1, k=var+'_LinSub')
    for seg in range(len(interd['segprops_dlist'])):
        inds=interd['segprops_dlist'][seg]['inds']
        i=interd['I(A)_LinSub_SG'][inds]*yinv
#        if i.sum()==0.:#LinSub attempted on all segments, here each segment is tried until 1 works
#            continue
        if vk in rawd.keys():
            v = rawd[vk]
        else:
            v = interd[vk]
        v=v[inds]
        posinds=numpy.where(i>zero_thresh)
        invboolarr=numpy.float32(i<=zero_thresh)
        istart_segs, len_segs, fitdy_segs, fitinterc_segs=inter.findzerosegs(
            invboolarr, boolDevFrac,  boolDevNOut, booldn_segstart, SGnpts=SavGolPts,
            dx=dx, maxfracoutliers=maxFracOutliers)
        if len(istart_segs)==0:
            # no Tafel segments
            interd['TafelSlope'].append(float('nan'))
            interd['TafelEstart'].append(float('nan'))
            interd['TafelFitVrange'].append(float('nan'))
            interd['TafelLogIex'].append(float('nan'))
            continue
        ind=numpy.argmax(len_segs)
        i0=istart_segs[ind]
        i1=i0+len_segs[ind]
        taffitinds=numpy.arange(i0, i1)
        interd['segprops_dlist'][seg]['TafelFitInds']=inds[taffitinds]
        i=i[i0:i1]
        i[i<zero_thresh]=zero_thresh #needed due to outliers
        v=v[i0:i1]
        il=numpy.log10(i)
        try:
            istart_segs, len_segs, fitdy_segs, fitinterc_segs, dy=inter.findlinearsegs(
                il, dyDevFrac, dyDevNOut, dn_segstart, dydev_abs=dyDevAbs, dx=dx, critdy_fracmaxdy=None)
        except:
            interd['TafelSlope'].append(float('nan'))
            interd['TafelEstart'].append(float('nan'))
            interd['TafelFitVrange'].append(float('nan'))
            interd['Tafel_logExCurrent'].append(float('nan'))
            continue
        if len(istart_segs)==0:
            # no Tafel segments
            interd['TafelSlope'].append(float('nan'))
            interd['TafelEstart'].append(float('nan'))
            interd['TafelFitVrange'].append(float('nan'))
            interd['TafelLogIex'].append(float('nan'))
            continue
        #only take those segments covering a certain V range and with a min current for the top 10th of the V range
        #   in the segment and positive slope for there on out and then take the steepest one.
        ind=None
        maxdy=0
        npts=critSegVRange/dx
        npts2=max(2, npts//10+1)
        for count2, (it0, slen, dyv) in enumerate(zip(istart_segs, len_segs, fitdy_segs)):
            if slen<npts:
                continue
            it1=it0+slen
            if numpy.mean(i[it1-npts2:it1])<critSegIEnd:
                continue
            if numpy.mean(v[it1-npts2:it1])<critSegVEnd:
                continue
            if numpy.any(dy[it1:]<0.):
                continue
            if dyv>maxdy:
                maxdy=dyv
                ind=count2
        if ind is None:
            # no Tafel segments
            interd['TafelSlope'].append(float('nan'))
            interd['TafelEstart'].append(float('nan'))
            interd['TafelFitVrange'].append(float('nan'))
            interd['TafelLogIex'].append(float('nan'))
            continue
        
        i0=istart_segs[ind]
        i1=i0+len_segs[ind]
        tafinds=numpy.arange(i0, i1)
        it=il[tafinds]
        vt=v[tafinds]
        fitdy, fitint=numpy.polyfit(vt, it, 1)

        interd['TafelSlope'].append(1./fitdy)
        interd['TafelEstart'].append(v[0])
        interd['TafelFitVrange'].append(vt.max()-vt.min())
        interd['TafelLogIex'].append(fitint)

        interd['segprops_dlist'][seg]['TafelInds']=inds[taffitinds][tafinds]
        
    #FOMs (the entire list):
    fomarr=numpy.array(interd['TafelSlope']) #in interd there is a fom for each segment but save the first not NaN one as scalar FOM
    goodinds=numpy.where(numpy.logical_not(numpy.isnan(fomarr)))[0]
    if len(goodinds)==0:
        return float('nan')
    return fomarr[goodinds[0]]