Niccko commited on
Commit
d1d7e79
·
1 Parent(s): 87627fc

Add download button

Browse files
Files changed (4) hide show
  1. app.py +46 -12
  2. fraunhofer_test.py +107 -10
  3. generate_dataset.py +48 -66
  4. zern_generator.py +12 -6
app.py CHANGED
@@ -1,8 +1,13 @@
 
 
1
  import gradio as gr
2
  import matplotlib.pyplot as plt
3
  #from fraunhofer_test import generate_diff
4
  from zern_generator import Zernike
5
  from fraunhofer_test import Fraunhofer
 
 
 
6
  css = """
7
  .container {
8
  # height: 50vh;
@@ -29,19 +34,25 @@ def get_zern_from_file(file):
29
 
30
  zernike = Zernike()
31
  fraunhofer = Fraunhofer(zernike)
32
-
33
  theme = gr.themes.Default(primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.pink)
34
  with gr.Blocks(theme=theme, css=css) as demo:
35
  with gr.Row():
36
  zern_sliders = []
37
-
38
  with gr.Column(scale=1):
39
- # file_inp = gr.File(label="Загрузка коэффициентов из файла", height="2em")
40
  with gr.Tab(label="Генератор"):
41
 
42
- defocus_amt = gr.Number(label="Величина дефокуса", value=2, interactive=True)
 
 
 
 
43
  with gr.Row():
44
- num_zernikes = gr.Number(label="Количество коэффициентов Цернике", value=6, interactive=True)
 
 
 
 
45
  show_zernikes_btn = gr.Button("Показать")
46
  sliders_container = gr.Column(elem_classes=["container"])
47
 
@@ -53,8 +64,14 @@ with gr.Blocks(theme=theme, css=css) as demo:
53
  count = min(count, 100)
54
  for i in range(count):
55
  term_name = f" - {zernike.term[i]}" if i < len(zernike.term) else ""
56
- sld = gr.Slider(key=i, label=f"Zernike {i+1}{term_name}", minimum=-100, interactive=True,
57
- step=0.01, value=0)
 
 
 
 
 
 
58
 
59
  sld.change(update_zerns, inputs=[gr.Number(value=i, visible=False), sld])
60
  sliders_container.add_child(sld)
@@ -64,7 +81,6 @@ with gr.Blocks(theme=theme, css=css) as demo:
64
  with gr.Tab(label="Настройки"):
65
  resolution_num = gr.Number(value=256, label="Разрешение")
66
 
67
- # file_inp.upload(get_zern_from_file, inputs=[file_inp], outputs=[*sliders_container.children])
68
 
69
  with gr.Column(scale=5):
70
  with gr.Tab(label="Экран"):
@@ -77,7 +93,9 @@ with gr.Blocks(theme=theme, css=css) as demo:
77
  btn_batch = gr.Button("Рассчитать тестовые экраны")
78
  with gr.Tab(label="Разница у фокуса"):
79
  plot_diff = gr.Plot(label="Разница в фокусе")
 
80
  btn_diff = gr.Button("Рассчитать разницу в фокусе")
 
81
 
82
  def on_button_click(resolution):
83
  return zernike.generate_zern_wavefront_fig(*[zerns[key] for key in sorted(zerns)])
@@ -85,10 +103,16 @@ with gr.Blocks(theme=theme, css=css) as demo:
85
  def on_settings_click(resolution):
86
  print(resolution)
87
  zernike.set_image_params(npix=resolution)
88
-
 
 
 
89
  def on_diff_button_click(defocus_amount):
 
 
 
90
  pl, mn, diff = fraunhofer.generate_diff(defocus_amount, *[zerns[key] for key in sorted(zerns)])
91
-
92
  fig, axs = plt.subplots(1, 3, figsize = (20, 10))
93
  axs[0].imshow(pl, cmap='grey')
94
  axs[1].imshow(mn, cmap='grey')
@@ -99,12 +123,22 @@ with gr.Blocks(theme=theme, css=css) as demo:
99
  axs[1].set_title(f"-{defocus_amount}")
100
  axs[2].axis('off')
101
  axs[2].set_title(f"Difference")
102
- return fig
 
 
 
 
 
 
 
 
 
 
103
 
104
 
105
  btn.click(on_button_click, inputs=[resolution_num], outputs=[plot_2d, plot_3d])
106
  btn_batch.click(zernike.generate_batch, inputs=[resolution_num], outputs=[plot_batch])
107
  resolution_num.change(on_settings_click, inputs=[resolution_num])
108
- btn_diff.click(on_diff_button_click, inputs=[defocus_amt], outputs=[plot_diff])
109
 
110
  demo.launch()
 
1
+ import os
2
+
3
  import gradio as gr
4
  import matplotlib.pyplot as plt
5
  #from fraunhofer_test import generate_diff
6
  from zern_generator import Zernike
7
  from fraunhofer_test import Fraunhofer
8
+ from PIL import Image
9
+ import numpy as np
10
+ import shutil
11
  css = """
