API
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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