Example #1
0
def test_planar2():
    el_phase = 30.0
    az_phase = 40.0
    B = n.zeros([500, 500])
    els = n.linspace(0, 90, num=500)
    azs = n.linspace(0, 360, num=500)
    bp = alib.planar_beam(az_phase,
                          el_phase,
                          60,
                          19,
                          az1=0.0,
                          el1=90.0,
                          a0=16.0,
                          I_0=10**4.3,
                          f=230e6)
    for ei, e in enumerate(els):
        for ai, a in enumerate(azs):
            k = coord.azel_ecef(60.0, 19.0, 0.0, a, e)
            B[ei, ai] = bp.gain(k)
    dB = 10.0 * n.log10(B)
    m = n.max(dB)
    plt.pcolormesh(azs, els, 10.0 * n.log10(B), vmin=m - 20.0, vmax=m)
    plt.axhline(el_phase)
    plt.axvline(az_phase)
    plt.colorbar()
    plt.show()
Example #2
0
def plot_gain(beam, res=1000, min_el=0.0):
    '''Plot the gain of a beam patterns as a function of elevation at :math:`0^\circ` degrees azimuth.
    
    :param BeamPattern beam: Beam pattern to plot.
    :param int res: Number of points to devide the set elevation range into.
    :param float min_el: Minimum elevation in degrees, elevation range is from this number to :math:`90^\circ`.
    '''
    #turn on TeX interperter
    plt.rc('text', usetex=True)

    fig = plt.figure(figsize=(15, 7))
    ax = fig.add_subplot(111)

    theta = n.linspace(min_el, 90.0, num=res)

    S = n.zeros((res, ))
    for i, th in enumerate(theta):
        k = coord.azel_ecef(beam.lat, beam.lon, 0.0, 0, th)
        S[i] = beam.gain(k)

    ax.plot(theta, n.log10(S) * 10.0)
    bottom, top = plt.ylim()
    plt.ylim((0, top))
    ax.set_xlabel('Elevation [deg]', fontsize=24)
    ax.set_ylabel('Gain $G$ [dB]', fontsize=24)
    plt.xticks(fontsize=17)
    plt.yticks(fontsize=17)
    ax.set_title('Gain pattern ' + beam.beam_name,\
        fontsize=28)

    plt.show()
Example #3
0
def test_planar4():
    bp = alib.planar_beam(0.0,
                          45.0,
                          60,
                          10,
                          az1=0.0,
                          el1=90.0,
                          a0=40.0,
                          I_0=10**4.3,
                          f=230e6)
    for phased_el in n.linspace(3, 90, num=10):
        bp.point(0.0, phased_el)
        gains = []
        els = n.linspace(0.0, 90.0, num=1000)
        for ei, e in enumerate(els):
            k = coord.azel_ecef(60.0, 10.0, 0.0, 0.0, e)
            g = bp.gain(k)
            gains.append(g)
        gains = n.array(gains)
        plt.plot(els, 10.0 * n.log10(gains), label="el=%1.2f" % (phased_el))

        plt.ylim([0, 50])
        plt.axvline(phased_el, color="black")
    plt.legend()
    plt.xlabel("Elevation angle (deg)")
    plt.ylabel("Gain (dB)")
    plt.title("Planar array gain as a function of pointing direction")
    plt.show()
Example #4
0
def plot_beams():
    min_el = 80.0
    bp = alib.airy_beam(90.0, 90, 60, 19, f=930e6, I_0=10**4.3, a=16.0)
    gains = []
    els = n.linspace(min_el, 90.0, num=1000)
    for a in els:
        k = coord.azel_ecef(60.0, 19.0, 0.0, 90, a)
        gains.append(bp.gain(k))
    gains = n.array(gains)
    plt.plot(els, 10.0 * n.log10(gains), label="airy")

    bp = alib.cassegrain_beam(90.0,
                              90,
                              60,
                              19,
                              f=930e6,
                              I_0=10**4.3,
                              a0=16.0,
                              a1=4.58)
    gains = []
    for a in els:
        k = coord.azel_ecef(60.0, 19.0, 0.0, 90, a)
        gains.append(bp.gain(k))
    gains = n.array(gains)
    plt.plot(els, 10.0 * n.log10(gains), label="cassegrain")

    bp = alib.planar_beam(0,
                          90.0,
                          60,
                          19,
                          I_0=10**4.3,
                          f=233e6,
                          a0=40.0,
                          az1=0,
                          el1=90.0)
    gains = []
    for a in els:
        k = coord.azel_ecef(60.0, 19.0, 0.0, 90, a)
        gains.append(bp.gain(k))
    gains = n.array(gains)

    plt.plot(els, 10.0 * n.log10(gains), label="planar")
    plt.ylim([0, 50])

    plt.legend()
    plt.show()
