In [1]:
%pylab inline
from scipy.optimize import basinhopping
from scipy.interpolate import UnivariateSpline
import pandas as pd
import csv
import shapely.affinity as af
import shapely.geometry as sh
from equivalent_ellipse import *
from scaled_figures import *
In [46]:
x_list = list()
y_list = list()
with open('../data/cutout_x.csv', 'r') as x_csvfile:
with open('../data/cutout_y.csv', 'r') as y_csvfile:
x_reader = csv.reader(x_csvfile, delimiter=',', lineterminator='\n')
y_reader = csv.reader(y_csvfile, delimiter=',', lineterminator='\n')
for row in x_reader:
x_list += [row]
for row in y_reader:
y_list += [row]
num_cutouts = len(x_list)
x_array = [0,]*num_cutouts
y_array = [0,]*num_cutouts
for i in range(num_cutouts):
x_array[i] = array(x_list[i], dtype='float')
y_array[i] = array(y_list[i], dtype='float')
cutout = [0,]*num_cutouts
for i in range(num_cutouts):
cutout[i] = shapely_cutout(x_array[i],y_array[i])
In [47]:
with open('cutout_factors','r') as f:
loaded_factor = eval(f.read())
dictArray = array(list(loaded_factor.items()),float)
cutoutRef = dictArray[:,0].astype(int)
factor = dictArray[:,1]
In [48]:
len(cutout)
Out[48]:
In [49]:
with open('custom_cutout_factors','r') as f:
loaded_custom_factor = eval(f.read())
# customDimensionsDict = {'5x13':[5,13],
# '5x10':[5,10],
# '5x8':[5,8],
# '4x13':[4,13],
# '4x10':[4,10],
# '4x8':[4,8],
# '4x6.5':[4,6.5],
# '3x13':[3,13],
# '3x9':[3,9],
# '3x6.5':[3,6.5],
# '3x5':[3,5]}
customDimensionsDict = {'5x8':[5,8],
'4x8':[4,8],
'4x6.5':[4,6.5],
'3x9':[3,9],
'3x6.5':[3,6.5],
'3x5':[3,5]}
customDataLabelList = list(customDimensionsDict.keys())
custom_factors = [loaded_custom_factor[x] for x in customDataLabelList]
custom_widths = [customDimensionsDict[x][0] for x in customDataLabelList]
custom_lengths = [customDimensionsDict[x][1] for x in customDataLabelList]
ellipse_cutouts = [0,]*len(custom_widths)
for i in range(len(custom_widths)):
ellipse_cutouts[i] = create_ellipse([0,0,custom_widths[i],custom_lengths[i],-45])
cutoutRef = append(cutoutRef,arange(len(cutout),len(cutout)+len(ellipse_cutouts)))
cutout.extend(ellipse_cutouts)
factor = append(factor,custom_factors)
In [50]:
# testCutout = cutout[70]
# testCutout
In [7]:
with open('circle_cutout_factors','r') as f:
loaded_circle_factor = eval(f.read())
circleDictArray = array(list(loaded_circle_factor.items()),float)
circleDiameter = circleDictArray[:,0]
circleFactor = circleDictArray[:,1]
In [8]:
scatter(circleDiameter,1/circleFactor)
circleFit = UnivariateSpline(circleDiameter,1/circleFactor)
diameter_i = linspace(circleDiameter.min(),circleDiameter.max())
plot(diameter_i,circleFit(diameter_i),'r--')
Out[8]:
In [9]:
minVal = 3
maxVal = 9
numZones = 100
In [10]:
# Create Zones
zoneWidth = linspace(minVal,maxVal,numZones)
zoneWeight = 70*circleFit.derivative()(zoneWidth)
circle = [0,]*(numZones)
circle[0] = sh.Point(0,0).buffer(minVal/2)
zone = [0,]*numZones
zone[0] = circle[0]
for i in range(1,numZones-1):
circle[i] = sh.Point(0,0).buffer(zoneWidth[i]/2)
zone[i] = circle[i].difference(circle[i-1])
zone[-1] = sh.Point(0,0).buffer(20).difference(circle[-2])
weightedArea = 0.
for i in range(numZones):
weightedArea += cutout[0].intersection(zone[i]).area * zoneWeight[i]
weightedArea
Out[10]:
In [11]:
cutout[0].area
Out[11]:
In [12]:
plot(zoneWidth,zoneWeight)
Out[12]:
In [13]:
def weightedAreaOptimise(x,inputShape):
a = x[0]
b = x[1]
movedShape =af.translate(inputShape, xoff=-a, yoff=-b)
weightedArea = 0.
for i in range(numZones):
weightedArea += movedShape.intersection(zone[i]).area * zoneWeight[i]
return -weightedArea
In [14]:
class MyTakeStep(object):
def __init__(self, stepsize=0.5):
self.stepsize = stepsize
def __call__(self, x):
s = self.stepsize
x[0] += np.random.uniform(-3*s, 3*s)
x[1] += np.random.uniform(-3*s, 3*s)
return x
def print_fun(x, f, accepted):
global successCount_basinhopping
global minVals_basinhopping
global nSuccess_basinhopping
a = x[0]
b = x[1]
f = np.around(f,4)
if accepted:
if np.all(np.isnan(minVals_basinhopping)):
minVals_basinhopping[0] = f
successCount_basinhopping = 1
print(("first local minima of %.4f at:\n"+
"[a,b] = [%.4f, %.4f]")
% (f,a,b))
elif (np.nanmin(minVals_basinhopping) == f):
minVals_basinhopping[successCount_basinhopping] = f
successCount_basinhopping += 1
print(("agreeing local minima of %.4f at:\n"+
"[a,b] = [%.4f, %.4f]")
% (f,a,b))
elif (np.nanmin(minVals_basinhopping) > f):
minVals_basinhopping[0] = f
successCount_basinhopping = 1
print(("new local minima of %.4f at:\n"+
"[a,b] = [%.4f, %.4f]")
% (f,a,b))
else:
print(("rejected local minima of %.4f at:\n"+
"[a,b] = [%.4f, %.4f]")
% (f,a,b))
else:
print(("failed to find local minima at:\n"+
"[a,b] = [%.4f, %.4f]")
% (a,b))
if successCount_basinhopping >= nSuccess_basinhopping:
return True
def optimise_middle(cutout,userNSuccess):
mytakestep = MyTakeStep()
global nSuccess_basinhopping
nSuccess_basinhopping = userNSuccess
global minVals_basinhopping
minVals_basinhopping = np.empty(nSuccess_basinhopping)
minVals_basinhopping[:] = np.nan
global successCount_basinhopping
successCount_basinhopping = 0
minimizer_kwargs = {"args": (cutout,), "method": 'L-BFGS-B',
"bounds": ((-5,5),(-5,5)) }
x0 = np.array([0,0])
output = basinhopping(weightedAreaOptimise,x0,
niter=1000,minimizer_kwargs=minimizer_kwargs,
take_step=mytakestep, callback=print_fun)
return output
In [15]:
middle_points = zeros([len(cutoutRef),2])
for j in range(len(cutoutRef)):
i = cutoutRef[j]
print("Cutout %.f" % (i))
output = optimise_middle(cutout[i],3)
middle_points[j,:] = output.x
print(" ")
In [15]:
In [15]:
In [51]:
predicted_factor = zeros(len(cutoutRef))
for j in range(len(cutoutRef)):
i = cutoutRef[j]
cutoutLineString = sh.LineString(cutout[i].exterior.coords)
steps = linspace(0,1,1000)
xcoords = zeros(len(steps))
ycoords = zeros(len(steps))
for k in range(len(steps)):
xycoords = cutoutLineString.interpolate(steps[k], normalized=True).xy
xcoords[k] = xycoords[0][0]
ycoords[k] = xycoords[1][0]
x_vals = xcoords
y_vals = ycoords
a = middle_points[j,0]
b = middle_points[j,1]
x_vals = array(x_vals,'float') - a
y_vals = array(y_vals,'float') - b
angles = arctan2(y_vals, x_vals) * 180 / pi
clockwise = sum(mod(diff(angles),360)) > sum(mod(-diff(angles),360))
diffAdj = 1 - 2*clockwise
sector_angles = mod(diffAdj*diff(angles),360)
wrong_direction = sector_angles > 180
while any(wrong_direction):
wrong_direction = append(wrong_direction,False)
x_vals = x_vals[~wrong_direction]
y_vals = y_vals[~wrong_direction]
angles = arctan2(y_vals, x_vals) * 180 / pi
sector_angles = mod(diffAdj*diff(angles),360)
wrong_direction = sector_angles > 180
radii = hypot(x_vals,y_vals)
sector_radii = radii[0:-1] + diff(radii)/2
angles = arctan2(y_vals, x_vals) * 180 / pi
sector_angles = mod(diffAdj*diff(angles),360)
predicted_factor[j] = 1/sum(circleFit(sector_radii*2) * sector_angles / 360)
In [52]:
predicted_factor
Out[52]:
In [53]:
difference = factor-predicted_factor
df = pd.DataFrame(transpose([cutoutRef,predicted_factor, factor,difference]))
df.columns = ['Reference','sector_predict', 'measured_factor','difference']
df.to_csv(path_or_buf = "sector_integration.csv", index=False)
df
Out[53]:
In [54]:
std(difference)
Out[54]:
In [70]:
# pos = 120
# ref = cutoutRef[pos]
# ref
ref = 57
pos = find(ref == cutoutRef)[0]
In [71]:
# i = 19
# i = 106
i = ref
# cutout[i] = cutout[i].buffer(0.001,resolution=100)
scaled_fig_start(12,12)
x_vals_show = cutout[i].exterior.xy[0]
y_vals_show = cutout[i].exterior.xy[1]
x_vals_show = array(x_vals_show,'float')
y_vals_show = array(y_vals_show,'float')
a = middle_points[pos,0]
b = middle_points[pos,1]
scatter(a,b,c='red',s=100, zorder=10)
for k in range(len(x_vals_show)):
plot([a,x_vals_show[k]],[b,y_vals_show[k]],'g')
plot(x_vals_show,y_vals_show,linewidth=3)
scaled_fig_end(12,12)
In [72]:
test = sh.LineString(cutout[i].exterior.coords)
steps = linspace(0,1,100)
xcoords = zeros(len(steps))
ycoords = zeros(len(steps))
for i in range(len(steps)):
xycoords = test.interpolate(steps[i], normalized=True).xy
xcoords[i] = xycoords[0][0]
ycoords[i] = xycoords[1][0]
In [73]:
scaled_fig_start(12,12)
a = middle_points[pos,0]
b = middle_points[pos,1]
scatter(a,b,c='red',s=100, zorder=10)
for k in range(len(xcoords)):
plot([a,xcoords[k]],[b,ycoords[k]],'g')
plot(xcoords,ycoords,linewidth=3)
scaled_fig_end(12,12)
In [74]:
i = 19
x_vals = xcoords
y_vals = ycoords
a = middle_points[i,0]
b = middle_points[i,1]
x_vals = array(x_vals,'float') - a
y_vals = array(y_vals,'float') - b
angles = arctan2(y_vals, x_vals) * 180 / pi
plot(angles)
Out[74]:
In [75]:
clockwise = sum(mod(diff(angles),360)) > sum(mod(-diff(angles),360))
diffAdj = 1 - 2*clockwise
sector_angles = mod(diffAdj*diff(angles),360)
plot(sector_angles)
Out[75]:
In [76]:
wrong_direction = sector_angles > 180
while any(wrong_direction):
wrong_direction = append(wrong_direction,False)
x_vals = x_vals[~wrong_direction]
y_vals = y_vals[~wrong_direction]
angles = arctan2(y_vals, x_vals) * 180 / pi
sector_angles = mod(diffAdj*diff(angles),360)
wrong_direction = sector_angles > 180
# wrong_direction
In [77]:
radii = hypot(x_vals,y_vals)
sector_radii = radii[0:-1] + diff(radii)/2
plot(sector_radii)
Out[77]:
In [78]:
angles = arctan2(y_vals, x_vals) * 180 / pi
sector_angles = mod(diffAdj*diff(angles),360)
plot(sector_angles)
Out[78]:
In [79]:
plot(cumsum(sector_angles),circleFit(sector_radii*2))
Out[79]:
In [81]:
1/sum(circleFit(sector_radii*2) * sector_angles / 360)
Out[81]:
In [ ]: