Пример #1
0
    def directional_response(self, theta, phi, polarization):
        """
        Generate the (complex) frequency-dependent directional response.

        For given angles and polarization direction, use the model of the
        directional and polarization gains of the antenna to generate a
        function for the interpolated response of the antenna with respect to
        frequency. Used with the `frequency_response` method to calculate
        effective heights.

        Parameters
        ----------
        theta : float
            Polar angle (radians) from which a signal is arriving.
        phi : float
            Azimuthal angle (radians) from which a signal is arriving.
        polarization : array_like
            Normalized polarization vector in the antenna coordinate system.

        Returns
        -------
        function
            A function which returns complex-valued voltage gains for given
            frequencies, using the values of incoming angle and polarization.

        See Also
        --------
        ARAAntenna.frequency_response : Calculate the (complex) frequency
                                        response of the antenna.

        """
        e_theta = [
            np.cos(theta) * np.cos(phi),
            np.cos(theta) * np.sin(phi), -np.sin(theta)
        ]
        e_phi = [-np.sin(phi), np.cos(phi), 0]
        theta_factor = np.dot(polarization, e_theta)
        phi_factor = np.dot(polarization, e_phi)
        theta_gains = complex_bilinear_interp(x=np.degrees(theta),
                                              y=np.degrees(phi),
                                              xp=self._response_zens,
                                              yp=self._response_azis,
                                              fp=self._theta_response,
                                              method='cartesian')
        phi_gains = complex_bilinear_interp(x=np.degrees(theta),
                                            y=np.degrees(phi),
                                            xp=self._response_zens,
                                            yp=self._response_azis,
                                            fp=self._phi_response,
                                            method='cartesian')
        freq_interpolator = lambda frequencies: complex_interp(
            x=frequencies,
            xp=self._response_freqs,
            fp=theta_factor * theta_gains + phi_factor * phi_gains,
            method='euler',
            outer=0)
        return freq_interpolator
 def test_euler_extrapolation(self):
     """Test euler complex extrapolation"""
     steps = np.arange(5)
     extrap_steps = [steps[0] - 1, steps[-1] + 1]
     gain = np.array([1, 2, 3, 2, 1])
     phase = np.radians([45, 90, 180, 90, 45])
     extrap = complex_interp(extrap_steps,
                             steps,
                             gain * np.exp(1j * phase),
                             method='euler',
                             outer=None)
     assert np.allclose(np.abs(extrap), [gain[0], gain[-1]])
     assert np.allclose(np.angle(extrap), [phase[0], phase[-1]])
     extrap2 = complex_interp(extrap_steps,
                              steps,
                              gain * np.exp(1j * phase),
                              method='euler',
                              outer=0)
     assert np.array_equal(extrap2, [0, 0])
 def test_cartesian_extrapolation(self):
     """Test cartesian complex extrapolation"""
     steps = np.arange(5)
     extrap_steps = [steps[0] - 1, steps[-1] + 1]
     real = np.array([1, 2, 3, 2, 1])
     imag = np.array([3, 2, 1, 2, 3])
     extrap = complex_interp(extrap_steps,
                             steps,
                             real + 1j * imag,
                             method='cartesian',
                             outer=None)
     assert np.array_equal(np.real(extrap), [real[0], real[-1]])
     assert np.array_equal(np.imag(extrap), [imag[0], imag[-1]])
     extrap2 = complex_interp(extrap_steps,
                              steps,
                              real + imag,
                              method='cartesian',
                              outer=0)
     assert np.array_equal(extrap2, [0, 0])
 def test_euler_phase_unwrapping(self):
     """Test phase unwrapping in euler complex interpolation"""
     steps = np.arange(5)
     interp_steps = steps[:-1] + 0.5
     gain = np.array([1, 2, 3, 2, 1])
     phase = np.radians([45, 90, 180, -90, -45])
     interp = complex_interp(interp_steps,
                             steps,
                             gain * np.exp(1j * phase),
                             method='euler')
     phase_interp = np.interp(interp_steps, steps, np.unwrap(phase))
     phase_interp = phase_interp % (2 * np.pi)
     phase_interp[phase_interp > np.pi] -= 2 * np.pi
     assert np.allclose(np.angle(interp), phase_interp)
 def test_euler_interpolation(self):
     """Test euler complex interpolation"""
     steps = np.arange(5)
     interp_steps = steps[:-1] + 0.5
     gain = np.array([1, 2, 3, 2, 1])
     phase = np.radians([45, 90, 180, 90, 45])
     interp = complex_interp(interp_steps,
                             steps,
                             gain * np.exp(1j * phase),
                             method='euler')
     gain_interp = np.interp(interp_steps, steps, gain)
     phase_interp = np.interp(interp_steps, steps, phase)
     assert np.allclose(np.abs(interp), gain_interp)
     assert np.array_equal(np.angle(interp), phase_interp)
 def test_cartesian_interpolation(self):
     """Test cartesian complex interpolation"""
     steps = np.arange(5)
     interp_steps = steps[:-1] + 0.5
     real = np.array([1, 2, 3, 2, 1])
     imag = np.array([3, 2, 1, 2, 3])
     interp = complex_interp(interp_steps,
                             steps,
                             real + 1j * imag,
                             method='cartesian')
     real_interp = np.interp(interp_steps, steps, real)
     imag_interp = np.interp(interp_steps, steps, imag)
     assert np.array_equal(np.real(interp), real_interp)
     assert np.array_equal(np.imag(interp), imag_interp)
Пример #7
0
    def interpolate_filter(self, frequencies):
        """
        Generate interpolated filter values for given frequencies.

        Calculate the interpolated values of the antenna's filter gain data
        for some frequencies.

        Parameters
        ----------
        frequencies : array_like
            1D array of frequencies (Hz) at which to calculate gains.

        Returns
        -------
        array_like
            Complex filter gain in voltage for the given `frequencies`.

        """
        return complex_interp(x=frequencies,
                              xp=self._filter_freqs,
                              fp=self._filter_response,
                              method='euler',
                              outer=0)