API
 
Loading...
Searching...
No Matches
utils.py
Go to the documentation of this file.
1import numpy as np
2import hcipy as hp
3from scipy.optimize import minimize
4import time
5
6
8 def __init__(self,wavelength=656E-9,bandwidth=100E-9,grating_angle=28,grating_freq=47):
9 self.wavelength = wavelength
10 self.bandwidth = bandwidth
11 self.grating_angle = grating_angle
12 self.grating_freq = grating_freq
13 self.normalized_wavelength = wavelength / 656E-9 #normalizing the wavelengths to the ha values
14 self.normalized_bandwidth = bandwidth / 656E-9
15 self.maxiter = 6
16 self.control_mtx = np.matrix([[0,0],])
17 self.current_speckle = None
18
19 '''this is all the gaussian fitting stuff'''
20 def set_measurement(self, data):
21 self.data = data
22
23 def make_gaussian(self, mu_x, mu_y, sigma_x,sigma_y, orientation):
24 def func(grid):
25 new_grid = grid.shifted([-mu_x, -mu_y]).rotated(orientation)
26 x = new_grid.x / sigma_x
27 y = new_grid.y / sigma_y
28 r2 = x**2 + y**2
29 return hp.Field(np.exp(-0.5 * r2), grid)
30 return func
31
32 def satellite_spot(self, amplitude, mu_x, mu_y, sigma_x, sigma_y, orientation, background):
33 def func(grid):
34 return hp.Field(amplitude * self.make_gaussian(mu_x, mu_y, sigma_x, sigma_y, orientation)(grid) + background, grid)
35 return func
36
37 def cost(self, theta):
38 fit = self.satellite_spot(*theta)(self.data.grid)
39 j = np.sum( (self.data - fit)**2)
40
41 aspect_ratio = np.abs(theta[3] / theta[4])
42 #print(f'current speckle: {self.current_speckle}')
43
44 ##boundary condition for the aspect ratio
45 if self.current_speckle == 0 or self.current_speckle == 2:
46 if aspect_ratio >= 1:
47 j+= 1E3 * aspect_ratio **2
48 elif self.current_speckle ==1 or self.current_speckle == 3:
49 if aspect_ratio <= 1:
50 j+= 1E3 * 1/aspect_ratio**2
51
52 return j
53
54 def fit(self,theta_est):
55 fitting = minimize(self.cost,theta_est,options={'maxiter':self.maxiter})
56 return fitting
57
59 M00 = np.sum(self.data)
60 M10 = np.sum(self.data * self.data.grid.x)
61 M01 = np.sum(self.data * self.data.grid.y)
62
63 centroid = [M10/M00,M01/M00]
64 return centroid
65
66 def estimate_angle(self):
67 M00 = np.sum(self.data)
68 M10 = np.sum(self.data * self.data.grid.x)
69 M01 = np.sum(self.data * self.data.grid.y)
70
71 M20 = np.sum(self.data * self.data.grid.x**2)
72 M02 = np.sum(self.data * self.data.grid.y**2)
73 M11 = np.sum(self.data * self.data.grid.y * self.data.grid.x)
74
75 mu10 = M10 / M00
76 mu01 = M01 / M00
77 mu20 = M20 / M00 - mu10**2
78 mu02 = M02 / M00 - mu01**2
79 mu11 = M11 / M00 - mu10 * mu01
80 angle = (1/2 * np.arctan2(2 * mu11, mu20 - mu02))
81
82 return angle
83
84 def find_speckle(self, image,speckle_number):
85 #this assumes that the units of the image x and y axes are lam/d at 656 nm. will this always be the case?
86 '''speckles are indexed from the top right going counter clockwise'''
87 grating_freq = self.grating_freq
88 grating_angle = self.grating_angle
89 corners = np.array([[0, grating_freq * self.normalized_wavelength],[grating_freq * self.normalized_wavelength,0],[0, -grating_freq * self.normalized_wavelength],[-grating_freq * self.normalized_wavelength,0]])
90 sizes = np.array([[8,20],[20,8],[8,20],[20,8]])
91 #sizes = np.array([[16,25],[25,16],[16,25],[25,16]])
92
93 rect = hp.make_rotated_aperture(hp.make_rectangular_aperture(size=sizes[speckle_number], center=corners[speckle_number]), np.deg2rad(-grating_angle))(image.grid)
94 speckle_img = rect * image
95 return speckle_img
96
97
98 def set_psf(self,psf):
99 self.psf = psf
100
102
103 speckle_angles = np.zeros(4)
104 sig_x = [0.8,3.5,0.8,3.5]
105 sig_y = [3.5,0.8,3.5,0.8]
106
107 for i in range(4):
108 img = self.find_speckle(self.psf,i)
109 self.current_speckle = i
110 self.set_measurement(img)
111
112 sigma_x = sig_x[i]
113 sigma_y = sig_y[i]
114 #orientation = np.radians(28)
115
116 orientation = self.estimate_angle()
117 if self.current_speckle == 0 or self.current_speckle ==2:
118 orientation = np.pi/2 - orientation
119 elif self.current_speckle == 1 or self.current_speckle == 3:
120 orientation = -orientation
121
122 #params common to all four
123 amplitude = self.data.max()
124 centroid = self.estimate_centroid()
125 mu_x = centroid[0]
126 mu_y = centroid[1]
127 background = 0
128
129 theta_est = np.array([amplitude, mu_x, mu_y, sigma_x, sigma_y, orientation, background])
130 fit = self.fit(theta_est)
131 speckle_angles[i] = np.degrees(fit.x[5])
132
133 self.current_speckle = None
134 speckle_angles = np.array(speckle_angles).T
135
136 return speckle_angles
137
138 def speckle_pairs(self, speckle_angles):
139 pair02 = speckle_angles[0] - speckle_angles[2]
140 pair13 = speckle_angles[1] - speckle_angles[3]
141 return np.array([pair02,pair13])
142
143 def calculate_command(self,speckle_angles):
144 predicted_disp = self.control_mtx * np.matrix(speckle_angles).T
145 predicted_disp = np.array(predicted_disp)
146 return -predicted_disp
147
148 def clear(self):
149 self.psf = None
150 self.data = None
151
152 def set_control_mtx(self,matrix):
153 self.control_mtx = matrix
154
155 '''this is stuff specifically for working with the real calibration datacubes'''
156 def window_field(self,data, center, width, height):
157 indx = data.grid.closest_to(center)
158 y_ind, x_ind = np.unravel_index(indx, data.shaped.shape)
159 cutout = data.shaped[(y_ind-height//2):(y_ind + height//2), (x_ind-width//2):(x_ind+width//2)]
160 sub_grid = hp.make_pupil_grid([width, height], [width * data.grid.delta[0], height * data.grid.delta[1]])
161 return hp.Field(cutout.ravel(), sub_grid)
162
163 def crop_image(self, image,extent=400,mask_diam=60):
164 #cutout a centered PSF
165 img = image/image.max()
166
167 img_subtracted = img >0.1
168 center_of_intensity = np.array([sum(img_subtracted*img_subtracted.grid.x)/sum(img_subtracted),sum(img_subtracted*img_subtracted.grid.y)/sum(img_subtracted)])
169 mask_ap = hp.make_circular_aperture(mask_diam,center_of_intensity)
170 mask = mask_ap(img_subtracted.grid)
171 mask = abs(mask - 1)
172 masked_img = mask * img
173
174 img = masked_img
175 img = self.window_field(img,[center_of_intensity[0],center_of_intensity[1]],extent,extent)
176 img /= img.max()
177
178 bk = np.median(img)
179 img -= bk
180 img = hp.Field([x if x>0 else 0 for x in img],img.grid)
181
182 return img
183
184 def crop_cube(self, data_cube,extent=400,mask_diam=60): #if you add the wavelength in here it'll make sure that nothing gets cut off of the edges
185 cropped_cube = []
186 for i in range(len(data_cube)):
187 img = self.crop_image(data_cube[i],extent,mask_diam)
188 cropped_cube.append(img)
189 return cropped_cube
190
191
192 def filter_image(self,img,low_freq = 0.01,high_freq=1):
193
194 ff = hp.FourierFilter(img.grid, hp.make_circular_aperture(2 * np.pi * low_freq))
195 filtered_img= np.real(ff.forward(img + 0j))
196 img = img - filtered_img
197
198 ff2 = hp.FourierFilter(img.grid, hp.make_circular_aperture(2 * np.pi * high_freq))
199 filtered_img = np.real(ff2.forward(img + 0j))
200 img = filtered_img
201
202 # binc, profile, std_profile, ncount = radial_profile(img,.25)
203 # r_coordinates = img.grid.as_('polar').r
204 # radial_map = np.interp(r_coordinates, binc, profile)
205
206 filtered_subtracted = img #- radial_map
207
208 return filtered_subtracted
209
speckle_pairs(self, speckle_angles)
Definition utils.py:138
satellite_spot(self, amplitude, mu_x, mu_y, sigma_x, sigma_y, orientation, background)
Definition utils.py:32
crop_image(self, image, extent=400, mask_diam=60)
Definition utils.py:163
current_speckle
boundary condition for the aspect ratio
Definition utils.py:17
crop_cube(self, data_cube, extent=400, mask_diam=60)
Definition utils.py:184
set_measurement(self, data)
Definition utils.py:20
calculate_command(self, speckle_angles)
Definition utils.py:143
window_field(self, data, center, width, height)
Definition utils.py:156
set_psf(self, psf)
Definition utils.py:98
cost(self, theta)
Definition utils.py:37
clear(self)
Definition utils.py:148
find_speckle(self, image, speckle_number)
Definition utils.py:84
make_gaussian(self, mu_x, mu_y, sigma_x, sigma_y, orientation)
Definition utils.py:23
normalized_wavelength
Definition utils.py:13
fit(self, theta_est)
Definition utils.py:54
set_control_mtx(self, matrix)
Definition utils.py:152
find_speckle_angles2(self)
Definition utils.py:101
estimate_centroid(self)
Definition utils.py:58
estimate_angle(self)
Definition utils.py:66
filter_image(self, img, low_freq=0.01, high_freq=1)
Definition utils.py:192
__init__(self, wavelength=656E-9, bandwidth=100E-9, grating_angle=28, grating_freq=47)
Definition utils.py:8