Example #5
0
    def antenna_pointing(self, t):
        '''Returns the instantaneous WGS84 ECEF pointing direction and the radar geographical location in WGS84 ECEF coordinates.
        
            :param float t: Seconds past a reference epoch to retrieve the pointing at.
        '''
        p0 = coord.geodetic2ecef(self._lat, self._lon, self._alt)

        point = self._pointing(t)

        if self._pointing_coord == 'ned':
            k0 = coord.ned2ecef(self._lat, self._lon, self._alt, point[0],
                                point[1], point[2])
        elif self._pointing_coord == 'enu':
            k0 = coord.enu2ecef(self._lat, self._lon, self._alt, point[0],
                                point[1], point[2])
        elif self._pointing_coord == 'azel':
            k0 = coord.azel_ecef(self._lat, self._lon, self._alt, point[0],
                                 point[1])

        return p0, k0
Example #6
0
def get_angles(passes, o, radar, dt=0.1):
    '''Takes the passes structure that is output from :func:`simulate_tracking.get_passes`, the space object and the radar system and calculates the zenith angle for all passes.

    :param dict passes: Output from :func:`simulate_tracking.get_passes` that contains information about passes of an space object.
    :param SpaceObject o: Space object that made the passes.
    :param RadarSystem radar: Radar system that defines the FOV.
    :param float dt: Time step for angle evaluation.
    :return: Tuple of list of lists of times and list of lists of angles corresponding to each pass.
    '''
    zenith_v = []
    tx_ecef = []
    rx_ecef = []
    for tx in radar._tx:
        tx_ecef.append(tx.ecef)
        zenith_v.append(coord.azel_ecef(tx.lat, tx.lon, 0.0, 0.0, 90.0))

    angs = []
    ts = []
    for txi, txp in enumerate(passes['t']):
        angs.append([])
        ts.append([])
        zenith = zenith_v[txi]
        txp0 = tx_ecef[txi]
        for ps in txp:
            t = n.arange(ps[0], ps[1], dt)
            ecef = o.get_orbit(t)

            pos_vecs = (ecef.T - txp0).T
            pos_vecs0 = pos_vecs / n.sqrt(pos_vecs[0, :]**2.0 +
                                          pos_vecs[1, :]**2.0 +
                                          pos_vecs[2, :]**2.0)
            z_angles = 180.0 * n.arccos(pos_vecs0[0, :] * zenith[0] +
                                        pos_vecs0[1, :] * zenith[1] +
                                        pos_vecs0[2, :] * zenith[2]) / n.pi

            angs[-1].append(z_angles)
            ts[-1].append(t)

    return ts, angs
Example #7
0
def test_planar3():
    S = n.zeros([100, 200])
    el_phase = 90.0
    bp = alib.planar_beam(0,
                          el_phase,
                          60,
                          19.0,
                          az1=0.0,
                          el1=el_phase,
                          a0=16.0,
                          I_0=10**4.3,
                          f=230e6)
    els = n.linspace(0, 90, num=100)
    azs = n.linspace(0, 360, num=200)

    for ei, e in enumerate(n.linspace(0, 90, num=100)):
        for ai, a in enumerate(n.linspace(0, 360, num=200)):
            k = coord.azel_ecef(60.0, 19.0, 0.0, a, e)
            S[ei, ai] = bp.gain(k)
    plt.pcolormesh(azs, els, 10.0 * n.log10(S), vmin=0, vmax=100)
    plt.axvline(el_phase)
    plt.colorbar()
    plt.show()
