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 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 R=uj0EL)M|tUg?dE{wHL3;Uxe7 literal 267616 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

8Dh{J%;D3)I%5rkEm&5aqK>&=gf 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

KK+ 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 delta 16478 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 diff --git a/docs/html/.doctrees/index.doctree b/docs/html/.doctrees/index.doctree index 448f45da329ef66a047ca177c59a56e43292bfbd..d07607753dc2d3e827d8c0101da9dc8bca7db126 100644 GIT binary patch delta 78 zcmbQ%#yG8waRZ;FtV?RLf`PG)f{}rd!Iai1jZP - MIT License — beampy 1.0 documentation + MIT License — beampy 1.1 documentation diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js index 07966ec..804564e 100644 --- a/docs/html/_static/documentation_options.js +++ b/docs/html/_static/documentation_options.js @@ -1,6 +1,6 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '1.0', + VERSION: '1.1', LANGUAGE: 'None', COLLAPSE_INDEX: false, BUILDER: 'html', diff --git a/docs/html/beampy.html b/docs/html/beampy.html index e16599c..e17f0d4 100644 --- a/docs/html/beampy.html +++ b/docs/html/beampy.html @@ -7,7 +7,7 @@ - Beampy modules — beampy 1.0 documentation + Beampy modules — beampy 1.1 documentation @@ -163,7 +163,7 @@

Beampy modules

-

List of all the modules used in Beampy as of Nov 23, 2020 for the version 1.0

+

List of all the modules used in Beampy as of Dec 03, 2020 for the version 1.1

Source codes

beampy.bpm

@@ -188,7 +188,7 @@

beampy.bpm
-class beampy.bpm.Bpm(width, no, delta_no, length_z, dist_z, nbr_z_disp, length_x, dist_x)
+class beampy.bpm.Bpm(no, length_z, dist_z, nbr_z_disp, length_x, dist_x)

Bases: object

The Bpm class is used to simulate light propagation - within small refractive index variation guides @@ -197,9 +197,7 @@

beampy.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) – Step over z (µm)

  • nbr_z_disp (int) – Number of points to display over z.

  • @@ -261,11 +259,12 @@

    beampy.bpm
    -all_modes(lo, offset_light=0)
    +all_modes(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) – Light offset from center in µm. 0 by default.

    @@ -287,7 +286,7 @@

    beampy.bpm
    -bpm_compute(chi3=1e-19, kerr=False, kerr_loop=1, variance_check=False, alpha=0, lost_beg=None, lost_end=None)
    +bpm_compute(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.

    @@ -321,13 +320,16 @@

    beampy.bpm
    -check_modes(lo)
    +check_modes(width, delta_no, lo)

    Return the last possible mode number. Could be merged with all_modes() but would increase the needed time to compute just to display a number.

    Parameters
    -

    lo (float) – Wavelength of the beam in vaccum (µm).

    +
      +
    • width (float) – Guide width defined as the diameter (µm) at 1/e^2 intensity.

    • +
    • lo (float) – Wavelength of the beam in vaccum (µm).

    • +
    Returns

    m – Number of the last possible mode for a squared guide.

    @@ -342,7 +344,7 @@

    beampy.bpm
    -create_curved_guides(shape, curve, half_delay, distance_factor, offset_guide=0)
    +create_curved_guides(shape, width, delta_no, curve, half_delay, distance_factor, offset_guide=0)

    Create two curved guides and one linear guide on the center (STIRAP).

    The central positions over x and z are defined as follow:

    Left guide: \(x_0-p_{min}-curve(z-length\_z/2-half\_delay)^2\)

    @@ -352,6 +354,8 @@

    beampy.bpmParameters

    -create_guides(shape, nbr_p, p, offset_guide=0)
    +create_guides(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.

    @@ -388,6 +392,7 @@

    beampy.bpmsquared_guide(), 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) – Distance between two guides center (µm).

  • offset_guide (float, optional) – Guide offset from the center (µm). 0 by default.

  • @@ -403,7 +408,7 @@

    beampy.bpmNotes

    This methods uses the following variables defined in Bpm: -nbr_z, nbr_x, x, dist_x, delta_no.

    +nbr_z, nbr_x, x, dist_x.

    @@ -433,7 +438,7 @@

    beampy.bpm
    -gauss_guide(gauss_pow)
    +gauss_guide(width, gauss_pow=1)

    A lambda function than return a centered super-Gaussian shape.

    \(e^{-(x/w)^{2P}}\)

    The waist is defined as width/2 and correspond to the 1/e @@ -441,15 +446,17 @@

    beampy.bpmexample_guides_x() for more details.

    Parameters
    -

    gauss_pow (int) – Index of the super-gaussian guide with 1 being a regural gaussian +

      +
    • 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

      +#Higher-order_Gaussian_or_super-Gaussian_function. +1 by Default.

    • +
    -

    Notes

    -

    This methods uses the width variable defined in Bpm.

    @@ -479,7 +486,7 @@

    beampy.bpm
    -guide_position(guide, size)
    +guide_position(peaks, guide, size)

    Return the left and right position index over x of a given guide for each z.

    @@ -504,7 +511,7 @@

    beampy.bpm
    -init_field(field, theta_ext, irrad, lo)
    +init_field(dn, field, theta_ext, irrad, lo)

    Initialize phase, field and power variables.

    Parameters
    @@ -540,7 +547,7 @@

    beampy.bpm
    -kerr_effect(chi3=1e-19, kerr_loop=1, variance_check=False, field_start=None, dn_start=None, phase_mat=None)
    +kerr_effect(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. See: https://optiwave.com/optibpm-manuals/bpm-non-linear-bpm-algorithm/

    @@ -575,7 +582,7 @@

    beampy.bpm
    -losses_position(guide_lost, width_lost)
    +losses_position(peaks, guide_lost, width_lost)

    Return the left and right position (x) index of a given area over z [x,z].

    @@ -601,7 +608,7 @@

    beampy.bpm
    -main_compute(chi3=1e-19, kerr=False, kerr_loop=1, variance_check=False, alpha=0, lost_beg=None, lost_end=None)
    +main_compute(dn, chi3=1e-19, kerr=False, kerr_loop=1, variance_check=False, alpha=0, lost_beg=None, lost_end=None)

    main method used to compute propagation.

    Parameters
    @@ -636,12 +643,16 @@

    beampy.bpm
    -mode_determ(mode)
    +mode_determ(width, delta_no, mode)

    Solve the transcendental equation tan=sqrt that give the modes allowed in a squared guide.

    Parameters
    -

    mode (int) – Number of the searched mode.

    +
      +
    • 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.

    • +
    Returns

    -mode_light(mode, lo, offset_light=0)
    +mode_light(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) – Wavelength of the beam in vaccum (µm).

    • offset_light (float, optional) – Light offset from center (µm). 0 by default.

    • @@ -684,7 +697,7 @@

      beampy.bpmNotes

      This methods uses the following variables defined in 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 Bpm: lo, ko.

    @@ -715,10 +728,15 @@

    beampy.bpm
    -squared_guide()
    +squared_guide(width)

    A lambda function than returns a centered rectangular shape.

    return 1 if \(x >= -width/2\) and \(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 Bpm.

    @@ -831,13 +849,8 @@

    beampy.user_interface
    -calculate_guide(topology='array')
    +calculate_guide()

    Initialized the Bpm class and creates the guides.

    -
    -
    Parameters
    -

    topology (str) – ‘array’ or ‘curved’.

    -
    -

    Notes

    Creats many variables, including :

    +
    +
    +find_guide_number(guide_number)
    +

    Return the waveguide group number for a given waveguide number.

    +
    +
    Parameters
    +

    guide_number (int) – Number of a waveguide

    +
    +
    Returns
    +

    guide_group_number – Number of the waveguide group

    +
    +
    Return type
    +

    int

    +
    +
    +
    +
    get_compute()
    @@ -918,18 +948,18 @@

    beampy.user_interface

    Set the saved values of the light variables on the interface.

    -
    -
    -on_click_array()
    -

    Compute and displayed a guide array.

    -
    -
    on_click_compute()

    Compute the propagation using the guide and light informations.

    +
    +
    +on_click_create_guide()
    +

    Create a new guide with the displayed variables.

    +
    +
    on_click_create_light()
    @@ -937,9 +967,9 @@

    beampy.user_interface

    -
    -on_click_curved()
    -

    Compute and displayed curved guides.

    +
    +on_click_delete_guide()
    +

    Delete the current displayed guide and displayed the next one.

    @@ -948,6 +978,12 @@

    beampy.user_interface

    Delete the current displayed beam and displayed the next one.

    +
    +
    +on_click_guide()
    +

    Compute and displayed the waguides.

    +
    +
    on_click_light()
    @@ -1017,7 +1053,7 @@

    beampy.user_interface
    -save_guide()
    +save_guide(guide_selec=False)

    Save the interface variables into the guides variables.

    diff --git a/docs/html/codes.html b/docs/html/codes.html index 74639f8..ff94299 100644 --- a/docs/html/codes.html +++ b/docs/html/codes.html @@ -7,7 +7,7 @@ - Source codes — beampy 1.0 documentation + Source codes — beampy 1.1 documentation @@ -210,12 +210,8 @@ 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 @@ -228,7 +224,7 @@ 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): """ @@ -239,12 +235,8 @@ 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 @@ -256,19 +248,13 @@ 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. @@ -327,20 +313,25 @@ # 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. @@ -353,23 +344,22 @@ 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. @@ -380,6 +370,8 @@ :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 @@ -397,10 +389,10 @@ 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) @@ -413,14 +405,15 @@ 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). @@ -437,6 +430,10 @@ ---------- 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 @@ -462,7 +459,7 @@ 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) @@ -470,27 +467,27 @@ # 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 # @@ -551,8 +548,7 @@ 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 @@ -560,13 +556,17 @@ 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. @@ -587,16 +587,18 @@ 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 @@ -612,19 +614,23 @@ 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 @@ -646,7 +652,7 @@ 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. @@ -655,50 +661,52 @@ 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 @@ -729,7 +737,7 @@ 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) @@ -740,7 +748,7 @@ 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 @@ -748,6 +756,8 @@ Parameters ---------- + width : float + Guide width defined as the diameter (µm) at 1/e^2 intensity. lo : float Wavelength of the beam in vaccum (µm). @@ -764,7 +774,7 @@ 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) @@ -855,7 +865,7 @@ 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. @@ -934,7 +944,7 @@ 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 * ( @@ -945,7 +955,7 @@ 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. @@ -972,11 +982,11 @@ 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) @@ -991,7 +1001,7 @@ # 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 @@ -1039,7 +1049,7 @@ 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]. @@ -1069,11 +1079,11 @@ 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. @@ -1115,7 +1125,7 @@ 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 @@ -1213,27 +1223,25 @@ 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. @@ -1279,9 +1287,10 @@ 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, :]) @@ -1296,7 +1305,7 @@ # 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): """ @@ -1344,6 +1353,7 @@ 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) @@ -1374,25 +1384,26 @@ 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) @@ -1421,17 +1432,19 @@ # 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() @@ -1487,7 +1500,7 @@ 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 @@ -1504,6 +1517,7 @@ 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) @@ -1542,9 +1556,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 @@ -1597,7 +1612,6 @@ 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) @@ -1609,7 +1623,6 @@ 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) @@ -1632,7 +1645,6 @@ 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) @@ -1644,10 +1656,21 @@ 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) @@ -1664,22 +1687,45 @@ 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) @@ -1687,35 +1733,22 @@ 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("") @@ -1724,16 +1757,13 @@ 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() @@ -1756,16 +1786,9 @@ 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") @@ -1789,7 +1812,6 @@ 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) @@ -1800,23 +1822,21 @@ 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") @@ -1833,6 +1853,7 @@ 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) @@ -1847,7 +1868,6 @@ 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) @@ -1861,9 +1881,10 @@ 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) @@ -1872,6 +1893,7 @@ 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) @@ -1930,80 +1952,89 @@ 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") @@ -2062,13 +2093,12 @@ 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) @@ -2128,8 +2158,8 @@ 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)) @@ -2139,8 +2169,8 @@ 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)) @@ -2159,35 +2189,44 @@ 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) @@ -2245,7 +2284,18 @@ 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", "<html><head/><body><p><span style=\" font-size:14pt; font-weight:600;\">Guides information</span></p></body></html>")) + 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")) @@ -2254,9 +2304,6 @@ 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")) @@ -2273,8 +2320,6 @@ 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")) @@ -2288,11 +2333,9 @@ 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", "<html><head/><body><p><span style=\" font-size:14pt; font-weight:600;\">Light information</span></p></body></html>")) self.label_lo.setToolTip(_translate("MainWindow", " Wavelengh in µm")) @@ -2307,7 +2350,7 @@ 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")) @@ -2335,6 +2378,10 @@ 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")) @@ -2344,9 +2391,8 @@ 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")) @@ -2448,6 +2494,20 @@ 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 = [] @@ -2457,15 +2517,17 @@ 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 @@ -2497,20 +2559,24 @@ """ 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) @@ -2585,15 +2651,10 @@ 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 : @@ -2607,13 +2668,12 @@ :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) @@ -2636,61 +2696,69 @@ 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) @@ -2702,6 +2770,7 @@ 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) @@ -2740,7 +2809,7 @@ 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): @@ -2762,6 +2831,8 @@ 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( @@ -2773,16 +2844,18 @@ 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]: @@ -2796,7 +2869,7 @@ 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) @@ -2826,7 +2899,7 @@ 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 @@ -2841,6 +2914,7 @@ 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) @@ -2865,13 +2939,50 @@ 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): @@ -2896,19 +3007,18 @@ 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() @@ -2941,7 +3051,7 @@ 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)] @@ -2984,7 +3094,7 @@ 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)] @@ -3046,7 +3156,7 @@ # 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) @@ -3059,45 +3169,52 @@ 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) @@ -3106,7 +3223,7 @@ 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 @@ -3160,33 +3277,39 @@ 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): @@ -3198,24 +3321,38 @@ 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): """ @@ -3238,6 +3375,7 @@ 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] = ( @@ -3276,6 +3414,7 @@ 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]) @@ -3284,16 +3423,19 @@ 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 @@ -3335,31 +3477,15 @@ 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') @@ -3394,7 +3520,7 @@ 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() @@ -3408,6 +3534,43 @@ 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. @@ -3421,6 +3584,7 @@ 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() @@ -3430,6 +3594,7 @@ 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) @@ -3446,6 +3611,44 @@ 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): """ @@ -3459,6 +3662,7 @@ 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) @@ -3546,31 +3750,29 @@ 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]) @@ -3585,6 +3787,7 @@ 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) @@ -3602,29 +3805,27 @@ 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() @@ -3678,23 +3879,40 @@ 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') @@ -3727,6 +3945,9 @@ 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/contact.html b/docs/html/contact.html index 098d9b8..2ab929b 100644 --- a/docs/html/contact.html +++ b/docs/html/contact.html @@ -7,7 +7,7 @@ - Contact — beampy 1.0 documentation + Contact — beampy 1.1 documentation diff --git a/docs/html/examples.html b/docs/html/examples.html index 67e9a8b..12f1377 100644 --- a/docs/html/examples.html +++ b/docs/html/examples.html @@ -7,7 +7,7 @@ - Examples — beampy 1.0 documentation + Examples — beampy 1.1 documentation diff --git a/docs/html/genindex.html b/docs/html/genindex.html index d1d4844..46e4524 100644 --- a/docs/html/genindex.html +++ b/docs/html/genindex.html @@ -8,7 +8,7 @@ - Index — beampy 1.0 documentation + Index — beampy 1.1 documentation @@ -161,6 +161,7 @@

    Index

    | B | C | E + | F | G | I | K @@ -280,6 +281,14 @@

    E

+

F

+ + +
+

G

    @@ -352,18 +361,20 @@

    M

    O

    -

    Last edit: Nov 23, 2020 for the version 1.0

    +

    Last edit: Dec 03, 2020 for the version 1.1

    diff --git a/docs/html/interface.html b/docs/html/interface.html index 3728167..c79ca5d 100644 --- a/docs/html/interface.html +++ b/docs/html/interface.html @@ -7,7 +7,7 @@ - Interface — beampy 1.0 documentation + Interface — beampy 1.1 documentation diff --git a/docs/html/objects.inv b/docs/html/objects.inv index 6db1e040c429bc62518a7468b0bf90c916d506a3..b5224d69d5b999b9711a8394d2b1dc7f933047e9 100644 GIT binary patch delta 832 zcmV-G1Hb&C2dM{;c7IE5+b|G@_dbP+W^1F_W|<%h14$7y4YDLCYHSmsNQIBY&Z^hw z^?H)>p{EnuqRf>fYW{DAtIViUKQQR4*VU zg4GI0RG3UC1!_{9C8m5zwz)h*1!$0Ev@CiWD)A07e$v&e!Lmu}DZ=PL->{^ZlhMv# zYhM|lde2)KPJjFa9u(CAHP|7W#zT8#`@eCwl3=r1iVCmy+zwI47=A_B&LU?po#M9* zv^^K_F&W^N++?xRIH!#2-B<$UcEzl4ogw3nxK^`xqUheP*JsKL@jl|nJD^-h&=PaS z?Ed>i$K>iEkOFP0aR{UA5}wlip>XkJKbL*Xi7_}PUw`1Du=5lj{vL*4Mht6@!Gyfg zJJ3j8SoC=8DRG?I6&$Fbs$zI|K2vaR4?mO}tp!)-^FonP0yk%~RyOCu1S4+B9OT)= zHRzbL_arM#_Bm3Tyc4#xVALi_s!n#mUe%eLnz-`?Fi0P3O-&qY;vf@6R{^)RG=p>` z#Bq5(PJfmuP7j6OAlVA>uq0#ElG2Qo$E8Uxk4lqT9`$N$uAYzDh<5}^)6(rB_A#ZS zK0$F+jk^teB`yRxA--GQ-2QyL&6F;#ob~)NtDC${cE9|c-BAKuLG7q-+M{LH;cuwf z)Qq^xox937bB1$ZPT*SWLfE~|ok4d63ZnK}bAMFXTJ4qNfzj2LM=4(>>G29i5_x&Qy|}jkJ(^kYs10qB)e@!aShy7 zIItat(6k2QrF)%qW;L;A@eIuFWsqr6r^mlPe^qAfj4i^nuROoahU42pnnbQ$H6v*A z>p6?Ss@=T#QRi*APlOPAe^1CBc6NpGp<046Ob-UFZVH-T;bW!%OR^a{2yONJhW`(E K4YU8c#)B?EC8`Xark^ZaqmLL>g^f}nTD&ZJ{(KzN2t{M_g>tIVk^(DZR4*VU zg5?rOR5zJW3e=>2)|m1s+2-;Lm7qb^(X!}iXv90n_(@l<2Fos~rwF4v`i3RNoQw_z zYx~LowR_&uaDU<_@Svy_sKE}|84vA|eR~&fDZys76b-KS!VXc#7=A_BpGD4LI>m1r zXnii=V=}-kxyfRsaX}f?o3RAS?TT6AHbcf8alIygqUheP*JsL0@jl|nJD|)ZXo~%V{-KnNP#xZID}Dl2~YX`p)h~4pNn10i7_}P&wp`Q+Ifoa{vL*4MhxqZ!Gyfg zJJ3j8SoC=8DRG>-EjUm~Rm1S+e5T;s9)74WS_`hu=Y=Ap25!z~RiI-|%9E@#x#CD^ zvP9TIfKfZ8Sjq%b+2c};*%lZkHSu4E3OF6F1P1AQnF!Yax78_wbR@)aeLhasDfVN9 z-ym7qd4E`vvFb@_#>(T;Y$6_&Cbc~3)!1A;AGH$i2$ZI^TkiHTo}j~Mz#;#C4R7+5X>A|42rl9#1K4uEAB&%V7U~A_$v_IeqX8!?WNkaO! C=AsP% diff --git a/docs/html/py-modindex.html b/docs/html/py-modindex.html index 66869cb..7989444 100644 --- a/docs/html/py-modindex.html +++ b/docs/html/py-modindex.html @@ -7,7 +7,7 @@ - Python Module Index — beampy 1.0 documentation + Python Module Index — beampy 1.1 documentation diff --git a/docs/html/results.html b/docs/html/results.html index f2d83fe..cd08c9a 100644 --- a/docs/html/results.html +++ b/docs/html/results.html @@ -7,7 +7,7 @@ - Results — beampy 1.0 documentation + Results — beampy 1.1 documentation diff --git a/docs/html/search.html b/docs/html/search.html index ff03409..f382c35 100644 --- a/docs/html/search.html +++ b/docs/html/search.html @@ -7,7 +7,7 @@ - Search — beampy 1.0 documentation + Search — beampy 1.1 documentation diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js index c5cde5c..a44873e 100644 --- a/docs/html/searchindex.js +++ b/docs/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["LICENSE","beampy","codes","contact","examples","index","interface","results"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":2,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["LICENSE.rst","beampy.rst","codes.rst","contact.rst","examples.rst","index.rst","interface.rst","results.rst"],objects:{"beampy.bpm":{Bpm:[1,1,1,""],example_bpm:[1,3,1,""]},"beampy.bpm.Bpm":{absorption:[1,2,1,""],airy_light:[1,2,1,""],all_modes:[1,2,1,""],bpm_compute:[1,2,1,""],check_modes:[1,2,1,""],create_curved_guides:[1,2,1,""],create_guides:[1,2,1,""],create_x_z:[1,2,1,""],gauss_guide:[1,2,1,""],gauss_light:[1,2,1,""],guide_position:[1,2,1,""],init_field:[1,2,1,""],kerr_effect:[1,2,1,""],losses_position:[1,2,1,""],main_compute:[1,2,1,""],mode_determ:[1,2,1,""],mode_light:[1,2,1,""],power_guide:[1,2,1,""],squared_guide:[1,2,1,""],squared_light:[1,2,1,""],variance:[1,2,1,""]},"beampy.examples":{example_free_propag:[4,3,1,""],example_gaussian_beam:[4,3,1,""],example_guides_x:[4,3,1,""],example_guides_z:[4,3,1,""],example_kerr:[4,3,1,""],example_stability:[4,3,1,""]},"beampy.interface":{Ui_MainWindow:[1,1,1,""]},"beampy.interface.Ui_MainWindow":{retranslateUi:[1,2,1,""],setupUi:[1,2,1,""]},"beampy.user_interface":{UserInterface:[1,1,1,""],open_app:[1,3,1,""],open_doc:[1,3,1,""]},"beampy.user_interface.UserInterface":{addmpl:[1,2,1,""],calculate_guide:[1,2,1,""],calculate_light:[1,2,1,""],calculate_propagation:[1,2,1,""],check_modes_display:[1,2,1,""],connect_buttons:[1,2,1,""],create_menu:[1,2,1,""],get_compute:[1,2,1,""],get_guide:[1,2,1,""],get_light:[1,2,1,""],on_click_array:[1,2,1,""],on_click_compute:[1,2,1,""],on_click_create_light:[1,2,1,""],on_click_curved:[1,2,1,""],on_click_delete_light:[1,2,1,""],on_click_light:[1,2,1,""],open_file:[1,2,1,""],open_file_name:[1,2,1,""],rmmpl:[1,2,1,""],save_compute:[1,2,1,""],save_file:[1,2,1,""],save_file_name:[1,2,1,""],save_guide:[1,2,1,""],save_light:[1,2,1,""],save_quick:[1,2,1,""],show_estimate_time:[1,2,1,""]},beampy:{"interface":[1,0,0,"-"],bpm:[1,0,0,"-"],examples:[4,0,0,"-"],user_interface:[1,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function"},terms:{"05e17":2,"14pt":2,"1e13":2,"1e3":2,"1e7":2,"1f77b4":2,"20000e13":2,"2nd":[1,2,5],"5e6":2,"5e7":2,"85e17":2,"\u03b4n":2,"\u03b8":2,"\u03bb":2,"\u03bcm":2,"break":2,"case":2,"class":[1,2],"comt\u00e9":[1,2,5],"default":[1,2],"final":[1,2],"float":[1,2],"function":[1,2,5,6],"import":[2,5],"int":[1,2],"new":[1,2],"r\u00e9gi":[1,2,5],"return":[1,2,4],"super":[1,2,4],"true":2,"try":[1,2],"universit\u00e9":[1,2,5],"while":2,AND:0,And:3,BUT:0,FOR:0,For:[3,5],NOT:0,Not:2,THE:0,The:[0,1,2,3,5],Then:[1,2],USE:0,Use:2,Used:[1,2],WITH:0,__file__:2,__init__:2,__main__:2,__name__:2,_delai:[1,2],_show_plot:2,_translat:2,about:[2,3],abov:0,abs:2,absorpt:[1,2],academ:[1,2,5],access:5,account:[1,2],aco:2,act:2,action:[0,2],activ:[1,2],adaptivedecimalsteptyp:2,add:[1,2],add_patch:2,add_subplot:2,addact:2,addfil:2,additem:2,addlayout:2,addmenu:2,addmpl:[1,2],addtab:2,addwidget:2,adiabat:[1,2,5],after:[1,2],again:2,ai_zero:2,air:2,airi:[1,2,7],airy_check:2,airy_light:[1,2],airy_zero:[1,2],ajust:[1,2],alert:[1,2],algorithm:[1,2],all:[0,1,2],all_mod:[1,2],all_modes_check:2,allow:[1,2,5],alpha:[1,2],alreadi:[1,2],also:[1,2],amplitud:[1,2],angl:[1,2],ani:[0,1,2,3],app:[1,2],append:2,applic:2,approxim:[1,2,4],area:[1,2],argument:[1,2],argv:2,aris:0,arrai:[1,2,4,6,7],articl:2,asin:2,ask:[1,2],assert:2,assign:2,associ:0,assum:2,astyp:2,author:0,avail:2,avoid:2,ax1:2,ax2:2,axes:2,axi:2,b_b:2,backend:2,backend_qt4agg:2,base:[1,2,5],beam1:2,beam2:2,beam3:2,beam:[1,2,4,5,6,7],beam_selec:[1,2],beampi:[3,4,7],becaus:2,befor:2,begin:2,being:[1,2],bellow:5,best:2,beta:[1,2],beta_m:[1,2],better:[1,2],between:[1,2,5],bewteen:[1,2],big:2,bigger:2,blog:2,bodi:2,bool:[1,2],bounderi:2,box:2,bpm:[4,5],bpm_comput:[1,2],broadband:[1,2,5],build:2,burlington:[1,2,5],button:[1,2],c_c:2,calcul:[1,2],calculate_guid:[1,2],calculate_guide_don:2,calculate_light:[1,2],calculate_propag:[1,2],calculatebutton_arrai:2,calculatebutton_comput:2,calculatebutton_curv:2,calculatebutton_light:2,call:[1,2],can:[1,2,5],cancel:2,canvas_5:2,canvas_compute_end:2,canvas_compute_propag:2,canvas_guide_in:2,canvas_guide_prop:2,canvas_light:2,care:2,ceil:2,center:[1,2],center_airi:2,central:[1,2],centralwidget:2,chang:[1,2],charact:2,charg:0,check:[1,2],check_mod:[1,2],check_modes_displai:[1,2],checkbox_check_pow:2,checkbox_kerr:2,checkbox_lost:2,checkbox_offset_light:2,checkbox_vari:2,chi3:[1,2],choic:[2,5],choos:2,choosen:[1,2],clad:[1,2],claim:0,clean:2,clear:2,click:2,close:2,closest:[1,2],cmap:2,code:[1,4,5],coeffici:[1,2],colormesh:2,com:[1,2,3,5],combobox_light:2,command:5,comparison:2,compil:[1,2,5],complex:2,comput:[1,2,5],condit:[0,2],condition_even_guid:2,confirm:[2,4],conjug:2,connect:[0,1,2],connect_button:[1,2],connectslotsbynam:2,constant:[1,2],contact:5,contain:[1,2,7],continu:[1,2],contract:0,control:[1,2,5],conventionn:[1,2],converg:[1,2],convert:[1,2],coordin:2,copi:0,copyright:0,core:[1,2],correct:[1,2,4],correcttonearestvalu:2,correspond:[1,2],cos:2,could:[1,2],count:2,cours:[1,2,5],crash:2,creat:[1,2],create_curved_guid:[1,2],create_guid:[1,2],create_menu:[1,2],create_x_z:[1,2],critic:2,cross:2,ctrl:2,cur_1:2,cur_2:2,cur_3:2,cur_pow:[1,2],cur_ref:2,current:[1,2],current_pow:[1,2],currentindex:2,curv:[1,2,4,6,7],curvatur:[1,2],cut:[1,2],damag:0,dan:[1,2,5],data:2,deal:0,debut:2,deconvolv:[1,2],def:2,defaultsteptyp:2,defin:[1,2],definit:[2,4],delai:2,delet:[1,2],delta_n:2,delta_no:[1,2],describ:[1,2,5],desgin:5,design:2,detail:[1,2,5],develop:[1,2,3,5],deviat:[1,2],dialog:[1,2],diamet:[1,2],dico:2,dictionari:2,differ:[1,2,4],direclti:5,direct:[1,2,5],directli:[1,2],displai:[1,2,4,5],dist_x:[1,2],dist_z:[1,2],distanc:[1,2],distance_factor:[1,2],distribut:0,divis:2,dn1:2,dn2:2,dn_1:2,dn_2:2,dn_3:2,dn_disp:2,dn_fix:2,dn_ref:2,dn_start:[1,2],dn_z:2,doc:[2,5],document:[0,1,2],doe:2,don:[1,2],done:[1,2,5],dontusenativedialog:2,doublespinbox_chi3:2,doublespinbox_curv:2,doublespinbox_dist_x:2,doublespinbox_dist_z:2,doublespinbox_distance_factor:2,doublespinbox_dn:2,doublespinbox_fwhm:2,doublespinbox_half_delai:2,doublespinbox_intensity_light:2,doublespinbox_length_x:2,doublespinbox_length_z:2,doublespinbox_lo:2,doublespinbox_lobe_s:2,doublespinbox_lost:2,doublespinbox_n:2,doublespinbox_offset_guid:2,doublespinbox_offset_light:2,doublespinbox_p:2,doublespinbox_theta_ext:2,doublespinbox_width:2,doublespinbox_width_lost:2,doubt:2,download:5,drasticli:2,dtype:2,due:[1,2],dure:[1,2,5],each:[1,2],edg:2,edgecolor:2,edit:[1,2,5],effect:[1,2,4],electr:[1,2],elif:2,elimin:[1,2,5],els:[1,2],empti:2,end:2,enough:2,enought:[1,2],enumer:2,environ:5,epnc:[1,2],equal:[1,2],equat:[1,2],error:2,estim:[1,2],estimate_time_displai:2,eta:2,even:[2,5],event:0,everi:2,exampl:5,example_bpm:[1,2],example_free_propag:[2,4],example_gaussian_beam:[2,4],example_guides_x:[1,2,4],example_guides_z:[2,4],example_kerr:[2,4],example_st:[2,4],exce:[1,2],except:[1,2],exec_:2,execpt:2,execut:2,exist:[1,2],exit:[1,2],exp:2,expand:2,experiment:[1,2],explain:[5,6],explan:5,express:0,ext:2,exterior:[1,2],extern:[1,2],extinct:[1,2],extrem:4,facecolor:2,factor:[1,2],fals:[1,2],fast:[1,2],featur:2,femto:[1,2,5],fft:2,fftshift:2,field:[1,2,4],field_1:2,field_2:2,field_3:2,field_i:2,field_ref:2,field_start:[1,2],field_x:[1,2],fieldrol:2,fig:2,figur:2,figurecanva:2,figurecanvasqtagg:2,file2:2,file:[0,1,2,5],filenam:[1,2],fill:2,fin:2,finish:2,finish_sum:2,first:[1,2,3],first_zero:2,fit:0,flat:[1,2,4],flux:2,folder2:2,folder:[2,5],follow:[0,1,2],font:2,form:2,formlayout:2,formlayout_10:2,formlayout_2:2,formlayout_5:2,formlayout_6:2,formlayout_8:2,formlayout_9:2,formlayout_estim:2,formlayout_lo_theta:2,found:[2,5],fourier:[1,2],frame_beam:2,frame_file_data:2,frame_guid:2,frame_kerr:2,frame_light:2,frame_lost:2,frame_window:2,franch:[1,2,5],free:[0,1,2,4],free_propag:[1,2],frequenc:2,fressengea:[1,2,5],from:[0,1,2,4,5,7],full:[1,2],func:2,fundament:[1,2,5],furnish:0,further:2,fwhm2:2,fwhm:[1,2,4],fwhm_final:2,gamma:[1,2],gamma_m:[1,2],gauss:[1,2],gauss_guid:[1,2],gauss_light:[1,2],gauss_pow:[1,2],gaussian:[1,2,4],gaussian_beam:2,gaussian_check:2,gaussian_funct:[1,2],gaussien:[1,2],gener:[1,2,5],get:[1,2],get_comput:[1,2],get_guid:[1,2],get_light:[1,2],get_yticklabel:2,getopenfilenam:2,getsavefilenam:2,github:[3,5],give:[1,2],given:[1,2],good:2,grai:2,grant:0,graph:2,graphic:2,grasser:[1,2,5],grid:2,gridlayout:2,gridlayout_creat_delete_beam:2,gui:2,guid:[1,2,4,5,6,7],guide_lost:[1,2],guide_posit:[1,2],guide_x:2,guide_z_arrai:2,guide_z_curv:2,h_m:[1,2],half:[1,2],half_delai:[1,2],happen:2,has:[1,2],have:[2,5],head:2,help:2,herebi:0,high:2,higher:[1,2],his:[1,2,5],holder:0,horizontallayout:2,horizontallayout_2:2,horizontallayout_4:2,how:2,html:[1,2],http:[1,2,3,5],i_min:2,icon:2,ident:2,ifft:2,illustr:[2,4],imag:[2,4],impact:2,imped:2,implement:[1,2,4],impli:0,inclinaison:[1,2],includ:[0,1,2],increas:[1,2],index:[1,2,4,5],indexerror:2,indexof:2,indic:[1,2],influenc:2,info:2,inform:[1,2,5],init_field:[1,2],initi:[1,2],initiali:[1,2,5],inject:2,input:[1,2],insid:[1,2],instead:2,institut:[1,2,5],intens:[1,2],interfac:[3,5],interm:2,interv:[1,2],irrad:[1,2],irradi:[1,2],ischeck:2,isfil:2,issu:2,item:2,jonathan:[0,1,2,3,5],jonathanp57:3,just:[1,2],kei:2,kerr:[1,2,4,5],kerr_check:2,kerr_effect:[1,2],kerr_loop:[1,2],keyerror:2,kind:0,label:2,label_chi3:2,label_correction_loop:2,label_curv:2,label_dist_x:2,label_dist_z:2,label_distance_factor:2,label_dn:2,label_fwhm:2,label_guide_lost:2,label_guides_inform:2,label_half_delai:2,label_intens:2,label_kerr_inform:2,label_length:2,label_length_x:2,label_light_inform:2,label_lo:2,label_lobe_s:2,label_lost:2,label_lost_inform:2,label_n:2,label_nb_p:2,label_nbr_z_disp:2,label_offset_guid:2,label_offset_light:2,label_p:2,label_theta_ext:2,label_width:2,label_width_lost:2,label_window_paramet:2,label_zero_cut:2,labelrol:2,laboratori:[1,2,5],lambda:[1,2],last:[1,2,5],last_zero:2,last_zero_po:2,later:[1,2,5],launch:5,left:[1,2],legend:2,len:2,leng_max:2,length:[1,2],length_x:[1,2],length_z:[1,2],lhs:2,liabil:0,liabl:0,licens:5,light:[1,2,5],like:[1,2],lim:2,limit:0,line:2,linear:[1,2],linemark:2,linestyl:2,link:2,linspac:2,list:[1,2,4],lmop:[1,2,5],lobe:[1,2],lobe_s:[1,2],loc:2,local:[1,2],locali:2,locat:2,log:[1,2],logo:2,longitudin:[1,2],loop:[1,2],loos:[1,2],lorrain:[1,2,5],loss:2,losses_posit:[1,2],lost:2,lost_beg:[1,2],lost_check:2,lost_end:[1,2],low:[1,2],lumer:2,made:[2,5],main:[1,2],main_comput:[1,2],mainli:[1,2,3,5],mainwindow:[1,2],make:[2,5],mani:[1,2],manual:[1,2],manuali:2,marcel:[0,1,2,3,5],marcelrsoub:3,massif:[1,2,5],master:[1,2,5],match:2,materi:2,math:2,mathematical_form:2,matlab:[1,2,5],matplotlib:[2,5],matrix:2,max:2,maximum:[1,2],menu:[1,2],menubar:2,merchant:0,merg:[0,1,2],meshgrid:2,messag:2,meth:[1,2],method:[1,2,5],methood:[1,2],middl:2,milieu:[1,2,5],min:[1,2],minim:[1,2],minimum:[1,2],miss:2,mit:5,mod:2,mode:[1,2],mode_check:2,mode_determ:[1,2],mode_light:[1,2],mode_max:2,mode_numb:2,modifi:[0,1,2,5],modul:[2,3,4,5],more:[1,2,4,5],mu_0:2,multipl:2,must:2,myapp:2,name:[1,2],navigationtoolbar2qt:2,navigationtoolbar:2,nbr:2,nbr_light:2,nbr_lost:[1,2],nbr_p:[1,2],nbr_p_max:2,nbr_point:2,nbr_step:2,nbr_x:[1,2],nbr_z:[1,2],nbr_z_disp:[1,2],necessari:2,need:[1,2],next:[1,2],nicola:[1,2,5],nl_control_amp:2,nl_mat:[1,2],nofram:2,non:[1,2,5],none:[1,2],noninfring:0,normal:2,note:[1,2],notic:0,nov:[1,5],nu_max:2,num:2,number:[1,2],numpi:[2,5],object:[1,2],obsolet:2,obtain:0,occur:[1,2],odd:2,offset:[1,2],offset_check:2,offset_guid:[1,2],offset_light:[1,2],offset_light_peak:2,okamoto:[1,2,5],on_click_arrai:[1,2],on_click_comput:[1,2],on_click_create_light:[1,2],on_click_curv:[1,2],on_click_delete_light:[1,2],on_click_light:[1,2],onc:2,one:[1,2],onli:2,onlin:[1,2,5],onto:[1,2],open:[1,2,5],open_app:[1,2,5],open_doc:[1,2],open_fil:[1,2],open_file_nam:[1,2],optibpm:[1,2],optic:[1,2,5],optim:2,option:[1,2],optiwav:[1,2],order:2,order_gaussian_or_sup:[1,2],org:[1,2,5],other:[0,1,2],otherwis:[0,1,2],oukraou:[1,2,5],out:[0,2],outer:2,outlook:3,over:[1,2,4],overlaps:2,overwrit:2,p_max:2,p_min:[1,2],packag:5,page:[6,7],paip:[1,2,5],paramet:[1,2,5],paraxi:[1,2],part:[2,4],particular:0,pas:[1,2],patch:2,path:2,pcolormesh:2,peak:[1,2],peaks_i:2,peaks_max:2,peaks_z:2,peltier:[0,1,2,3,5],per:[1,2],perform:2,periodiqu:[1,2,5],permiss:0,permit:0,person:0,phase:[1,2],phase_mat:[1,2],phase_mat_demi:2,phd:[1,2,5],photon:[1,2,5],phy:[1,2,5],pip:5,pixel:2,pleas:3,plot:[1,2],plot_comput:2,plot_guid:2,plot_light:2,plt:2,png:2,point:[1,2],pointinghandcursor:2,poli:2,polygon:2,portion:0,pos_beg:2,pos_end:2,posi:2,posit:[1,2],positio:2,possibl:[1,2,4],pow:2,pow_index:[1,2],pow_index_guid:2,power:[1,2,4],power_check:2,power_guid:[1,2],precis:2,prepar:2,press:2,prev_pow:2,prevent:2,previou:2,previous:2,previous_beam:2,principl:[1,2],print:2,process_tim:2,profil:2,program:2,progress_pow:[1,2],project:[2,5],propag:[1,2,4,5],provid:0,publish:0,purpos:0,pushbutton_cancel_comput:2,pushbutton_cancel_guid:2,pushbutton_cancel_light:2,pushbutton_create_beam:2,pushbutton_delete_beam:2,pushbutton_estimate_tim:2,pushbutton_mode_numb:2,pushbutton_save_beam:2,pypi:5,pyplot:2,pyqt5:[1,2],pyqtslot:2,python:[2,3,5],pythonpath:5,pythonspot:[1,2],pyuic5:2,qabstractspinbox:2,qapplic:2,qcheckbox:2,qcombobox:2,qcoreappl:2,qcursor:2,qdoublespinbox:2,qfiledialog:2,qformlayout:2,qframe:2,qframe_beam_cr:2,qgridlayout:2,qhboxlayout:2,qicon:2,qlabel:2,qlcdnumber:2,qmainwindow:[1,2],qmetaobject:2,qpushbutton:2,qradiobutton:2,qsize:2,qsizepolici:2,qspaceritem:2,qspinbox:2,qstring:2,qt5:5,qtabwidget:2,qtcore:2,qtgui:2,qtwidget:[1,2],question:3,quick:[1,2],quit:2,qvboxlayout:2,qwidget:2,radian:2,radiant:2,radiobutton_airi:2,radiobutton_all_mod:2,radiobutton_gaussian:2,radiobutton_gaussian_light:2,radiobutton_mod:2,radiobutton_squar:2,radiobutton_squared_light:2,rais:[1,2],rang:2,rcnelson:2,reach:2,read:2,readthedoc:[2,5],real:[2,4],realist:[1,2],recent:2,rectangular:[1,2],reduc:2,reefract:[1,2],refer:2,refract:[1,2,4,5],regur:[1,2],rei:0,rel:[1,2],remain:2,remind:2,remov:[1,2],removewidget:2,replac:2,repositori:5,requir:5,reseaux:[1,2,5],resiz:2,resolut:[1,2],restoreoverridecursor:2,restrict:0,result:[1,2,5,6],retranslateui:[1,2],rev:[1,2,5],rhs:2,right:[0,1,2],rmmpl:[1,2],roll:2,round:2,run:2,runtimeerror:2,safeti:2,sai:2,same:2,sampl:2,save:[1,2],save_comput:[1,2],save_fil:[1,2],save_file_nam:[1,2],save_guid:[1,2],save_light:[1,2],save_quick:[1,2],scipi:[1,2],search:[1,2],see:[1,2,5],select:[1,2],self:[1,2],sell:0,set:[1,2,5,6],set_color:2,set_tight_layout:2,set_titl:2,set_xlabel:2,set_xlim:2,set_ylabel:2,set_ylim:2,setaccessibledescript:2,setautofillbackground:2,setbuddi:2,setcentralwidget:2,setcheck:2,setcorrectionmod:2,setcurrentindex:2,setcursor:2,setdecim:2,setdigitcount:2,setdis:2,setdisplayintegerbas:2,seten:2,setframeshadow:2,setframeshap:2,seticon:2,setitem:2,setmaximum:2,setmaximums:2,setminimum:2,setminimums:2,setmousetrack:2,setobjectnam:2,setopenexternallink:2,setoverridecursor:2,setprefix:2,setproperti:2,setsegmentstyl:2,setshortcut:2,setsinglestep:2,setstatustip:2,setsteptyp:2,setsuffix:2,settabord:2,settabtext:2,settext:2,settooltip:2,setupui:[1,2],setvalu:2,setwidget:2,setwindowicon:2,setwindowtitl:2,sever:[1,2],shall:0,shape:[1,2],shape_gauss_check:2,shape_squared_check:2,share:[1,2],shift:2,show:[2,4],show_estimate_tim:[1,2],simul:[1,2,3,5],sin:2,sin_theta_m:2,situat:2,size:[1,2],slow:2,small:[1,2],softwar:0,soliton:[1,2,5,6,7],solu:2,solv:[1,2],soubkovski:[1,2,3,5],sourc:[1,5],space:[1,2],spaceritem10:2,spaceritem11:2,spaceritem12:2,spaceritem13:2,spaceritem14:2,spaceritem1:2,spaceritem2:2,spaceritem3:2,spaceritem4:2,spaceritem5:2,spaceritem6:2,spaceritem7:2,spaceritem8:2,spaceritem9:2,spaceritem:2,spacial:2,span:2,spanningrol:2,spatiaux:[1,2,5],special:[1,2],speed:2,spinbox_airy_zero:2,spinbox_gauss_pow:2,spinbox_guide_lost:2,spinbox_kerr_loop:2,spinbox_mod:2,spinbox_nb_p:2,spinbox_nbr_z_disp:2,spinbox_offset_light_peak:2,split:2,spot_siz:2,spyder:2,sqrt:[1,2],squar:[1,2],square_check:2,squared_guid:[1,2],squared_light:[1,2],stai:2,standard:[1,2],start:2,step:[1,2],stirap:[1,2,6],str:[1,2],style:2,subject:0,sublicens:0,subplot:2,substanti:0,sum:[1,2],support:2,suppos:2,sure:[2,5],suscept:[1,2],sys:2,system:[2,4],t_compute_end:2,t_compute_start:2,t_guide_end:2,t_guide_start:2,t_light_end:2,t_light_start:2,t_power_end:2,t_power_start:2,tab:[1,2],tab_arrai:2,tab_curv:2,tab_index:2,tabwidget_comput:2,tabwidget_guid:2,tabwidget_light:2,tabwidget_main:2,tabwidget_morphology_guid:2,take:[1,2],tan:[1,2],temp:2,tensor:[1,2],term:[1,2],test:[1,2,4],test_1:2,test_2:2,test_3:2,test_4:2,test_5:2,test_6:2,test_7:2,text:2,than:[1,2,4],thank:2,thei:[1,2],them:[1,2],theori:2,thesi:[1,2,5],theta:2,theta_c:2,theta_ext:[1,2],theta_m:2,thi:[0,1,2,5,6,7],third:[1,2],those:2,three:5,through:2,time:[1,2],titl:2,too:2,toolbar_2:2,toolbar_3:2,toolbar_4:2,toolbar_5:2,toolbar_guide_in:2,toolbar_guide_prop:2,top:[1,2,4],topolog:[1,2],tort:0,touch:[1,2],transcendent:[1,2],translat:2,transport:[1,2,5],transvers:[1,2],trapz:2,trigger:2,tutorialspoint:2,twinx:2,two:[1,2,4],txt:[2,5],type:1,ui_mainwindow:[1,2],under:[1,2,5],understand:2,unit:[1,2],univers:[1,2,5],unknown:2,upper:2,use:[0,2],used:[1,2,5],useful:2,useless:2,user:[1,2,5],user_interfac:5,userinterfac:[1,2],uses:[1,2],using:[1,2,5],usual:2,utf:2,vaccum:[1,2],val:2,valu:[1,2,4],valueerror:[1,2],vari:5,variabl:[1,2],variable_nam:2,varianc:[1,2],variance_check:[1,2],variat:[1,2,4],vector:[1,2],version:[1,2,5],vert:2,verticallayout:2,verticallayout_comput:2,verticallayout_compute_plot:2,verticallayout_guid:2,verticallayout_light:2,w0_final:2,w_0:2,waist:[1,2,4],waitcursor:2,want:2,warn:2,warranti:0,wave:2,waveguid:[1,2,5],wavelengh:2,wavelenght:[1,2],wavelength:[1,2],webbrows:2,weight:2,were:[1,2],what:2,when:[1,2],where:[1,2],whether:0,which:2,whole:5,whom:0,width:[1,2,4],width_lost:[1,2],wiki:[1,2],wikipedia:[1,2],window:[1,2],witdh:2,within:[1,2],without:[0,1,2],won:2,word:[1,2],would:[1,2],write:2,www:2,x_0:[1,2],x_airi:2,x_beg:[1,2],x_end:[1,2],x_max:2,x_min:2,xlim:2,yes:2,ylim:2,you:2,z_disp:2,zero:[1,2],zero_po:2,zip:2},titles:["MIT License","Beampy modules","Source codes","Contact","Examples","Welcome to Beampy\u2019s documentation!","Interface","Results"],titleterms:{beampi:[1,2,5],bpm:[1,2],code:2,contact:3,document:5,exampl:[2,4],indic:5,instal:5,interfac:[1,2,6],licens:0,link:5,mit:0,modul:1,overview:5,refer:5,result:7,softwar:5,sourc:2,start:5,tabl:5,user_interfac:[1,2],welcom:5}}) \ No newline at end of file +Search.setIndex({docnames:["LICENSE","beampy","codes","contact","examples","index","interface","results"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":2,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,sphinx:56},filenames:["LICENSE.rst","beampy.rst","codes.rst","contact.rst","examples.rst","index.rst","interface.rst","results.rst"],objects:{"beampy.bpm":{Bpm:[1,1,1,""],example_bpm:[1,3,1,""]},"beampy.bpm.Bpm":{absorption:[1,2,1,""],airy_light:[1,2,1,""],all_modes:[1,2,1,""],bpm_compute:[1,2,1,""],check_modes:[1,2,1,""],create_curved_guides:[1,2,1,""],create_guides:[1,2,1,""],create_x_z:[1,2,1,""],gauss_guide:[1,2,1,""],gauss_light:[1,2,1,""],guide_position:[1,2,1,""],init_field:[1,2,1,""],kerr_effect:[1,2,1,""],losses_position:[1,2,1,""],main_compute:[1,2,1,""],mode_determ:[1,2,1,""],mode_light:[1,2,1,""],power_guide:[1,2,1,""],squared_guide:[1,2,1,""],squared_light:[1,2,1,""],variance:[1,2,1,""]},"beampy.examples":{example_free_propag:[4,3,1,""],example_gaussian_beam:[4,3,1,""],example_guides_x:[4,3,1,""],example_guides_z:[4,3,1,""],example_kerr:[4,3,1,""],example_stability:[4,3,1,""]},"beampy.interface":{Ui_MainWindow:[1,1,1,""]},"beampy.interface.Ui_MainWindow":{retranslateUi:[1,2,1,""],setupUi:[1,2,1,""]},"beampy.user_interface":{UserInterface:[1,1,1,""],open_app:[1,3,1,""],open_doc:[1,3,1,""]},"beampy.user_interface.UserInterface":{addmpl:[1,2,1,""],calculate_guide:[1,2,1,""],calculate_light:[1,2,1,""],calculate_propagation:[1,2,1,""],check_modes_display:[1,2,1,""],connect_buttons:[1,2,1,""],create_menu:[1,2,1,""],find_guide_number:[1,2,1,""],get_compute:[1,2,1,""],get_guide:[1,2,1,""],get_light:[1,2,1,""],on_click_compute:[1,2,1,""],on_click_create_guide:[1,2,1,""],on_click_create_light:[1,2,1,""],on_click_delete_guide:[1,2,1,""],on_click_delete_light:[1,2,1,""],on_click_guide:[1,2,1,""],on_click_light:[1,2,1,""],open_file:[1,2,1,""],open_file_name:[1,2,1,""],rmmpl:[1,2,1,""],save_compute:[1,2,1,""],save_file:[1,2,1,""],save_file_name:[1,2,1,""],save_guide:[1,2,1,""],save_light:[1,2,1,""],save_quick:[1,2,1,""],show_estimate_time:[1,2,1,""]},beampy:{"interface":[1,0,0,"-"],bpm:[1,0,0,"-"],examples:[4,0,0,"-"],user_interface:[1,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:function"},terms:{"05e17":2,"14pt":2,"1e13":2,"1e3":2,"1e7":2,"1f77b4":2,"20000e13":2,"2nd":[1,2,5],"5e6":2,"5e7":2,"85e17":2,"\u03b4n":2,"\u03b8":2,"\u03bb":2,"\u03bcm":2,"break":2,"case":2,"class":[1,2],"comt\u00e9":[1,2,5],"default":[1,2],"final":[1,2],"float":[1,2],"function":[1,2,5,6],"import":[2,5],"int":[1,2],"new":[1,2],"r\u00e9gi":[1,2,5],"return":[1,2,4],"super":[1,2,4],"true":2,"try":[1,2],"universit\u00e9":[1,2,5],"while":2,AND:0,And:3,BUT:0,FOR:0,For:[3,5],NOT:0,Not:2,THE:0,The:[0,1,2,3,5],Then:[1,2],USE:0,Use:2,Used:[1,2],WITH:0,__file__:2,__init__:2,__main__:2,__name__:2,_delai:[1,2],_show_plot:2,_translat:2,about:[2,3],abov:0,abs:2,absorpt:[1,2],academ:[1,2,5],access:5,account:[1,2],accur:2,aco:2,act:2,action:[0,2],activ:[1,2],adaptivedecimalsteptyp:[],add:[1,2],add_patch:2,add_subplot:2,addact:2,addfil:2,additem:2,addlayout:2,addmenu:2,addmpl:[1,2],addtab:2,addwidget:2,adiabat:[1,2,5],after:[1,2],again:2,ai_zero:2,air:2,airi:[1,2,7],airy_check:2,airy_light:[1,2],airy_zero:[1,2],ajust:[1,2],alert:[1,2],algorithm:[1,2],all:[0,1,2],all_mod:[1,2],all_modes_check:2,allow:[1,2,5],alpha:[1,2],alreadi:[1,2],also:[1,2],amplitud:[1,2],angl:[1,2],ani:[0,1,2,3],app:[1,2],append:2,applic:2,approxim:[1,2,4],area:[1,2],argument:[1,2],argv:2,aris:0,arrai:[1,2,4,6,7],articl:2,asin:2,ask:[1,2],assert:2,assign:2,associ:0,assum:2,astyp:2,author:0,avail:2,avoid:2,ax1:2,ax2:2,axes:2,axi:2,b_b:2,backend:2,backend_qt4agg:2,background:2,base:[1,2,5],beam1:2,beam2:2,beam3:2,beam:[1,2,4,5,6,7],beam_selec:[1,2],beampi:[3,4,7],becaus:2,befor:2,begin:2,being:[1,2],bellow:5,best:2,beta:[1,2],beta_m:[1,2],better:[1,2],between:[1,2,5],bewteen:[1,2],big:2,bigger:2,blog:2,bodi:2,bool:[1,2],bounderi:2,box:2,bpm:[4,5],bpm_comput:[1,2],broadband:[1,2,5],build:2,burlington:[1,2,5],button:[1,2],c_c:2,calcul:[1,2],calculate_guid:[1,2],calculate_guide_don:2,calculate_light:[1,2],calculate_propag:[1,2],calculatebutton_arrai:[],calculatebutton_comput:2,calculatebutton_curv:[],calculatebutton_guid:2,calculatebutton_light:2,call:[1,2],can:[1,2,5],cancel:2,canvas_5:2,canvas_compute_end:2,canvas_compute_propag:2,canvas_guide_in:2,canvas_guide_prop:2,canvas_light:2,care:2,ceil:2,center:[1,2],center_airi:2,central:[1,2],centralwidget:2,chang:[1,2],charact:2,charg:0,check:[1,2],check_mod:[1,2],check_modes_displai:[1,2],checkbox_check_pow:2,checkbox_kerr:2,checkbox_lost:2,checkbox_offset_light:2,checkbox_vari:2,chi3:[1,2],choic:[2,5],choos:2,choosen:[1,2],clad:[1,2],claim:0,clean:2,clear:2,click:2,close:2,closest:[1,2],cmap:2,code:[1,4,5],coeffici:[1,2],colormesh:2,com:[1,2,3,5],combobox_guid:2,combobox_light:2,command:5,comparison:2,compil:[1,2,5],complex:2,comput:[1,2,5],condit:[0,2],condition_even_guid:[],confirm:[2,4],conjug:2,connect:[0,1,2],connect_button:[1,2],connectslotsbynam:2,constant:[1,2],contact:5,contain:[1,2,7],continu:[1,2],contract:0,control:[1,2,5],conventionn:[1,2],converg:[1,2],convert:[1,2],coordin:2,copi:0,copyright:0,core:[1,2],correct:[1,2,4],correcttonearestvalu:2,correspond:[1,2],cos:2,could:[1,2],count:2,cours:[1,2,5],crash:2,creat:[1,2],create_curved_guid:[1,2],create_guid:[1,2],create_menu:[1,2],create_x_z:[1,2],critic:2,cross:2,ctrl:2,cur_1:2,cur_2:2,cur_3:2,cur_pow:[1,2],cur_ref:2,current:[1,2],current_pow:[1,2],currentindex:2,curv:[1,2,4,6,7],curvatur:[1,2],cut:[1,2],damag:0,dan:[1,2,5],data:2,deal:0,debut:2,dec:[1,5],deconvolv:[1,2],def:2,defaultsteptyp:[],defin:[1,2],definit:[2,4],delai:2,delet:[1,2],delta_n:2,delta_no:[1,2],describ:[1,2,5],desgin:5,design:2,detail:[1,2,5],develop:[1,2,3,5],deviat:[1,2],dialog:[1,2],diamet:[1,2],dico:2,dictionari:2,differ:[1,2,4],direclti:5,direct:[1,2,5],directli:[1,2],displai:[1,2,4,5],dist_x:[1,2],dist_z:[1,2],distanc:[1,2],distance_factor:[1,2],distribut:0,divis:2,dn1:2,dn2:2,dn_1:2,dn_2:2,dn_3:2,dn_disp:2,dn_fix:2,dn_ref:2,dn_start:[1,2],dn_z:2,doc:[2,5],document:[0,1,2],doe:2,doing:2,don:[1,2],done:[1,2,5],dontusenativedialog:2,doublespinbox_chi3:2,doublespinbox_curv:2,doublespinbox_dist_x:2,doublespinbox_dist_z:2,doublespinbox_distance_factor:2,doublespinbox_dn:2,doublespinbox_fwhm:2,doublespinbox_half_delai:2,doublespinbox_intensity_light:2,doublespinbox_length_x:2,doublespinbox_length_z:2,doublespinbox_lo:2,doublespinbox_lobe_s:2,doublespinbox_lost:2,doublespinbox_n:2,doublespinbox_offset_guid:2,doublespinbox_offset_light:2,doublespinbox_p:2,doublespinbox_theta_ext:2,doublespinbox_width:2,doublespinbox_width_lost:2,doubt:2,download:5,drasticli:2,dtype:2,due:[1,2],dure:[1,2,5],each:[1,2],edg:2,edgecolor:2,edit:[1,2,5],effect:[1,2,4],electr:[1,2],elif:2,elimin:[1,2,5],els:[1,2],empti:2,end:2,enough:2,enought:[1,2],enumer:2,environ:5,epnc:[1,2],equal:[1,2],equat:[1,2],error:2,estim:[1,2],estimate_time_displai:2,eta:2,evanescent:2,even:[2,5],event:0,everi:2,exampl:5,example_bpm:[1,2],example_free_propag:[2,4],example_gaussian_beam:[2,4],example_guides_x:[1,2,4],example_guides_z:[2,4],example_kerr:[2,4],example_st:[2,4],exce:[1,2],except:[1,2],exec_:2,execpt:2,execut:2,exist:[1,2],exit:[1,2],exp:2,expand:2,experiment:[1,2],explain:[5,6],explan:5,express:0,ext:2,exterior:[1,2],extern:[1,2],extinct:[1,2],extrem:4,facecolor:2,factor:[1,2],fals:[1,2],fast:[1,2],featur:2,femto:[1,2,5],fft:2,fftshift:2,field:[1,2,4],field_1:2,field_2:2,field_3:2,field_i:2,field_ref:2,field_start:[1,2],field_x:[1,2],fieldrol:2,fig:2,figur:2,figurecanva:2,figurecanvasqtagg:2,file2:2,file:[0,1,2,5],filenam:[1,2],fill:2,fin:2,find_guide_numb:[1,2],finish:2,finish_sum:2,first:[1,2,3],first_zero:2,fit:0,flat:[1,2,4],flux:2,folder2:2,folder:[2,5],follow:[0,1,2],font:2,form:2,formlayout:2,formlayout_10:2,formlayout_2:2,formlayout_5:2,formlayout_6:2,formlayout_8:2,formlayout_9:2,formlayout_estim:2,formlayout_lo_theta:2,found:[2,5],fourier:[1,2],frame_beam:2,frame_file_data:2,frame_guid:2,frame_kerr:2,frame_light:2,frame_lost:2,frame_window:2,franch:[1,2,5],free:[0,1,2,4],free_propag:[1,2],frequenc:2,fressengea:[1,2,5],from:[0,1,2,4,5,7],full:[1,2],func:2,fundament:[1,2,5],furnish:0,further:[],fwhm2:2,fwhm:[1,2,4],fwhm_final:2,gamma:[1,2],gamma_m:[1,2],gauss:[1,2],gauss_guid:[1,2],gauss_light:[1,2],gauss_pow:[1,2],gaussian:[1,2,4],gaussian_beam:2,gaussian_check:2,gaussian_funct:[1,2],gaussien:[1,2],gener:[1,2,5],get:[1,2],get_comput:[1,2],get_guid:[1,2],get_light:[1,2],get_yticklabel:2,getopenfilenam:2,getsavefilenam:2,github:[3,5],give:[1,2],given:[1,2],good:2,grai:2,grant:0,graph:2,graphic:2,grasser:[1,2,5],grid:2,gridlayout:2,gridlayout_2:2,gridlayout_creat_delete_beam:2,group:[1,2],gui:2,guid:[1,2,4,5,6,7],guide_group_numb:[1,2],guide_index:2,guide_lost:[1,2],guide_numb:[1,2],guide_posit:[1,2],guide_selec:[1,2],guide_x:2,guide_z_arrai:2,guide_z_curv:2,h_m:[1,2],half:[1,2],half_delai:[1,2],happen:2,has:[1,2],have:[2,5],head:2,help:2,herebi:0,high:2,higher:[1,2],his:[1,2,5],holder:0,horizontallayout:2,horizontallayout_2:2,horizontallayout_4:2,how:2,html:[1,2],http:[1,2,3,5],i_min:2,icon:2,ident:2,ifft:2,illustr:[2,4],imag:[2,4],impact:2,imped:2,implement:[1,2,4],impli:0,inclinaison:[1,2],includ:[0,1,2],increas:[1,2],index:[1,2,4,5],indexerror:2,indexof:2,indic:[1,2],influenc:2,info:2,inform:[1,2,5],init_field:[1,2],initi:[1,2],initiali:[1,2,5],inject:2,input:[1,2],insid:[1,2],instead:2,institut:[1,2,5],intens:[1,2],interfac:[3,5],interm:2,interv:[1,2],irrad:[1,2],irradi:[1,2],ischeck:2,isfil:2,issu:2,item:2,its:2,jonathan:[0,1,2,3,5],jonathanp57:3,just:[1,2],kei:2,kerr:[1,2,4,5],kerr_check:2,kerr_effect:[1,2],kerr_loop:[1,2],keyerror:2,kind:0,know:2,label:2,label_chi3:2,label_correction_loop:2,label_curv:2,label_dist_x:2,label_dist_z:2,label_distance_factor:2,label_dn:2,label_fwhm:2,label_guide_lost:2,label_guide_nbr_ref:2,label_guides_inform:2,label_half_delai:2,label_intens:2,label_kerr_inform:2,label_length:2,label_length_x:2,label_light_inform:2,label_lo:2,label_lobe_s:2,label_lost:2,label_lost_inform:2,label_n:2,label_nb_p:2,label_nbr_z_disp:2,label_offset_guid:2,label_offset_light:2,label_p:2,label_theta_ext:2,label_width:2,label_width_lost:2,label_window_paramet:2,label_zero_cut:2,labelrol:2,laboratori:[1,2,5],lambda:[1,2],last:[1,2,5],last_zero:2,last_zero_po:2,later:[1,2,5],launch:5,left:[1,2],legend:2,len:2,leng_max:[],length:[1,2],length_max:2,length_x:[1,2],length_z:[1,2],lhs:2,liabil:0,liabl:0,licens:5,light:[1,2,5],like:[1,2],lim:2,limit:0,line:2,linear:[1,2],linemark:2,linestyl:2,link:2,linspac:2,list:[1,2,4],lmop:[1,2,5],lobe:[1,2],lobe_s:[1,2],loc:2,local:[1,2],locali:2,locat:2,log:[1,2],logo:2,longitudin:[1,2],loop:[1,2],loos:[1,2],lorrain:[1,2,5],loss:2,losses_posit:[1,2],lost:2,lost_beg:[1,2],lost_check:2,lost_end:[1,2],low:[1,2],lumer:2,made:[2,5],mai:2,main:[1,2],main_comput:[1,2],mainli:[1,2,3,5],mainwindow:[1,2],make:[2,5],mani:[1,2],manual:[1,2],manuali:2,marcel:[0,1,2,3,5],marcelrsoub:3,massif:[1,2,5],master:[1,2,5],match:2,materi:2,math:2,mathematical_form:2,matlab:[1,2,5],matplotlib:[2,5],matrix:2,max:2,maximum:[1,2],menu:[1,2],menubar:2,merchant:0,merg:[0,1,2],meshgrid:2,messag:2,meth:[1,2],method:[1,2,5],methood:[1,2],middl:2,milieu:[1,2,5],min:[1,2],minim:[1,2],minimum:[1,2],miss:2,mit:5,mod:2,mode:[1,2],mode_check:2,mode_determ:[1,2],mode_guide_ref:2,mode_light:[1,2],mode_max:2,mode_numb:2,modifi:[0,1,2,5],modul:[2,3,4,5],more:[1,2,4,5],mu_0:2,multipl:2,must:2,myapp:2,name:[1,2],navigationtoolbar2qt:2,navigationtoolbar:2,nbr:2,nbr_guid:2,nbr_light:2,nbr_lost:[1,2],nbr_p:[1,2],nbr_p_max:2,nbr_point:2,nbr_step:2,nbr_x:[1,2],nbr_z:[1,2],nbr_z_disp:[1,2],necessari:2,need:[1,2],next:[1,2],nicola:[1,2,5],nl_control_amp:2,nl_mat:[1,2],nofram:2,non:[1,2,5],none:[1,2],noninfring:0,normal:2,note:[1,2],notic:0,nov:[],nu_max:2,num:2,num_gd:2,number:[1,2],numpi:[2,5],object:[1,2],obsolet:2,obtain:0,occur:[1,2],odd:2,offset:[1,2],offset_check:2,offset_guid:[1,2],offset_light:[1,2],offset_light_peak:2,okamoto:[1,2,5],on_click_arrai:[],on_click_comput:[1,2],on_click_create_guid:[1,2],on_click_create_light:[1,2],on_click_curv:[1,2],on_click_delete_guid:[1,2],on_click_delete_light:[1,2],on_click_guid:[1,2],on_click_light:[1,2],onc:2,one:[1,2],onli:2,onlin:[1,2,5],onto:[1,2],open:[1,2,5],open_app:[1,2,5],open_doc:[1,2],open_fil:[1,2],open_file_nam:[1,2],optibpm:[1,2],optic:[1,2,5],optim:2,option:[1,2],optiwav:[1,2],order:2,order_gaussian_or_sup:[1,2],org:[1,2,5],other:[0,1,2],otherwis:[0,1,2],oukraou:[1,2,5],out:[0,2],outer:2,outlook:3,over:[1,2,4],overlap:2,overlaps:2,overwrit:2,p_max:2,p_min:[1,2],packag:5,page:[6,7],paip:[1,2,5],paramet:[1,2,5],paraxi:[1,2],part:[2,4],particular:0,pas:[1,2],patch:2,path:2,pcolormesh:2,peak:[1,2],peaks_i:2,peaks_max:2,peaks_z:2,peltier:[0,1,2,3,5],per:[1,2],perform:2,periodiqu:[1,2,5],permiss:0,permit:0,person:0,phase:[1,2],phase_mat:[1,2],phase_mat_demi:2,phd:[1,2,5],photon:[1,2,5],phy:[1,2,5],pip:5,pixel:2,pleas:3,plot:[1,2],plot_comput:2,plot_guid:2,plot_light:2,plt:2,png:2,point:[1,2],pointinghandcursor:2,poli:2,polygon:2,portion:0,pos_beg:2,pos_end:2,posi:2,posit:[1,2],positio:2,possibl:[1,2,4],pow:2,pow_index:[1,2],pow_index_guid:2,power:[1,2,4],power_check:2,power_guid:[1,2],precis:2,prepar:2,press:2,prev_pow:2,prevent:2,previou:2,previous:2,previous_beam:2,previous_guid:2,principl:[1,2],print:2,process_tim:2,profil:2,program:2,progress_pow:[1,2],project:[2,5],propag:[1,2,4,5],propos:2,provid:0,publish:0,purpos:0,pushbutton_cancel_comput:2,pushbutton_cancel_guid:2,pushbutton_cancel_light:2,pushbutton_create_beam:2,pushbutton_create_guid:2,pushbutton_delete_beam:2,pushbutton_delete_guid:2,pushbutton_estimate_tim:2,pushbutton_mode_numb:2,pushbutton_save_beam:2,pushbutton_save_guid:2,pypi:5,pyplot:2,pyqt5:[1,2],pyqtslot:2,python:[2,3,5],pythonpath:5,pythonspot:[1,2],pyuic5:2,qabstractspinbox:2,qapplic:2,qcheckbox:2,qcombobox:2,qcoreappl:2,qcursor:2,qdoublespinbox:2,qfiledialog:2,qformlayout:2,qframe:2,qframe_beam_cr:2,qframe_guide_cr:2,qgridlayout:2,qhboxlayout:2,qicon:2,qlabel:2,qlcdnumber:2,qmainwindow:[1,2],qmetaobject:2,qpushbutton:2,qradiobutton:2,qsize:2,qsizepolici:2,qspaceritem:2,qspinbox:2,qstring:2,qt5:5,qtabwidget:2,qtcore:2,qtgui:2,qtwidget:[1,2],question:3,quick:[1,2],quit:2,qvboxlayout:2,qwidget:2,radian:2,radiant:2,radiobutton_airi:2,radiobutton_all_mod:2,radiobutton_gaussian:2,radiobutton_gaussian_light:2,radiobutton_mod:2,radiobutton_squar:2,radiobutton_squared_light:2,rais:[1,2],rang:2,rcnelson:2,reach:2,read:2,readthedoc:[2,5],real:[2,4],realist:[1,2],recent:2,rectangular:[1,2],reduc:2,reefract:[1,2],ref:2,refer:2,refract:[1,2,4,5],regur:[1,2],rei:0,rel:[1,2],remain:2,remind:2,remov:[1,2],removewidget:2,replac:2,repositori:5,requir:5,reseaux:[1,2,5],resiz:2,resolut:[1,2],restoreoverridecursor:2,restrict:0,result:[1,2,5,6],retranslateui:[1,2],rev:[1,2,5],rhs:2,right:[0,1,2],rmmpl:[1,2],roll:2,round:2,run:2,runtimeerror:2,safeti:2,sai:2,same:2,sampl:2,save:[1,2],save_comput:[1,2],save_fil:[1,2],save_file_nam:[1,2],save_guid:[1,2],save_light:[1,2],save_quick:[1,2],scipi:[1,2],search:[1,2],see:[1,2,5],select:[1,2],self:[1,2],sell:0,set:[1,2,5,6],set_color:2,set_tight_layout:2,set_titl:2,set_xlabel:2,set_xlim:2,set_ylabel:2,set_ylim:2,setaccessibledescript:2,setautofillbackground:2,setbuddi:2,setcentralwidget:2,setcheck:2,setcorrectionmod:2,setcurrentindex:2,setcursor:2,setdecim:2,setdigitcount:2,setdis:2,setdisplayintegerbas:2,seten:2,setframeshadow:2,setframeshap:2,seticon:2,setitem:2,setmaximum:2,setmaximums:2,setminimum:2,setminimums:2,setmousetrack:2,setobjectnam:2,setopenexternallink:2,setoverridecursor:2,setprefix:2,setproperti:2,setsegmentstyl:2,setshortcut:2,setsinglestep:2,setstatustip:2,setsteptyp:[],setsuffix:2,settabord:2,settabtext:2,settext:2,settooltip:2,settooltipdur:2,setupui:[1,2],setvalu:2,setwidget:2,setwindowicon:2,setwindowtitl:2,sever:[1,2],shall:0,shape:[1,2],shape_gauss_check:2,shape_squared_check:2,share:[1,2],shift:2,show:[2,4],show_estimate_tim:[1,2],simul:[1,2,3,5],sin:2,sin_theta_m:2,situat:2,size:[1,2],slow:2,small:[1,2],softwar:0,soliton:[1,2,5,6,7],solu:2,solv:[1,2],soubkovski:[1,2,3,5],sourc:[1,5],space:[1,2],spaceritem10:2,spaceritem11:2,spaceritem12:2,spaceritem13:2,spaceritem14:[],spaceritem1:2,spaceritem2:2,spaceritem3:2,spaceritem4:2,spaceritem5:2,spaceritem6:2,spaceritem7:2,spaceritem8:2,spaceritem9:2,spaceritem:2,spacial:2,span:2,spanningrol:2,spatiaux:[1,2,5],special:[1,2],speed:2,spinbox_airy_zero:2,spinbox_gauss_pow:2,spinbox_guide_lost:2,spinbox_guide_nbr_ref:2,spinbox_kerr_loop:2,spinbox_mod:2,spinbox_nb_p:2,spinbox_nbr_z_disp:2,spinbox_offset_light_peak:2,split:2,spot_siz:2,spyder:2,sqrt:[1,2],squar:[1,2],square_check:2,squared_guid:[1,2],squared_light:[1,2],stai:2,standard:[1,2],start:2,step:[1,2],stirap:[1,2,6],str:[1,2],style:2,styledpanel:2,subject:0,sublicens:0,subplot:2,substanti:0,sum:[1,2],support:2,suppos:2,sure:[2,5],suscept:[1,2],sys:2,system:[2,4],t_compute_end:2,t_compute_start:2,t_guide_end:2,t_guide_start:2,t_light_end:2,t_light_start:2,t_power_end:2,t_power_start:2,tab:[1,2],tab_arrai:2,tab_curv:2,tab_index:2,tabwidget_comput:2,tabwidget_guid:2,tabwidget_light:2,tabwidget_main:2,tabwidget_morphology_guid:2,take:[1,2],tan:[1,2],temp:2,tensor:[1,2],term:[1,2],test:[1,2,4],test_1:2,test_2:2,test_3:2,test_4:2,test_5:2,test_6:2,test_7:2,text:2,than:[1,2,4],thank:2,thei:[1,2],them:[1,2],theori:2,thesi:[1,2,5],theta:2,theta_c:2,theta_ext:[1,2],theta_m:2,thi:[0,1,2,5,6,7],third:[1,2],those:2,three:5,through:2,time:[1,2],titl:2,todo:2,toggl:2,too:2,toolbar_2:2,toolbar_3:2,toolbar_4:2,toolbar_5:2,toolbar_guide_in:2,toolbar_guide_prop:2,top:[1,2,4],topolog:2,tort:0,touch:[1,2],transcendent:[1,2],translat:2,transport:[1,2,5],transvers:[1,2],trapz:2,trigger:2,tutorialspoint:2,twinx:2,two:[1,2,4],txt:[2,5],type:1,ui_mainwindow:[1,2],under:[1,2,5],understand:2,unit:[1,2],univers:[1,2,5],unknown:2,unless:2,upper:2,use:[0,2],used:[1,2,5],useful:2,useless:2,user:[1,2,5],user_interfac:5,userinterfac:[1,2],uses:[1,2],using:[1,2,5],usual:2,utf:2,vaccum:[1,2],val:2,valu:[1,2,4],valueerror:[1,2],vari:5,variabl:[1,2],variable_nam:2,varianc:[1,2],variance_check:[1,2],variat:[1,2,4],vector:[1,2],version:[1,2,5],vert:2,verticallayout:2,verticallayout_comput:2,verticallayout_compute_plot:2,verticallayout_guid:2,verticallayout_light:2,w0_final:2,w_0:2,waguid:[1,2],waist:[1,2,4],waitcursor:2,want:2,warn:2,warranti:0,wave:2,waveguid:[1,2,5],wavelengh:2,wavelenght:[1,2],wavelength:[1,2],webbrows:2,weight:2,were:[1,2],what:2,when:[1,2],where:[1,2],whether:0,which:2,whole:5,whom:0,width:[1,2,4],width_lost:[1,2],wiki:[1,2],wikipedia:[1,2],window:[1,2],witdh:[],within:[1,2],without:[0,1,2],won:2,word:[1,2],would:[1,2],write:2,www:2,x_0:[1,2],x_airi:2,x_beg:[1,2],x_end:[1,2],x_max:2,x_min:2,xlim:2,yes:2,ylim:2,you:2,z_disp:2,zero:[1,2],zero_po:2,zip:2},titles:["MIT License","Beampy modules","Source codes","Contact","Examples","Welcome to Beampy\u2019s documentation!","Interface","Results"],titleterms:{beampi:[1,2,5],bpm:[1,2],code:2,contact:3,document:5,exampl:[2,4],indic:5,instal:5,interfac:[1,2,6],licens:0,link:5,mit:0,modul:1,overview:5,refer:5,result:7,softwar:5,sourc:2,start:5,tabl:5,user_interfac:[1,2],welcom:5}}) \ No newline at end of file