def test_dpa_gain(self):
        hor_dirs = [0, 1.49, 360 - 1.49, 1.51, 360 - 1.51, 90, 320]
        gains = antenna.GetRadarNormalizedAntennaGains(hor_dirs, 0)
        self.assertEqual(
            np.max(np.abs(gains - np.array([0, 0, 0, -25, -25, -25, -25]))), 0)
        for k, hor in enumerate(hor_dirs):
            gain = antenna.GetRadarNormalizedAntennaGains(hor, 0)
            self.assertEqual(gain, gains[k])

        gains = antenna.GetRadarNormalizedAntennaGains([5, 8.6, 11.4, 20], 10)
        self.assertEqual(np.max(np.abs(gains - np.array([-25, 0, 0, -25]))), 0)

        gains = antenna.GetRadarNormalizedAntennaGains(
            [5, 8.99, 9.01, 10, 10.99, 11.01], 10, radar_beamwidth=2)
        self.assertEqual(
            np.max(np.abs(gains - np.array([-25, -25, 0, 0, 0, -25]))), 0)
예제 #2
0
def calcAggregatedInterference(protection_point,
                               low_freq,
                               high_freq,
                               grants,
                               inc_ant_height,
                               num_iter,
                               beamwidth,
                               neighbor_distances,
                               min_azimuth=0,
                               max_azimuth=360,
                               do_max=False):
    """Computes the 95% aggregated interference quantile on a protected point.

  Inputs:
    protection_point:  A protection point location, having attributes 'latitude' and
                       'longitude'.
    low_freq:          The low frequency of protection constraint (Hz).
    high_freq:         The high frequency of protection constraint (Hz).
    grants:            A list of CBSD |data.CbsdGrantInfo| active grants.
    inc_ant_height:    The reference incumbent antenna height (meters).
    num_iter:          The number of Monte Carlo iterations.
    beamwidth:         The protection antenna beamwidth (degree).
    min_azimuth:       The minimum azimuth (degrees) for incumbent transmission.
    max_azimuth:       The maximum azimuth (degrees) for incumbent transmission.
    neighbor_distances: The neighborhood distances (km) as a sequence:
      [cata_dist, catb_dist, cata_oob_dist, catb_oob_dist]
    do_max:            If True, returns the maximum interference over all radar azimuth.

  Returns:
    The 95% aggregated interference (dB) either:
      - as a vector (ndarray) of length N, where the element k corresponds to
          azimuth k * (beamwith/2). The length N is thus equal to 2 * 360 / beamwith,
          (or 2 * azimuth_range / beamwidth if using a smaller azimuth range than
           360 degrees, as specified by min_azimuth/max_azimuth).
      - or the maximum over all radar azimuth, if `do_max` is set to True.
  """
    dpa_type = findDpaType(low_freq, high_freq)
    if not beamwidth: beamwidth = 360

    # Assign values to the protection constraint
    constraint = data.ProtectionConstraint(
        latitude=protection_point.latitude,
        longitude=protection_point.longitude,
        low_frequency=low_freq,
        high_frequency=high_freq,
        entity_type=data.ProtectedEntityType.DPA)

    # DPA Purge algorithm for OOB
    if dpa_type is DpaType.OUT_OF_BAND:
        cbsds_grants_map = defaultdict(list)
        for grant in grants:
            key = grant.uniqueCbsdKey()
            _addMinFreqGrantToFront(cbsds_grants_map[key], grant)
        # Reset the grants to the minimum frequency grant for each CBSDs.
        grants = [cbsd_grants[0] for cbsd_grants in cbsds_grants_map.values()]

    # Identify CBSD grants in the neighborhood of the protection constraint
    neighbor_grants, _ = findGrantsInsideNeighborhood(grants, constraint,
                                                      dpa_type,
                                                      neighbor_distances)
    if not neighbor_grants:
        return np.asarray(-1000)
    interf_matrix = np.zeros((num_iter, len(neighbor_grants)))
    bearings = np.zeros(len(neighbor_grants))
    for k, grant in enumerate(neighbor_grants):
        interf, _ = computeInterference(grant, constraint, inc_ant_height,
                                        num_iter, dpa_type)
        interf_matrix[:, k] = interf.randomInterference
        bearings[k] = interf.bearing_c_cbsd

    interf_matrix = 10**(interf_matrix / 10.)
    azimuths = findAzimuthRange(min_azimuth, max_azimuth, beamwidth)

    agg_interf = np.zeros(len(azimuths))
    for k, azi in enumerate(azimuths):
        dpa_gains = antenna.GetRadarNormalizedAntennaGains(
            bearings, azi, beamwidth)
        dpa_interf = interf_matrix * 10**(dpa_gains / 10.0)
        agg_interf[k] = np.percentile(np.sum(dpa_interf, axis=1),
                                      PROTECTION_PERCENTILE,
                                      interpolation='lower')
    agg_interf = 10 * np.log10(agg_interf)
    return np.max(agg_interf) if do_max else agg_interf
예제 #3
0
def find_nc(I, bearings, t, beamwidth, min_azimuth, max_azimuth):
    """Returns the index (nc) of the grant in the ordered list of grants such that
  the protection percentile of the interference from the first nc grants is below the
  threshold for all azimuths of the receiver antenna.

  Inputs:
    I:      2D array of interference contributions (dBm/10 MHz); columns
            correspond to grants, and rows correspond to Monte Carlo iterations.
    bearings: a list of bearings from protection point to CBSDs.
    t:      protection percentile threshold (dBm/10 MHz)
    beamwidth: protection antenna beamwidth (degree).
    min_azimuth: minimim protection azimuth (degree).
    max_azimuth: maximum protection azimuth (degree).

  Returns:
    nc:     index nc that defines the move list to be {G_nc+1, G_nc+2, ..., G_Nc}
  """
    # Create array of incumbent antenna azimuth angles (degrees).
    azimuths = findAzimuthRange(min_azimuth, max_azimuth, beamwidth)

    # Initialize nc to Nc.
    Nc = I.shape[1]
    nc = Nc

    # Convert protection threshold and interference matrix to linear units.
    t_mW = np.power(10.0, t / 10.0)
    I_mW = np.power(10.0, I / 10.0)

    # Loop through every azimuth angle.
    for azi in azimuths:

        # Calculate interference contributions at output of receiver antenna.
        dpa_gains = antenna.GetRadarNormalizedAntennaGains(
            bearings, azi, beamwidth)
        IG = I_mW * 10**(dpa_gains / 10.0)

        # Compute the protection percentile of the aggregate interference, and remove
        # grants until the protection threshold is met or all grants are moved.
        agg_interf = np.percentile(np.sum(IG[:, 0:nc], axis=1),
                                   PROTECTION_PERCENTILE,
                                   interpolation='lower')
        if agg_interf <= t_mW:
            continue

        # Conduct binary search for nc.
        hi = nc
        lo = 0
        while (hi - lo) > 1:
            mid = (hi + lo) / 2
            agg_interf = np.percentile(np.sum(IG[:, 0:mid], axis=1),
                                       PROTECTION_PERCENTILE,
                                       interpolation='lower')
            if agg_interf > t_mW:
                hi = mid
            else:
                lo = mid

        nc = lo
        if nc == 0:
            return 0

    return nc