Files
Misc-Downhole-Diagnostics/findCorners.py
Patrick McDonagh a1714c722f Initial Commit
2016-07-01 16:43:39 -05:00

167 lines
5.9 KiB
Python

# Python program to analyze cards
import matplotlib.pyplot as plt
import readCardFile as rcf
import math
import os, sys
def main(sl = 100):
# Setup Data
slices = int(sl) # number of horizontal slices to evaluate
#downhole = rcf.readFile("{0}/{1}".format(os.getcwd(), "testCard.csv"))[1] # read in CSV file output from POConsole/POCloud
downhole = rcf.readFile()[1]
num_points = len(downhole)
dh_pos = list(map(lambda x: x[0], downhole))
dh_pos_max = max(dh_pos)
dh_pos_min = min(dh_pos)
dh_lod = list(map(lambda x: x[1], downhole))
dh_lod_max = max(dh_lod)
dh_lod_min = min(dh_lod)
max_p = (dh_pos_max, dh_lod[dh_pos.index(dh_pos_max)])
min_p = (dh_pos_min, dh_lod[dh_pos.index(dh_pos_min)])
def determine_d_pos(min, max, num_slices):
return (max - min) / num_slices
d_pos = determine_d_pos(dh_pos_min, dh_pos_max, slices)
def distribute_positions(min, max, num_slices, dp):
""" distributes positions equally between the max and min values. Returns a list of positions """
p_targ = []
for i in range(0, num_slices):
p_targ.append(min + i * dp)
return p_targ
position_targets = distribute_positions(dh_pos_min, dh_pos_max, slices, d_pos)
def lineresolve(x1,x2,y1,y2,targ):
m = ((y2-y1)/(x2-x1))
b = y1 - m * x1
return(m * targ + b)
def find_top_slices():
""" finds the top slices of a card. Returns a list of (position,load) tuples"""
t_slices = []
last_pos_index = 0
for i in range(0,slices):
targ = position_targets[i]
for j in range(last_pos_index, num_points -1):
if (dh_pos[j] <= targ and dh_pos[j+1] > targ):
found_i = j
next_i = j+1
fake_load = lineresolve(dh_pos[found_i], dh_pos[next_i], dh_lod[found_i], dh_lod[next_i], targ)
t_slices.append((targ, fake_load))
last_pos_index = found_i
break
return t_slices
top_slices = find_top_slices()
print("== TOP ==")
for i in top_slices:
print("{0} - {1}".format(i[0], i[1]))
def find_bot_slices():
""" finds the top slices of a card. Returns a list of (position,load) tuples"""
b_slices = []
last_pos_index = 0
for i in range(0,slices):
targ = position_targets[i]
for j in range(0, num_points -1):
if (dh_pos[j] > targ and dh_pos[j+1] <= targ):
found_i = j
next_i = j+1
fake_load = lineresolve(dh_pos[found_i], dh_pos[next_i], dh_lod[found_i], dh_lod[next_i], targ)
b_slices.append((targ, fake_load))
#last_pos_index = found_i
break
return b_slices
bot_slices = find_bot_slices()
print("== BOTTOM ==")
for i in bot_slices:
print("{0} - {1}".format(i[0], i[1]))
def distance_to_line(x0,y0):
""" Finds the perpendicular distance from a point to the line between max and min points"""
x1 = min_p[0]
x2 = max_p[0]
# y1 = min_p[1]
# y2 = max_p[1]
y1 = dh_lod_min
y2 = dh_lod_max
d = abs((y2-y1)*x0 - (x2-x1)*y0 + x2*y1 - y2*x1) / math.sqrt(math.pow(y2-y1,2) + math.pow(x2-x1,2))
return d
top_d = []
bot_d = []
# Here's where we get the distance from each point to the line
for i in range(1,slices):
try:
top_d.append(distance_to_line(top_slices[i][0], top_slices[i][1]))
except Exception:
print("Error - top_d, index: {0}".format(i))
try:
bot_d.append(distance_to_line(bot_slices[i][0], bot_slices[i][1]))
except Exception:
print("Error - bot_d, index: {0}".format(i))
top_cor_i = top_d.index(max(top_d))
bot_cor_i = bot_d.index(max(bot_d))
top_corner = top_slices[top_cor_i]
bot_corner = bot_slices[bot_cor_i]
tubing_movement = top_corner[0] - dh_pos_min
fillage = (bot_corner[0] - dh_pos_min)/(dh_pos_max - (dh_pos_min + tubing_movement)) * 100
print("=================================================")
print("Tubing Movement: {0} in.".format(round(tubing_movement,3)))
print("Fill Percent: {0}%".format(round(fillage, 3)))
#determine difference between gas interference and incomplete fill
po_area = 0.0
actual_area = 0.0
bot_last = bot_slices[-1]
gas_line = []
for i in range(bot_cor_i, len(bot_slices)):
gas_line_load = lineresolve(bot_corner[0], bot_last[0], bot_corner[1], bot_last[1], bot_slices[i][0])
gas_line.append((bot_slices[i][0], gas_line_load))
po_area = po_area + (bot_last[0] - gas_line_load) * d_pos
actual_area = actual_area + abs(gas_line_load - bot_slices[i][1]) * d_pos
area_ratio = actual_area / po_area
print ("\nFull Area: {0}\nActual Area: {1}".format(po_area, actual_area))
print("\nIncomplete Fillage Score:{0}%\nGas Interference Score:{1}%".format(round(area_ratio*100,3), round((1-area_ratio)*100,3)))
print("=================================================")
plt.figure()
plt.subplot(211)
plt.plot(list(map(lambda x: x[0], downhole)), list(map(lambda x: x[1], downhole)) ,'r')
plt.plot(list(map(lambda x: x[0], top_slices)), list(map(lambda x: x[1], top_slices)) ,'b')
plt.plot(list(map(lambda x: x[0], bot_slices)), list(map(lambda x: x[1], bot_slices)) ,'g')
plt.plot(list(map(lambda x: x[0], gas_line)), list(map(lambda x: x[1], gas_line)) ,'m')
plt.subplot(212)
plt.plot(list(map(lambda x: x[0], top_slices))[1:], top_d ,'r')
plt.plot(list(map(lambda x: x[0], bot_slices))[1:], bot_d ,'y')
#ax2.axvline(x=top_corner[0])
#ax2.axvline(x=bot_corner[0])
plt.grid(True)
plt.show()
if __name__ == "__main__":
if len(sys.argv) > 1:
main(sys.argv[1])
else:
main()