Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
 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)
Beispiel #7
0
    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