# Python program to analyze cards import matplotlib.pyplot as plt import numpy as np import readCardFile as rcf import math # Setup Data slices = 250 # number of horizontal slices to evaluate regN = 10 # regression level downhole = rcf.readFile()[1] # read in CSV file output from POConsole/POCloud # helper functions def __find_incremental_load(target_position, downholeArray, lastResult): up_point_greater = [0, 0] up_point_lesser = [0, 0] down_point_greater = [0, 0] down_point_lesser = [0, 0] up_point_found = False down_point_found = False for ind in range(1, len(downholeArray)): # print(downholeArray[i][0]) if (downholeArray[ind][0] > target_position) and (downholeArray[ind - 1][0] <= target_position): up_point_greater = [downholeArray[ind][0], downholeArray[ind][1]] up_point_lesser = [downholeArray[ind - 1][0], downholeArray[ind - 1][1]] up_point_found = True if (downholeArray[ind][0] <= target_position) and (downholeArray[ind - 1][0] > target_position): down_point_greater = [downholeArray[ind][0], downholeArray[ind][1]] down_point_lesser = [downholeArray[ind - 1][0], downholeArray[ind - 1][1]] down_point_found = True if up_point_found & down_point_found: m_up = (up_point_greater[1] - up_point_lesser[1]) / (up_point_greater[0] - up_point_lesser[0]) b_up = up_point_greater[1] - (m_up * up_point_greater[0]) up_middle = (m_up * target_position) + b_up m_down = (down_point_greater[1] - down_point_lesser[1]) / (down_point_greater[0] - down_point_lesser[0]) b_down = down_point_greater[1] - (m_down * down_point_greater[0]) down_middle = (m_down * target_position) + b_down return [up_middle - down_middle, up_middle, down_middle] else: return lastResult def findLine(x1,y1,x2,y2): # finds the slope and intercept of a line between two points m = (y2-y1)/(x2-x1) b = y1 - m*x1 return(m,b) def vectorDist(x1,y1,x2,y2): return math.sqrt((x2-x1)**2 + (y2-y1)**2) def perpDist(x,y,m,b): # line as mx+b return abs(m*x + (-1) * y + b) / math.sqrt( m**2 + (-1)**2) # find min & max position minPosition = min(downhole, key = lambda x:x[0]) minLoad = min(downhole, key = lambda x:x[1]) maxPosition = max(downhole, key = lambda x:x[0]) maxLoad = max(downhole, key = lambda x:x[1]) downholeLoadSpan = maxLoad[1] - minLoad[1] # split cards into equal slices sliceLength = (maxPosition[0] - minPosition[0]) / (slices + 1) slicesAll = [] topSlices = [] bottomSlices = [] sliceDelta = [] posSlices = [] for j in range(0, slices): targetPosition = j * sliceLength + minPosition[0] nextTargetPosition = (j + 1) * sliceLength + minPosition[0] # interpret mean point of each slice if j > 0: sliver = __find_incremental_load(targetPosition, downhole, slicesAll[j - 1]) else: sliver = __find_incremental_load(targetPosition, downhole, [0, 0, 0]) slicesAll.append(sliver) sliceDelta.append(sliver[0]) topSlices.append(sliver[1]) bottomSlices.append(sliver[2]) posSlices.append(targetPosition) topC = np.polyfit(posSlices, topSlices, regN) botC = np.polyfit(posSlices, bottomSlices, regN) topReg = [] botReg = [] for i in range(0,len(posSlices)): x = posSlices[i] tr = 0 br = 0 for j in range(0,regN+1): tr += topC[j] * x**(regN-j) br += botC[j] * x**(regN-j) topReg.append(tr) botReg.append(br) p,l = zip(*downhole) (tm,tb) = findLine(posSlices[0], topSlices[0], posSlices[-1], topSlices[-1]) (bm,bb) = findLine(posSlices[0], bottomSlices[0], posSlices[-1], bottomSlices[-1]) #(tm,tb) = findLine(minPosition[0], minPosition[1], maxPosition[0], maxPosition[1]) #(bm,bb) = findLine(minPosition[0], minPosition[1], maxPosition[0], maxPosition[1]) linePos = np.linspace(posSlices[0], posSlices[-1], len(posSlices)) topDist = [] bottomDist = [] tLine = [] bLine = [] corner_topLeft = (0, 0) corner_fillage = (0, 0) maxTopDist = 0.0 maxBotDist = 0.0 for i in range(0, len(posSlices)): tLineY = linePos[i] * tm + tb #td = vectorDist(posSlices[i], topSlices[i], linePos[i], tLineY) td = perpDist(posSlices[i], topSlices[i], tm, tb) topDist.append(td) tLine.append(tLineY) if td > maxTopDist: maxTopDist = td corner_topLeft = (posSlices[i], topSlices[i]) tLine.append(tLineY) bLineY = linePos[i] * bm + bb #bd = vectorDist(posSlices[i], bottomSlices[i], linePos[i], bLineY) bd = perpDist(posSlices[i], bottomSlices[i], bm, bb) bLine.append(bLineY) bottomDist.append(bd) if bd > maxBotDist: maxBotDist = bd corner_fillage = (posSlices[i], bottomSlices[i]) fillPercent = (corner_fillage[0] - minPosition[0])/(maxPosition[0] - corner_topLeft[0]) * 100 print("Fill:", fillPercent) fig = plt.figure(figsize=(12, 9)) fig.canvas.set_window_title('Downhole Card Analysis') # plt.plot(p, l, 'g') # plot actual card plt.plot(posSlices, topSlices, 'r') # plot bottom points plt.plot(posSlices, bottomSlices, 'r') # plot bottom points # plt.plot(posSlices, topReg, 'b') # plt.plot(posSlices, botReg, 'b') # plt.plot(posSlices, topDist, 'y') # plt.plot(posSlices, bottomDist, 'g') plt.axvline(x=corner_topLeft[0]) plt.axvline(x=corner_fillage[0]) # plt.plot(linePos, tLine, 'orange') # plt.plot(linePos, bLine, 'purple') plt.grid(True) plt.show()