12
  .container {
13
  # height: 50vh;
 
34
 
35
  zernike = Zernike()
36
  fraunhofer = Fraunhofer(zernike)
37
+ curr_diff = None
38
  theme = gr.themes.Default(primary_hue=gr.themes.colors.red, secondary_hue=gr.themes.colors.pink)
39
  with gr.Blocks(theme=theme, css=css) as demo:
40
  with gr.Row():
41
  zern_sliders = []
 
42
  with gr.Column(scale=1):
 
43
  with gr.Tab(label="Генератор"):
44
 
45
+ defocus_amt = gr.Number(
46
+ label="Величина дефокуса",
47
+ value=2,
48
+ interactive=True
49
+ )
50
  with gr.Row():
51
+ num_zernikes = gr.Number(
52
+ label="Количество коэффициентов Цернике",
53
+ value=6,
54
+ interactive=True
55
+ )
56
  show_zernikes_btn = gr.Button("Показать")
57
  sliders_container = gr.Column(elem_classes=["container"])
58
 
 
64
  count = min(count, 100)
65
  for i in range(count):
66
  term_name = f" - {zernike.term[i]}" if i < len(zernike.term) else ""
67
+ sld = gr.Slider(
68
+ key=i,
69
+ label=f"Zernike {i+1}{term_name}",
70
+ minimum=-100,
71
+ interactive=True,
72
+ step=0.01,
73
+ value=0
74
+ )
75
 
76
  sld.change(update_zerns, inputs=[gr.Number(value=i, visible=False), sld])
77
  sliders_container.add_child(sld)
 
81
  with gr.Tab(label="Настройки"):
82
  resolution_num = gr.Number(value=256, label="Разрешение")
83
 
 
84
 
85
  with gr.Column(scale=5):
86
  with gr.Tab(label="Экран"):
 
93
  btn_batch = gr.Button("Рассчитать тестовые экраны")
94
  with gr.Tab(label="Разница у фокуса"):
95
  plot_diff = gr.Plot(label="Разница в фокусе")
96
+
97
  btn_diff = gr.Button("Рассчитать разницу в фокусе")
98
+ file_download = gr.File(label="Скачать")
99
 
100
  def on_button_click(resolution):
101
  return zernike.generate_zern_wavefront_fig(*[zerns[key] for key in sorted(zerns)])
 
103
  def on_settings_click(resolution):
104
  print(resolution)
105
  zernike.set_image_params(npix=resolution)
106
+
107
+
108
+
109
+
110
  def on_diff_button_click(defocus_amount):
111
+ shutil.rmtree("temp", ignore_errors=True)
112
+ os.makedirs("temp")
113
+ global curr_diff
114
  pl, mn, diff = fraunhofer.generate_diff(defocus_amount, *[zerns[key] for key in sorted(zerns)])
115
+ curr_diff = diff
116
  fig, axs = plt.subplots(1, 3, figsize = (20, 10))
117
  axs[0].imshow(pl, cmap='grey')
118
  axs[1].imshow(mn, cmap='grey')
 
123
  axs[1].set_title(f"-{defocus_amount}")
124
  axs[2].axis('off')
125
  axs[2].set_title(f"Difference")
126
+
127
+ a = np.min(curr_diff)
128
+ b = np.max(curr_diff)
129
+ img_arr = ((curr_diff - a) / (b - a) * 255).astype(np.uint8)
130
+ img = Image.fromarray(np.stack([img_arr] * 3, axis=-1), mode='RGB')
131
+ z = [str(zerns[key]) for key in sorted(zerns)]
132
+
133
+ filename = f'temp/{"_".join(z[1:])}.png'
134
+ img.save(filename)
135
+
136
+ return fig, filename
137
 
138
 
139
  btn.click(on_button_click, inputs=[resolution_num], outputs=[plot_2d, plot_3d])
140
  btn_batch.click(zernike.generate_batch, inputs=[resolution_num], outputs=[plot_batch])
141
  resolution_num.change(on_settings_click, inputs=[resolution_num])
142
+ btn_diff.click(on_diff_button_click, inputs=[defocus_amt], outputs=[plot_diff, file_download])
143
 
144
  demo.launch()
fraunhofer_test.py CHANGED
@@ -2,7 +2,9 @@ import matplotlib.pyplot as plt
2
  import cupy as cp
3
  import numpy as np
4
  import math
5
- from cupyx.scipy.fft import fft2, fftshift, ifftshift
 
 
6
  from zern_generator import Zernike
7
 
8
 
@@ -10,7 +12,7 @@ def denoise(screen: np.ndarray):
10
  return np.where(np.abs(screen) < 1e-4, 0, screen)
11
 
12
 
13
- class Fraunhofer:
14
  def __init__(self, zernike: Zernike):
15
  self.focal_distance = 100 * 10 ** -3
16
  self.distance = 100 * 10 ** -3
@@ -21,17 +23,15 @@ class Fraunhofer:
21
 
22
  self.zernike = zernike
23
 
24
- # def _denoise(screen: np.ndarray):
25
- # return np.where(np.abs(screen) < 1e-4, 0, screen)
26
 
27
  def get_focal_point(self,input_screen):
28
  input_screen_gpu = cp.asarray(input_screen)
29
- #phase_mul = ((cp.exp(1j*self.k*self.distance) * cp.exp(1j*self.k*(self.zernike.xv**2 + self.zernike.yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
30
- U_fraun = fft2(ifftshift(input_screen_gpu), overwrite_x=True)
31
- #U_fraun = fftshift(U_fraun * phase_mul)
32
- U_fraun = fftshift(U_fraun)
33
-
34
-
35
  I_fraun = cp.abs(U_fraun)**2
36
  return I_fraun / cp.max(I_fraun)
37
 
@@ -52,11 +52,108 @@ class Fraunhofer:
52
  focal_image_plus = denoise(self.get_focal_point(wf_c*cp.exp(f_plus_c * 1j)))
53
  focal_image_minus = denoise(self.get_focal_point(wf_c*cp.exp(f_minus_c * 1j)))
54
 
 
55
  return (
56
  cp.asnumpy(focal_image_plus),
57
  cp.asnumpy(focal_image_minus),
58
  cp.asnumpy(focal_image_plus - focal_image_minus)
59
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
 
2
  import cupy as cp
3
  import numpy as np
4
  import math
5
+ from numpy.fft import fft2, fftshift, ifftshift
6
+ from cupyx.scipy import fft as fft_gpu
7
+
8
  from zern_generator import Zernike
9
 
10
 
 
12
  return np.where(np.abs(screen) < 1e-4, 0, screen)
13
 
14
 
15
+ class FraunhoferGPU:
16
  def __init__(self, zernike: Zernike):
17
  self.focal_distance = 100 * 10 ** -3
18
  self.distance = 100 * 10 ** -3
 
23
 
24
  self.zernike = zernike
25
 
 
 
26
 
27
  def get_focal_point(self,input_screen):
28
  input_screen_gpu = cp.asarray(input_screen)
29
+ xv = cp.asarray(self.zernike.xv)
30
+ yv = cp.asarray(self.zernike.yv)
31
+ phase_mul = ((cp.exp(1j*self.k*self.distance) * cp.exp(1j*self.k*(xv**2 + yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
32
+ U_fraun = fft_gpu.fft2(fft_gpu.ifftshift(input_screen_gpu), overwrite_x=True)
33
+ U_fraun = fftshift(U_fraun * phase_mul)
34
+
35
  I_fraun = cp.abs(U_fraun)**2
36
  return I_fraun / cp.max(I_fraun)
37
 
 
52
  focal_image_plus = denoise(self.get_focal_point(wf_c*cp.exp(f_plus_c * 1j)))
53
  focal_image_minus = denoise(self.get_focal_point(wf_c*cp.exp(f_minus_c * 1j)))
54
 
55
+
56
  return (
57
  cp.asnumpy(focal_image_plus),
58
  cp.asnumpy(focal_image_minus),
59
  cp.asnumpy(focal_image_plus - focal_image_minus)
60
  )
61
+
62
+ class Fraunhofer:
63
+ def __init__(self, zernike: Zernike):
64
+ self.focal_distance = 100 * 10 ** -3
65
+ self.distance = 100 * 10 ** -3
66
+ self.radius = 5 * 10 ** -3
67
+ self.span = (-(10 ** -2), 10 ** -2)
68
+ self.wavelength = 500 * 10 ** -9
69
+ self.k = 2*math.pi/self.wavelength
70
+
71
+ self.zernike = zernike
72
+
73
+ # def _denoise(screen: np.ndarray):
74
+ # return np.where(np.abs(screen) < 1e-4, 0, screen)
75
+
76
+ def get_focal_point(self,input_screen):
77
+ input_screen_gpu = np.asarray(input_screen)
78
+ phase_mul = ((np.exp(1j*self.k*self.distance) * np.exp(1j*self.k*(self.zernike.xv**2 + self.zernike.yv**2)/(2*self.distance)))/(1j*self.wavelength*self.distance))
79
+ U_fraun = fft2(ifftshift(input_screen_gpu))
80
+ U_fraun = fftshift(U_fraun * phase_mul)
81
+ #U_fraun = fftshift(U_fraun)
82
+
83
+
84
+ I_fraun = np.abs(U_fraun)**2
85
+ return I_fraun / np.max(I_fraun)
86
+
87
+
88
+ def generate_diff(self, defocus_amount, *zernikes):
89
+ zernikes = list(zernikes)
90
+ if len(zernikes) < 5:
91
+ zernikes += [0] * (5-len(zernikes))
92
+
93
+ wf = self.zernike.generate_zern_screen([1], self.radius)
94
+
95
+ f_plus = self.zernike.generate_zern_screen(
96
+ self.zernike.add_defocus(defocus_amount,zernikes),
97
+ norm_radius=self.radius
98
+ )
99
+ f_minus = self.zernike.generate_zern_screen(
100
+ self.zernike.add_defocus(-defocus_amount,zernikes),
101
+ norm_radius=self.radius
102
+ )
103
+
104
+ wf_c = np.asarray(wf)
105
+ f_plus_c = np.asarray(f_plus)
106
+ f_minus_c = np.asarray(f_minus)
107
+ focal_image_plus = denoise(
108
+ self.get_focal_point(wf_c*np.exp(f_plus_c * 1j))
109
+ )
110
+ focal_image_minus = denoise(
111
+ self.get_focal_point(wf_c*np.exp(f_minus_c * 1j))
112
+ )
113
+ diff = focal_image_plus - focal_image_minus
114
+ normalized_diff = diff / cp.max(diff)
115
+
116
+ return (
117
+ cp.asnumpy(focal_image_plus),
118
+ cp.asnumpy(focal_image_minus),
119
+ cp.asnumpy(normalized_diff)
120
+ )
121
+
122
 
123
 
124
+ if __name__ == "__main__":
125
+ zernike = Zernike()
126
+ zernike.set_image_params(npix=2 ** 8)
127
+ zoom_factor = 20
128
+ f = Fraunhofer(zernike=zernike)
129
+ ratio = (f.wavelength*f.focal_distance)/f.radius
130
+ zernikes = [[1 if i == j else 0 for i in range(0,24)] for j in range(20,24)]
131
+ print(zernikes)
132
+ fig, ax = plt.subplots(4,1)
133
+ for i, z in enumerate(zernikes):
134
+ print(zernike._osa_to_noll_list(z))
135
+ wf_a = zernike.generate_zern_screen([1], 0.01/zoom_factor)
136
+ wf_c = zernike.generate_zern_screen(z, 0.01/zoom_factor)
137
+ wf_c_nz = zernike.generate_zern_screen(z, 0.01)
138
+ wf = wf_a * np.exp(wf_c*1j)
139
+
140
+
141
+ focal = f.get_focal_point(wf)
142
+
143
+
144
+
145
+ zoom = ratio*zoom_factor
146
+ #ax[i][0].imshow(np.abs(wf_c_nz))
147
+
148
+ ax[i].imshow(np.abs(focal))
149
+ ax[i].imshow(np.abs(focal))
150
+ ax[0].set_title("Zernike 5 - DEFOCUS")
151
+ ax[1].set_title("Zernike 6 - V-PR-ASTIGMATISM")
152
+ ax[2].set_title("Zernike 7 - V-TREFOIL")
153
+ ax[3].set_title("Zernike 8 - V-PR_COMA")
154
+ ax[0].axis('off')
155
+ ax[1].axis('off')
156
+ ax[2].axis('off')
157
+ ax[3].axis('off')
158
+ plt.show()
159
 
generate_dataset.py CHANGED
@@ -1,6 +1,6 @@
1
  from zern_generator import Zernike
2
  from PIL import Image
3
- from fraunhofer_test import Fraunhofer
4
  import cupy as cp
5
  import matplotlib.pyplot as plt
6
  import itertools
@@ -12,69 +12,40 @@ import numpy as np
12
 
13
  zernike = Zernike()
14
  zernike.set_image_params(npix=2 ** 8)
15
- fraunhofer = Fraunhofer(zernike)
16
 
17
 
18
- def generate_image(z):
19
-
20
-
21
- start_time = time()
22
  arr = fraunhofer.generate_diff(1, 0, *z)
23
  a = cp.min(arr[2])
24
  b = cp.max(arr[2])
25
  img_arr = ((arr[2] - a) / (b - a) * 255).astype(cp.uint8)
26
  img = Image.fromarray(np.stack([img_arr] * 3, axis=-1), mode='RGB')
27
- generation_end_time = time()
28
- if True:
29
- coeffs = '_'.join([f'{x:.2f}' for x in z[2:]])
30
- if not os.path.exists(f'./screens_gpu/{z[0]}/{z[1]}'):
31
- try:
32
- os.makedirs(f'./screens_gpu/{z[0]}/{z[1]}')
33
- except:
34
- pass
35
- filename = f'./screens_gpu/{z[0]}/{z[1]}/{coeffs}_.png'
36
- img.save(filename)
37
- save_end_time = time()
38
- else:
39
- plt.imshow(img)
40
- plt.colorbar()
41
- plt.show()
42
- return generation_end_time - start_time, save_end_time - generation_end_time
43
-
44
-
45
- def generate_dataset(zs):
46
- c = 0
47
- window_size = 50
48
- times = []
49
- start_time = time()
50
- total_images = len(zs)
51
  num_workers = 24
52
  if num_workers is None:
53
  num_workers = cpu_count()
54
 
55
  with Pool(num_workers) as pool:
56
  results = []
57
-
58
  for result in pool.imap_unordered(generate_image, zs):
59
- c += 1
60
-
61
  results.append(result)
62
-
63
- current_time = time()
64
- iteration_time = current_time - start_time
65
- times.append(iteration_time)
66
- if len(times) > window_size:
67
- times.pop(0)
68
- avg_iteration_time = sum(times) / len(times)
69
-
70
- # if c % 10 == 0:
71
- # os.system('cls')
72
- # print(f"Generated {c}/{total_images}")
73
- # elapsed_time = current_time - start_time
74
- # print(f"Elapsed time: {elapsed_time:.2f} s")
75
- # remaining_images = total_images - c
76
- # estimated_remaining_time = avg_iteration_time * remaining_images
77
- # print(f"Estimated remaining time: {estimated_remaining_time:.2f} s")
78
  for result in results:
79
  result.get()
80
 
@@ -92,22 +63,33 @@ def generate_dataset_gpu(zs):
92
  for z in zs:
93
 
94
  generate_image(z)
95
-
96
-
97
- if __name__ == '__main__':
98
- rng = (-5, 5)
99
- step = 0.5
100
- points = tuple(np.linspace(*rng, int((rng[1] - rng[0]) / step + 1)))
101
  points_as_tuples = tuple(float(x) for x in points)
 
102
 
103
- zernikes = np.array(list(set(itertools.product(points_as_tuples, repeat=3))))
104
-
105
- # print("Total images: ", len(zernikes))
106
- # total_gen_time, total_save_time = 0, 0
107
- # for z in zernikes:
108
- # gen_time, save_time = generate_image(z)
109
- # total_save_time += save_time
110
- # total_gen_time += gen_time
111
- # print("Average generation time: ", total_gen_time/len(zernikes))
112
- # print("Average save time: ", total_save_time/len(zernikes))
113
- generate_dataset(zernikes)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from zern_generator import Zernike
2
  from PIL import Image
3
+ from fraunhofer_test import Fraunhofer, FraunhoferGPU
4
  import cupy as cp
5
  import matplotlib.pyplot as plt
6
  import itertools
 
12
 
13
  zernike = Zernike()
14
  zernike.set_image_params(npix=2 ** 8)
15
+ fraunhofer = FraunhoferGPU(zernike)
16
 
17
 
18
+ def generate_image(z, group_depth):
 
 
 
19
  arr = fraunhofer.generate_diff(1, 0, *z)
20
  a = cp.min(arr[2])
21
  b = cp.max(arr[2])
22
  img_arr = ((arr[2] - a) / (b - a) * 255).astype(cp.uint8)
23
  img = Image.fromarray(np.stack([img_arr] * 3, axis=-1), mode='RGB')
24
+
25
+ coeffs = '_'.join([f'{x:.2f}' for x in z[group_depth:]])
26
+ group = "/".join([str(x) for x in z[:group_depth]])
27
+ path = f'./screens_tst/{group}'
28
+ if not os.path.exists(path):
29
+ try:
30
+ os.makedirs(path)
31
+ except:
32
+ print("Directory already exists. Skipping.")
33
+ filename = f'{path}/{coeffs}_.png'
34
+ img.save(filename)
35
+
36
+
37
+
38
+
39
+ def generate_dataset(range, step, kf_cnt):
40
+ zs = get_zernike_coeffs(range, step, kf_cnt)
 
 
 
 
 
 
 
41
  num_workers = 24
42
  if num_workers is None:
43
  num_workers = cpu_count()
44
 
45
  with Pool(num_workers) as pool:
46
  results = []
 
47
  for result in pool.imap_unordered(generate_image, zs):
 
 
48
  results.append(result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  for result in results:
50
  result.get()
51
 
 
63
  for z in zs:
64
 
65
  generate_image(z)
66
+
67
+ def get_zernike_coeffs(range, step, kf_cnt):
68
+ points = tuple(np.linspace(*range, int((range[1] - range[0]) / step + 1)))
 
 
 
69
  points_as_tuples = tuple(float(x) for x in points)
70
+ return np.array(list(set(itertools.product(points_as_tuples, repeat=kf_cnt))))
71
 
72
+ if __name__ == '__main__':
73
+ # rng = (-5, 5)
74
+ # step = 0.5
75
+ # points = tuple(np.linspace(*rng, int((rng[1] - rng[0]) / step + 1)))
76
+ # points_as_tuples = tuple(float(x) for x in points)
77
+
78
+ zernikes = get_zernike_coeffs((-5,5), 0.25, 2)
79
+
80
+ print("Total images: ", len(zernikes))
81
+ total_gen_time, total_save_time = 0, 0
82
+ start = time()
83
+ for i, z in enumerate(zernikes):
84
+ generate_image(z, 1)
85
+ if i % 100 == 0:
86
+ print(f"{i}/{len(zernikes)}")
87
+ print("Average generation time: ", (time()-start)/len(zernikes))
88
+
89
+ # generate_dataset(zernikes)
90
+ # last = 1
91
+ # for i in range(1,6):
92
+
93
+ # p = get_zernike_coeffs([-5,5], 0.25, i)
94
+ # print(f"Количество коэфф-ов: {i} -> Количество комбинаций: {len(p)}")
95
+ # last = len(p)
zern_generator.py CHANGED
@@ -56,10 +56,12 @@ class Zernike:
56
  degree = math.ceil((-3 + math.sqrt(8 * num_zerns + 1)) / 2)
57
  zerns = list(zerns) + [0] * int((((degree + 1) * (degree + 2) / 2) - len(zerns)))
58
  cart = RZern(degree)
59
-
 
60
  cart.make_cart_grid(self.xv / norm_radius, self.yv / norm_radius)
61
-
62
- screen = np.array(cart.eval_grid(np.array(zerns), matrix=True))
 
63
  screen[mask == 0] = 0
64
  screen[np.isnan(screen)] = 0
65
  return screen
@@ -113,7 +115,6 @@ class Zernike:
113
  first = (n * (n + 1)) // 2
114
  second = abs(m)
115
  third = 0
116
- # I wanted to simplify the logic but it seems to work like a colander
117
  if m > 0 and n % 4 in [0, 1]:
118
  third = 0
119
  elif m < 0 and n % 4 in [2, 3]:
@@ -129,11 +130,16 @@ class Zernike:
129
  return self._mn_to_noll(*self._osa_to_mn(idx))
130
 
131
  def _osa_to_noll_list(self, zernikes):
132
- indexed_zerns = sorted(map(lambda x: (self._osa_to_noll(x[0]), x[1]), enumerate(zernikes)), key=lambda x: x[0])
 
 
 
133
  used_indeces = [x for x, _ in indexed_zerns]
134
  mn, mx = min(used_indeces), max(used_indeces)
135
  missing_indeces = set(range(mn, mx + 1)) - set(used_indeces)
136
- return [x[1] for x in list(sorted(indexed_zerns + [(x, 0) for x in missing_indeces]))]
 
 
137
 
138
 
139
  term = ["PISTON", "V-TILT", "H-TILT", "DEFOCUS", "O-PR-ASTIGMATISM", "V-PR-ASTIGMATISM", "V-PR-COMA", "H-PR-COMA",
 
56
  degree = math.ceil((-3 + math.sqrt(8 * num_zerns + 1)) / 2)
57
  zerns = list(zerns) + [0] * int((((degree + 1) * (degree + 2) / 2) - len(zerns)))
58
  cart = RZern(degree)
59
+
60
+
61
  cart.make_cart_grid(self.xv / norm_radius, self.yv / norm_radius)
62
+
63
+ screen = cart.eval_grid(np.array(zerns), matrix=True)
64
+ screen = np.array(screen)
65
  screen[mask == 0] = 0
66
  screen[np.isnan(screen)] = 0
67
  return screen
 
115
  first = (n * (n + 1)) // 2
116
  second = abs(m)
117
  third = 0
 
118
  if m > 0 and n % 4 in [0, 1]:
119
  third = 0
120
  elif m < 0 and n % 4 in [2, 3]:
 
130
  return self._mn_to_noll(*self._osa_to_mn(idx))
131
 
132
  def _osa_to_noll_list(self, zernikes):
133
+ indexed_zerns = sorted(
134
+ map(lambda x: (self._osa_to_noll(x[0]), x[1]), enumerate(zernikes)),
135
+ key=lambda x: x[0]
136
+ )
137
  used_indeces = [x for x, _ in indexed_zerns]
138
  mn, mx = min(used_indeces), max(used_indeces)
139
  missing_indeces = set(range(mn, mx + 1)) - set(used_indeces)
140
+ return [x[1] for x in
141
+ list(sorted(indexed_zerns + [(x, 0) for x in missing_indeces]))
142
+ ]
143
 
144
 
145
  term = ["PISTON", "V-TILT", "H-TILT", "DEFOCUS", "O-PR-ASTIGMATISM", "V-PR-ASTIGMATISM", "V-PR-COMA", "H-PR-COMA",