def __call__(self, domain: Domain, ports: List[int], fields: List[Field]) -> Tuple[List[int], List[Field]]: output_fields: List[Field] = [] gain_in_bw_lin = cmath.sqrt(util.db_to_linear(self.gain_in_bw)) gain_out_bw_lin = cmath.sqrt(util.db_to_linear(self.gain_out_bw)) for field in fields: # Pulse for i in range(len(field)): nu: np.ndarray = field.nu[i] - self.nu_offset nu_gains = np.where((nu > (self.center_nu + self.nu_bw)) | (nu < (self.center_nu - self.nu_bw)), gain_out_bw_lin, gain_in_bw_lin) nu_gains_shift = FFT.ifftshift(nu_gains) field[i] = FFT.ifft(nu_gains_shift * FFT.fft(field[i])) # Noise if (self.NOISE): gain_in_bw_lin_ = util.db_to_linear(self.gain_in_bw) gain_out_bw_lin_ = util.db_to_linear(self.gain_out_bw) nu_noise: np.ndarray = domain.noise_nu nu_gains_ = np.where((nu_noise > (self.center_nu + self.nu_bw)) | (nu_noise < (self.center_nu - self.nu_bw)), gain_out_bw_lin_, gain_in_bw_lin_) print(nu_gains_) field.noise *= nu_gains_ output_fields.append(field) return self.output_ports(ports), output_fields
def spectral_power(A, normalize=False): r""" Parameters ---------- A : Pulse field envelope. normalize : If True, normalize the power array. Returns ------- : The spectral power density of the pulse. :math:`[a.u.]` Notes ----- .. math:: P^\lambda(\lambda) = |\mathcal{F}\{A(t)\}|^2 """ if (isinstance(A, List)): res: List[np.ndarray] = [] for i in range(len(A)): res.append(Field.spectral_power(A[i], normalize)) return res else: P: np.ndarray = np.zeros(A.shape) if (A.ndim > 1): # multidimensional for i in range(A.shape[0]): P[i] = np.real(Field.sq_mod(FFT.fft(A[i]))) if (normalize): P[i] /= np.amax(P[i]) P[i] = FFT.ifftshift(P[i]) else: P = np.real(Field.sq_mod(FFT.fft(A))) # np.real to remove 0j if (normalize): P /= np.amax(P) P = FFT.ifftshift(P) return np.real(P) # np.real to remove 0j
def spectral_phase(A, unwrap=False): r""" Parameters ---------- A : Pulse field envelope. unwrap : If True, unwrap the phase array (see numpy.unwrap). Returns ------- : The spectral phase of the pulse. Notes ----- .. math:: \phi(\lambda) = Arg\big(\mathcal{F}\{A(t)\}\big) """ if (isinstance(A, List)): res: List[np.ndarray] = [] for i in range(len(A)): res.append(Field.spectral_phase(A[i], unwrap)) return res else: phase: np.ndarray = np.zeros(A.shape) if (A.ndim > 1): for i in range(A.shape[0]): phase[i] = np.angle(FFT.fft(A[i])) if (unwrap): phase[i] = np.unwrap(phase[i]) phase[i] = FFT.ifftshift(phase[i]) else: phase = np.angle(FFT.fft(A)) if (unwrap): phase = np.unwrap(phase[i]) phase = FFT.ifftshift(phase) return phase
def spectral_power(A, normalize=False): if (isinstance(A, List)): res = [] for i in range(len(A)): res.append(Field.spectral_power(A[i], normalize)) return res else: P = np.zeros(A.shape) if (A.ndim > 1): # multidimensional for i in range(A.shape[0]): P[i] = np.real(Field.sq_mod(FFT.fft(A[i]))) if (normalize): P[i] /= np.amax(P[i]) P[i] = FFT.ifftshift(P[i]) else: P = np.real(Field.sq_mod(FFT.fft(A))) # np.real to remove 0j if (normalize): P /= np.amax(P) P = FFT.ifftshift(P) return np.real(P) # np.real to remove 0j
def spectral_power(A: Array, normalize: bool = False): if (A is not None): if (A.ndim > 1): # multidimensional P = np.zeros(A.shape) for i in range(A.shape[0]): P[i] = np.real(Field.sq_mod(FFT.fft(A[i]))) if (normalize): P[i] /= np.amax(P[i]) P[i] = FFT.ifftshift(P[i]) else: P = np.real(Field.sq_mod(FFT.fft(A))) # np.real to remove 0j if (normalize): P /= np.amax(P) P = FFT.ifftshift(P) return np.real(P) # np.real to remove 0j else: util.warning_terminal( "Can not get spectral power of a " "nonexistent field, request ignored, return null field") return None
def set(self, waves: Array[cst.NPFT], h: float, z: float) -> None: self._step = int(round(z / h)) self._call_counter += 1 # Set parameters ----------------------------------------------- if (self._sigma_e_mccumber): omega = FFT.ifftshift( self._omega) # could also change in abstract equation for i in range(len(self._center_omega_s)): self._sigma_e_s[i] = McCumber.calc_cross_section_emission( self._sigma_a_s[i], omega, 0.0, self.N_0[self._step - 1], self.N_1[self._step - 1], self._T) for i in range(len(self._center_omega_p)): self._sigma_e_p[i] = McCumber.calc_cross_section_emission( self._sigma_a_p[i], omega, 0.0, self.N_0[self._step - 1], self.N_1[self._step - 1], self._T) # Add pump and signal power space step ------------------------- if (not self._iter): # first iteration to_add_s = np.zeros((1, ) + self._shape_step_s) to_add_p = np.zeros((1, ) + self._shape_step_p) self._power_s_f = np.vstack((self._power_s_f, to_add_s)) self._power_s_b = np.vstack((to_add_s, self._power_s_b)) self._power_p_f = np.vstack((self._power_p_f, to_add_p)) self._power_p_b = np.vstack((to_add_p, self._power_p_b)) self._power_ase_f = np.vstack((self._power_ase_f, to_add_s)) self._power_ase_b = np.vstack((to_add_s, self._power_ase_b)) if (self._coprop): # First iteration forward self._N_1 = np.hstack((self._N_1, [0.0])) else: # First iteration backward -> self._forward is False self._N_1 = np.hstack(([0.0], self._N_1)) self._step = 0 # construct backward array in bottom-up # Set signal power --------------------------------------------- # Truth table: # if coprop : iter |forward| to do # 0 | T | set pump # 1 | F | set pump # 2 | T | set pump & set signal # if counterprop: iter|forward| to do # 0 | T | set pump # 1 | F | set pump & set signal if (self._step_update): if (self._forward): if (self._signal_on): self._power_s_f[self._step - 1] = self._get_power_s(waves) self._power_p_f[self._step - 1] = self._get_power_p(waves) else: if (self._signal_on): self._power_s_b[self._step + 1] = self._get_power_s(waves) self._power_p_b[self._step + 1] = self._get_power_p(waves)
def __call__(self, domain: Domain, ports: List[int], fields: List[Field] ) -> Tuple[List[int], List[Field]]: output_fields: List[Field] = [] for field in fields: # Channels for i in range(len(field)): window = np.zeros(field[i].shape, dtype=complex) window = FlatTopFilter.amplitude_transfer_function(field.nu[i], self.center_nu, self.nu_bw, self.nu_offset) window_shift = FFT.ifftshift(window) field[i] = FFT.ifft(window_shift * FFT.fft(field[i])) # Noise if (self.NOISE): field.noise *= FlatTopFilter.transfer_function(domain.noise_nu, self.center_nu, self.nu_bw, self.nu_offset) output_fields.append(field) return self.output_ports(ports), output_fields