From 5abd195108662f4ea956d4a060c7087d46fa160e Mon Sep 17 00:00:00 2001
From: Jonathan Peltier
Date: Thu, 3 Dec 2020 23:44:32 +0100
Subject: [PATCH] v1.1 Allow multiple waveguides
This update allow to add, delete waveguides like it was already possible with beams.
---
beampy/__init__.py | 2 +-
beampy/bpm.py | 214 ++--
beampy/interface.py | 266 ++---
beampy/interface.ui | 1068 ++++++++++---------
beampy/user_interface.py | 597 +++++++----
docs/html/.buildinfo | 2 +-
docs/html/.doctrees/beampy.doctree | Bin 267616 -> 282796 bytes
docs/html/.doctrees/codes.doctree | Bin 379462 -> 403371 bytes
docs/html/.doctrees/environment.pickle | Bin 34476 -> 35214 bytes
docs/html/.doctrees/index.doctree | Bin 17174 -> 17174 bytes
docs/html/LICENSE.html | 2 +-
docs/html/_static/documentation_options.js | 2 +-
docs/html/beampy.html | 130 ++-
docs/html/codes.html | 1079 ++++++++++++--------
docs/html/contact.html | 2 +-
docs/html/examples.html | 2 +-
docs/html/genindex.html | 19 +-
docs/html/index.html | 4 +-
docs/html/interface.html | 2 +-
docs/html/objects.inv | Bin 929 -> 937 bytes
docs/html/py-modindex.html | 2 +-
docs/html/results.html | 2 +-
docs/html/search.html | 2 +-
docs/html/searchindex.js | 2 +-
24 files changed, 2009 insertions(+), 1390 deletions(-)
diff --git a/beampy/__init__.py b/beampy/__init__.py
index 9a2383a..c5a6f14 100644
--- a/beampy/__init__.py
+++ b/beampy/__init__.py
@@ -29,7 +29,7 @@
# module
from beampy import examples
-__version__ = "1.0"
+__version__ = "1.1"
def help():
diff --git a/beampy/bpm.py b/beampy/bpm.py
index e98baea..03ce481 100644
--- a/beampy/bpm.py
+++ b/beampy/bpm.py
@@ -43,12 +43,8 @@ class Bpm():
Parameters
----------
- width : float
- Guide width defined as the diameter (µm) at 1/e^2 intensity.
no : float
Refractive index of the cladding.
- delta_no : float
- Difference of refractive index between the core and the cladding.
length_z : float
Size of the compute window over z (µm).
dist_z : float
@@ -61,7 +57,7 @@ class Bpm():
Step over x (µm)
"""
- def __init__(self, width, no, delta_no,
+ def __init__(self, no,
length_z, dist_z, nbr_z_disp,
length_x, dist_x):
"""
@@ -72,12 +68,8 @@ def __init__(self, width, no, delta_no,
Parameters
----------
- width : float
- Guide width defined as the diameter (µm) at 1/e^2 intensity.
no : float
Refractive index of the cladding
- delta_no : float
- Difference of refractive index between the core and the cladding.
length_z : float
Size of the compute window over z (µm).
dist_z : float
@@ -89,19 +81,13 @@ def __init__(self, width, no, delta_no,
dist_x : float
Step over x (µm).
"""
- self.width = width
self.no = no
- self.delta_no = delta_no
self.length_z = length_z
self.dist_z = dist_z
self.nbr_z_disp = nbr_z_disp
self.dist_x = dist_x
self.length_x = length_x
- if delta_no > no/10:
- print("Careful: index variation is too high:")
- print(delta_no, ">", no, "/ 10")
-
def create_x_z(self):
"""
Create the x, z array and ajust the resolution variables.
@@ -160,20 +146,25 @@ def create_x_z(self):
# Guides #
- def squared_guide(self):
+ def squared_guide(self, width):
"""
A lambda function than returns a centered rectangular shape.
return 1 if :math:`x >= -width/2` and :math:`x <= width/2`
else return 0.
+ Parameters
+ ----------
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
+
Notes
-----
This methods uses the width variable defined in :class:`Bpm`.
"""
- return lambda t: (t >= -self.width/2) & (t <= self.width/2)
+ return lambda t: (t >= -width/2) & (t <= width/2)
- def gauss_guide(self, gauss_pow):
+ def gauss_guide(self, width, gauss_pow=1):
"""
A lambda function than return a centered super-Gaussian shape.
@@ -186,23 +177,22 @@ def gauss_guide(self, gauss_pow):
Parameters
----------
- gauss_pow : int
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
+ gauss_pow : int, optional
Index of the super-gaussian guide with 1 being a regural gaussian
guide and 4 being the conventionnal super-gaussian guide used to
- describe realistic guides.
+ describe realistic waveguides.
See on en.wikipedia.org/wiki/Gaussian_function
- #Higher-order_Gaussian_or_super-Gaussian_function
-
- Notes
- -----
- This methods uses the width variable defined in :class:`Bpm`.
+ #Higher-order_Gaussian_or_super-Gaussian_function.
+ 1 by Default.
"""
- if self.width == 0:
+ if width == 0:
return lambda t: 0
- w = self.width / 2 # want diameter at 1/e =width so 2*w=witdh
+ w = width / 2 # want diameter at 1/e =width so 2*w=width
return lambda t: np.exp(-(t / w)**(2*gauss_pow))
- def create_guides(self, shape, nbr_p, p, offset_guide=0):
+ def create_guides(self, shape, delta_no, nbr_p, p, offset_guide=0, z=0):
"""
Create an array of guides over x using peaks positions and for a given
shape.
@@ -213,6 +203,8 @@ def create_guides(self, shape, nbr_p, p, offset_guide=0):
:meth:`squared_guide`, :meth:`gauss_guide` or any lambda function
that takes one argument and return the relative refractive index
for the input position.
+ delta_no : float
+ Difference of refractive index between the core and the cladding.
nbr_p : int
Number of guides.
p : float
@@ -230,10 +222,10 @@ def create_guides(self, shape, nbr_p, p, offset_guide=0):
Notes
-----
This methods uses the following variables defined in :class:`Bpm`:
- nbr_z, nbr_x, x, dist_x, delta_no.
+ nbr_z, nbr_x, x, dist_x.
"""
- self.peaks = np.zeros((nbr_p, self.nbr_z))
- self.dn = np.zeros((self.nbr_z, self.nbr_x))
+ peaks = np.zeros((nbr_p, self.nbr_z))
+ dn = np.zeros((self.nbr_z, self.nbr_x))
dn_z = np.zeros(self.nbr_x)
peaks_z = (p*np.linspace(-nbr_p/2, nbr_p/2-1, nbr_p)
@@ -246,14 +238,15 @@ def create_guides(self, shape, nbr_p, p, offset_guide=0):
dn_z += np.roll(dn_fix, int(round(peaks_z[i] / self.dist_x)))
# only necessary because this program can have curved guides
+ # TODO: implement z start end
+ dn[:] = dn_z
for i in range(self.nbr_z):
- self.dn[i, :] = dn_z
- self.peaks[:, i] = peaks_z
+ peaks[:, i] = peaks_z
- self.dn = self.dn * self.delta_no # give a value to the shape
- return [self.peaks, self.dn]
+ dn = dn * delta_no # give a value to the shape
+ return [peaks, dn]
- def create_curved_guides(self, shape, curve, half_delay,
+ def create_curved_guides(self, shape, width, delta_no, curve, half_delay,
distance_factor, offset_guide=0):
"""
Create two curved guides and one linear guide on the center (STIRAP).
@@ -270,6 +263,10 @@ def create_curved_guides(self, shape, curve, half_delay,
----------
shape : method
:meth:`square` or :meth:`gauss`
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
+ delta_no : float
+ Difference of refractive index between the core and the cladding.
curve : float
curvature factor in :math:`10^{-8} µm^{-2}`.
half_delay : float
@@ -295,7 +292,7 @@ def create_curved_guides(self, shape, curve, half_delay,
Notes
-----
This methods uses the following variables defined in :class:`Bpm`:
- length_z, nbr_z, width, nbr_x, x, dist_x, delta_no.
+ length_z, nbr_z, width, nbr_x, x, dist_x.
"""
# all points over z
z = np.linspace(0, self.length_z, self.nbr_z)
@@ -303,27 +300,27 @@ def create_curved_guides(self, shape, curve, half_delay,
# left curved guide
sa = (- offset_guide
+ curve*(z - self.length_z/2 - half_delay)**2
- + self.width*distance_factor)
+ + width*distance_factor)
# right curved guide
sb = (offset_guide
+ curve*(z - self.length_z/2 + half_delay)**2
- + self.width*distance_factor)
+ + width*distance_factor)
- self.peaks = np.array([-sa,
- np.array([offset_guide] * self.nbr_z),
- sb])
+ peaks = np.array([-sa,
+ np.array([offset_guide] * self.nbr_z),
+ sb])
- self.dn = np.zeros((self.nbr_z, self.nbr_x))
+ dn = np.zeros((self.nbr_z, self.nbr_x))
dn_fix = shape(self.x) # guide shape center on 0
for i in range(self.nbr_z):
- self.dn[i, :] = np.roll(dn_fix, int(round(-sa[i] / self.dist_x))) \
+ dn[i, :] = np.roll(dn_fix, int(round(-sa[i] / self.dist_x))) \
+ np.roll(dn_fix, int(round(offset_guide / self.dist_x))) \
+ np.roll(dn_fix, int(round(sb[i] / self.dist_x)))
- self.dn = self.dn * self.delta_no # give a value to the shape
- return [self.peaks, self.dn]
+ dn = dn * delta_no # give a value to the shape
+ return [peaks, dn]
# Light #
@@ -384,8 +381,7 @@ def squared_light(self, fwhm, offset_light=0):
field = np.zeros(self.nbr_x)
for j in range(self.nbr_x):
- if (self.x[j] >= -fwhm/2
- and self.x[j] <= fwhm/2):
+ if self.x[j] >= -fwhm/2 and self.x[j] <= fwhm/2:
field[j] = 1
else:
field[j] = 0
@@ -393,13 +389,17 @@ def squared_light(self, fwhm, offset_light=0):
field = np.roll(field, int(round(offset_light / self.dist_x)))
return field
- def mode_determ(self, mode):
+ def mode_determ(self, width, delta_no, mode):
"""
Solve the transcendental equation tan=sqrt that give the modes
allowed in a squared guide.
Parameters
----------
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
+ delta_no : float
+ Difference of refractive index between the core and the cladding.
mode : int
Number of the searched mode.
@@ -420,16 +420,18 @@ def mode_determ(self, mode):
Notes
-----
This methods uses the following variables defined in :class:`Bpm`:
- lo, width, no, delta_no, ko.
+ lo, no, ko.
"""
- lim = self.lo/(2 * self.width * (self.no + self.delta_no)) - 1e-12
- theta_c = acos(self.no / (self.no + self.delta_no)) # Critical angle
+ width = float(width)
+ delta_no = float(delta_no)
+ lim = self.lo/(2 * width * (self.no + delta_no)) - 1e-12
+ theta_c = acos(self.no / (self.no + delta_no)) # Critical angle
solu = np.linspace(
mode*lim + 0.000001,
(mode + 1) * lim,
round(1 + (lim - 0.000001)/0.000001))
lhs = np.tan(
- pi * self.width * (self.no + self.delta_no) / self.lo * solu
+ pi * width * (self.no + delta_no) / self.lo * solu
- mode*pi/2)
rhs = np.sqrt(
0j # to avoid sqrt error when complexe
@@ -445,19 +447,23 @@ def mode_determ(self, mode):
sin_theta_m = solu[i_min]
theta_m = asin(sin_theta_m) # angle at which the mode propagate
- beta_m = self.ko * (self.no + self.delta_no) * cos(theta_m)
- h_m = sqrt((self.ko * (self.no + self.delta_no))**2 - beta_m**2)
+ beta_m = self.ko * (self.no + delta_no) * cos(theta_m)
+ h_m = sqrt((self.ko * (self.no + delta_no))**2 - beta_m**2)
gamma_m = (self.no * self.ko
* np.sqrt((cos(theta_m) / cos(theta_c))**2 - 1))
return [h_m, gamma_m, beta_m]
- def mode_light(self, mode, lo, offset_light=0):
+ def mode_light(self, width, delta_no, mode, lo, offset_light=0):
"""
Create light based on propagated mode inside a squared guide.
Parameters
----------
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
+ delta_no : float
+ Difference of refractive index between the core and the cladding.
mode : int
Number of the searched mode.
lo : float
@@ -479,7 +485,7 @@ def mode_light(self, mode, lo, offset_light=0):
Notes
-----
This methods uses the following variables defined in :class:`Bpm`:
- nbr_x, width, x and the :meth`mode_determ` method.
+ nbr_x, x and the :meth`mode_determ` method.
This method create the following variables in :class:`Bpm`:
lo, ko.
@@ -488,50 +494,52 @@ def mode_light(self, mode, lo, offset_light=0):
self.ko = 2 * pi / self.lo # linear wave vector in free space (1/µm)
field = np.zeros(self.nbr_x)
- [h_m, gamma_m, beta_m] = self.mode_determ(mode)
+ [h_m, gamma_m, beta_m] = self.mode_determ(width, delta_no, mode)
if mode % 2 == 0: # if even mode
- b_b = cos(h_m * self.width / 2) # Continuity value where x=width/2
+ b_b = cos(h_m * width / 2) # Continuity value where x=width/2
for j in range(self.nbr_x): # Compute light based on h,gamma,beta
- if abs(self.x[j]) <= self.width/2: # in core
+ if abs(self.x[j]) <= width/2: # in core
field[j] = cos(h_m * self.x[j])
else: # in cladding
field[j] = b_b * exp(-gamma_m * (
abs(self.x[j])
- - self.width/2))
+ - width/2))
else: # if odd mode
- c_c = sin(h_m * self.width / 2) # Continuity value where x=width/2
+ c_c = sin(h_m * width / 2) # Continuity value where x=width/2
for j in range(self.nbr_x): # Compute light based on h,gamma,beta
- if abs(self.x[j]) <= self.width/2: # in core
+ if abs(self.x[j]) <= width/2: # in core
field[j] = sin(h_m * self.x[j])
- elif self.x[j] >= self.width/2: # Right cladding
+ elif self.x[j] >= width/2: # Right cladding
field[j] = c_c * exp(-gamma_m * (
self.x[j]
- - self.width/2))
+ - width/2))
else: # Left cladding
field[j] = -c_c * exp(gamma_m * (
self.x[j]
- + self.width/2))
+ + width/2))
field = np.roll(field, int(round(offset_light / self.dist_x)))
return [field, h_m, gamma_m, beta_m]
- def all_modes(self, lo, offset_light=0):
+ def all_modes(self, width, delta_no, lo, offset_light=0):
"""
Compute all modes allowed by the guide and sum them into one field.
Parameters
----------
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
lo : float
Wavelength of the beam in vaccum in µm.
offset_light : float, optional
@@ -562,7 +570,7 @@ def all_modes(self, lo, offset_light=0):
while True:
try:
[field_i, h_m, gamma_m, beta_m] = self.mode_light(
- i, lo, offset_light)
+ width, delta_no, i, lo, offset_light)
field = field + field_i
h = np.append(h, h_m)
gamma = np.append(gamma, gamma_m)
@@ -573,7 +581,7 @@ def all_modes(self, lo, offset_light=0):
return [field, h, gamma, beta]
- def check_modes(self, lo):
+ def check_modes(self, width, delta_no, lo):
"""
Return the last possible mode number.
Could be merged with :meth:`all_modes` but would increase the needed
@@ -581,6 +589,8 @@ def check_modes(self, lo):
Parameters
----------
+ width : float
+ Guide width defined as the diameter (µm) at 1/e^2 intensity.
lo : float
Wavelength of the beam in vaccum (µm).
@@ -597,7 +607,7 @@ def check_modes(self, lo):
while True:
try:
- self.mode_light(i, lo)
+ self.mode_light(width, delta_no, i, lo)
i += 1
except ValueError:
print("This guide can propagate up to the modes", i-1)
@@ -688,7 +698,7 @@ def airy_light(self, lobe_size, airy_zero, offset_light=0):
return [field, airy_zero]
- def init_field(self, field, theta_ext, irrad, lo):
+ def init_field(self, dn, field, theta_ext, irrad, lo):
"""
Initialize phase, field and power variables.
@@ -767,7 +777,7 @@ def init_field(self, field, theta_ext, irrad, lo):
self.phase_mat = fftshift(np.exp(-1j * self.dist_z / 2 * fr))
# Refractive index modulation
- self.nl_mat = self.ko * self.dist_z * self.dn
+ self.nl_mat = self.ko * self.dist_z * dn
# Initial irradiance
self.current_power = self.epnc * (
@@ -778,7 +788,7 @@ def init_field(self, field, theta_ext, irrad, lo):
return [self.progress_pow]
- def guide_position(self, guide, size):
+ def guide_position(self, peaks, guide, size):
"""
Return the left and right position index over x of a given guide
for each z.
@@ -805,11 +815,11 @@ def guide_position(self, guide, size):
x_beg = np.zeros(self.nbr_z, dtype=int) # Note: don't use x_end=x_beg
x_end = np.zeros(self.nbr_z, dtype=int) # Because id would be ==
- if self.peaks.shape[0] != 0:
+ if peaks.shape[0] != 0:
for j in range(self.nbr_z):
- pos_beg = (self.peaks[guide, j] - size/2) # Left position
+ pos_beg = (peaks[guide, j] - size/2) # Left position
# If the position is out of boundery, change interval to
# (-length_x/2, length_x)
@@ -824,7 +834,7 @@ def guide_position(self, guide, size):
# Search the closest index value for this position
x_beg[j] = np.where(self.x >= pos_beg)[0][0]
- pos_end = (self.peaks[guide, j] + size/2)
+ pos_end = (peaks[guide, j] + size/2)
if pos_end < self.x[0] or pos_end > self.x[-1]:
pos_end = pos_end % self.length_x
@@ -872,7 +882,7 @@ def power_guide(self, x_beg, x_end):
P /= np.trapz(self.progress_pow[0, ], axis=0)
return P
- def losses_position(self, guide_lost, width_lost):
+ def losses_position(self, peaks, guide_lost, width_lost):
"""
Return the left and right position (x) index of a given area
over z [x,z].
@@ -902,11 +912,11 @@ def losses_position(self, guide_lost, width_lost):
lost_end = np.zeros((self.nbr_z, self.nbr_lost), dtype=int)
for j, n in enumerate(guide_lost):
[lost_beg[:, j],
- lost_end[:, j]] = self.guide_position(n, width_lost[j])
+ lost_end[:, j]] = self.guide_position(peaks, n, width_lost[j])
return [lost_beg, lost_end]
- def kerr_effect(self, chi3=1e-19, kerr_loop=1, variance_check=False,
+ def kerr_effect(self, dn, chi3=1e-19, kerr_loop=1, variance_check=False,
field_start=None, dn_start=None, phase_mat=None):
"""
Kerr effect: refractive index modulation by the light intensity.
@@ -948,7 +958,7 @@ def kerr_effect(self, chi3=1e-19, kerr_loop=1, variance_check=False,
i, epnc, no, ko, dist_z and the :meth:`variance` method.
"""
# Set the default value if none were given
- dn_start = self.dn[self.i, :] if dn_start is None else dn_start
+ dn_start = dn[self.i, :] if dn_start is None else dn_start
nl_mat = self.ko * self.dist_z * dn_start
field_start = self.field if field_start is None else field_start
phase_mat = self.phase_mat if phase_mat is None else phase_mat
@@ -1046,27 +1056,25 @@ def absorption(self, alpha, lost_beg, lost_end):
This methods uses the following variables defined in :class:`Bpm`:
nbr_lost, i, field, dist_z, nbr_x.
"""
+ # TODO: implement nbr_lost into the interface
for n in range(self.nbr_lost):
if lost_beg[self.i, n] <= lost_end[self.i, n]: # Normal case
-
- for j in range(lost_beg[self.i, n], lost_end[self.i, n]+1):
- self.field[j] *= exp(-alpha * self.dist_z)
+ a, b = lost_beg[self.i, n], lost_end[self.i, n]+1
+ self.field[a:b] *= exp(-alpha*self.dist_z)
else: # Take into account guide crossing the window edges
+ a, b = lost_beg[self.i, n], self.nbr_x
+ self.field[a:b] *= exp(-alpha*self.dist_z)
- for j in range(lost_beg[self.i, n], self.nbr_x):
- self.field[j] *= exp(-alpha * self.dist_z)
-
- for j in range(0, lost_end[self.i, n]+1):
- self.field[j] *= exp(-alpha * self.dist_z)
+ a, b = 0, lost_end[self.i, n]+1
+ self.field[a:b] *= exp(-alpha*self.dist_z)
return self.field
- def bpm_compute(self, chi3=1e-19, kerr=False, kerr_loop=1,
+ def bpm_compute(self, dn, chi3=1e-19, kerr=False, kerr_loop=1,
variance_check=False,
alpha=0, lost_beg=None, lost_end=None):
-
"""
Compute BPM principle : free_propag over dz/2, index modulation,
free_propag over dz/2.
@@ -1112,9 +1120,10 @@ def bpm_compute(self, chi3=1e-19, kerr=False, kerr_loop=1,
self.field = self.absorption(alpha, lost_beg, lost_end)
if kerr:
- [self.dn[self.i, :], self.nl_mat[self.i, :],
+ [dn[self.i, :], self.nl_mat[self.i, :],
self.field, self.current_power] = self.kerr_effect(
- chi3=chi3, kerr_loop=kerr_loop, variance_check=variance_check)
+ dn, chi3=chi3, kerr_loop=kerr_loop,
+ variance_check=variance_check)
else:
# Influence of the index modulation on the field
self.field *= np.exp(1j * self.nl_mat[self.i, :])
@@ -1129,7 +1138,7 @@ def bpm_compute(self, chi3=1e-19, kerr=False, kerr_loop=1,
# useless but act as a reminder for what the the method does
return self.current_power
- def main_compute(self, chi3=1e-19, kerr=False, kerr_loop=1,
+ def main_compute(self, dn, chi3=1e-19, kerr=False, kerr_loop=1,
variance_check=False,
alpha=0, lost_beg=None, lost_end=None):
"""
@@ -1177,6 +1186,7 @@ def main_compute(self, chi3=1e-19, kerr=False, kerr_loop=1,
self.i = i
# Compute non-linear and linear propagation for every z
self.bpm_compute(
+ dn,
chi3=chi3, kerr=kerr, kerr_loop=kerr_loop,
variance_check=variance_check, alpha=alpha,
lost_beg=lost_beg, lost_end=lost_end)
@@ -1207,25 +1217,26 @@ def example_bpm():
dist_x = 0.1
length_x = 500
- bpm = Bpm(width, no, delta_no,
+ bpm = Bpm(no,
length_z, dist_z, nbr_z_disp,
length_x, dist_x)
[length_z, nbr_z, nbr_z_disp, length_x, nbr_x, x] = bpm.create_x_z()
-# shape = bpm.squared_guide()
- shape = bpm.gauss_guide(4)
+# shape = bpm.squared_guide(width)
+ shape = bpm.gauss_guide(width, 4)
nbr_p = 3
p = 13
offset_guide = 0
[peaks, dn] = bpm.create_guides(
- shape, nbr_p, p, offset_guide=offset_guide)
+ shape, delta_no, nbr_p, p, offset_guide=offset_guide)
# curve = 40 * 1E-8
# half_delay = 1000
# distance_factor = 1.2
-# [peaks, dn] = bpm.create_curved_guides(shape, curve, half_delay,
+# [peaks, dn] = bpm.create_curved_guides(shape, width, delta_no,
+# curve, half_delay,
# distance_factor,
# offset_guide=offset_guide)
@@ -1254,17 +1265,19 @@ def example_bpm():
# field_i = bpm.squared_light(fwhm, offset_light=offset_light)
# [field_i, h, gamma, beta] = bpm.all_modes(
+# width, delta_no
# lo, offset_light=offset_light)
# mode = 0
# [field_i, h, gamma, beta] = bpm.mode_light(
+# width, delta_no,
# mode, lo, offset_light=offset_light)
field[i] = field_i
irrad = [1 * 1E13]*nbr_light
theta_ext = 0
- [progress_pow] = bpm.init_field(field, theta_ext, irrad, lo)
+ [progress_pow] = bpm.init_field(dn, field, theta_ext, irrad, lo)
def _show_plot(pow_index):
plt.figure()
@@ -1320,7 +1333,7 @@ def _show_plot(pow_index):
width_lost = np.array([width_lost])
alpha = alpha/1000
[lost_beg, lost_end] = bpm.losses_position(
- guide_lost, width_lost)
+ peaks, guide_lost, width_lost)
else:
alpha = 0
lost_beg = 0
@@ -1337,6 +1350,7 @@ def _show_plot(pow_index):
debut = time.process_time()
[progress_pow] = bpm.main_compute(
+ dn,
chi3=chi3, kerr=kerr, kerr_loop=kerr_loop,
variance_check=variance_check, alpha=alpha,
lost_beg=lost_beg, lost_end=lost_end)
diff --git a/beampy/interface.py b/beampy/interface.py
index 9c48bb5..d748cc1 100644
--- a/beampy/interface.py
+++ b/beampy/interface.py
@@ -2,9 +2,10 @@
# Form implementation generated from reading ui file 'interface.ui'
#
-# Created by: PyQt5 UI code generator 5.13.1
+# Created by: PyQt5 UI code generator 5.15.1
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
@@ -57,7 +58,6 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_length_z.setDecimals(3)
self.doubleSpinBox_length_z.setMinimum(0.001)
self.doubleSpinBox_length_z.setMaximum(100000.0)
- self.doubleSpinBox_length_z.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_length_z.setProperty("value", 10000.0)
self.doubleSpinBox_length_z.setObjectName("doubleSpinBox_length_z")
self.formLayout_10.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_length_z)
@@ -69,7 +69,6 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_dist_z.setDecimals(3)
self.doubleSpinBox_dist_z.setMinimum(0.001)
self.doubleSpinBox_dist_z.setMaximum(100000.0)
- self.doubleSpinBox_dist_z.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_dist_z.setProperty("value", 1.0)
self.doubleSpinBox_dist_z.setObjectName("doubleSpinBox_dist_z")
self.formLayout_10.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_dist_z)
@@ -92,7 +91,6 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_length_x.setDecimals(3)
self.doubleSpinBox_length_x.setMinimum(0.001)
self.doubleSpinBox_length_x.setMaximum(10000.0)
- self.doubleSpinBox_length_x.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_length_x.setProperty("value", 1000.0)
self.doubleSpinBox_length_x.setObjectName("doubleSpinBox_length_x")
self.formLayout_10.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_length_x)
@@ -104,10 +102,21 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_dist_x.setDecimals(3)
self.doubleSpinBox_dist_x.setMinimum(0.001)
self.doubleSpinBox_dist_x.setMaximum(100.0)
- self.doubleSpinBox_dist_x.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_dist_x.setProperty("value", 0.2)
self.doubleSpinBox_dist_x.setObjectName("doubleSpinBox_dist_x")
self.formLayout_10.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_dist_x)
+ self.label_n = QtWidgets.QLabel(self.frame_window)
+ self.label_n.setObjectName("label_n")
+ self.formLayout_10.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_n)
+ self.doubleSpinBox_n = QtWidgets.QDoubleSpinBox(self.frame_window)
+ self.doubleSpinBox_n.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
+ self.doubleSpinBox_n.setDecimals(6)
+ self.doubleSpinBox_n.setMinimum(1.0)
+ self.doubleSpinBox_n.setMaximum(1000.0)
+ self.doubleSpinBox_n.setSingleStep(0.1)
+ self.doubleSpinBox_n.setProperty("value", 2.14)
+ self.doubleSpinBox_n.setObjectName("doubleSpinBox_n")
+ self.formLayout_10.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_n)
self.verticalLayout_guide.addWidget(self.frame_window)
spacerItem = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
self.verticalLayout_guide.addItem(spacerItem)
@@ -124,22 +133,45 @@ def setupUi(self, MainWindow):
self.frame_guides.setObjectName("frame_guides")
self.formLayout_6 = QtWidgets.QFormLayout(self.frame_guides)
self.formLayout_6.setObjectName("formLayout_6")
+ self.comboBox_guide = QtWidgets.QComboBox(self.frame_guides)
+ self.comboBox_guide.setMaximumSize(QtCore.QSize(100, 16777215))
+ self.comboBox_guide.setObjectName("comboBox_guide")
+ self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.comboBox_guide)
+ self.Qframe_guide_create = QtWidgets.QFrame(self.frame_guides)
+ self.Qframe_guide_create.setFrameShape(QtWidgets.QFrame.StyledPanel)
+ self.Qframe_guide_create.setFrameShadow(QtWidgets.QFrame.Raised)
+ self.Qframe_guide_create.setObjectName("Qframe_guide_create")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.Qframe_guide_create)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.pushButton_save_guide = QtWidgets.QPushButton(self.Qframe_guide_create)
+ self.pushButton_save_guide.setObjectName("pushButton_save_guide")
+ self.gridLayout_2.addWidget(self.pushButton_save_guide, 1, 0, 1, 1)
+ self.pushButton_delete_guide = QtWidgets.QPushButton(self.Qframe_guide_create)
+ self.pushButton_delete_guide.setObjectName("pushButton_delete_guide")
+ self.gridLayout_2.addWidget(self.pushButton_delete_guide, 0, 1, 1, 1)
+ self.pushButton_create_guide = QtWidgets.QPushButton(self.Qframe_guide_create)
+ self.pushButton_create_guide.setObjectName("pushButton_create_guide")
+ self.gridLayout_2.addWidget(self.pushButton_create_guide, 0, 0, 1, 1)
+ self.pushButton_cancel_guide = QtWidgets.QPushButton(self.Qframe_guide_create)
+ self.pushButton_cancel_guide.setStatusTip("")
+ self.pushButton_cancel_guide.setObjectName("pushButton_cancel_guide")
+ self.gridLayout_2.addWidget(self.pushButton_cancel_guide, 1, 1, 1, 1)
+ self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.SpanningRole, self.Qframe_guide_create)
self.label_width = QtWidgets.QLabel(self.frame_guides)
self.label_width.setObjectName("label_width")
- self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_width)
+ self.formLayout_6.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_width)
self.doubleSpinBox_width = QtWidgets.QDoubleSpinBox(self.frame_guides)
self.doubleSpinBox_width.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_width.setDecimals(3)
self.doubleSpinBox_width.setMinimum(0.0)
self.doubleSpinBox_width.setMaximum(10000.0)
self.doubleSpinBox_width.setSingleStep(1.0)
- self.doubleSpinBox_width.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)
self.doubleSpinBox_width.setProperty("value", 8.0)
self.doubleSpinBox_width.setObjectName("doubleSpinBox_width")
- self.formLayout_6.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_width)
+ self.formLayout_6.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_width)
self.label_offset_guide = QtWidgets.QLabel(self.frame_guides)
self.label_offset_guide.setObjectName("label_offset_guide")
- self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_offset_guide)
+ self.formLayout_6.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_offset_guide)
self.doubleSpinBox_offset_guide = QtWidgets.QDoubleSpinBox(self.frame_guides)
self.doubleSpinBox_offset_guide.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_offset_guide.setDecimals(3)
@@ -147,35 +179,22 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_offset_guide.setMaximum(5000.0)
self.doubleSpinBox_offset_guide.setProperty("value", 0.0)
self.doubleSpinBox_offset_guide.setObjectName("doubleSpinBox_offset_guide")
- self.formLayout_6.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_offset_guide)
- self.doubleSpinBox_n = QtWidgets.QDoubleSpinBox(self.frame_guides)
- self.doubleSpinBox_n.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
- self.doubleSpinBox_n.setDecimals(6)
- self.doubleSpinBox_n.setMinimum(1.0)
- self.doubleSpinBox_n.setMaximum(1000.0)
- self.doubleSpinBox_n.setSingleStep(0.1)
- self.doubleSpinBox_n.setProperty("value", 2.14)
- self.doubleSpinBox_n.setObjectName("doubleSpinBox_n")
- self.formLayout_6.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_n)
- self.label_n = QtWidgets.QLabel(self.frame_guides)
- self.label_n.setObjectName("label_n")
- self.formLayout_6.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_n)
+ self.formLayout_6.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_offset_guide)
self.label_dn = QtWidgets.QLabel(self.frame_guides)
self.label_dn.setObjectName("label_dn")
- self.formLayout_6.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_dn)
+ self.formLayout_6.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_dn)
self.doubleSpinBox_dn = QtWidgets.QDoubleSpinBox(self.frame_guides)
self.doubleSpinBox_dn.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_dn.setDecimals(6)
self.doubleSpinBox_dn.setMinimum(1e-06)
self.doubleSpinBox_dn.setMaximum(1000.0)
- self.doubleSpinBox_dn.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_dn.setProperty("value", 0.001)
self.doubleSpinBox_dn.setObjectName("doubleSpinBox_dn")
- self.formLayout_6.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_dn)
+ self.formLayout_6.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_dn)
self.radioButton_gaussian = QtWidgets.QRadioButton(self.frame_guides)
self.radioButton_gaussian.setChecked(True)
self.radioButton_gaussian.setObjectName("radioButton_gaussian")
- self.formLayout_6.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.radioButton_gaussian)
+ self.formLayout_6.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.radioButton_gaussian)
self.spinBox_gauss_pow = QtWidgets.QSpinBox(self.frame_guides)
self.spinBox_gauss_pow.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.spinBox_gauss_pow.setSuffix("")
@@ -184,16 +203,13 @@ def setupUi(self, MainWindow):
self.spinBox_gauss_pow.setSingleStep(1)
self.spinBox_gauss_pow.setProperty("value", 4)
self.spinBox_gauss_pow.setObjectName("spinBox_gauss_pow")
- self.formLayout_6.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.spinBox_gauss_pow)
+ self.formLayout_6.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.spinBox_gauss_pow)
self.radioButton_squared = QtWidgets.QRadioButton(self.frame_guides)
self.radioButton_squared.setObjectName("radioButton_squared")
- self.formLayout_6.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.radioButton_squared)
- self.verticalLayout_guide.addWidget(self.frame_guides)
- spacerItem1 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
- self.verticalLayout_guide.addItem(spacerItem1)
- self.tabWidget_morphology_guide = QtWidgets.QTabWidget(self.tabWidget_guide)
- self.tabWidget_morphology_guide.setMinimumSize(QtCore.QSize(370, 0))
- self.tabWidget_morphology_guide.setMaximumSize(QtCore.QSize(370, 16777215))
+ self.formLayout_6.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.radioButton_squared)
+ self.tabWidget_morphology_guide = QtWidgets.QTabWidget(self.frame_guides)
+ self.tabWidget_morphology_guide.setMinimumSize(QtCore.QSize(350, 0))
+ self.tabWidget_morphology_guide.setMaximumSize(QtCore.QSize(350, 16777215))
self.tabWidget_morphology_guide.setToolTip("")
self.tabWidget_morphology_guide.setObjectName("tabWidget_morphology_guide")
self.tab_array = QtWidgets.QWidget()
@@ -216,16 +232,9 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_p.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_p.setDecimals(3)
self.doubleSpinBox_p.setMaximum(10000.0)
- self.doubleSpinBox_p.setStepType(QtWidgets.QAbstractSpinBox.DefaultStepType)
self.doubleSpinBox_p.setProperty("value", 15.0)
self.doubleSpinBox_p.setObjectName("doubleSpinBox_p")
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_p)
- self.calculateButton_array = QtWidgets.QPushButton(self.tab_array)
- self.calculateButton_array.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
- self.calculateButton_array.setObjectName("calculateButton_array")
- self.formLayout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.calculateButton_array)
- spacerItem2 = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
- self.formLayout.setItem(2, QtWidgets.QFormLayout.LabelRole, spacerItem2)
self.tabWidget_morphology_guide.addTab(self.tab_array, "")
self.tab_curved = QtWidgets.QWidget()
self.tab_curved.setObjectName("tab_curved")
@@ -249,7 +258,6 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_half_delay.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_half_delay.setDecimals(3)
self.doubleSpinBox_half_delay.setMaximum(100000.0)
- self.doubleSpinBox_half_delay.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_half_delay.setProperty("value", 1000.0)
self.doubleSpinBox_half_delay.setObjectName("doubleSpinBox_half_delay")
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_half_delay)
@@ -260,23 +268,21 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_distance_factor.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_distance_factor.setDecimals(3)
self.doubleSpinBox_distance_factor.setMaximum(10000.0)
- self.doubleSpinBox_distance_factor.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_distance_factor.setProperty("value", 1.2)
self.doubleSpinBox_distance_factor.setObjectName("doubleSpinBox_distance_factor")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_distance_factor)
- self.calculateButton_curved = QtWidgets.QPushButton(self.tab_curved)
- self.calculateButton_curved.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
- self.calculateButton_curved.setObjectName("calculateButton_curved")
- self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.calculateButton_curved)
self.tabWidget_morphology_guide.addTab(self.tab_curved, "")
- self.verticalLayout_guide.addWidget(self.tabWidget_morphology_guide)
- spacerItem3 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.verticalLayout_guide.addItem(spacerItem3)
- self.pushButton_cancel_guide = QtWidgets.QPushButton(self.tabWidget_guide)
- self.pushButton_cancel_guide.setMaximumSize(QtCore.QSize(100, 16777215))
- self.pushButton_cancel_guide.setStatusTip("")
- self.pushButton_cancel_guide.setObjectName("pushButton_cancel_guide")
- self.verticalLayout_guide.addWidget(self.pushButton_cancel_guide)
+ self.formLayout_6.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.tabWidget_morphology_guide)
+ self.verticalLayout_guide.addWidget(self.frame_guides)
+ self.calculateButton_guide = QtWidgets.QPushButton(self.tabWidget_guide)
+ self.calculateButton_guide.setMaximumSize(QtCore.QSize(370, 16777215))
+ self.calculateButton_guide.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
+ self.calculateButton_guide.setObjectName("calculateButton_guide")
+ self.verticalLayout_guide.addWidget(self.calculateButton_guide)
+ spacerItem1 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
+ self.verticalLayout_guide.addItem(spacerItem1)
+ spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ self.verticalLayout_guide.addItem(spacerItem2)
self.horizontalLayout_2.addLayout(self.verticalLayout_guide)
self.plot_guide = QtWidgets.QVBoxLayout()
self.plot_guide.setObjectName("plot_guide")
@@ -293,6 +299,7 @@ def setupUi(self, MainWindow):
self.label_light_informations.setObjectName("label_light_informations")
self.verticalLayout_light.addWidget(self.label_light_informations)
self.frame_light = QtWidgets.QFrame(self.tabWidget_light)
+ self.frame_light.setMinimumSize(QtCore.QSize(370, 0))
self.frame_light.setMaximumSize(QtCore.QSize(370, 16777215))
self.frame_light.setFrameShape(QtWidgets.QFrame.Box)
self.frame_light.setFrameShadow(QtWidgets.QFrame.Raised)
@@ -307,7 +314,6 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_lo.setDecimals(4)
self.doubleSpinBox_lo.setMinimum(0.01)
self.doubleSpinBox_lo.setMaximum(100.0)
- self.doubleSpinBox_lo.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_lo.setProperty("value", 1.5)
self.doubleSpinBox_lo.setObjectName("doubleSpinBox_lo")
self.formLayout_lo_theta.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_lo)
@@ -321,9 +327,10 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_theta_ext.setObjectName("doubleSpinBox_theta_ext")
self.formLayout_lo_theta.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_theta_ext)
self.verticalLayout_light.addWidget(self.frame_light)
- spacerItem4 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
- self.verticalLayout_light.addItem(spacerItem4)
+ spacerItem3 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
+ self.verticalLayout_light.addItem(spacerItem3)
self.frame_beam = QtWidgets.QFrame(self.tabWidget_light)
+ self.frame_beam.setMinimumSize(QtCore.QSize(370, 0))
self.frame_beam.setMaximumSize(QtCore.QSize(370, 16777215))
self.frame_beam.setFrameShape(QtWidgets.QFrame.Box)
self.frame_beam.setFrameShadow(QtWidgets.QFrame.Raised)
@@ -332,6 +339,7 @@ def setupUi(self, MainWindow):
self.formLayout_5.setObjectName("formLayout_5")
self.comboBox_light = QtWidgets.QComboBox(self.frame_beam)
self.comboBox_light.setMaximumSize(QtCore.QSize(100, 16777215))
+ self.comboBox_light.setToolTipDuration(-1)
self.comboBox_light.setObjectName("comboBox_light")
self.formLayout_5.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.comboBox_light)
self.Qframe_beam_create = QtWidgets.QFrame(self.frame_beam)
@@ -390,80 +398,89 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_intensity_light.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_intensity_light.setDecimals(5)
self.doubleSpinBox_intensity_light.setMaximum(10000.0)
- self.doubleSpinBox_intensity_light.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_intensity_light.setProperty("value", 1.0)
self.doubleSpinBox_intensity_light.setObjectName("doubleSpinBox_intensity_light")
self.formLayout_5.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_intensity_light)
+ spacerItem4 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.formLayout_5.setItem(7, QtWidgets.QFormLayout.LabelRole, spacerItem4)
self.radioButton_gaussian_light = QtWidgets.QRadioButton(self.frame_beam)
self.radioButton_gaussian_light.setEnabled(True)
self.radioButton_gaussian_light.setChecked(True)
self.radioButton_gaussian_light.setObjectName("radioButton_gaussian_light")
self.formLayout_5.setWidget(8, QtWidgets.QFormLayout.SpanningRole, self.radioButton_gaussian_light)
+ spacerItem5 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.formLayout_5.setItem(9, QtWidgets.QFormLayout.LabelRole, spacerItem5)
self.radioButton_squared_light = QtWidgets.QRadioButton(self.frame_beam)
self.radioButton_squared_light.setChecked(False)
self.radioButton_squared_light.setObjectName("radioButton_squared_light")
self.formLayout_5.setWidget(10, QtWidgets.QFormLayout.SpanningRole, self.radioButton_squared_light)
+ spacerItem6 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.formLayout_5.setItem(12, QtWidgets.QFormLayout.LabelRole, spacerItem6)
self.radioButton_mode = QtWidgets.QRadioButton(self.frame_beam)
self.radioButton_mode.setObjectName("radioButton_mode")
self.formLayout_5.setWidget(13, QtWidgets.QFormLayout.LabelRole, self.radioButton_mode)
self.spinBox_mode = QtWidgets.QSpinBox(self.frame_beam)
+ self.spinBox_mode.setEnabled(False)
self.spinBox_mode.setAutoFillBackground(False)
self.spinBox_mode.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.spinBox_mode.setMaximum(50)
self.spinBox_mode.setObjectName("spinBox_mode")
self.formLayout_5.setWidget(13, QtWidgets.QFormLayout.FieldRole, self.spinBox_mode)
+ self.spinBox_guide_nbr_ref = QtWidgets.QSpinBox(self.frame_beam)
+ self.spinBox_guide_nbr_ref.setEnabled(False)
+ self.spinBox_guide_nbr_ref.setObjectName("spinBox_guide_nbr_ref")
+ self.formLayout_5.setWidget(15, QtWidgets.QFormLayout.FieldRole, self.spinBox_guide_nbr_ref)
+ self.pushButton_mode_number = QtWidgets.QPushButton(self.frame_beam)
+ self.pushButton_mode_number.setObjectName("pushButton_mode_number")
+ self.formLayout_5.setWidget(17, QtWidgets.QFormLayout.LabelRole, self.pushButton_mode_number)
+ self.mode_number = QtWidgets.QLCDNumber(self.frame_beam)
+ self.mode_number.setMaximumSize(QtCore.QSize(100, 16777215))
+ self.mode_number.setObjectName("mode_number")
+ self.formLayout_5.setWidget(17, QtWidgets.QFormLayout.FieldRole, self.mode_number)
+ spacerItem7 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.formLayout_5.setItem(18, QtWidgets.QFormLayout.LabelRole, spacerItem7)
self.radioButton_all_modes = QtWidgets.QRadioButton(self.frame_beam)
self.radioButton_all_modes.setObjectName("radioButton_all_modes")
- self.formLayout_5.setWidget(16, QtWidgets.QFormLayout.LabelRole, self.radioButton_all_modes)
+ self.formLayout_5.setWidget(19, QtWidgets.QFormLayout.LabelRole, self.radioButton_all_modes)
+ spacerItem8 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
+ self.formLayout_5.setItem(21, QtWidgets.QFormLayout.LabelRole, spacerItem8)
self.radioButton_airy = QtWidgets.QRadioButton(self.frame_beam)
self.radioButton_airy.setObjectName("radioButton_airy")
- self.formLayout_5.setWidget(19, QtWidgets.QFormLayout.LabelRole, self.radioButton_airy)
+ self.formLayout_5.setWidget(22, QtWidgets.QFormLayout.LabelRole, self.radioButton_airy)
self.label_zero_cut = QtWidgets.QLabel(self.frame_beam)
self.label_zero_cut.setObjectName("label_zero_cut")
- self.formLayout_5.setWidget(20, QtWidgets.QFormLayout.LabelRole, self.label_zero_cut)
+ self.formLayout_5.setWidget(23, QtWidgets.QFormLayout.LabelRole, self.label_zero_cut)
self.spinBox_airy_zero = QtWidgets.QSpinBox(self.frame_beam)
+ self.spinBox_airy_zero.setEnabled(False)
self.spinBox_airy_zero.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.spinBox_airy_zero.setMinimum(1)
self.spinBox_airy_zero.setMaximum(10000)
self.spinBox_airy_zero.setProperty("value", 10)
self.spinBox_airy_zero.setObjectName("spinBox_airy_zero")
- self.formLayout_5.setWidget(20, QtWidgets.QFormLayout.FieldRole, self.spinBox_airy_zero)
+ self.formLayout_5.setWidget(23, QtWidgets.QFormLayout.FieldRole, self.spinBox_airy_zero)
self.label_lobe_size = QtWidgets.QLabel(self.frame_beam)
self.label_lobe_size.setObjectName("label_lobe_size")
- self.formLayout_5.setWidget(21, QtWidgets.QFormLayout.LabelRole, self.label_lobe_size)
+ self.formLayout_5.setWidget(24, QtWidgets.QFormLayout.LabelRole, self.label_lobe_size)
self.doubleSpinBox_lobe_size = QtWidgets.QDoubleSpinBox(self.frame_beam)
+ self.doubleSpinBox_lobe_size.setEnabled(False)
self.doubleSpinBox_lobe_size.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_lobe_size.setMaximum(10000.0)
self.doubleSpinBox_lobe_size.setProperty("value", 8.0)
self.doubleSpinBox_lobe_size.setObjectName("doubleSpinBox_lobe_size")
- self.formLayout_5.setWidget(21, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_lobe_size)
- spacerItem5 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
- self.formLayout_5.setItem(18, QtWidgets.QFormLayout.LabelRole, spacerItem5)
- spacerItem6 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
- self.formLayout_5.setItem(12, QtWidgets.QFormLayout.LabelRole, spacerItem6)
- spacerItem7 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
- self.formLayout_5.setItem(7, QtWidgets.QFormLayout.LabelRole, spacerItem7)
- spacerItem8 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
- self.formLayout_5.setItem(15, QtWidgets.QFormLayout.LabelRole, spacerItem8)
- self.pushButton_mode_number = QtWidgets.QPushButton(self.frame_beam)
- self.pushButton_mode_number.setObjectName("pushButton_mode_number")
- self.formLayout_5.setWidget(14, QtWidgets.QFormLayout.LabelRole, self.pushButton_mode_number)
- self.mode_number = QtWidgets.QLCDNumber(self.frame_beam)
- self.mode_number.setMaximumSize(QtCore.QSize(100, 16777215))
- self.mode_number.setObjectName("mode_number")
- self.formLayout_5.setWidget(14, QtWidgets.QFormLayout.FieldRole, self.mode_number)
- spacerItem9 = QtWidgets.QSpacerItem(20, 5, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
- self.formLayout_5.setItem(9, QtWidgets.QFormLayout.LabelRole, spacerItem9)
+ self.formLayout_5.setWidget(24, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_lobe_size)
+ self.label_guide_nbr_ref = QtWidgets.QLabel(self.frame_beam)
+ self.label_guide_nbr_ref.setObjectName("label_guide_nbr_ref")
+ self.formLayout_5.setWidget(15, QtWidgets.QFormLayout.LabelRole, self.label_guide_nbr_ref)
self.verticalLayout_light.addWidget(self.frame_beam)
- spacerItem10 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
- self.verticalLayout_light.addItem(spacerItem10)
+ spacerItem9 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
+ self.verticalLayout_light.addItem(spacerItem9)
self.calculateButton_light = QtWidgets.QPushButton(self.tabWidget_light)
self.calculateButton_light.setMaximumSize(QtCore.QSize(370, 16777215))
self.calculateButton_light.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
self.calculateButton_light.setObjectName("calculateButton_light")
self.verticalLayout_light.addWidget(self.calculateButton_light)
- spacerItem11 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.verticalLayout_light.addItem(spacerItem11)
+ spacerItem10 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ self.verticalLayout_light.addItem(spacerItem10)
self.horizontalLayout_4.addLayout(self.verticalLayout_light)
self.plot_light = QtWidgets.QVBoxLayout()
self.plot_light.setObjectName("plot_light")
@@ -522,13 +539,12 @@ def setupUi(self, MainWindow):
self.doubleSpinBox_lost.setCorrectionMode(QtWidgets.QAbstractSpinBox.CorrectToNearestValue)
self.doubleSpinBox_lost.setDecimals(5)
self.doubleSpinBox_lost.setMaximum(10000.0)
- self.doubleSpinBox_lost.setStepType(QtWidgets.QAbstractSpinBox.AdaptiveDecimalStepType)
self.doubleSpinBox_lost.setProperty("value", 1.0)
self.doubleSpinBox_lost.setObjectName("doubleSpinBox_lost")
self.formLayout_8.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.doubleSpinBox_lost)
self.verticalLayout_compute.addWidget(self.frame_lost)
- spacerItem12 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
- self.verticalLayout_compute.addItem(spacerItem12)
+ spacerItem11 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
+ self.verticalLayout_compute.addItem(spacerItem11)
self.label_kerr_informations = QtWidgets.QLabel(self.tabWidget_compute)
self.label_kerr_informations.setMinimumSize(QtCore.QSize(0, 62))
self.label_kerr_informations.setMouseTracking(True)
@@ -588,8 +604,8 @@ def setupUi(self, MainWindow):
self.pushButton_estimate_time.setObjectName("pushButton_estimate_time")
self.formLayout_estimate.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.pushButton_estimate_time)
self.verticalLayout_compute.addLayout(self.formLayout_estimate)
- spacerItem13 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
- self.verticalLayout_compute.addItem(spacerItem13)
+ spacerItem12 = QtWidgets.QSpacerItem(20, 10, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Maximum)
+ self.verticalLayout_compute.addItem(spacerItem12)
self.calculateButton_compute = QtWidgets.QPushButton(self.tabWidget_compute)
self.calculateButton_compute.setMinimumSize(QtCore.QSize(370, 0))
self.calculateButton_compute.setMaximumSize(QtCore.QSize(370, 16777215))
@@ -599,8 +615,8 @@ def setupUi(self, MainWindow):
self.checkBox_check_power = QtWidgets.QCheckBox(self.tabWidget_compute)
self.checkBox_check_power.setObjectName("checkBox_check_power")
self.verticalLayout_compute.addWidget(self.checkBox_check_power)
- spacerItem14 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.verticalLayout_compute.addItem(spacerItem14)
+ spacerItem13 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
+ self.verticalLayout_compute.addItem(spacerItem13)
self.verticalLayout_compute_plot.addLayout(self.verticalLayout_compute)
self.pushButton_cancel_compute = QtWidgets.QPushButton(self.tabWidget_compute)
self.pushButton_cancel_compute.setMaximumSize(QtCore.QSize(100, 16777215))
@@ -619,35 +635,44 @@ def setupUi(self, MainWindow):
self.retranslateUi(MainWindow)
self.tabWidget_main.setCurrentIndex(0)
self.tabWidget_morphology_guide.setCurrentIndex(0)
- self.checkBox_offset_light.clicked['bool'].connect(self.doubleSpinBox_offset_light.setDisabled)
+ self.checkBox_offset_light.toggled['bool'].connect(self.doubleSpinBox_offset_light.setDisabled)
self.checkBox_kerr.clicked['bool'].connect(self.frame_kerr.setEnabled)
- self.checkBox_offset_light.clicked['bool'].connect(self.spinBox_offset_light_peak.setEnabled)
+ self.checkBox_offset_light.toggled['bool'].connect(self.spinBox_offset_light_peak.setEnabled)
self.checkBox_lost.clicked['bool'].connect(self.frame_lost.setEnabled)
self.checkBox_kerr.clicked['bool'].connect(self.checkBox_variance.setEnabled)
self.comboBox_light.activated['QString'].connect(self.pushButton_cancel_light.click)
+ self.comboBox_guide.activated['QString'].connect(self.pushButton_cancel_guide.click)
+ self.radioButton_airy.toggled['bool'].connect(self.doubleSpinBox_lobe_size.setEnabled)
+ self.radioButton_airy.toggled['bool'].connect(self.spinBox_airy_zero.setEnabled)
+ self.radioButton_mode.toggled['bool'].connect(self.spinBox_mode.setEnabled)
+ self.radioButton_gaussian.toggled['bool'].connect(self.spinBox_gauss_pow.setEnabled)
+ self.radioButton_mode.toggled['bool'].connect(self.spinBox_guide_nbr_ref.setEnabled)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
MainWindow.setTabOrder(self.tabWidget_main, self.doubleSpinBox_length_z)
MainWindow.setTabOrder(self.doubleSpinBox_length_z, self.doubleSpinBox_dist_z)
MainWindow.setTabOrder(self.doubleSpinBox_dist_z, self.spinBox_nbr_z_disp)
MainWindow.setTabOrder(self.spinBox_nbr_z_disp, self.doubleSpinBox_length_x)
MainWindow.setTabOrder(self.doubleSpinBox_length_x, self.doubleSpinBox_dist_x)
- MainWindow.setTabOrder(self.doubleSpinBox_dist_x, self.doubleSpinBox_width)
+ MainWindow.setTabOrder(self.doubleSpinBox_dist_x, self.doubleSpinBox_n)
+ MainWindow.setTabOrder(self.doubleSpinBox_n, self.comboBox_guide)
+ MainWindow.setTabOrder(self.comboBox_guide, self.pushButton_create_guide)
+ MainWindow.setTabOrder(self.pushButton_create_guide, self.pushButton_delete_guide)
+ MainWindow.setTabOrder(self.pushButton_delete_guide, self.pushButton_save_guide)
+ MainWindow.setTabOrder(self.pushButton_save_guide, self.pushButton_cancel_guide)
+ MainWindow.setTabOrder(self.pushButton_cancel_guide, self.doubleSpinBox_width)
MainWindow.setTabOrder(self.doubleSpinBox_width, self.doubleSpinBox_offset_guide)
- MainWindow.setTabOrder(self.doubleSpinBox_offset_guide, self.doubleSpinBox_n)
- MainWindow.setTabOrder(self.doubleSpinBox_n, self.doubleSpinBox_dn)
+ MainWindow.setTabOrder(self.doubleSpinBox_offset_guide, self.doubleSpinBox_dn)
MainWindow.setTabOrder(self.doubleSpinBox_dn, self.radioButton_gaussian)
MainWindow.setTabOrder(self.radioButton_gaussian, self.spinBox_gauss_pow)
MainWindow.setTabOrder(self.spinBox_gauss_pow, self.radioButton_squared)
MainWindow.setTabOrder(self.radioButton_squared, self.tabWidget_morphology_guide)
MainWindow.setTabOrder(self.tabWidget_morphology_guide, self.spinBox_nb_p)
MainWindow.setTabOrder(self.spinBox_nb_p, self.doubleSpinBox_p)
- MainWindow.setTabOrder(self.doubleSpinBox_p, self.calculateButton_array)
- MainWindow.setTabOrder(self.calculateButton_array, self.doubleSpinBox_curve)
+ MainWindow.setTabOrder(self.doubleSpinBox_p, self.calculateButton_guide)
+ MainWindow.setTabOrder(self.calculateButton_guide, self.doubleSpinBox_curve)
MainWindow.setTabOrder(self.doubleSpinBox_curve, self.doubleSpinBox_half_delay)
MainWindow.setTabOrder(self.doubleSpinBox_half_delay, self.doubleSpinBox_distance_factor)
- MainWindow.setTabOrder(self.doubleSpinBox_distance_factor, self.calculateButton_curved)
- MainWindow.setTabOrder(self.calculateButton_curved, self.pushButton_cancel_guide)
- MainWindow.setTabOrder(self.pushButton_cancel_guide, self.doubleSpinBox_lo)
+ MainWindow.setTabOrder(self.doubleSpinBox_distance_factor, self.doubleSpinBox_lo)
MainWindow.setTabOrder(self.doubleSpinBox_lo, self.doubleSpinBox_theta_ext)
MainWindow.setTabOrder(self.doubleSpinBox_theta_ext, self.comboBox_light)
MainWindow.setTabOrder(self.comboBox_light, self.pushButton_create_beam)
@@ -705,7 +730,18 @@ def retranslateUi(self, MainWindow):
self.label_dist_x.setText(_translate("MainWindow", "x step"))
self.doubleSpinBox_dist_x.setToolTip(_translate("MainWindow", "Step over x in µm"))
self.doubleSpinBox_dist_x.setSuffix(_translate("MainWindow", " µm"))
+ self.label_n.setToolTip(_translate("MainWindow", "Refractive index of the background \"cladding\""))
+ self.label_n.setText(_translate("MainWindow", "n background"))
+ self.doubleSpinBox_n.setToolTip(_translate("MainWindow", "Refractive index of the cladding"))
self.label_guides_information.setText(_translate("MainWindow", "
Guides information
"))
+ self.comboBox_guide.setToolTip(_translate("MainWindow", "Select the waveguide"))
+ self.pushButton_save_guide.setText(_translate("MainWindow", "save waveguide"))
+ self.pushButton_delete_guide.setToolTip(_translate("MainWindow", "Delete the current displayed waveguide"))
+ self.pushButton_delete_guide.setText(_translate("MainWindow", "delete waveguide"))
+ self.pushButton_create_guide.setToolTip(_translate("MainWindow", "Add a new waveguide with current displayed values"))
+ self.pushButton_create_guide.setText(_translate("MainWindow", "add waveguide"))
+ self.pushButton_cancel_guide.setToolTip(_translate("MainWindow", "cancel guide changes"))
+ self.pushButton_cancel_guide.setText(_translate("MainWindow", "Cancel changes"))
self.label_width.setToolTip(_translate("MainWindow", "Guide width define as the diameter in µm at 1/e"))
self.label_width.setText(_translate("MainWindow", "Width"))
self.doubleSpinBox_width.setToolTip(_translate("MainWindow", "Guide width define as the diameter in µm at 1/e"))
@@ -714,9 +750,6 @@ def retranslateUi(self, MainWindow):
self.label_offset_guide.setText(_translate("MainWindow", "Guide offset"))
self.doubleSpinBox_offset_guide.setToolTip(_translate("MainWindow", "Guide offset from the center in µm"))
self.doubleSpinBox_offset_guide.setSuffix(_translate("MainWindow", " µm"))
- self.doubleSpinBox_n.setToolTip(_translate("MainWindow", "Refractive index of the cladding"))
- self.label_n.setToolTip(_translate("MainWindow", "Refractive index of the cladding"))
- self.label_n.setText(_translate("MainWindow", "n"))
self.label_dn.setToolTip(_translate("MainWindow", "Difference of refractive index between the core and the cladding"))
self.label_dn.setText(_translate("MainWindow", "Δn"))
self.doubleSpinBox_dn.setToolTip(_translate("MainWindow", "Difference of refractive index between the core and the cladding"))
@@ -733,8 +766,6 @@ def retranslateUi(self, MainWindow):
self.label_p.setText(_translate("MainWindow", "Interval between guides"))
self.doubleSpinBox_p.setToolTip(_translate("MainWindow", "Distance between two guides center in µm"))
self.doubleSpinBox_p.setSuffix(_translate("MainWindow", " µm"))
- self.calculateButton_array.setToolTip(_translate("MainWindow", "Compute an array of guides"))
- self.calculateButton_array.setText(_translate("MainWindow", "Compute array of guides"))
self.tabWidget_morphology_guide.setTabText(self.tabWidget_morphology_guide.indexOf(self.tab_array), _translate("MainWindow", "waveguide array"))
self.label_curve.setToolTip(_translate("MainWindow", "curvature factor in 10^-8 1/µm^2"))
self.label_curve.setText(_translate("MainWindow", "Curvature"))
@@ -748,11 +779,9 @@ def retranslateUi(self, MainWindow):
self.label_distance_factor.setText(_translate("MainWindow", "p_min/width"))
self.doubleSpinBox_distance_factor.setToolTip(_translate("MainWindow", "Distance factor: p_min/width"))
self.doubleSpinBox_distance_factor.setSuffix(_translate("MainWindow", " µm"))
- self.calculateButton_curved.setToolTip(_translate("MainWindow", "Compute the curved guides define as : - offset_guide + curve*(z - length_z/2 - half_delay)**2 + width*distance_factor)"))
- self.calculateButton_curved.setText(_translate("MainWindow", "Compute curved guides"))
self.tabWidget_morphology_guide.setTabText(self.tabWidget_morphology_guide.indexOf(self.tab_curved), _translate("MainWindow", "curved waveguides"))
- self.pushButton_cancel_guide.setToolTip(_translate("MainWindow", "cancel guide changes"))
- self.pushButton_cancel_guide.setText(_translate("MainWindow", "Cancel changes"))
+ self.calculateButton_guide.setToolTip(_translate("MainWindow", "Compute an array of guides"))
+ self.calculateButton_guide.setText(_translate("MainWindow", "Compute guides"))
self.tabWidget_main.setTabText(self.tabWidget_main.indexOf(self.tabWidget_guide), _translate("MainWindow", "Guides"))
self.label_light_informations.setText(_translate("MainWindow", "Light information
"))
self.label_lo.setToolTip(_translate("MainWindow", " Wavelengh in µm"))
@@ -767,7 +796,7 @@ def retranslateUi(self, MainWindow):
self.pushButton_delete_beam.setToolTip(_translate("MainWindow", "Delete the current displayed beam"))
self.pushButton_delete_beam.setText(_translate("MainWindow", "delete beam"))
self.pushButton_create_beam.setToolTip(_translate("MainWindow", "Add a new beam with current displayed values"))
- self.pushButton_create_beam.setText(_translate("MainWindow", "create beam"))
+ self.pushButton_create_beam.setText(_translate("MainWindow", "add beam"))
self.pushButton_save_beam.setToolTip(_translate("MainWindow", "Save current displayed values"))
self.pushButton_save_beam.setText(_translate("MainWindow", "save beam"))
self.pushButton_cancel_light.setToolTip(_translate("MainWindow", "Return to previously saved values"))
@@ -795,6 +824,10 @@ def retranslateUi(self, MainWindow):
self.radioButton_mode.setToolTip(_translate("MainWindow", "select the n mode based on a squared guide"))
self.radioButton_mode.setText(_translate("MainWindow", "Mode"))
self.spinBox_mode.setToolTip(_translate("MainWindow", "The n mode based on a squared guide"))
+ self.spinBox_guide_nbr_ref.setToolTip(_translate("MainWindow", "Waveguide number to use its width in the mode calculation"))
+ self.pushButton_mode_number.setToolTip(_translate("MainWindow", "Displayed the number of the last mode that can propagate in the rectangular guide"))
+ self.pushButton_mode_number.setText(_translate("MainWindow", "Show max mode"))
+ self.mode_number.setToolTip(_translate("MainWindow", "Number of the last mode that can propagate in the guide"))
self.radioButton_all_modes.setToolTip(_translate("MainWindow", "Select all possible modes for a squared guide"))
self.radioButton_all_modes.setText(_translate("MainWindow", "All modes"))
self.radioButton_airy.setToolTip(_translate("MainWindow", "Select a Airy beam"))
@@ -804,9 +837,8 @@ def retranslateUi(self, MainWindow):
self.spinBox_airy_zero.setToolTip(_translate("MainWindow", "Choose to cut at the n zero of the Airy function"))
self.label_lobe_size.setText(_translate("MainWindow", "First lobe size"))
self.doubleSpinBox_lobe_size.setSuffix(_translate("MainWindow", " µm"))
- self.pushButton_mode_number.setToolTip(_translate("MainWindow", "Displayed the number of the last mode that can propagate in the rectangular guide"))
- self.pushButton_mode_number.setText(_translate("MainWindow", "Show max mode"))
- self.mode_number.setToolTip(_translate("MainWindow", "Number of the last mode that can propagate in the guide"))
+ self.label_guide_nbr_ref.setToolTip(_translate("MainWindow", "Waveguide number to use its width in the mode calculation"))
+ self.label_guide_nbr_ref.setText(_translate("MainWindow", "Guide number ref"))
self.calculateButton_light.setToolTip(_translate("MainWindow", "Compute the beams"))
self.calculateButton_light.setText(_translate("MainWindow", "Compute light"))
self.tabWidget_main.setTabText(self.tabWidget_main.indexOf(self.tabWidget_light), _translate("MainWindow", "Light"))
diff --git a/beampy/interface.ui b/beampy/interface.ui
index 94c2701..20184bf 100644
--- a/beampy/interface.ui
+++ b/beampy/interface.ui
@@ -127,9 +127,6 @@
100000.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
10000.000000000000000
@@ -165,9 +162,6 @@
100000.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
1.000000000000000
@@ -235,9 +229,6 @@
10000.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
1000.000000000000000
@@ -273,14 +264,46 @@
100.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
0.200000000000000
+ -
+
+
+ Refractive index of the background "cladding"
+
+
+ n background
+
+
+
+ -
+
+
+ Refractive index of the cladding
+
+
+ QAbstractSpinBox::CorrectToNearestValue
+
+
+ 6
+
+
+ 1.000000000000000
+
+
+ 1000.000000000000000
+
+
+ 0.100000000000000
+
+
+ 2.140000000000000
+
+
+
@@ -340,7 +363,72 @@
QFrame::Raised
- -
+
-
+
+
+
+ 100
+ 16777215
+
+
+
+ Select the waveguide
+
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ save waveguide
+
+
+
+ -
+
+
+ Delete the current displayed waveguide
+
+
+ delete waveguide
+
+
+
+ -
+
+
+ Add a new waveguide with current displayed values
+
+
+ add waveguide
+
+
+
+ -
+
+
+ cancel guide changes
+
+
+
+
+
+ Cancel changes
+
+
+
+
+
+
+ -
Guide width define as the diameter in µm at 1/e
@@ -350,7 +438,7 @@
- -
+
-
Guide width define as the diameter in µm at 1/e
@@ -373,15 +461,12 @@
1.000000000000000
-
- QAbstractSpinBox::DefaultStepType
-
8.000000000000000
- -
+
-
Guide offset from the center in µm
@@ -391,7 +476,7 @@
- -
+
-
Guide offset from the center in µm
@@ -416,42 +501,7 @@
- -
-
-
- Refractive index of the cladding
-
-
- QAbstractSpinBox::CorrectToNearestValue
-
-
- 6
-
-
- 1.000000000000000
-
-
- 1000.000000000000000
-
-
- 0.100000000000000
-
-
- 2.140000000000000
-
-
-
-
-
-
- Refractive index of the cladding
-
-
- n
-
-
-
- -
Difference of refractive index between the core and the cladding
@@ -461,7 +511,7 @@
- -
+
-
Difference of refractive index between the core and the cladding
@@ -478,15 +528,12 @@
1000.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
0.001000000000000
- -
+
-
Choose super-gaussian guides
@@ -499,7 +546,7 @@
- -
+
-
Order of the super-Gaussian beam, 1 is gaussian, 4 is the usual super-Gaussian
@@ -527,7 +574,7 @@
- -
+
-
Choose squared guides
@@ -537,9 +584,221 @@
+ -
+
+
+
+ 350
+ 0
+
+
+
+
+ 350
+ 16777215
+
+
+
+
+
+
+ 0
+
+
+
+ waveguide array
+
+
+
-
+
+
+ Number of guides
+
+
+ Numbers of guides
+
+
+
+ -
+
+
+ Number of guides
+
+
+ QAbstractSpinBox::CorrectToNearestValue
+
+
+ 1000
+
+
+ 11
+
+
+
+ -
+
+
+ Distance between two guides center in µm
+
+
+ Interval between guides
+
+
+
+ -
+
+
+ Distance between two guides center in µm
+
+
+ QAbstractSpinBox::CorrectToNearestValue
+
+
+ µm
+
+
+ 3
+
+
+ 10000.000000000000000
+
+
+ 15.000000000000000
+
+
+
+
+
+
+
+ curved waveguides
+
+
+ -
+
+
+ curvature factor in 10^-8 1/µm^2
+
+
+ Curvature
+
+
+
+ -
+
+
+ curvature factor in 10^-8 1/µm^2
+
+
+ QAbstractSpinBox::CorrectToNearestValue
+
+
+ * 10^-8 1/µm^2
+
+
+ 3
+
+
+ -100000000.000000000000000
+
+
+ 100000000.000000000000000
+
+
+ 40.000000000000000
+
+
+
+ -
+
+
+ Half distance over z in µm bewteen the two external guides where they are the closest
+
+
+ Half delay
+
+
+
+ -
+
+
+ Half distance over z in µm bewteen the two external guides where they are the closest
+
+
+ QAbstractSpinBox::CorrectToNearestValue
+
+
+ µm
+
+
+ 3
+
+
+ 100000.000000000000000
+
+
+ 1000.000000000000000
+
+
+
+ -
+
+
+ Distance factor: p_min/width
+
+
+ p_min/width
+
+
+
+ -
+
+
+ Distance factor: p_min/width
+
+
+ QAbstractSpinBox::CorrectToNearestValue
+
+
+ µm
+
+
+ 3
+
+
+ 10000.000000000000000
+
+
+ 1.200000000000000
+
+
+
+
+
+
+
+ -
+
+
+
+ 370
+ 16777215
+
+
+
+ PointingHandCursor
+
+
+ Compute an array of guides
+
+
+ Compute guides
+
+
+
-
@@ -556,250 +815,6 @@
- -
-
-
-
- 370
- 0
-
-
-
-
- 370
- 16777215
-
-
-
-
-
-
- 0
-
-
-
- waveguide array
-
-
-
-
-
-
- Number of guides
-
-
- Numbers of guides
-
-
-
- -
-
-
- Number of guides
-
-
- QAbstractSpinBox::CorrectToNearestValue
-
-
- 1000
-
-
- 11
-
-
-
- -
-
-
- Distance between two guides center in µm
-
-
- Interval between guides
-
-
-
- -
-
-
- Distance between two guides center in µm
-
-
- QAbstractSpinBox::CorrectToNearestValue
-
-
- µm
-
-
- 3
-
-
- 10000.000000000000000
-
-
- QAbstractSpinBox::DefaultStepType
-
-
- 15.000000000000000
-
-
-
- -
-
-
- PointingHandCursor
-
-
- Compute an array of guides
-
-
- Compute array of guides
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Maximum
-
-
-
- 20
- 20
-
-
-
-
-
-
-
-
- curved waveguides
-
-
- -
-
-
- curvature factor in 10^-8 1/µm^2
-
-
- Curvature
-
-
-
- -
-
-
- curvature factor in 10^-8 1/µm^2
-
-
- QAbstractSpinBox::CorrectToNearestValue
-
-
- * 10^-8 1/µm^2
-
-
- 3
-
-
- -100000000.000000000000000
-
-
- 100000000.000000000000000
-
-
- 40.000000000000000
-
-
-
- -
-
-
- Half distance over z in µm bewteen the two external guides where they are the closest
-
-
- Half delay
-
-
-
- -
-
-
- Half distance over z in µm bewteen the two external guides where they are the closest
-
-
- QAbstractSpinBox::CorrectToNearestValue
-
-
- µm
-
-
- 3
-
-
- 100000.000000000000000
-
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
-
- 1000.000000000000000
-
-
-
- -
-
-
- Distance factor: p_min/width
-
-
- p_min/width
-
-
-
- -
-
-
- Distance factor: p_min/width
-
-
- QAbstractSpinBox::CorrectToNearestValue
-
-
- µm
-
-
- 3
-
-
- 10000.000000000000000
-
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
-
- 1.200000000000000
-
-
-
- -
-
-
- PointingHandCursor
-
-
- Compute the curved guides define as : - offset_guide + curve*(z - length_z/2 - half_delay)**2 + width*distance_factor)
-
-
- Compute curved guides
-
-
-
-
-
-
-
-
@@ -813,25 +828,6 @@
- -
-
-
-
- 100
- 16777215
-
-
-
- cancel guide changes
-
-
-
-
-
- Cancel changes
-
-
-
-
@@ -861,6 +857,12 @@
-
+
+
+ 370
+ 0
+
+
370
@@ -904,9 +906,6 @@
100.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
1.500000000000000
@@ -962,6 +961,12 @@
-
+
+
+ 370
+ 0
+
+
370
@@ -986,6 +991,9 @@
Select the beam
+
+ -1
+
-
@@ -1013,7 +1021,7 @@
Add a new beam with current displayed values
- create beam
+ add beam
@@ -1163,14 +1171,27 @@
10000.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
1.000000000000000
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 5
+
+
+
+
-
@@ -1182,10 +1203,26 @@
Gaussian
-
- true
+
+ true
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
-
+
+
+ 20
+ 5
+
+
+
-
@@ -1200,6 +1237,22 @@
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 5
+
+
+
+
-
@@ -1212,6 +1265,9 @@
-
+
+ false
+
The n mode based on a squared guide
@@ -1226,7 +1282,56 @@
- -
+
-
+
+
+ false
+
+
+ Waveguide number to use its width in the mode calculation
+
+
+
+ -
+
+
+ Displayed the number of the last mode that can propagate in the rectangular guide
+
+
+ Show max mode
+
+
+
+ -
+
+
+
+ 100
+ 16777215
+
+
+
+ Number of the last mode that can propagate in the guide
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 5
+
+
+
+
+ -
Select all possible modes for a squared guide
@@ -1236,7 +1341,23 @@
- -
+
-
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Minimum
+
+
+
+ 20
+ 5
+
+
+
+
+ -
Select a Airy beam
@@ -1246,7 +1367,7 @@
- -
+
-
Choose to cut at the n zero of the Airy function
@@ -1256,8 +1377,11 @@
- -
+
-
+
+ false
+
Choose to cut at the n zero of the Airy function
@@ -1275,15 +1399,18 @@
- -
+
-
First lobe size
- -
+
-
+
+ false
+
QAbstractSpinBox::CorrectToNearestValue
@@ -1298,109 +1425,16 @@
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Minimum
-
-
-
- 20
- 5
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Minimum
-
-
-
- 20
- 5
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Minimum
-
-
-
- 20
- 5
-
-
-
-
-
-
-
- Qt::Vertical
-
-
- QSizePolicy::Minimum
-
-
-
- 20
- 5
-
-
-
-
- -
-
+
- Displayed the number of the last mode that can propagate in the rectangular guide
+ Waveguide number to use its width in the mode calculation
- Show max mode
-
-
-
- -
-
-
-
- 100
- 16777215
-
-
-
- Number of the last mode that can propagate in the guide
+ Guide number ref
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Minimum
-
-
-
- 20
- 5
-
-
-
-
@@ -1609,9 +1643,6 @@
10000.000000000000000
-
- QAbstractSpinBox::AdaptiveDecimalStepType
-
1.000000000000000
@@ -1924,9 +1955,14 @@
spinBox_nbr_z_disp
doubleSpinBox_length_x
doubleSpinBox_dist_x
+ doubleSpinBox_n
+ comboBox_guide
+ pushButton_create_guide
+ pushButton_delete_guide
+ pushButton_save_guide
+ pushButton_cancel_guide
doubleSpinBox_width
doubleSpinBox_offset_guide
- doubleSpinBox_n
doubleSpinBox_dn
radioButton_gaussian
spinBox_gauss_pow
@@ -1934,12 +1970,10 @@
tabWidget_morphology_guide
spinBox_nb_p
doubleSpinBox_p
- calculateButton_array
+ calculateButton_guide
doubleSpinBox_curve
doubleSpinBox_half_delay
doubleSpinBox_distance_factor
- calculateButton_curved
- pushButton_cancel_guide
doubleSpinBox_lo
doubleSpinBox_theta_ext
comboBox_light
@@ -1979,17 +2013,17 @@
checkBox_offset_light
- clicked(bool)
+ toggled(bool)
doubleSpinBox_offset_light
setDisabled(bool)
- 119
- 87
+ 141
+ 369
- 134
- 87
+ 273
+ 398
@@ -2000,28 +2034,28 @@
setEnabled(bool)
- 87
- 87
+ 109
+ 342
- 230
- 87
+ 252
+ 427
checkBox_offset_light
- clicked(bool)
+ toggled(bool)
spinBox_offset_light_peak
setEnabled(bool)
- 119
- 87
+ 141
+ 369
- 134
- 87
+ 273
+ 372
@@ -2032,12 +2066,12 @@
setEnabled(bool)
- 134
- 87
+ 156
+ 135
- 183
- 87
+ 205
+ 220
@@ -2048,12 +2082,12 @@
setEnabled(bool)
- 134
- 87
+ 156
+ 342
- 134
- 87
+ 167
+ 434
@@ -2064,12 +2098,108 @@
click()
- 98
- 256
+ 130
+ 238
+
+
+ 379
+ 311
+
+
+
+
+ comboBox_guide
+ activated(QString)
+ pushButton_cancel_guide
+ click()
+
+
+ 90
+ 400
+
+
+ 298
+ 467
+
+
+
+
+ radioButton_airy
+ toggled(bool)
+ doubleSpinBox_lobe_size
+ setEnabled(bool)
+
+
+ 61
+ 630
+
+
+ 268
+ 680
+
+
+
+
+ radioButton_airy
+ toggled(bool)
+ spinBox_airy_zero
+ setEnabled(bool)
+
+
+ 61
+ 630
+
+
+ 268
+ 654
+
+
+
+
+ radioButton_mode
+ toggled(bool)
+ spinBox_mode
+ setEnabled(bool)
+
+
+ 65
+ 524
+
+
+ 268
+ 525
+
+
+
+
+ radioButton_gaussian
+ toggled(bool)
+ spinBox_gauss_pow
+ setEnabled(bool)
+
+
+ 73
+ 581
+
+
+ 250
+ 582
+
+
+
+
+ radioButton_mode
+ toggled(bool)
+ spinBox_guide_nbr_ref
+ setEnabled(bool)
+
+
+ 65
+ 524
- 303
- 341
+ 268
+ 557
diff --git a/beampy/user_interface.py b/beampy/user_interface.py
index 57c02a8..ee39a4c 100644
--- a/beampy/user_interface.py
+++ b/beampy/user_interface.py
@@ -45,6 +45,20 @@ def __init__(self):
self.setupUi(self) # Linked to Ui_MainWindow through interface.py
# Prepare variables before assigning values to them
+ self.width = []
+ self.offset_guide = []
+ self.delta_no = []
+ self.shape_gauss_check = []
+ self.gauss_pow = np.array([], dtype=int)
+ self.shape_squared_check = []
+ self.nbr_p = np.array([], dtype=int)
+ self.p = []
+ self.curve = []
+ self.half_delay = []
+ self.distance_factor = []
+ self.tab_index = []
+ self.previous_guide = 0
+
self.fwhm = []
self.offset_light = []
self.irrad = []
@@ -54,15 +68,17 @@ def __init__(self):
self.mode_check = []
self.all_modes_check = []
self.mode = np.array([], dtype=int)
+ self.mode_guide_ref = np.array([], dtype=int)
self.offset_light_peak = np.array([], dtype=int)
self.airy_check = []
self.airy_zero = np.array([], dtype=int)
self.lobe_size = []
self.previous_beam = 0
+ self.on_click_create_guide() # Initialized variables with buttons
self.on_click_create_light() # Initialized variables with buttons
- self.calculate_guide('array') # Compute guide
+ self.calculate_guide() # Compute guide
self.calculate_light() # Compute light
self.addmpl('guide') # Display guide
@@ -94,20 +110,24 @@ def connect_buttons(self):
"""
Connect the interface buttons to their corresponding functions:
- :meth:`.on_click_array`, :meth:`.on_click_curved`,
+ :meth:`.on_click_guide`, :meth:`.on_click_curved`,
:meth:`.on_click_light`, :meth:`.on_click_compute`,
:meth:`.on_click_create_light`, :meth:`.on_click_delete_light`,
:meth:`.save_light`, :meth:`.get_guide`,
:meth:`.get_light`, :meth:`.get_compute`,
:meth:`.show_estimate_time`, :meth:`.check_modes_display`.
"""
- self.calculateButton_array.clicked.connect(self.on_click_array)
- self.calculateButton_curved.clicked.connect(self.on_click_curved)
+ self.calculateButton_guide.clicked.connect(self.on_click_guide)
self.calculateButton_light.clicked.connect(self.on_click_light)
self.calculateButton_compute.clicked.connect(self.on_click_compute)
self.pushButton_create_beam.clicked.connect(self.on_click_create_light)
self.pushButton_delete_beam.clicked.connect(self.on_click_delete_light)
self.pushButton_save_beam.clicked.connect(self.save_light)
+ self.pushButton_create_guide.clicked.connect(
+ self.on_click_create_guide)
+ self.pushButton_delete_guide.clicked.connect(
+ self.on_click_delete_guide)
+ self.pushButton_save_guide.clicked.connect(self.save_guide)
self.pushButton_cancel_guide.clicked.connect(self.get_guide)
self.pushButton_cancel_light.clicked.connect(self.get_light)
self.pushButton_cancel_compute.clicked.connect(self.get_compute)
@@ -182,15 +202,10 @@ def create_menu(self):
icon.addFile(folder+'icons/help-about.png', QSize(22, 22))
action.setIcon(icon)
- def calculate_guide(self, topology='array'):
+ def calculate_guide(self):
"""
Initialized the :class:`.Bpm` class and creates the guides.
- Parameters
- ----------
- topology : str
- 'array' or 'curved'.
-
Notes
-----
Creats many variables, including :
@@ -204,13 +219,12 @@ def calculate_guide(self, topology='array'):
:meth:`.create_guides`, :meth:`.create_curved_guides`.
"""
print("calculate guide")
- self.topology = topology
t_guide_start = time.process_time()
self.save_guide() # Get all guide values
# Create the Bpm class (overwrite existing one)
- self.bpm = Bpm(self.width, self.no, self.delta_no,
+ self.bpm = Bpm(self.no,
self.length_z, self.dist_z, self.nbr_z_disp,
self.length_x, self.dist_x)
@@ -233,61 +247,69 @@ def calculate_guide(self, topology='array'):
print("change the condition nbr_x * nbr_z in calculate_guide")
raise RuntimeError("Too many points:", self.nbr_x*self.nbr_z)
- # Waveguide shape choice
- if self.shape_squared_check:
- shape = self.bpm.squared_guide() # Squared guides
- elif self.shape_gauss_check:
- shape = self.bpm.gauss_guide(self.gauss_pow) # Gaussian guides
+ nbr_guide = self.comboBox_guide.count() # Number of guide set
+
+ self.peaks = np.zeros((0, self.nbr_z))
+ self.dn = np.zeros((self.nbr_z, self.nbr_x))
- # Topology waveguides choice
- if topology == 'array':
+ for i in range(nbr_guide):
+ # Waveguide shape choice
+ if self.shape_squared_check[i]: # Squared guides
+ shape = self.bpm.squared_guide(self.width[i])
+ elif self.shape_gauss_check[i]: # Gaussian guides
+ shape = self.bpm.gauss_guide(self.width[i],
+ gauss_pow=self.gauss_pow[i])
- leng_max = self.length_x - self.dist_x
+ # Topology waveguides choice
+ if self.tab_index[i] == 0: # array of waveguides
+ length_max = self.length_x - self.dist_x
- if self.nbr_p*self.p > leng_max:
- # give info about possible good values
- print("nbr_p*p> length_x: ")
- print(self.nbr_p*self.p, ">", leng_max)
+ if self.nbr_p[i]*self.p[i] > length_max:
+ # give info about possible good values
+ print("nbr_p*p> length_x: ")
+ print(self.nbr_p[i]*self.p[i], ">", length_max)
- print("p_max=", round(leng_max/self.nbr_p, 3))
+ print("p_max=", round(length_max/self.nbr_p[i], 3))
- if int(leng_max / self.p) == leng_max / self.p:
- print("nbr_p_max=", int(leng_max / self.p)-1)
- else:
- print("nbr_p_max=", int(leng_max / self.p))
+ if int(length_max / self.p[i]) == length_max / self.p[i]:
+ print("nbr_p_max=", int(length_max / self.p[i])-1)
+ else:
+ print("nbr_p_max=", int(length_max / self.p[i]))
- self.nbr_p = 0
+ self.nbr_p[i] = 0
+ [peaks, dn] = self.bpm.create_guides(
+ shape, self.delta_no[i], self.nbr_p[i], self.p[i],
+ offset_guide=self.offset_guide[i])
- # choose guides position when even number
-# condition_even_guide = 'center' # default
-# if self.nbr_p % 2 == 0:
-# if condition_even_guide == 'left':
-# self.offset_guide -= self.p / 2
-# elif condition_even_guide == 'right':
-# self.offset_guide += self.p / 2
+ elif self.tab_index[i] == 1: # curved waveguides
+ curve = self.curve[i] * 1E-8 # curvature factor
+ [peaks, dn] = self.bpm.create_curved_guides(
+ shape, self.width[i], self.delta_no[i],
+ curve, self.half_delay[i], self.distance_factor[i],
+ offset_guide=self.offset_guide[i])
- [self.peaks, self.dn] = self.bpm.create_guides(
- shape, self.nbr_p, self.p, offset_guide=self.offset_guide)
+ if self.delta_no[i] > self.no/10:
+ print("Careful: index variation is too high for guide", i, ":")
+ print(self.delta_no[i], ">", self.no, "/ 10")
- elif topology == 'curved':
- curve = self.curve * 1E-8 # curvature factor
- [self.peaks, self.dn] = self.bpm.create_curved_guides(
- shape, curve, self.half_delay, self.distance_factor,
- offset_guide=self.offset_guide)
+ self.peaks = np.append(self.peaks, peaks, 0)
+ self.dn = np.add(self.dn, dn)
- # Display guides
- self.z_disp = np.linspace(0,
- self.length_z / 1000,
- self.nbr_z_disp + 1)
+ # Display guides
+ self.z_disp = np.linspace(0,
+ self.length_z/1000,
+ self.nbr_z_disp+1)
- self.xv, self.zv = np.meshgrid(self.x, self.z_disp)
- self.dn_disp = np.linspace(0,
- self.nbr_z - 1,
- self.nbr_z_disp + 1, dtype=int)
+ self.xv, self.zv = np.meshgrid(self.x, self.z_disp)
+ self.dn_disp = np.linspace(0,
+ self.nbr_z-1,
+ self.nbr_z_disp+1, dtype=int)
# only display available settings
- if self.nbr_p == 0 or self.p == 0:
+ # (don't propose offset from guide if no guide)
+ if 0 in self.nbr_p or 0 in self.p:
self.spinBox_offset_light_peak.setDisabled(True)
+ self.spinBox_guide_nbr_ref.setDisabled(True)
self.doubleSpinBox_offset_light.setEnabled(True)
self.checkBox_offset_light.setChecked(False)
self.checkBox_offset_light.setDisabled(True)
@@ -299,6 +321,7 @@ def calculate_guide(self, topology='array'):
else:
self.checkBox_offset_light.setEnabled(True)
self.spinBox_offset_light_peak.setMaximum(self.peaks.shape[0]-1)
+ self.spinBox_guide_nbr_ref.setMaximum(self.peaks.shape[0]-1)
self.checkBox_lost.setEnabled(True)
self.spinBox_guide_lost.setMaximum(self.peaks.shape[0]-1)
self.checkBox_check_power.setEnabled(True)
@@ -337,7 +360,7 @@ def calculate_light(self):
nbr_light = self.comboBox_light.count() # Number of beams
field = np.zeros((nbr_light, self.nbr_x))
- if sum(self.all_modes_check) > 0: # Display only once the max mode
+ if 1 in self.all_modes_check: # Display only once the max mode
self.check_modes_display()
for i in range(nbr_light):
@@ -359,6 +382,8 @@ def calculate_light(self):
else:
offset_light = self.offset_light[i]
+ guide_index = self.find_guide_number(self.mode_guide_ref[i])
+
# Compute lights
if self.gaussian_check[i]:
field_i = self.bpm.gauss_light(
@@ -370,16 +395,18 @@ def calculate_light(self):
elif self.all_modes_check[i]:
field_i = self.bpm.all_modes(
+ self.width[guide_index], self.delta_no[guide_index],
self.lo, offset_light=offset_light)[0]
elif self.mode_check[i]:
try:
field_i = self.bpm.mode_light(
+ self.width[guide_index], self.delta_no[guide_index],
self.mode[i], self.lo, offset_light=offset_light)[0]
except ValueError as ex: # Say that no mode exist
- print(ex, "for the beam", i)
+ print(ex, "for the beam", i+1)
continue # Go to the next field
elif self.airy_check[i]:
@@ -393,7 +420,7 @@ def calculate_light(self):
irrad = self.irrad # Irradiance or power (GW/cm^2)
irrad = irrad * 1E13 # (W/m^2)
[self.progress_pow] = self.bpm.init_field(
- field, self.theta_ext, irrad, self.lo)
+ self.dn, field, self.theta_ext, irrad, self.lo)
t_light_end = time.process_time()
print('light time: ', t_light_end-t_light_start)
@@ -423,7 +450,7 @@ def calculate_propagation(self):
if self.lost_check:
alpha = self.alpha/1000
[lost_beg, lost_end] = self.bpm.losses_position(
- self.guide_lost, self.width_lost)
+ self.peaks, self.guide_lost, self.width_lost)
else:
alpha = 0
lost_beg = 0
@@ -438,6 +465,7 @@ def calculate_propagation(self):
print("Time estimate:", estimation)
[self.progress_pow] = self.bpm.main_compute(
+ self.dn,
chi3=chi3, kerr=kerr, kerr_loop=kerr_loop,
variance_check=variance_check, alpha=alpha,
lost_beg=lost_beg, lost_end=lost_end)
@@ -462,13 +490,50 @@ def show_estimate_time(self):
self.estimate_time_display.display(estimation)
+ def find_guide_number(self, guide_number):
+ """
+ Return the waveguide group number for a given waveguide number.
+
+
+ Parameters
+ ----------
+ guide_number : int
+ Number of a waveguide
+
+ Returns
+ -------
+ guide_group_number : int
+ Number of the waveguide group
+ """
+ num_gd = -1
+ for j, n in enumerate(self.nbr_p):
+
+ if self.tab_index[j] == 0:
+
+ for _ in range(n):
+ num_gd += 1
+ if num_gd == guide_number:
+ guide_group_number = j
+ break
+ elif self.tab_index[j] == 1:
+ for _ in range(3):
+ num_gd += 1
+ if num_gd == guide_number:
+ guide_group_number = j
+ break
+ return guide_group_number
+
def check_modes_display(self):
"""
Display on the interface the last mode that can propagated into a
squared guide.
"""
lo = self.doubleSpinBox_lo.value()
- mode_max = self.bpm.check_modes(lo)
+
+ guide_index = self.find_guide_number(
+ self.spinBox_guide_nbr_ref.value())
+ mode_max = self.bpm.check_modes(
+ self.width[guide_index], self.delta_no[guide_index], lo)
self.mode_number.display(mode_max)
def addmpl(self, tab='guide', pow_index=0):
@@ -493,19 +558,18 @@ def addmpl(self, tab='guide', pow_index=0):
x_min = self.x[0]
x_max = self.x[-1]
-
- if (self.topology == 'array' # If array of guides
- and self.nbr_p != 0 and self.p != 0 # If guides exists
- and self.peaks[0, 0] >= self.x[0] # If guides in the windows
- and self.peaks[-1, -1] <= self.x[-1]):
- x_min = self.offset_guide - self.nbr_p*self.p
- x_max = self.offset_guide + self.nbr_p*self.p
-
- if (self.topology == 'curved' # If curved guides
- and self.peaks[0, 0] >= self.x[0] # If guides in the windows
- and self.peaks[-1, -1] <= self.x[-1]):
- x_min = self.peaks[0, 0] - self.width
- x_max = self.peaks[-1, -1] + self.width
+ if (0 in self.tab_index # If array of guides
+ and 0 not in self.nbr_p and 0 not in self.p # If guides exists
+ and self.peaks.min() >= self.x[0] # If guides in the windows
+ and self.peaks.max() <= self.x[-1]):
+ x_min = np.min(self.offset_guide - self.nbr_p*self.p)
+ x_max = np.max(self.offset_guide + self.nbr_p*self.p)
+
+ if (1 in self.tab_index # If curved guides
+ and self.peaks.min() >= self.x[0] # If guides in the windows
+ and self.peaks.max() <= self.x[-1]):
+ x_min = self.peaks.min() - self.width.max()
+ x_max = self.peaks.max() + self.width.max()
if tab == 'guide':
fig = Figure()
@@ -538,7 +602,7 @@ def addmpl(self, tab='guide', pow_index=0):
ax2.set_xlabel('x (µm)')
ax2.set_ylabel(r'$\Delta_n$')
- if self.nbr_p != 0:
+ if sum(self.nbr_p) > 0:
verts = [(self.x[0], 0),
*zip(self.x, self.dn[pow_index_guide, :]),
(self.x[-1], 0)]
@@ -581,7 +645,7 @@ def addmpl(self, tab='guide', pow_index=0):
ax1.set_ylabel(r'$\Delta_n$')
ax2.set_ylabel('Irradiance ($GW.cm^{-2}$)')
- if self.nbr_p != 0:
+ if 0 not in self.nbr_p:
verts = [(self.x[0], 0),
*zip(self.x, self.dn[pow_index_guide, :]),
(self.x[-1], 0)]
@@ -643,7 +707,7 @@ def addmpl(self, tab='guide', pow_index=0):
# Display guides power
if (self.checkBox_check_power.isChecked() and
- self.nbr_p != 0 and self.p != 0):
+ 0 not in self.nbr_p and 0 not in self.p):
t_power_start = time.process_time()
fig = Figure()
# fig.set_tight_layout(True)
@@ -656,45 +720,52 @@ def addmpl(self, tab='guide', pow_index=0):
style = list(lines.lineStyles.keys())[0:-3]
style = style + list(lines.lineMarkers.keys())[0:-16]
- if self.topology == 'array':
- x_beg = np.zeros((self.nbr_p, self.nbr_z), dtype=int)
- x_end = np.zeros((self.nbr_p, self.nbr_z), dtype=int)
- P = np.zeros((self.nbr_p, self.nbr_z_disp+1))
-
- for n in range(self.nbr_p):
- [x_beg[n, :],
- x_end[n, :]] = self.bpm.guide_position(n, self.p)
-
- elif self.topology == 'curved':
- x_beg = np.zeros((3, self.nbr_z), dtype=int)
- x_end = np.zeros((3, self.nbr_z), dtype=int)
- P = np.zeros((3, self.nbr_z_disp+1))
-
- # Choose precision at the end for right guide if can
- # and choose safety when guides overlapse
- if self.peaks[2, -1] <= self.x[-1]:
- # When further of each other (good for right end)
- p0 = self.peaks[2, -1] - self.peaks[1, -1]
-
- else:
- # When closest to each other (good when close)
- p0 = self.width * self.distance_factor
-
- for n in range(3):
- [x_beg[n, :],
- x_end[n, :]] = self.bpm.guide_position(n, p0)
-
- for n in range(self.peaks.shape[0]):
- P[n, :] = self.bpm.power_guide(x_beg[n, :],
- x_end[n, :])
+ x_beg = np.zeros((self.peaks.shape[0], self.nbr_z),
+ dtype=int)
+ x_end = np.zeros((self.peaks.shape[0], self.nbr_z),
+ dtype=int)
+ P = np.zeros((self.peaks.shape[0], self.nbr_z_disp+1))
+
+ num_gd = 0
+ for i, n in enumerate(self.nbr_p):
+
+ if self.tab_index[i] == 0:
+
+ for _ in range(n):
+ [x_beg[num_gd, :],
+ x_end[num_gd, :]] = self.bpm.guide_position(
+ self.peaks, num_gd, self.p[i])
+ num_gd += 1
+
+ elif self.tab_index[i] == 1:
+ # Choose precision at the end for right guide
+ # and choose safety when guides overlapse
+ if self.peaks[num_gd+2, -1] <= self.x[-1]:
+ # accurate at end but may overlap before
+ p0 = (self.peaks[num_gd+2, -1]
+ - self.peaks[num_gd+1, -1])
+
+ else:
+ # accurate in middle but miss evanescente part
+ p0 = self.width[i] * self.distance_factor[i]
+
+ for j in range(3):
+ [x_beg[num_gd, :],
+ x_end[num_gd, :]] = self.bpm.guide_position(
+ self.peaks, num_gd, p0)
+ num_gd += 1
+
+ for i in range(self.peaks.shape[0]):
+ P[i, :] = self.bpm.power_guide(x_beg[i, :],
+ x_end[i, :])
# plot each power with a different style (nbr_p < 29)
- if n < 29:
- ax1.plot(self.z_disp, P[n, :],
- style[n], label='P'+str(n))
+ if i < 29:
+ ax1.plot(self.z_disp, P[i, :],
+ style[i], label='P'+str(i))
else: # to have no error but same style
- ax1.plot(self.z_disp, P[n, :],
- '', label='P'+str(n))
+ ax1.plot(self.z_disp, P[i, :],
+ '', label='P'+str(i))
self.canvas_5 = FigureCanvas(fig)
self.verticalLayout_compute_plot.addWidget(self.canvas_5)
@@ -703,7 +774,7 @@ def addmpl(self, tab='guide', pow_index=0):
self.canvas_5,
coordinates=True)
self.verticalLayout_compute_plot.addWidget(self.toolbar_5)
- if self.nbr_p > 10:
+ if self.peaks.shape[0] > 10:
ax1.legend(loc="upper right") # Fast if many plot
else:
ax1.legend() # Best if not too many plot
@@ -757,33 +828,39 @@ def rmmpl(self, tab, pow_index=0):
self.plot_compute.removeWidget(self.toolbar_4)
self.toolbar_4.close()
- def save_guide(self):
+ def save_guide(self, guide_selec=False):
"""
Save the interface variables into the guides variables.
"""
+ # if more than one guide and if no guide selected manualy
+ if str(guide_selec) == 'False':
+ guide_selec = int(self.comboBox_guide.currentIndex()) # Choice
+
self.length_z = self.doubleSpinBox_length_z.value()
self.dist_z = self.doubleSpinBox_dist_z.value()
self.nbr_z_disp = self.spinBox_nbr_z_disp.value()
self.length_x = self.doubleSpinBox_length_x.value()
self.dist_x = self.doubleSpinBox_dist_x.value()
-
- self.width = self.doubleSpinBox_width.value()
- self.offset_guide = self.doubleSpinBox_offset_guide.value()
self.no = self.doubleSpinBox_n.value()
- self.delta_no = self.doubleSpinBox_dn.value()
-
- self.shape_gauss_check = float(self.radioButton_gaussian.isChecked())
- self.gauss_pow = int(self.spinBox_gauss_pow.value())
- self.shape_squared_check = float(self.radioButton_squared.isChecked())
-
- self.nbr_p = self.spinBox_nb_p.value()
- self.p = self.doubleSpinBox_p.value()
- self.curve = self.doubleSpinBox_curve.value()
- self.half_delay = self.doubleSpinBox_half_delay.value()
- self.distance_factor = self.doubleSpinBox_distance_factor.value()
-
- self.tab_index = self.tabWidget_morphology_guide.currentIndex()
+ self.width[guide_selec] = self.doubleSpinBox_width.value()
+ self.offset_guide[
+ guide_selec] = self.doubleSpinBox_offset_guide.value()
+ self.delta_no[guide_selec] = self.doubleSpinBox_dn.value()
+ self.shape_gauss_check[guide_selec] = float(
+ self.radioButton_gaussian.isChecked())
+ self.gauss_pow[guide_selec] = int(self.spinBox_gauss_pow.value())
+ self.shape_squared_check[guide_selec] = float(
+ self.radioButton_squared.isChecked())
+ self.nbr_p[guide_selec] = self.spinBox_nb_p.value()
+ self.p[guide_selec] = self.doubleSpinBox_p.value()
+ self.curve[guide_selec] = self.doubleSpinBox_curve.value()
+ self.half_delay[guide_selec] = self.doubleSpinBox_half_delay.value()
+ self.distance_factor[
+ guide_selec] = self.doubleSpinBox_distance_factor.value()
+
+ self.tab_index[
+ guide_selec] = self.tabWidget_morphology_guide.currentIndex()
# print("Guide variables saved")
def get_guide(self):
@@ -795,24 +872,38 @@ def get_guide(self):
self.spinBox_nbr_z_disp.setValue(self.nbr_z_disp)
self.doubleSpinBox_length_x.setValue(self.length_x)
self.doubleSpinBox_dist_x.setValue(self.dist_x)
-
- self.doubleSpinBox_width.setValue(self.width)
- self.doubleSpinBox_offset_guide.setValue(self.offset_guide)
self.doubleSpinBox_n.setValue(self.no)
- self.doubleSpinBox_dn.setValue(self.delta_no)
- self.radioButton_gaussian.setChecked(self.shape_gauss_check)
- self.spinBox_gauss_pow.setValue(self.gauss_pow)
- self.radioButton_squared.setChecked(self.shape_squared_check)
+ guide_selec = int(self.comboBox_guide.currentIndex()) # choice
- self.spinBox_nb_p.setValue(self.nbr_p)
- self.doubleSpinBox_p.setValue(self.p)
+ if self.previous_guide != guide_selec:
+ self.save_guide(self.previous_guide)
- self.doubleSpinBox_curve.setValue(self.curve)
- self.doubleSpinBox_half_delay.setValue(self.half_delay)
- self.doubleSpinBox_distance_factor.setValue(self.distance_factor)
-
- self.tabWidget_morphology_guide.setCurrentIndex(self.tab_index)
+ if self.comboBox_guide.count() >= 1: # if more than one beams
+ guide_selec = int(self.comboBox_guide.currentIndex()) # choice
+ else: # Not supposed to happen
+ raise ValueError("Can't have no guide variables")
+
+ self.doubleSpinBox_width.setValue(self.width[guide_selec])
+ self.doubleSpinBox_offset_guide.setValue(
+ self.offset_guide[guide_selec])
+ self.doubleSpinBox_dn.setValue(self.delta_no[guide_selec])
+ self.radioButton_gaussian.setChecked(
+ self.shape_gauss_check[guide_selec])
+ self.spinBox_gauss_pow.setValue(self.gauss_pow[guide_selec])
+ self.radioButton_squared.setChecked(
+ self.shape_squared_check[guide_selec])
+ self.spinBox_nb_p.setValue(self.nbr_p[guide_selec])
+ self.doubleSpinBox_p.setValue(self.p[guide_selec])
+ self.doubleSpinBox_curve.setValue(self.curve[guide_selec])
+ self.doubleSpinBox_half_delay.setValue(self.half_delay[guide_selec])
+ self.doubleSpinBox_distance_factor.setValue(
+ self.distance_factor[guide_selec])
+ self.tabWidget_morphology_guide.setCurrentIndex(
+ self.tab_index[guide_selec])
+ self.spinBox_gauss_pow.setEnabled(self.shape_gauss_check[guide_selec])
+
+ self.previous_guide = guide_selec # Save the # of the current guide
def save_light(self, beam_selec=False):
"""
@@ -835,6 +926,7 @@ def save_light(self, beam_selec=False):
self.offset_light[beam_selec] = self.doubleSpinBox_offset_light.value()
self.irrad[beam_selec] = self.doubleSpinBox_intensity_light.value()
self.mode[beam_selec] = self.spinBox_mode.value()
+ self.mode_guide_ref[beam_selec] = self.spinBox_guide_nbr_ref.value()
self.offset_check[beam_selec] = (
self.checkBox_offset_light.isChecked())
self.offset_light_peak[beam_selec] = (
@@ -873,6 +965,7 @@ def get_light(self):
self.offset_light[beam_selec])
self.doubleSpinBox_intensity_light.setValue(self.irrad[beam_selec])
self.spinBox_mode.setValue(self.mode[beam_selec])
+ self.spinBox_guide_nbr_ref.setValue(self.mode_guide_ref[beam_selec])
self.checkBox_offset_light.setChecked(self.offset_check[beam_selec])
self.spinBox_offset_light_peak.setValue(
self.offset_light_peak[beam_selec])
@@ -881,16 +974,19 @@ def get_light(self):
self.radioButton_squared_light.setChecked(
self.square_check[beam_selec])
self.radioButton_mode.setChecked(self.mode_check[beam_selec])
- self.radioButton_all_modes.setChecked(
- self.all_modes_check[beam_selec])
+ self.radioButton_all_modes.setChecked(self.all_modes_check[beam_selec])
+ self.radioButton_airy.setChecked(self.airy_check[beam_selec])
+ self.spinBox_airy_zero.setValue(self.airy_zero[beam_selec])
+ self.doubleSpinBox_lobe_size.setValue(self.lobe_size[beam_selec])
# if checkBox_offset_light checked then activate
self.spinBox_offset_light_peak.setEnabled(
self.offset_check[beam_selec])
self.doubleSpinBox_offset_light.setDisabled(
self.offset_check[beam_selec])
- self.radioButton_airy.setChecked(self.airy_check[beam_selec])
- self.spinBox_airy_zero.setValue(self.airy_zero[beam_selec])
- self.doubleSpinBox_lobe_size.setValue(self.lobe_size[beam_selec])
+ self.spinBox_airy_zero.setEnabled(self.airy_check[beam_selec])
+ self.doubleSpinBox_lobe_size.setEnabled(self.airy_check[beam_selec])
+ self.spinBox_mode.setEnabled(self.mode_check[beam_selec])
+ self.spinBox_guide_nbr_ref.setEnabled(self.mode_check[beam_selec])
self.previous_beam = beam_selec # Save the number of the current beam
@@ -932,31 +1028,15 @@ def get_compute(self):
self.checkBox_check_power.setChecked(self.power_check)
@pyqtSlot()
- def on_click_array(self):
+ def on_click_guide(self):
"""
- Compute and displayed a guide array.
+ Compute and displayed the waguides.
"""
# print('button click guide array')
QApplication.setOverrideCursor(Qt.WaitCursor)
self.rmmpl('guide')
self.rmmpl('light')
- self.calculate_guide('array')
- self.calculate_light()
- self.addmpl('guide')
- self.addmpl('light')
- QApplication.restoreOverrideCursor()
- self.show_estimate_time()
-
- @pyqtSlot()
- def on_click_curved(self):
- """
- Compute and displayed curved guides.
- """
-# print('button click guide curved')
- QApplication.setOverrideCursor(Qt.WaitCursor)
- self.rmmpl('guide')
- self.rmmpl('light')
- self.calculate_guide('curved')
+ self.calculate_guide()
self.calculate_light()
self.addmpl('guide')
self.addmpl('light')
@@ -991,7 +1071,7 @@ def on_click_compute(self):
if not self.calculate_guide_done:
self.rmmpl('guide')
- self.calculate_guide(self.topology)
+ self.calculate_guide()
self.addmpl('guide')
self.rmmpl(tab='light')
self.calculate_light()
@@ -1005,6 +1085,43 @@ def on_click_compute(self):
QApplication.restoreOverrideCursor()
+ @pyqtSlot()
+ def on_click_create_guide(self):
+ """Create a new guide with the displayed variables.
+ """
+ width = self.doubleSpinBox_width.value()
+ offset_guide = self.doubleSpinBox_offset_guide.value()
+ delta_no = self.doubleSpinBox_dn.value()
+ shape_gauss_check = self.radioButton_gaussian.isChecked()
+ gauss_pow = int(self.spinBox_gauss_pow.value())
+ shape_squared_check = self.radioButton_squared.isChecked()
+ nbr_p = self.spinBox_nb_p.value()
+ p = self.doubleSpinBox_p.value()
+ curve = self.doubleSpinBox_curve.value()
+ half_delay = self.doubleSpinBox_half_delay.value()
+ distance_factor = self.doubleSpinBox_distance_factor.value()
+ tab_index = self.tabWidget_morphology_guide.currentIndex()
+
+ self.width = np.append(self.width, width)
+ self.offset_guide = np.append(self.offset_guide, offset_guide)
+ self.delta_no = np.append(self.delta_no, delta_no)
+ self.shape_gauss_check = np.append(self.shape_gauss_check,
+ shape_gauss_check)
+ self.gauss_pow = np.append(self.gauss_pow, gauss_pow)
+ self.shape_squared_check = np.append(self.shape_squared_check,
+ shape_squared_check)
+ self.nbr_p = np.append(self.nbr_p, nbr_p)
+ self.p = np.append(self.p, p)
+ self.curve = np.append(self.curve, curve)
+ self.half_delay = np.append(self.half_delay, half_delay)
+ self.distance_factor = np.append(self.distance_factor, distance_factor)
+ self.tab_index = np.append(self.tab_index, tab_index)
+
+ nbr_guide = self.comboBox_guide.count() # how many item left
+ self.comboBox_guide.addItem("Guide "+str(nbr_guide+1)) # add new index
+ self.comboBox_guide.setCurrentIndex(nbr_guide) # show new index
+ self.previous_beam = nbr_guide # Change the current selected guide
+
@pyqtSlot()
def on_click_create_light(self):
"""Create a new beam with the displayed variables.
@@ -1018,6 +1135,7 @@ def on_click_create_light(self):
mode_check = self.radioButton_mode.isChecked()
all_modes_check = self.radioButton_all_modes.isChecked()
mode = self.spinBox_mode.value()
+ mode_guide_ref = self.spinBox_guide_nbr_ref.value()
offset_light_peak = self.spinBox_offset_light_peak.value()
airy_check = self.radioButton_airy.isChecked()
airy_zero = self.spinBox_airy_zero.value()
@@ -1027,6 +1145,7 @@ def on_click_create_light(self):
self.offset_light = np.append(self.offset_light, offset_light)
self.irrad = np.append(self.irrad, irrad)
self.mode = np.append(self.mode, mode)
+ self.mode_guide_ref = np.append(self.mode_guide_ref, mode_guide_ref)
self.offset_check = np.append(self.offset_check, offset_check)
self.offset_light_peak = np.append(self.offset_light_peak,
offset_light_peak)
@@ -1043,6 +1162,44 @@ def on_click_create_light(self):
self.comboBox_light.setCurrentIndex(nbr_light) # show new index
self.previous_beam = nbr_light # Change the current selected beam
+ @pyqtSlot()
+ def on_click_delete_guide(self):
+ """
+ Delete the current displayed guide and displayed the next one.
+ """
+ nbr_guide = self.comboBox_guide.count()
+
+ if nbr_guide > 1: # Can't delete if remains only 1 guide
+ guide_selec = int(self.comboBox_guide.currentIndex()) # choice
+ self.width = np.delete(self.width, guide_selec)
+ self.offset_guide = np.delete(self.offset_guide, guide_selec)
+ self.delta_no = np.delete(self.delta_no, guide_selec)
+ self.shape_gauss_check = np.delete(self.shape_gauss_check,
+ guide_selec)
+ self.gauss_pow = np.delete(self.gauss_pow, guide_selec)
+ self.shape_squared_check = np.delete(self.shape_squared_check,
+ guide_selec)
+ self.nbr_p = np.delete(self.nbr_p, guide_selec)
+ self.p = np.delete(self.p, guide_selec)
+ self.curve = np.delete(self.curve, guide_selec)
+ self.half_delay = np.delete(self.half_delay, guide_selec)
+ self.distance_factor = np.delete(self.distance_factor, guide_selec)
+
+ nbr_guide -= 1
+
+ self.comboBox_guide.clear() # remove all beams number
+
+ for i in range(nbr_guide): # create again with new number
+ self.comboBox_guide.addItem("Guide "+str(i+1))
+
+ # set same guide index if not the last else reduce the index by 1
+ if guide_selec == nbr_guide and guide_selec != 0:
+ guide_selec -= 1
+
+ self.comboBox_guide.setCurrentIndex(guide_selec)
+ self.previous_guide = guide_selec # Change the selected guide
+ self.get_guide() # Display values of the previous or next guide
+
@pyqtSlot()
def on_click_delete_light(self):
"""
@@ -1056,6 +1213,7 @@ def on_click_delete_light(self):
self.offset_light = np.delete(self.offset_light, beam_selec)
self.irrad = np.delete(self.irrad, beam_selec)
self.mode = np.delete(self.mode, beam_selec)
+ self.mode_guide_ref = np.delete(self.mode_guide_ref, beam_selec)
self.offset_check = np.delete(self.offset_check, beam_selec)
self.offset_light_peak = np.delete(self.offset_light_peak,
beam_selec)
@@ -1143,31 +1301,29 @@ def open_file(self, filename):
self.save_compute()
# Guide variables
-# if dico.get('length_z') is not None: # if want to continue without the
-# variable and choose the displayed values instead
+# if dico.get('length_z') is not None: # TODO: if want to continue
+# without the variable and choose the displayed values instead
self.length_z = float(dico['length_z'][0])
self.dist_z = float(dico['dist_z'][0])
self.nbr_z_disp = int(dico['nbr_z_disp'][0])
self.length_x = float(dico['length_x'][0])
self.dist_x = float(dico['dist_x'][0])
-
- self.width = float(dico['width'][0])
- self.offset_guide = float(dico['offset_guide'][0])
self.no = float(dico['no'][0])
- self.delta_no = float(dico['delta_no'][0])
-
- self.shape_gauss_check = float(dico['shape_gauss_check'][0])
- self.gauss_pow = int(dico['gauss_pow'][0])
- self.shape_squared_check = float(dico['shape_squared_check'][0])
- self.nbr_p = int(dico['nbr_p'][0])
- self.p = float(dico['p'][0])
-
- self.curve = float(dico['curve'][0])
- self.half_delay = float(dico['half_delay'][0])
- self.distance_factor = float(dico['distance_factor'][0])
-
- self.tab_index = int(dico['tab_index'][0])
+ self.width = np.array(dico['width'], dtype=float)
+ self.offset_guide = np.array(dico['offset_guide'], dtype=float)
+ self.delta_no = np.array(dico['delta_no'], dtype=float)
+ self.shape_gauss_check = np.array(dico['shape_gauss_check'],
+ dtype=float)
+ self.gauss_pow = np.array(dico['gauss_pow'], dtype=int)
+ self.shape_squared_check = np.array(dico['shape_squared_check'],
+ dtype=float)
+ self.nbr_p = np.array(dico['nbr_p'], dtype=int)
+ self.p = np.array(dico['p'], dtype=float)
+ self.curve = np.array(dico['curve'], dtype=float)
+ self.half_delay = np.array(dico['half_delay'], dtype=float)
+ self.distance_factor = np.array(dico['distance_factor'], dtype=float)
+ self.tab_index = np.array(dico['tab_index'], dtype=float)
# Light variables
self.lo = float(dico['lo'][0])
@@ -1182,6 +1338,7 @@ def open_file(self, filename):
self.mode_check = np.array(dico['mode_check'], dtype=float)
self.all_modes_check = np.array(dico['all_modes_check'], dtype=float)
self.mode = np.array(dico['mode'], dtype=int)
+ self.mode_guide_ref = np.array(dico['mode_guide_ref'], dtype=int)
self.offset_light_peak = np.array(
dico['offset_light_peak'], dtype=int)
self.airy_check = np.array(dico['airy_check'], dtype=float)
@@ -1199,29 +1356,27 @@ def open_file(self, filename):
self.variance_check = float(dico['variance_check'][0])
self.power_check = float(dico['power_check'][0])
+ nbr_guide = len(self.width)
+ self.comboBox_guide.clear() # Remove all guides number
+
nbr_light = len(self.fwhm)
self.comboBox_light.clear() # Remove all beams number
+ for i in range(nbr_guide): # Create again with new number
+ self.comboBox_guide.addItem("Guide "+str(i+1))
+
for i in range(nbr_light): # Create again with new number
self.comboBox_light.addItem("Beam "+str(i+1))
+ self.previous_guide = 0 # Change the current selected guide
self.previous_beam = 0 # Change the current selected beam
- if self.tab_index == 0 and self.nbr_p != 0: # Array of guides
- self.spinBox_offset_light_peak.setMaximum(self.nbr_p-1)
- self.spinBox_guide_lost.setMaximum(self.nbr_p-1)
- elif self.tab_index == 1: # Curved guides
- self.spinBox_offset_light_peak.setMaximum(3-1)
- self.spinBox_guide_lost.setMaximum(3-1)
-
self.get_guide() # Set guides boxes value
self.get_light() # Set lights boxes value
self.get_compute() # Set compute boxes value
- if self.tab_index == 0: # If openned file uses array
- self.on_click_array()
- elif self.tab_index == 1: # If openned file uses curved guides
- self.on_click_curved()
+ self.on_click_guide()
+
print("file openned")
@pyqtSlot()
@@ -1275,23 +1430,40 @@ def save_file(self, filename):
f.write('nbr_z_disp ' + str(self.nbr_z_disp) + '\n')
f.write('length_x ' + str(self.length_x) + '\n')
f.write('dist_x ' + str(self.dist_x) + '\n')
-
- f.write('width ' + str(self.width) + '\n')
- f.write('offset_guide ' + str(self.offset_guide) + '\n')
f.write('no ' + str(self.no) + '\n')
- f.write('delta_no ' + str(self.delta_no) + '\n')
-
- f.write('shape_gauss_check ' + str(self.shape_gauss_check) + '\n')
- f.write('gauss_pow ' + str(self.gauss_pow) + '\n')
- f.write('shape_squared_check ' + str(self.shape_squared_check) + '\n')
-
- f.write('nbr_p ' + str(self.nbr_p) + '\n')
- f.write('p ' + str(self.p) + '\n')
- f.write('curve ' + str(self.curve) + '\n')
- f.write('half_delay ' + str(self.half_delay) + '\n')
- f.write('distance_factor ' + str(self.distance_factor) + '\n')
- f.write('tab_index ' + str(self.tab_index) + '\n')
+ f.write('width ' + str(self.width).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('offset_guide ' + str(
+ self.offset_guide).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('delta_no ' + str(
+ self.delta_no).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('shape_gauss_check ' + str(
+ self.shape_gauss_check).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('gauss_pow ' + str(
+ self.gauss_pow).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('shape_squared_check ' + str(
+ self.shape_squared_check).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('nbr_p ' + str(self.nbr_p).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('p ' + str(self.p).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('curve ' + str(self.curve).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('half_delay ' + str(
+ self.half_delay).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('distance_factor ' + str(
+ self.distance_factor).replace("[", "").replace("]", "")
+ + '\n')
+ f.write('tab_index ' + str(
+ self.tab_index).replace("[", "").replace("]", "")
+ + '\n')
# light variables
f.write('lo ' + str(self.lo) + '\n')
@@ -1324,6 +1496,9 @@ def save_file(self, filename):
f.write('mode '
+ str(self.mode).replace("[", "").replace("]", "")
+ '\n')
+ f.write('mode_guide_ref '
+ + str(self.mode_guide_ref).replace("[", "").replace("]", "")
+ + '\n')
f.write('offset_light_peak '
+ str(self.offset_light_peak).replace("[", "").replace("]", "")
+ '\n')
diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo
index ee2b428..c92be7d 100644
--- a/docs/html/.buildinfo
+++ b/docs/html/.buildinfo
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: f59b17170e3fd0facf68b8b965daf0aa
+config: bdd796130c314b580a9aff17bba9e306
tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docs/html/.doctrees/beampy.doctree b/docs/html/.doctrees/beampy.doctree
index 3a5697aaf0a03e01a399b68d04c432cb2dbf6864..1a13f955262297b541c0ef7ed7efb5c01c281403 100644
GIT binary patch
literal 282796
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 nIkq
z-(zU58duX?;