Example #8
0
def ray_trace(dn=datetime(2016, 6, 21, 12, 00),
              f=233e6,
              lat=e3d._tx[0].lat,
              lon=e3d._tx[0].lon,
              elevation=30.0,
              az=180.0,
              fpref="",
              plot=False):

    np = 1000
    alts = n.linspace(0, 4000, num=np)
    distance = n.linspace(0, 4000, num=np)
    ne = n.zeros(np)
    ne2 = n.zeros(np)
    dnex = n.zeros(np)
    dtheta = n.zeros(np)
    dalt = n.zeros(np)
    dney = n.zeros(np)
    dnez = n.zeros(np)
    xyz_prev = 0.0
    px = n.zeros(np)
    dk = n.zeros(np)
    py = n.zeros(np)
    pz = n.zeros(np)
    p0x = n.zeros(np)
    p0y = n.zeros(np)
    p0z = n.zeros(np)

    # initial direction and position
    k = coord.azel_ecef(lat, lon, 10e3, az, elevation)
    k0 = k
    p = coord.geodetic2ecef(lat, lon, 10e3)
    pe = coord.geodetic2ecef(lat, lon, 10e3)
    p0 = coord.geodetic2ecef(lat, lon, 10e3)
    dh = 4e3
    vg = 1.0

    p_orig = p
    ray_time = 0.0

    for ai, a in enumerate(alts):
        p = p + k * dh * vg
        p0 = p0 + k0 * dh
        ray_time += dh / c.c

        dpx = p + n.array([1.0, 0.0, 0.0]) * dh
        dpy = p + n.array([0.0, 1.0, 0.0]) * dh
        dpz = p + n.array([0.0, 0.0, 1.0]) * dh

        llh = coord.ecef2geodetic(p[0], p[1], p[2])
        llh_1 = coord.ecef2geodetic(p0[0], p0[1], p0[2])
        dalt[ai] = llh_1[2] - llh[2]

        if llh[2] / 1e3 > 1900:
            break
        alts[ai] = llh[2] / 1e3
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            ne[ai] = pt.ne * 1e6
            f_p = 8.98 * n.sqrt(ne[ai])
            v_g = n.sqrt(1.0 - (f_p / f)**2.0)
        else:
            ne[ai] = 0.0

        llh = coord.ecef2geodetic(dpx[0], dpx[1], dpx[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dnex[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dnex[ai] = 0.0

        llh = coord.ecef2geodetic(dpy[0], dpy[1], dpy[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dney[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dney[ai] = 0.0

        llh = coord.ecef2geodetic(dpz[0], dpz[1], dpz[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dnez[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dnez[ai] = 0.0
        grad = n.array([dnex[ai], dney[ai], dnez[ai]])
        px[ai] = p[0]
        py[ai] = p[1]
        pz[ai] = p[2]
        p0x[ai] = p0[0]
        p0y[ai] = p0[1]
        p0z[ai] = p0[2]
        #        print(ai)
        dk[ai] = n.arccos(
            n.dot(k0, k) / (n.sqrt(n.dot(k0, k0)) * n.sqrt(n.dot(k, k))))
        # no bending if gradient too small
        if n.dot(grad, grad) > 100.0:
            grad1 = grad / n.sqrt(n.dot(grad, grad))

            p2 = p + k * dh
            llh = coord.ecef2geodetic(p2[0], p2[1], p2[2])
            pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
            pt.run_iri()
            if pt.ne > 0.0:
                ne2 = pt.ne * 1e6
            else:
                ne2 = 0.0
            f0 = 8.98 * n.sqrt(ne[ai])
            n0 = n.sqrt(1.0 - (f0 / f)**2.0)
            f1 = 8.98 * n.sqrt(ne2)
            n1 = n.sqrt(1.0 - (f1 / f)**2.0)

            theta0 = n.arccos(
                n.dot(grad, k) /
                (n.sqrt(n.dot(grad, grad)) * n.sqrt(n.dot(k, k))))
            # angle cannot be over 90
            if theta0 > n.pi / 2.0:
                theta0 = n.pi - theta0
            sin_theta_1 = (n0 / n1) * n.sin(theta0)
            dtheta[ai] = 180.0 * n.arcsin(
                sin_theta_1) / n.pi - 180.0 * theta0 / n.pi
            #            print("n0/n1 %1.10f theta0 %1.2f theta1-theta0 %1.10f"%(n0/n1,180.0*theta0/n.pi,dtheta[ai]))
            cos_theta_1 = n.sqrt(1.0 - sin_theta_1**2.0)
            k_ref = (n0 / n1) * k + (
                (n0 / n1) * n.cos(theta0) - cos_theta_1) * grad1
            # normalize
            k_ref / n.sqrt(n.dot(k_ref, k_ref))
            k = k_ref

            angle = n.arccos(
                n.dot(grad, k) / n.sqrt(n.dot(grad, grad)) *
                n.sqrt(n.dot(k, k)))

    los_time = n.sqrt(n.dot(p_orig - p, p_orig - p)) / c.c
    excess_ionospheric_delay = ray_time - los_time
    print("Excess propagation time %1.20f mus" % ((1e6 *
                                                   (ray_time - los_time))))

    theta = n.arccos(
        n.dot(k0, k) / (n.sqrt(n.dot(k0, k0)) * n.sqrt(n.dot(k, k))))

    theta_p = n.arccos(
        n.dot(p0, p) / (n.sqrt(n.dot(p0, p0)) * n.sqrt(n.dot(p, p))))

    llh0 = coord.ecef2geodetic(px[ai - 2], py[ai - 2], pz[ai - 2])
    llh1 = coord.ecef2geodetic(p0x[ai - 2], p0y[ai - 2], p0z[ai - 2])
    print("d_coord")
    print(llh0 - llh1)
    if plot:
        print(p0 - p)
        print(180.0 * theta_p / n.pi)
        fig = plt.figure(figsize=(14, 8))
        plt.clf()
        plt.subplot(131)
        plt.title("Elevation=%1.0f" % (elevation))
        plt.plot(n.sqrt((p0x - px)**2.0 + (p0y - py)**2.0 + (p0z - pz)**2.0),
                 alts,
                 label="Total error")
        plt.plot(dalt, alts, label="Altitude error")
        plt.ylim([0, 1900])
        #        plt.xlim([-50,800.0])
        plt.grid()
        plt.legend()
        plt.xlabel("Position error (m)")
        plt.ylabel("Altitude km")

        plt.subplot(132)
        plt.plot(dtheta * 1e6, alts)
        #        plt.plot(1e6*180.0*dk/n.pi,alts)
        plt.xlabel("Ray-bending ($\mu$deg/km)")
        plt.ylabel("Altitude km")
        plt.title("Total error=%1.2g (deg)" % (180.0 * theta_p / n.pi))
        plt.ylim([0, 1900])
        plt.subplot(133)
        plt.plot(ne, alts)
        plt.xlabel("$N_{\mathrm{e}}$ ($\mathrm{m}^{-3}$)")
        plt.ylabel("Altitude km")
        plt.ylim([0, 1900])
        #    ax.plot(px,py,pz)
        plt.tight_layout()
        plt.savefig("ref-%s-%d-%d.png" % (fpref, f / 1e6, elevation))
        plt.close()

    return (p0, p, 180.0 * theta_p / n.pi, excess_ionospheric_delay)
Example #9
0
def ray_trace_error(dn=datetime(2016, 6, 21, 12, 00),
                    f=233e6,
                    lat=e3d._tx[0].lat,
                    lon=e3d._tx[0].lon,
                    elevation=30.0,
                    az=180.0,
                    fpref="",
                    ionosphere=False,
                    error_std=0.05,
                    plot=False):

    np = 2000
    alts = n.repeat(1e99, np)
    distance = n.linspace(0, 4000, num=np)
    ne = n.zeros(np)
    ne2 = n.zeros(np)
    dtheta = n.zeros(np)
    dalt = n.zeros(np)
    dnex = n.zeros(np)
    dney = n.zeros(np)
    dnez = n.zeros(np)
    xyz_prev = 0.0
    dk = n.zeros(np)
    px = n.zeros(np)
    py = n.zeros(np)
    pz = n.zeros(np)
    t_vec = n.zeros(np)
    t_i_vec = n.zeros(np)
    k_vecs = []
    # initial direction and position
    k = coord.azel_ecef(lat, lon, 10e3, az, elevation)
    k0 = k
    p = coord.geodetic2ecef(lat, lon, 10e3)
    dh = 4e3
    dt = 20e-6
    # correlated errors std=1, 100 km correlation length
    scale_length = 40.0
    ne_errors_x = n.convolve(
        n.repeat(1.0 / n.sqrt(scale_length), scale_length),
        n.random.randn(10000))
    ne_errors_y = n.convolve(
        n.repeat(1.0 / n.sqrt(scale_length), scale_length),
        n.random.randn(10000))
    ne_errors_z = n.convolve(
        n.repeat(1.0 / n.sqrt(scale_length), scale_length),
        n.random.randn(10000))

    p_orig = p
    ray_time = 0.0
    v_c = c.c
    for ai, a in enumerate(alts):
        # go forward in time
        dhp = v_c * dt
        p = p + k * dhp
        ray_time += dt
        print(ray_time * 1e6)
        t_vec[ai + 1] = dt
        k_vecs.append(k)

        dpx = p + n.array([1.0, 0.0, 0.0]) * dh
        dpy = p + n.array([0.0, 1.0, 0.0]) * dh
        dpz = p + n.array([0.0, 0.0, 1.0]) * dh

        llh = coord.ecef2geodetic(p[0], p[1], p[2])

        if llh[2] / 1e3 > 2100:
            break
        alts[ai] = llh[2] / 1e3
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            ne[ai] = pt.ne * (1.0 + error_std * ne_errors_x[ai]) * 1e6
            if ionosphere:
                f0 = 8.98 * n.sqrt(ne[ai])
                f_p = 8.98 * n.sqrt(ne[ai])
                # update group velocity
                v_c = c.c * n.sqrt(1.0 - (f0 / f)**2.0)
        else:
            ne[ai] = 0.0

        llh = coord.ecef2geodetic(dpx[0], dpx[1], dpx[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dnex[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dnex[ai] = 0.0

        llh = coord.ecef2geodetic(dpy[0], dpy[1], dpy[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dney[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dney[ai] = 0.0

        llh = coord.ecef2geodetic(dpz[0], dpz[1], dpz[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dnez[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dnez[ai] = 0.0

        grad = n.array([dnex[ai], dney[ai], dnez[ai]])

        px[ai] = p[0]
        py[ai] = p[1]
        pz[ai] = p[2]

        dk[ai] = n.arccos(
            n.dot(k0, k) / (n.sqrt(n.dot(k0, k0)) * n.sqrt(n.dot(k, k))))
        # no bending if gradient too small
        if n.dot(grad, grad) > 100.0 and ionosphere:
            grad1 = grad / n.sqrt(n.dot(grad, grad))

            p2 = p + k * dh
            llh = coord.ecef2geodetic(p2[0], p2[1], p2[2])
            pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
            pt.run_iri()
            if pt.ne > 0.0:
                ne2 = pt.ne * (1.0 + error_std * ne_errors_x[ai]) * 1e6
            else:
                ne2 = 0.0
            f0 = 8.98 * n.sqrt(ne[ai])
            n0 = n.sqrt(1.0 - (f0 / f)**2.0)
            f1 = 8.98 * n.sqrt(ne2)
            n1 = n.sqrt(1.0 - (f1 / f)**2.0)

            theta0 = n.arccos(
                n.dot(grad, k) /
                (n.sqrt(n.dot(grad, grad)) * n.sqrt(n.dot(k, k))))
            # angle cannot be over 90
            if theta0 > n.pi / 2.0:
                theta0 = n.pi - theta0
            sin_theta_1 = (n0 / n1) * n.sin(theta0)
            dtheta[ai] = 180.0 * n.arcsin(
                sin_theta_1) / n.pi - 180.0 * theta0 / n.pi
            #            print("n0/n1 %1.10f theta0 %1.2f theta1-theta0 %1.10f"%(n0/n1,180.0*theta0/n.pi,dtheta[ai]))
            cos_theta_1 = n.sqrt(1.0 - sin_theta_1**2.0)
            k_ref = (n0 / n1) * k + (
                (n0 / n1) * n.cos(theta0) - cos_theta_1) * grad1
            # normalize
            k_ref / n.sqrt(n.dot(k_ref, k_ref))
            k = k_ref

            angle = n.arccos(
                n.dot(grad, k) / n.sqrt(n.dot(grad, grad)) *
                n.sqrt(n.dot(k, k)))

    return (t_vec, px, py, pz, alts, ne, k_vecs)
Example #10
0
def rcs_psf(radar,
            txi,
            rxi,
            az,
            el,
            SNR,
            R,
            samp=1000,
            min_el=30.0,
            RCS_lim=10.0,
            hist_res=25):
    tx = radar._tx[txi]
    rx = radar._rx[rxi]

    G = tx.beam
    G.point(az, el)

    num = 0
    it = 0
    k_set = n.empty((3, ), dtype=n.float)
    k_all = n.empty((3, samp), dtype=n.float)
    sig = n.empty((samp, ), dtype=n.float)

    while num < samp:
        it += 1

        k_set = draw_sph(1, min_el)
        k_set.shape = (k_set.size, )

        k_ecef = coord.azel_ecef(G.lat, G.lon, 0.0,
                                 n.degrees(n.arctan2(k_set[1], k_set[0])),
                                 n.degrees(n.arcsin(k_set[2])))
        Gc = G.gain(k_ecef)
        rcs = SNR * (
            4.0 * n.pi
        )**3 * R**4 * scipy.constants.k * rx.rx_noise * tx.coh_int_bandwidth / (
            tx.tx_power * Gc**2 * tx.wavelength)

        if rcs < RCS_lim:
            print('iter {}, samp {}, rcs {} m^2 dB'.format(
                it, num, 10.0 * n.log10(rcs)))

            sig[num] = rcs
            k_all[0, num] = k_set[0]
            k_all[1, num] = k_set[1]
            k_all[2, num] = k_set[2]
            num += 1

    fig = plt.figure()
    ax = fig.add_subplot(111)

    ax.hist(n.log10(sig), hist_res, density=True)

    n.savetxt('sig_data.txt', sig)

    ax.set_xlabel('$\log_{10}(RCS)$ [1]', fontsize=24)
    ax.set_ylabel('Probability', fontsize=24)
    ax.set_title(
        'RCS distribution: SNR {} dB, R {} km, (az, el) = ({}, {}), samp include {} %'
        .format(10.0 * n.log10(SNR), R * 1e-3, az, el,
                float(it) / float(num) * 100.0),
        fontsize=20)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    ax.plot(k_all[0, :], k_all[1, :], k_all[2, :], '.b')
    ax.set_xlabel('$k_x$ [1]', fontsize=24)
    ax.set_ylabel('$k_y$ [1]', fontsize=24)

    ax.set_aspect('equal')
    max_range = 1.5
    ax.set_xlim(-max_range, max_range)
    ax.set_ylim(-max_range, max_range)
    ax.set_zlim(-max_range, max_range)

    plt.show()

    return sig, k_all
Example #11
0
def get_passes_simple(o,radar,t0,t1,max_dpos=100e3,debug=False, sanity_check=False):
    '''Follow object and find peak SNR. Assume that this occurs for minimum zenith angle of each TX.

    :param SpaceObject o: The object in space to be followed.
    :param RadarSystem radar: The radar system used for tracking.
    :param float t0: Start time for tracking
    :param float t1: End time for tracking
    :param float max_dpos: Maximum separation in m between orbital evaluation points, used to calculate time-step size by approximating orbits as circles
    :param bool debug: Verbose output
    :param bool sanity_check: Even more verbose output
    :return: Tuple of (Peak SNR for tracking, Number of receivers that can observe, time of best detection)
    '''


    # figure out the number of time points we need to evaluate to meet the max_dpos criteria
    num_t = simulate_tracking.find_linspace_num(t0, t1, o.a*1e3, o.e, max_dpos=max_dpos)
    
    # time vector
    t=n.linspace(t0,t1,num=num_t)
    dt = (t1-t0)/num_t

    # propagate object for all time points requested
    ecef=o.get_orbit(t)

    # zenith angles
    zenith = []
    
    # tx and rx site locations in ecef
    tx_ecef = []
    rx_ecef = []
    # zenith directions for each tx and rx site
    zenith_tx = []
    zenith_tx = []    
    for tx in radar._tx:
        tx_ecef.append( tx.ecef )
        zenith_tx.append( coord.azel_ecef(tx.lat, tx.lon, 0.0, 0.0, 90.0) )

    zenith_rx = []
    for rx in radar._rx:
        rx_ecef.append( rx.ecef )
        zenith_rx.append( coord.azel_ecef(rx.lat, rx.lon, 0.0, 0.0, 90.0) )
    
    # position vectors between tx and rx
    pos_rx = []
    for rxp0 in rx_ecef:
        pos_vec=(ecef.T-rxp0).T
        pos_rx.append(pos_vec)

    n_tx=len(radar._tx)
    n_rx=len(radar._rx)

    # peak snr for tx->rx combo
    peak_snr=n.zeros([n_tx,n_rx])
    # number of receivers that can observe TX
    n_rx_detections=n.zeros(n_tx)

    # for each transmitter
    for txi,txp0 in enumerate(tx_ecef):
        # tx 
        tx = radar._tx[txi]
        # zenith direction vector for this TX
        zenith = zenith_tx[txi]
        # position vector
        pos_tx=(ecef.T-txp0).T
        # unit vector for tx->target position vector
        pos_tx0=pos_tx/n.sqrt(pos_tx[0,:]**2.0+pos_tx[1,:]**2.0+pos_tx[2,:]**2.0)
        
        # zenith -> target angle
        z_angles_tx=180.0*n.arccos(pos_tx0[0,:]*zenith[0]+pos_tx0[1,:]*zenith[1]+pos_tx0[2,:]*zenith[2])/n.pi

        # peak elevation angle
        min_z=n.min(z_angles_tx)

        det_idx=n.argmin(z_angles_tx)        
        if min_z < (90.0-radar._tx[txi].el_thresh):
            # object possibly detectable
            pos_vec=pos_rx[txi][:,det_idx]
            tx_dist=n.linalg.norm(pos_vec)

            # point tx antenna towards target
            k0 = tx.point_ecef(pos_vec)
            gain_tx = tx.beam.gain(k0)
            # for all receivers
            for rxi,rx in enumerate(radar._rx):
                # position vector
                pos_rx_now=pos_rx[rxi][:,det_idx]
                # distance
                rx_dist=n.linalg.norm(pos_rx_now)
                # unit vector
                pos_rx_now0=pos_rx_now/rx_dist

                if sanity_check:
                    pos = radar._rx[rxi].ecef + pos_rx_now0*rx_dist
                    print("diff %d"%(rxi))
                    print((ecef[:,det_idx] - pos))
                
                zenith = zenith_rx[rxi]
                # rx zenith -> target angle
                z_angle_rx=180.0*n.arccos(pos_rx_now0[0]*zenith[0]+pos_rx_now0[1]*zenith[1]+pos_rx_now0[2]*zenith[2])/n.pi

                # point towards object
                k0 = rx.point_ecef(pos_rx_now)
                
                gain_rx = rx.beam.gain(k0)
                
                snr=debris.hard_target_enr(gain_tx,
                               gain_rx,
                               rx.wavelength,
                               tx.tx_power,
                               tx_dist,
                               rx_dist,
                               diameter_m=o.diam,
                               bandwidth=tx.coh_int_bandwidth,
                               rx_noise_temp=rx.rx_noise)

                peak_snr[txi,rxi]=snr
                if snr >= tx.enr_thresh:
                    n_rx_detections[txi]+=1.0
                    print("oid %d inc %1.2f diam %1.2f tx %d rx %d snr %1.2g min_range %1.2f (km) tx_dist %1.2f (km) rx_dist %1.2f (km) tx_zenith angle %1.2f rx zenith angle %1.2f"%(o.oid,o.i,o.diam,txi,rxi,snr,((1.0-o.e)*o.a)-6371.0,tx_dist/1e3,rx_dist/1e3,min_z,z_angle_rx))
                else:
                    print("oid {} not detected, SNR = {}".format(o.oid, snr))
    return peak_snr, n_rx_detections, t[det_idx]
Example #12
0
def time_compare_library_beams():
    e3d = alib.e3d_array_beam(az0=0.0, el0=90.0, I_0=10**4.3)
    bp1 = alib.airy_beam(az0=0.0,
                         el0=90.0,
                         lat=60,
                         lon=19,
                         f=233e6,
                         I_0=10**4.3,
                         a=40.0)
    bp2 = alib.cassegrain_beam(az0=0.0,
                               el0=90.0,
                               lat=60,
                               lon=19,
                               f=233e6,
                               I_0=10**4.3,
                               a0=80.0,
                               a1=80.0 / 16.0 * 2.29)
    bp3 = alib.planar_beam(az0=0.0,
                           el0=90.0,
                           lat=60,
                           lon=19,
                           f=233e6,
                           I_0=10**4.3,
                           a0=40.0,
                           az1=0,
                           el1=90.0)

    import time
    k = coord.azel_ecef(e3d.lat, e3d.lon, 0.0, 0, 87.0)
    test_n = 500
    t = n.zeros((test_n, 4))
    for i in range(test_n):
        t0 = time.clock()
        g = e3d.gain(k)
        t[i, 0] = time.clock() - t0

        t0 = time.clock()
        g = bp1.gain(k)
        t[i, 1] = time.clock() - t0

        t0 = time.clock()
        g = bp2.gain(k)
        t[i, 2] = time.clock() - t0

        t0 = time.clock()
        g = bp3.gain(k)
        t[i, 3] = time.clock() - t0

    print('Exec time %s: mean %.5f s, std %.5f s' % (
        e3d.beam_name,
        n.mean(t[:, 0]),
        n.std(t[:, 0]),
    ))
    print('Exec time %s: mean %.5f s, std %.5f s' % (
        bp1.beam_name,
        n.mean(t[:, 1]),
        n.std(t[:, 1]),
    ))
    print('Exec time %s: mean %.5f s, std %.5f s' % (
        bp2.beam_name,
        n.mean(t[:, 2]),
        n.std(t[:, 2]),
    ))
    print('Exec time %s: mean %.5f s, std %.5f s' % (
        bp3.beam_name,
        n.mean(t[:, 3]),
        n.std(t[:, 3]),
    ))

    print('Exec time %s vs %s: mean %.5f, std %.5f' % (
        e3d.beam_name,
        bp3.beam_name,
        n.mean(t[:, 0]) / n.mean(t[:, 3]),
        n.std(t[:, 0]) / n.std(t[:, 3]),
    ))
Example #13
0
def find_pass_interval(t, o, radar, logger=None):
    '''Find a pass inside the FOV of a radar given a series of times for a space object.
    
    :param numpy.ndarray t: Linear vector of times to use as a base to find pass in seconds relative space object epoch.
    :param SpaceObject o: Space object to find pass interval for.
    :param RadarSystem radar: Radar system that defines the FOV.
    :return: Tuple of (passes, passes_id, idx_v, postx_v, posrx_v), description below.

    **Return data:**

        * passes: Three layers of lists where first layer is a list corresponding to every RX antenna of the radar system. Second layer is the a entry in the list for every pass. Last layer of lists is a list of two elements where the first is the time in seconds when object enters the FOV and second is the time in seconds when the object leaves the FOV.
        * passes_id: Same structure as the passes data but with the time indices's instead of the actual times.
        * idx_v: List of arrays of indices's of input time vector where the space object is inside the TX FOV, length of list is equal to the number of TX stations.
        * postx_v: list of arrays containing the position of the space object relative the TX stations, length of list is equal to number of TX stations and the array is the length of the input time vector.
        * posrx_v: list of arrays containing the position of the space object relative the RX stations, length of list is equal to number of RX stations and the array is the length of the input time vector.
    '''
    ecef = o.get_orbit(t)

    dt = (n.max(t) - n.min(t)) / len(t)

    zenith_v = []
    tx_ecef = []
    rx_ecef = []
    for tx in radar._tx:
        tx_ecef.append(tx.ecef)
        zenith_v.append(coord.azel_ecef(tx.lat, tx.lon, 0.0, 0.0, 90.0))
    for rx in radar._rx:
        rx_ecef.append(rx.ecef)

    postx_v = []
    posrx_v = []
    idx_v = []
    for rxp0 in rx_ecef:
        pos_vecs = (ecef.T - rxp0).T
        posrx_v.append(pos_vecs)

    # for each transmitter
    for txi, txp0 in enumerate(tx_ecef):
        zenith = zenith_v[txi]
        pos_vecs = (ecef.T - txp0).T
        pos_vecs0 = pos_vecs / n.sqrt(pos_vecs[0, :]**2.0 +
                                      pos_vecs[1, :]**2.0 +
                                      pos_vecs[2, :]**2.0)

        # elevation angle for transmitter
        z_angles = 180.0 * n.arccos(pos_vecs0[0, :] * zenith[0] +
                                    pos_vecs0[1, :] * zenith[1] +
                                    pos_vecs0[2, :] * zenith[2]) / n.pi

        # there the elevation angle is larger than elevation cutoff
        idx = n.where(z_angles < (90.0 - radar._tx[txi].el_thresh))[0]
        postx_v.append(pos_vecs)
        idx_v.append(idx)

        if logger is not None:
            logger.debug("txi{}: idx {} ".format(txi, len(idx)))

        #remove later
        #plt.plot(z_angles)
        #plt.show()

    #find passes
    #format
    # [tx num][pass num][0 = above, 1 = below]
    passes = [None] * len(radar._tx)
    passes_id = [None] * len(radar._tx)
    for txi, idx in enumerate(idx_v):
        if len(idx) > 0:
            Tv = t[idx]
            passes[txi] = [[Tv[0]]]
            passes_id[txi] = [[0]]
            for ti in range(len(Tv) - 1):
                if Tv[ti + 1] - Tv[ti] > 3 * dt:
                    passes[txi][-1].append(Tv[ti])
                    passes[txi].append([Tv[ti + 1]])

                    passes_id[txi][-1].append(ti)
                    passes_id[txi].append([ti + 1])
            passes[txi][-1].append(Tv[-1])
            passes_id[txi][-1].append(len(Tv) - 1)

    return passes, passes_id, idx_v, postx_v, posrx_v
Example #14
0
def get_scan_snr(t, o, radar):
    '''Takes a series of times, a space object and a radar system and calculates the SNR for that space object given the scan pattern of the radar over the given times.

    :param numpy.ndarray t: Times in seconds relative space object epoch over witch SNR should be evaluated.
    :param SpaceObject o: Space object to be measured.
    :param RadarSystem radar: Radar system that performs the measurement.
    :return: List of lists of numpy.ndarray's corresponding to TX antenna index, RX antenna index and SNR-array in that order of list depth.
    '''

    ecef = o.get_orbit(t)

    zenith_v = []
    tx_ecef = []
    rx_ecef = []
    for tx in radar._tx:
        tx_ecef.append(tx.ecef)
        zenith_v.append(coord.azel_ecef(tx.lat, tx.lon, 0.0, 0.0, 90.0))
    for rx in radar._rx:
        rx_ecef.append(rx.ecef)

    postx_v = []
    posrx_v = []
    idx_v = []
    rx_dets = 0
    for rxp0 in rx_ecef:
        pos_vecs = (ecef.T - rxp0).T
        posrx_v.append(pos_vecs)

    # for each transmitter
    for txi, txp0 in enumerate(tx_ecef):
        zenith = zenith_v[txi]
        pos_vecs = (ecef.T - txp0).T
        pos_vecs0 = pos_vecs / n.sqrt(pos_vecs[0, :]**2.0 +
                                      pos_vecs[1, :]**2.0 +
                                      pos_vecs[2, :]**2.0)

        postx_v.append(pos_vecs)

    snrs = [None] * len(radar._tx)
    for txi, tx in enumerate(radar._tx):
        snrs[txi] = [None] * len(radar._rx)
        for rxi, rx in enumerate(radar._rx):
            snr_curve = []
            for I in range(len(t)):
                tx_dist = n.linalg.norm(postx_v[txi][:, I])

                k_obj_tx = coord.ecef2local(
                    lat=tx.lat,
                    lon=tx.lon,
                    alt=tx.alt,
                    x=postx_v[txi][0, I],
                    y=postx_v[txi][1, I],
                    z=postx_v[txi][2, I],
                )
                k_obj_rx = coord.ecef2local(
                    lat=rx.lat,
                    lon=rx.lon,
                    alt=rx.alt,
                    x=posrx_v[txi][0, I],
                    y=posrx_v[txi][1, I],
                    z=posrx_v[txi][2, I],
                )

                k0 = tx.get_scan(t[I]).local_pointing(t[I])  #get scan pointing
                tx.beam.point_k0(k0)
                gain_tx = tx.beam.gain(k_obj_tx)

                rx_dist = n.linalg.norm(posrx_v[rxi][:, I])

                rx.beam.point_k0(k_obj_rx)
                gain_rx = rx.beam.gain(k_obj_rx)

                snr = debris.hard_target_enr(gain_tx,
                                             gain_rx,
                                             rx.wavelength,
                                             tx.tx_power,
                                             tx_dist,
                                             rx_dist,
                                             diameter_m=o.d,
                                             bandwidth=tx.coh_int_bandwidth,
                                             rx_noise_temp=rx.rx_noise)

                snr_curve.append(snr)

            snr_curve = n.array(snr_curve)
            snrs[txi][rxi] = snr_curve
    return snrs