166 lines
5.2 KiB
Python
166 lines
5.2 KiB
Python
# 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()
|