import proper
import numpy as np
import scipy as sc
import matplotlib.pyplot as plt
%matplotlib inline
import cv2 as cv
from skimage import data, color
from skimage.transform import hough_circle
from skimage.feature import peak_local_max, canny
from skimage.draw import circle_perimeter, circle
from skimage.util import img_as_ubyte
from scipy import ndimage
from skimage.transform import resize, downscale_local_mean
# old algorithm levels
#threshold1 = 0.16
#threshold2 = 0.205
#threshold1 = 0.18
#threshold2 = 0.24
#threshold1 = 0.03
#threshold2 = 0.0454
#threshold1 = 0.11
#threshold2 = 0.118
#threshold1 = 0.3
#threshold2 = 0.3
# ok for unoccluded
threshold1 = 0.18
threshold2 = 0.27
# ok for occluded
#threshold1 = 0.27
#threshold2 = 0.38
import random as rng
rng.seed(12345)
def thresh_callback(src_gray, val):
threshold = val
_, contours, _ = cv.findContours(src_gray, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
contours_poly = [None]*len(contours)
centers = [None]*len(contours)
radius = [None]*len(contours)
for i, c in enumerate(contours):
contours_poly[i] = cv.approxPolyDP(c, 3, True)
centers[i], radius[i] = cv.minEnclosingCircle(contours_poly[i])
drawing = np.zeros((src_gray.shape[0], src_gray.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
colore = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours_poly, i, colore)
cv.circle(drawing, (int(centers[i][0]), int(centers[i][1])), int(radius[i]), colore, 2)
print("Max r", np.max(radius))
fig, ax = plt.subplots(1,1, figsize=(15,10))
ax.imshow(drawing + color.gray2rgb(src_gray) )
plt.show()
return np.max(radius)
def plateauLevel(input_image):
imm = np.copy(input_image)
imax = (np.max(input_image))
imm *= 1.0/imax
imm_cap = np.where(imm < threshold1, 0.0, 1.0)
count = np.sum(imm_cap)
guessR = np.sqrt(float(count)/np.pi)
guessCenter = ndimage.measurements.center_of_mass(imm_cap)
plateauRadius = 0.8 * guessR # 0.8 * guessR
print(guessR)
print(guessCenter)
# fig, ax = plt.subplots(1,1, figsize=(15,10))
# ax.imshow(input_image)
# plt.show()
immInnerDisc = input_image*0.0
rr, cc = circle(guessCenter[0], guessCenter[1], plateauRadius)
immInnerDisc[rr, cc] = 1.0
plateauImage = np.where(immInnerDisc >=0.97, input_image, 0.0)
plateauImageMask = np.where(immInnerDisc >=0.97, 1.0, 0.0)
#fig, ax = plt.subplots(1,1, figsize=(15,10))
#ax.imshow(plateauImage)
#plt.show()
plateauLevelOut = np.sum(plateauImage)/np.sum(plateauImageMask)
print('plateauLevel:', plateauLevelOut/imax)
return plateauLevelOut
def computeDiameter(input_image):
imm = np.copy(input_image)
threshold = plateauLevel(imm)
imm *= 1.0/threshold
imm_cap = np.where(imm < threshold2, 0.0, 1.0)
count = np.sum(imm_cap)
guess = 2*int(np.sqrt(float(count)/np.pi))
# print(guess)
#plt.imshow(imm_cap, cmap='hot')
soglie = [0.5]
cx = [0]
cy = [0]
ii = 0
image = (input_image/np.max(input_image))
# imm_cap = resize(imm_cap, (4096, 4096), order=1)
# imm_cap = resize(imm_cap, (2*2472, 2*3296), order=1)
imm_cap = resize(imm_cap, (2*imm_cap.shape[0], 2*imm_cap.shape[1]) , order=1)
sx = ndimage.sobel(imm_cap, axis=0, mode='constant',cval=0)
sy = ndimage.sobel(imm_cap, axis=1, mode='constant',cval=0)
sob = np.hypot(sx, sy)
sob = sob/np.max(sob)
idx = sob[:,:] > soglie[ii]
sob *= 0.0;
sob[idx] = 1
edges = img_as_ubyte(sob)
image_C = color.gray2rgb(edges)
# thresh = 50 # 25 # initial threshold
# rr_alt = thresh_callback(edges, thresh)
# return rr_alt # radius-0.5
hough_radii = np.arange(guess-1, guess+4, 1)
hough_res = hough_circle(edges, hough_radii)
centers = []
accums = []
radii = []
image_C = downscale_local_mean(edges, (4,4))
image_C = color.gray2rgb(image_C)
for radius, h in zip(hough_radii, hough_res):
num_peaks = 1
peaks = peak_local_max(h, num_peaks=num_peaks)
centers.extend(peaks)
accums.extend(h[peaks[:, 0], peaks[:, 1]])
radii.extend([radius] * num_peaks)
# print(radii)
for idx in np.argsort(accums)[::-1][:1]:
center_x, center_y = centers[idx]
center_x = center_x//4
center_y = center_y//4
radius = radii[idx]
ccx, ccy = circle_perimeter(center_y, center_x, radii[idx]//5)
image_C[ccy, ccx] = (255, 0, 0)
center_x, center_y = centers[0]
center_x = center_x//4
center_y = center_y//4
#radius = radii[0]
print('radius', radius)
sss = 900//4
fig, ax = plt.subplots(1,1, figsize=(15,10))
# ax.imshow(image_C[center_x-sss:center_x+sss, center_y-sss:center_y+sss])
ax.imshow(image_C) # [center_x-sss:center_x+sss, center_y-sss:center_y+sss])
plt.show()
cx[ii] = center_x
cy[ii] = center_y
# print('centri', float(center_x)/2.0+0.5, float(center_y)/2.0+0.5)
return radius-0.5
from scipy import stats
def fitAndShow(xx, dd, method=1):
if method==1:
a,b = np.polyfit(dd, xx, 1)
else:
a, b, r_value, p_value, std_err = stats.linregress(dd, xx)
# print('p_value**2:', p_value**2, 'std_err:', std_err)
print('a:', format(a, '.4f'))
# print('1/a:', format(1/a, '.4f'))
print('b:', format(b, '.4f'))
N = float(dd.shape[0])
deltaPrime = N * np.sum(np.multiply(dd,dd)) - np.sum(dd)**2
err = xx - a*dd - b
sigmaSquare = (1.0/(N-2)) * np.sum(np.multiply(xx,xx))
aSigma = (sigmaSquare/deltaPrime) * np.sum(np.multiply(dd,dd))
print( 'aSigma:', format(np.sqrt(aSigma), '.4f') )
print( '(aSigma/a)*100:', format(100*np.sqrt(aSigma)/a, '.3f') )
plt.figure(figsize=(15,10))
plt.plot(dd, xx, 'yo', dd, a*dd+b, '--k')
plt.show()
def simple_system(wavelength, gridsize, br, offset, aperture_diameter, f_number):
focal_ratio = f_number
diam = aperture_diameter
focal_length = diam * focal_ratio
beam_ratio = br
wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio)
proper.prop_circular_aperture(wfo, diam/2.0)
proper.prop_define_entrance(wfo)
proper.prop_lens(wfo, focal_length)
proper.prop_propagate(wfo, focal_length + offset, TO_PLANE=False)
gridsize = proper.prop_get_gridsize( wfo )
print( proper.prop_get_fratio( wfo ))
(wfo, sampling) = proper.prop_end(wfo)
return (wfo, sampling, gridsize)
def occluded_system(wavelength, gridsize, br, offset, aperture_diameter, f_number):
focal_ratio = f_number
diam = aperture_diameter
focal_length = diam * focal_ratio
beam_ratio = br
wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio)
proper.prop_circular_aperture(wfo, diam/2) # aperture (primary mirror)
# Normalizzato a 1 il diametro esterno della pupilla si ha:
# spessore dello spider: 9.4e-3
# diametro oscuramento centrale: 0.094
proper.prop_circular_obscuration(wfo, 0.094 * diam/2) # secondary mirror obscuration
# diam/2== fully obscured
# secondary vane (vertical)
proper.prop_rectangular_obscuration(wfo, 9.4e-3 * diam, diam, 0, 0, NORM=False, ROTATION=45.0)
# secondary vane (horizontal)
proper.prop_rectangular_obscuration(wfo, diam, 9.4e-3 * diam, 0, 0, NORM=False, ROTATION=45.0)
proper.prop_define_entrance(wfo)
proper.prop_lens(wfo, focal_length)
proper.prop_propagate(wfo, focal_length + offset, TO_PLANE=False)
gridsize = proper.prop_get_gridsize( wfo )
print( proper.prop_get_fratio( wfo ))
(wfo, sampling) = proper.prop_end(wfo)
return (wfo, sampling, gridsize)
def funcFilter(x, y):
return 0.997916 - 0.0491551*y - 0.414188*(y**2) + 0.0322198*x + 0.000797465*x*y - 0.0105691*x*(y**2)- 0.411941*(x**2) + 0.0124160*(x**2)*y + 0.0507806*(x**2)*(y**2)
def apoFilter():
xaxis = np.linspace(-2, 2, 2048)
yaxis = np.linspace(-2, 2, 2048)
x, y = np.meshgrid(xaxis, yaxis)
return funcFilter(x, y)
def gaussian_occluded_system(wavelength, gridsize, br, offset, aperture_diameter, f_number):
focal_ratio = f_number
diam = aperture_diameter
focal_length = diam * focal_ratio
beam_ratio = br
wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio)
proper.prop_circular_aperture(wfo, diam/2) # aperture (primary mirror)
occrad_m = aperture_diameter/2.0
r = proper.prop_radius(wfo)
print('occrad_m:', occrad_m)
h = np.sqrt(-0.5 * occrad_m**2 / np.log(1 - np.sqrt(0.5)))
print('h:', h)
gauss_spot = np.exp(-0.5 * (r/h)**2)
custom_spot = gauss_spot.copy()
custom_spot *= 0.0
custom_spot = apoFilter()
custom_spot = np.where(custom_spot < 0.0, 0.0, custom_spot)
plt.imshow(gauss_spot, cmap='hot')
plt.show()
plt.imshow(custom_spot, cmap='hot')
plt.colorbar()
plt.show()
proper.prop_multiply(wfo, custom_spot)
proper.prop_define_entrance(wfo)
proper.prop_lens(wfo, focal_length)
proper.prop_propagate(wfo, focal_length + offset, TO_PLANE=False)
gridsize = proper.prop_get_gridsize( wfo )
print( proper.prop_get_fratio( wfo ))
(wfo, sampling) = proper.prop_end(wfo)
return (wfo, sampling, gridsize)
def runmodel_off(model, Fnumber, system=simple_system):
gridsize = model['grid_size']
wavelengths = model['wavelengths']
beam_ratio = model['beam_ratio']
offsets = model['offset']
aperture_diameter = model['aperture_diameter']
r1 = [0]*len(offsets)
s1 = [0]*len(offsets)
gs1 = [0]*len(offsets)
ii=0
tot= len(offsets)*len(wavelengths)
for i, offset in enumerate(offsets):
r1[i] = np.zeros([gridsize, gridsize])
for j, w in enumerate(wavelengths):
r1ij, s1j, gs = system(w, gridsize, beam_ratio, offset, aperture_diameter, Fnumber)
ii+=1
print("Done:%f2" % (100* ii/tot))
print(gs)
gs1[i] =gs
s1[i] =s1j
r1[i] += r1ij
return r1, s1, gs1
def runmodel_w(model, Fnumber):
gridsize = model['grid_size']
wavelengths = model['wavelengths']
beam_ratio = model['beam_ratio']
offsets = model['offset']
aperture_diameter = model['aperture_diameter']
r1 = [0]*len(wavelengths)
s1 = [0]*len(wavelengths)
gs1 = [0]*len(wavelengths)
ii=0
tot = len(offsets)*len(wavelengths)
offset = offsets[0]
for j, w in enumerate(wavelengths):
r1[j], s1[j], gs1[j] = simple_system(w, gridsize, beam_ratio, offset, aperture_diameter, Fnumber)
print("Done:%f2" % (100* j/tot))
return r1, s1, gs1
def showResult_offset(model, r1, s1, showImages=False):
gridsize = r1[0].shape[0]
gridsizeF = float(r1[0].shape[0])
if showImages:
fig, (ax1, ax2, ax3, ax4) = plt.subplots(4,1, figsize=(15,60))
else:
fig, (ax4) = plt.subplots(1,1, figsize=(15,10))
if showImages:
ax1.matshow(r1[0])
ax2.matshow(r1[1])
ax3.matshow(r1[2])
# ax5.matshow(r1[2]-r1[3])
# ax6.matshow(r1[1]-r1[4])
# ax7.matshow(r1[0]-r1[5])
# print("Max diff:", np.mean( np.abs(r1[0]-r1[5]) ) )
# print("Max image:", np.mean( np.abs(r1[0]) ) )
FN = [0] * len(r1)
for i in range(len(r1)):
section = (r1[i][:, gridsize//2])
norm_section = (1.0/np.max(section))*section
x_coords = np.array(np.linspace( 0, s1[i]*gridsizeF, gridsize)) - s1[i]*gridsizeF/2.0
section_cap = np.where(norm_section < 0.155, 0.0, 1.0)
# ax4.plot(np.linspace( -s1[i]*gridsize//2, s1[i]*(gridsize - gridsize//2), gridsize), section)
ax4.set_yticks(np.arange(0, 1., 0.05))
plt.ylim((0., 1))
ax4.plot(x_coords, norm_section)
# ax4.plot(x_coords, section_cap)
section_cap_list = section_cap.tolist()
section_cap_diff = np.array([section_cap_list[i] - section_cap_list[i+1] for i in range(len(section_cap_list)-1)])
# ax4.plot(x_coords[:-1], section_cap_diff)
#rx = x_coords[np.where(norm_section>=0.999)]
rx = x_coords[np.where(section_cap_diff>=0.999)]
FN[i] = (-model['offset'][i])/(2.0*rx)
print("FN", FN)
#print("gs1", gs1)
plt.grid()
plt.show()
def showResult_w(model, r1, s1):
gridsize = r1[0].shape[0]
gridsizeF = float(r1[0].shape[0])
fig, (ax4) = plt.subplots(1,1, figsize=(15,10))
FN = [0] * len(r1)
for i in range(len(r1)):
section = (r1[i][:, gridsize//2])
norm_section = (1.0/np.max(section))*section
x_coords = np.array(np.linspace( 0, s1[i]*gridsizeF, gridsize)) - s1[i]*gridsizeF/2.0
section_cap = np.where(norm_section < 0.157, 0.0, 1.0)
ax4.plot(x_coords[gridsize//5:2*gridsize//5], norm_section[gridsize//5:2*gridsize//5])
section_cap_list = section_cap.tolist()
section_cap_diff = np.array([section_cap_list[i] - section_cap_list[i+1] for i in range(len(section_cap_list)-1)])
rx = x_coords[np.where(section_cap_diff>=0.999)]
print(FN)
print(gs1)
plt.show()
model1a = {}
model1a['grid_size'] = 4096
model1a['wavelengths'] = np.linspace(500*1e-9, 1600*1e-9, 1)
model1a['beam_ratio'] = 0.5
model1a['offset'] = np.linspace(-0.09, -0.08, 3) # -0.12
model1a['aperture_diameter'] = 0.011
#rrt1, r1 = runmodel_w(model1)
r1a, s1a, gs1a = runmodel_off(model1a, 13.5)
print(s1a)
showResult_offset(model1a, r1a, s1a)
dda = [0] * len(s1a)
for i in range(len(s1a)):
dda[i] = computeDiameter(r1a[i])
print((-model1a['offset'][i])/(dda[i]*s1a[i]))
from astropy.io import fits
fitsdata = fits.open('C:\\Users\\Fabio\\JupyterNotebooks\\f13-11mm-out-1mm.fits')
fitsdata.info()
images = fitsdata[0].data
images_d = images.copy()
plt.figure(figsize=(10,10))
cube = images_d[1:14].copy()
#imm[images_d[0]<300] = 0
plt.imshow(cube[12], cmap='hot')
dda = [0] * 13
for i in range(13):
dda[i] = computeDiameter(cube[i])
print(dda)
from scipy import stats
def fitAndShow(xx, dd, method=1):
if method==1:
a,b = np.polyfit(dd, xx, 1)
else:
a, b, r_value, p_value, std_err = stats.linregress(dd, xx)
# print('p_value**2:', p_value**2, 'std_err:', std_err)
print('a:', format(a, '.4f'))
# print('1/a:', format(1/a, '.4f'))
print('b:', format(b, '.4f'))
N = float(dd.shape[0])
deltaPrime = N * np.sum(np.multiply(dd,dd)) - np.sum(dd)**2
err = xx - a*dd - b
sigmaSquare = (1.0/(N-2)) * np.sum(np.multiply(xx,xx))
aSigma = (sigmaSquare/deltaPrime) * np.sum(np.multiply(dd,dd))
print( 'aSigma:', format(np.sqrt(aSigma), '.4f') )
print( '(aSigma/a)*100:', format(100*np.sqrt(aSigma)/a, '.3f') )
plt.figure(figsize=(15,10))
plt.plot(dd, xx, 'yo', dd, a*dd+b, '--k')
plt.show()
print(dda)
ll =len(dda)
xx = np.linspace(1, ll, ll) * 0.001
dd = ( np.asarray(dda)) * 7.4e-6
#dd -= np.mean(dd)
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
# fitting con campioni pari e dispari
ll = len(dda)//2
xx = np.linspace(1, ll, ll ) * 0.002
dda_d = [dda[2*i+1] for i in range(ll) ]
dd = np.asarray(dda_d) * 7.4e-6
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
ll = len(dda)//2+1
xx = np.linspace(1, ll, ll ) * 0.002
dda_p = [dda[2*i] for i in range(ll) ]
dd = np.asarray(dda_p) * 7.4e-6
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
model1a = {}
model1a['grid_size'] = 2048
model1a['wavelengths'] = np.linspace(750*1e-9, 750*1e-9, 1)
model1a['beam_ratio'] = 0.5
#model1a['offset'] = np.linspace(-0.09, -0.08, 3) # -0.12
model1a['offset'] = np.linspace(0.045, 0.09, 6) # -0.12
model1a['aperture_diameter'] = 0.011
#rrt1, r1 = runmodel_w(model1)
r1a, s1a, gs1a = runmodel_off(model1a, 13.5, gaussian_occluded_system)
print(s1a)
showResult_offset(model1a, r1a, s1a)
dda = [0] * len(s1a)
for i in range(len(s1a)):
dda[i] = computeDiameter(r1a[i])
print((-model1a['offset'][i])/(dda[i]*s1a[i]))
from astropy.io import fits
frames = [ 'extra11454.fit',
'extra10623(saturated_point).fit',
'extra9641(saturated_ghost).fit',
'extra8668(saturated_ghost).fit',
'extra7613(saturated_ghost).fit',
'extra6593.fit',
'extra5582.fit',
'extra4686.fit',
'extra3570.fit',
'extra2573.fit' ]
distances=[ 0,
8.31,
18.13,
27.86,
38.41,
48.61,
58.72,
67.68,
78.84,
88.81
]
cube = [0] * 10
fig, ax1 = plt.subplots(1,1, figsize=(15,10))
for ii, fname in enumerate(frames):
fitsdata = fits.open('C:\\Users\\Fabio\\JupyterNotebooks\\' + fname)
fitsdata.info()
image = fitsdata[0].data
images_d = image.copy()
plt.figure(figsize=(10,10))
backgroud_level = np.average(images_d[1800:,1800:])
##imm[images_d[0]<300] = 0
images_d = images_d - np.ones(images_d.shape) * backgroud_level
print(backgroud_level)
ax1.plot(images_d[1076,:])
#plt.imshow(images_d, cmap='hot')
cube[ii] = images_d.astype(np.float32)
plt.show()
dda = [0] * 10
for i in range(10):
dda[i] = computeDiameter(cube[i])
print(dda)
ll =len(dda)
xx = np.asarray(distances) * 0.001 # np.linspace(1, ll, ll) * 0.001
dd = ( np.asarray(dda)) * 5.5e-6
print(xx, dd)
#dd -= np.mean(dd)
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
model1 = {}
model1['grid_size'] = 2049
model1['wavelengths'] = np.linspace(500*1e-9, 600*1e-9, 1)
model1['beam_ratio'] = 0.5
model1['offset'] = np.linspace(-0.05, -0.035, 3)
model1['aperture_diameter'] = 1.116
#rrt1, r1 = runmodel_w(model1)
r1, s1, gs1 = runmodel_off(model1, 13.63, occluded_system)
print(s1)
showResult_offset(model1, r1, s1, True)
dd = [0] * len(s1)
for i in range(len(s1)):
dd[i] = computeDiameter(r1[i])
print((-model1['offset'][i])/(dd[i]*s1[i]))
model3 = {}
model3['grid_size'] = 2049
model3['wavelengths'] = np.linspace(500*1e-9, 600*1e-9, 1)
model3['beam_ratio'] = 0.5
model3['offset'] = np.linspace(0.05, 0.035, 3)
model3['aperture_diameter'] = 1.116
#rrt1, r1 = runmodel_w(model1)
r3, s3, gs3 = runmodel_off(model3, 13.63, occluded_system)
print(s3)
showResult_offset(model3, r3, s3, True)
dd3 = [0] * len(s3)
for i in range(len(s3)):
dd3[i] = computeDiameter(r3[i])
print((-model3['offset'][i])/(dd3[i]*s3[i]))
dda = [0] * 13
for i in range(13):
dda[i] = computeDiameter(cube[i])
print(dda)
print(dda)
ll =len(dda)
xx = np.linspace(1, ll, ll) * 0.001
dd = ( np.asarray(dda)) * 7.4e-6
#dd -= np.mean(dd)
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
# fitting con campioni pari e dispari
ll = len(dda)//2
xx = np.linspace(1, ll, ll ) * 0.002
dda_d = [dda[2*i+1] for i in range(ll) ]
dd = np.asarray(dda_d) * 7.4e-6
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
ll = len(dda)//2+1
xx = np.linspace(1, ll, ll ) * 0.002
dda_p = [dda[2*i] for i in range(ll) ]
dd = np.asarray(dda_p) * 7.4e-6
fitAndShow(xx, dd, 2)
#res = stats.theilslopes(xx, dd, 0.90)
#print(res)
#model2 = {}
#model2['grid_size'] = 2049
#model2['wavelengths'] = np.linspace(500*1e-9, 800*1e-9, 11)
#model2['beam_ratio'] = 0.5
#model2['offset'] = np.linspace(-0.9, -0.09, 1) # -0.12
#model2['aperture_diameter'] = 0.011
#
#r2, s2, gs2 = runmodel_w(model2, 13.5)
# showResult_w(model2, r2, s2)