def test_small_height(self): lat1, lng1 = 37.756672, -122.508512 lat2, lng2 = 37.754406, -122.388342 res_bad = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, 0, lat2, lng2, -1, cbsd_indoor=False, reliability=0.5, freq_mhz=3625., region='SUBURBAN') res_expected = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, 1, lat2, lng2, 1, cbsd_indoor=False, reliability=0.5, freq_mhz=3625., region='SUBURBAN') self.assertEqual(res_bad.db_loss, res_expected.db_loss) self.assertEqual(res_bad.incidence_angles, res_expected.incidence_angles)
def test_ehata_mean(self): lat1, lng1, height1 = 37.751985, -122.443890, 20.0 lat2, lng2, height2 = 37.771594, -122.253895, 10.0 expected_med_loss = 161.93 expected_offset = -12.45 self.assertAlmostEqual( wf_hybrid._GetMedianToMeanOffsetDb(3625., False), expected_offset, 2) res_med = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=0.5, freq_mhz=3625., region='SUBURBAN') res_mean = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=-1, freq_mhz=3625., region='SUBURBAN') self.assertAlmostEqual(res_mean[0], res_med[0] + expected_offset, 2)
def get_rx_signal_point((cbsd, location)): """ This Method returns the Rx Signal Strength of a CBSD to a location using Hybrid Model Input: cbsd: a cbsd object :type cbsd CBSD location, the coordinate of the location :type location Tuple[float, float] Returns: Rx_Signal: The signal strength, float """ lat_rx = location[0] # latitude of the location lon_rx = location[1] # longitude of the location height_rx = 0 # Default AGL of the Rx location is set to 0 # call the method in wf_hybrid (hybrid model) to calculate the propagation loss from the CBSD to the location loss = wf_hybrid.CalcHybridPropagationLoss(cbsd.latitude, cbsd.longitude, cbsd.height, lat_rx, lon_rx, height_rx, cbsd_indoor=cbsd.indoor, region=cbsd.region_type, reliability=0.5) # Convert to Rx Signal Rx_Signal = cbsd.TxPower - loss[0] return Rx_Signal
def test_average_itm(self): lat1, lng1, height1 = 37.756672, -122.508512, 20.0 lat2, lng2, height2 = 37.754406, -122.388342, 1.5 reliabilities = np.arange(0.01, 1.0, 0.01) losses = [] for rel in reliabilities: res = wf_itm.CalcItmPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=rel, freq_mhz=3625.) losses.append(res.db_loss) avg_res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=-1, freq_mhz=3625., region='SUBURBAN', return_internals=True) self.assertEqual(avg_res.internals['hybrid_opcode'], wf_hybrid.HybridMode.ITM_DOMINANT) self.assertAlmostEqual( avg_res.db_loss, -10 * np.log10(np.mean(10**(-np.array(losses) / 10.))), 5)
def _CalculateDbLossForEachPointAndGetContour(install_param, eirp_capability, antenna_gain, cbsd_region_type, latitudes, longitudes): """Returns Vertex Point Distance for each azimuth with signal strength greater than or equal to Threshold""" db_loss = np.zeros(len(latitudes), dtype=np.float64) lat_cbsd, lon_cbsd = install_param['latitude'], install_param['longitude'] height_cbsd = install_param['height'] for index, lat_lon in enumerate(zip(latitudes, longitudes)): lat, lon = lat_lon db_loss[index] = wf_hybrid.CalcHybridPropagationLoss( lat_cbsd, lon_cbsd, height_cbsd, lat, lon, RX_HEIGHT, cbsd_indoor=install_param['indoorDeployment'], reliability=0.5, region=cbsd_region_type, is_height_cbsd_amsl=( install_param['heightType'] == 'AMSL')).db_loss index_cond, = np.where( (eirp_capability - install_param['antennaGain'] + antenna_gain) - db_loss >= THRESHOLD_PER_10MHZ) return index_cond.shape[0] * 0.2
def computeInterferencePpaGwpzPoint(cbsd_grant, constraint, h_inc_ant, max_eirp, region_type='SUBURBAN'): """Computes interference that a grant causes to GWPZ or PPA protection area. Routine to compute interference neighborhood grant causes to protection point within GWPZ or PPA protection area. Args: cbsd_grant: A CBSD grant of type |data.CbsdGrantInfo|. constraint: The protection constraint of type |data.ProtectionConstraint|. h_inc_ant: The reference incumbent antenna height (in meters). max_eirp: The maximum EIRP allocated to the grant during IAP procedure region_type: Region type of the GWPZ or PPA area: 'URBAN', 'SUBURBAN' or 'RURAL'. Returns: The interference contribution (dBm). """ # Get the propagation loss and incident angles for area entity db_loss, incidence_angles, _ = wf_hybrid.CalcHybridPropagationLoss( cbsd_grant.latitude, cbsd_grant.longitude, cbsd_grant.height_agl, constraint.latitude, constraint.longitude, h_inc_ant, cbsd_grant.indoor_deployment, reliability=-1, freq_mhz=FREQ_PROP_MODEL_MHZ, region=region_type) # Compute CBSD antenna gain in the direction of protection point ant_gain = antenna.GetStandardAntennaGains(incidence_angles.hor_cbsd, cbsd_grant.antenna_azimuth, cbsd_grant.antenna_beamwidth, cbsd_grant.antenna_gain) # Get the exact overlap of the grant over the GWPZ area channels if constraint.entity_type == data.ProtectedEntityType.GWPZ_AREA: grant_overlap_bandwidth = min(cbsd_grant.high_frequency, constraint.high_frequency) \ - max(cbsd_grant.low_frequency, constraint.low_frequency) else: grant_overlap_bandwidth = RBW_HZ # Get the interference value for area entity eirp = getEffectiveSystemEirp(max_eirp, cbsd_grant.antenna_gain, ant_gain, grant_overlap_bandwidth) interference = eirp - db_loss return interference
def test_indoor(self): lat1, lng1, height1 = 37.756672, -122.508512, 20.0 lat2, lng2, height2 = 37.754406, -122.388342, 10.0 res_outdoor = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, cbsd_indoor=False, reliability=0.5, freq_mhz=3625., region='SUBURBAN') res_indoor = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, cbsd_indoor=True, reliability=0.5, freq_mhz=3625., region='SUBURBAN') self.assertEqual(res_indoor.db_loss, res_outdoor.db_loss + 15)
def test_rural_mode(self): lat1, lng1, height1 = 37.756672, -122.508512, 50.0 lat2, lng2, height2 = 37.756559, -122.507882, 10.0 # about 50m away reliability = 0.5 res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=reliability, freq_mhz=3625., region='RURAL', return_internals=True) self.assertEqual(res.db_loss, res.internals['itm_db_loss']) self.assertEqual(res.internals['hybrid_opcode'], wf_hybrid.HybridMode.ITM_RURAL)
def test_100m_mode(self): lat1, lng1, height1 = 37.756672, -122.508512, 10.0 lat2, lng2, height2 = 37.756559, -122.507882, 10.0 # about 50m away reliability = 0.5 res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=reliability, freq_mhz=3625., region='SUBURBAN', return_internals=True) self.assertAlmostEqual(res.db_loss, 79.167, 3) self.assertEqual(res.internals['hybrid_opcode'], wf_hybrid.HybridMode.FSL)
def test_1km_mode(self): lat1, lng1, height1 = 37.756672, -122.508512, 20.0 lat2, lng2, height2 = 37.762314, -122.500973, 10.0 # 912 meters away reliability = 0.5 res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=reliability, freq_mhz=3625., region='URBAN', return_internals=True) self.assertAlmostEqual(res.db_loss, 144.836, 3) self.assertEqual(res.internals['hybrid_opcode'], wf_hybrid.HybridMode.EHATA_FSL_INTERP)
def test_ehata_dominant(self): lat1, lng1, height1 = 37.751985, -122.443890, 20.0 lat2, lng2, height2 = 37.771594, -122.253895, 10.0 reliability = 0.5 expected_loss = 150.680 res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=reliability, freq_mhz=3625., region='SUBURBAN', return_internals=True) self.assertAlmostEqual(res.db_loss, expected_loss, 2) self.assertEqual(res.internals['hybrid_opcode'], wf_hybrid.HybridMode.EHATA_DOMINANT)
def test_over_80km(self): lat1, lng1, height1 = 37.751985, -122.443890, 20.0 lat2, lng2, height2 = 37.094745, -122.040671, 10.0 # 81km away expected_loss = 286.903 expected_itm_loss = 269.067 res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=0.5, freq_mhz=3625., region='SUBURBAN', return_internals=True) self.assertAlmostEqual(res.db_loss, expected_loss, 3) self.assertAlmostEqual(expected_itm_loss, res.internals['itm_db_loss'], 0) self.assertEqual(res.internals['hybrid_opcode'], wf_hybrid.HybridMode.ITM_CORRECTED)
def test_itm_dominant(self): lat1, lng1, height1 = 37.756672, -122.508512, 20.0 lat2, lng2, height2 = 37.754406, -122.388342, 10.0 reliability = 0.5 expected_itm_loss = 211.47 res = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, height1, lat2, lng2, height2, reliability=reliability, freq_mhz=3625., region='SUBURBAN', return_internals=True) self.assertAlmostEqual(res.db_loss, expected_itm_loss, 2) self.assertEqual(res.db_loss, res.internals['itm_db_loss']) self.assertEqual(res.internals['hybrid_opcode'], wf_hybrid.HybridMode.ITM_DOMINANT) self.assertEqual(res.internals['itm_err_num'], wf_hybrid.wf_itm.ItmErrorCode.WARNING)
def get_im_point(cbsd1, cbsd2): """ Call Hybrid propagation model to calculate Interference Metric of CBSD1 that is interferred by CBSD2 Using Point Coordination Input: cbsd1: CBSD object that is interferred. :type cbsd1: CBSD cbsd2: CBSD object that is interferring (as noise). :type cbsd2: CBSD Returns: Interference Metrics as float """ # Call Hybrid Propagation Model to calculate signal loss from cbsd2 at the location of cbsd1 loss = wf_hybrid.CalcHybridPropagationLoss(cbsd2.latitude, cbsd2.longitude, cbsd2.height, cbsd1.latitude, cbsd1.longitude, cbsd1.height, cbsd_indoor=cbsd2.indoor, region=cbsd2.region_type, reliability=0.5) # Calculate Signal Strength by substracting loss from the transmitter power Ix = cbsd2.TxPower - loss[0] # Use Global I_min, I_max to calculate the Interference Metric if Ix < I_min: return 0 elif Ix > I_max: return 1.0 else: return float(Ix - I_min) / (I_max - I_min)
indoor = True lng1 = -117.162408646 agl1 = 3 rels = [-1, 0.5] rt = "RURAL" lat2 = 32.74049506692264 lng2 = -117.14025198345544 agl2 = 1.5 for rel in rels: loss_hybrid = wf_hybrid.CalcHybridPropagationLoss(lat1, lng1, agl1, lat2, lng2, agl2, cbsd_indoor=indoor, region=rt, reliability=rel) loss_itm = wf_itm.CalcItmPropagationLoss(lat1, lng1, agl1, lat2, lng2, agl2, cbsd_indoor=indoor, reliability=rel) print "Reliablity: ", rel print "Hybrid Loss:", loss_hybrid[0], "dbm:", 26 - loss_hybrid[0]
def computePropagationAntennaModel(request): reliability_level = request['reliabilityLevel'] if reliability_level not in [-1, 0.05, 0.95]: raise ValueError('reliability_level not in [-1, 0.05, 0.95]') tx = request['cbsd'] if ('fss' in request) and ('ppa' in request): raise ValueError('fss and ppa in request') elif 'ppa' in request: rx = {} rx['height'] = 1.5 isfss = False coordinates = [] ppa = request['ppa'] arcsec = 1 ppa_points = geoutils.GridPolygon(ppa['geometry'], arcsec) if len(ppa_points) == 1: rx['longitude'] = ppa_points[0][0] rx['latitude'] = ppa_points[0][1] elif len(ppa_points) == 0: raise ValueError('ppa boundary contains no protection point') else: raise ValueError( 'ppa boundary contains more than a single protection point') region_val = drive.nlcd_driver.RegionNlcdVote( [[rx['latitude'], rx['longitude']]]) elif 'fss' in request: isfss = True rx = request['fss'] else: raise ValueError('Neither fss nor ppa in request') # ITM pathloss (if receiver type is FSS) or the hybrid model pathloss (if receiver type is PPA) and corresponding antenna gains. # The test specification notes that the SAS UUT shall use default values for w1 and w2 in the ITM model. result = {} if isfss: path_loss = wf_itm.CalcItmPropagationLoss( tx['latitude'], tx['longitude'], tx['height'], rx['latitude'], rx['longitude'], rx['height'], cbsd_indoor=tx['indoorDeployment'], reliability=reliability_level, freq_mhz=3625., is_height_cbsd_amsl=(tx['heightType'] == 'AMSL')) result['pathlossDb'] = path_loss.db_loss gain_tx_rx = antenna.GetStandardAntennaGains( path_loss.incidence_angles.hor_cbsd, ant_azimuth=tx['antennaAzimuth'], ant_beamwidth=tx['antennaBeamwidth'], ant_gain=tx['antennaGain']) result['txAntennaGainDbi'] = gain_tx_rx if 'rxAntennaGainRequired' in rx: hor_dirs = path_loss.incidence_angles.hor_rx ver_dirs = path_loss.incidence_angles.ver_rx gain_rx_tx = antenna.GetFssAntennaGains(hor_dirs, ver_dirs, rx['antennaAzimuth'], rx['antennaElevation'], rx['antennaGain']) result['rxAntennaGainDbi'] = gain_rx_tx else: path_loss = wf_hybrid.CalcHybridPropagationLoss( tx['latitude'], tx['longitude'], tx['height'], rx['latitude'], rx['longitude'], rx['height'], cbsd_indoor=tx['indoorDeployment'], reliability=-1, freq_mhz=3625., region=region_val, is_height_cbsd_amsl=(tx['heightType'] == 'AMSL')) result['pathlossDb'] = path_loss.db_loss gain_tx_rx = antenna.GetStandardAntennaGains( path_loss.incidence_angles.hor_cbsd, ant_azimuth=tx['antennaAzimuth'], ant_beamwidth=tx['antennaBeamwidth'], ant_gain=tx['antennaGain']) result['txAntennaGainDbi'] = gain_tx_rx return result
def test_same_location(self): result = wf_hybrid.CalcHybridPropagationLoss(45, -80, 10, 45, -80, 10) self.assertEqual(result.db_loss, 0) self.assertTupleEqual(result.incidence_angles, (0, 0, 0, 0))
def CalcHybrid(rel, rx_lat, rx_lng): res = wf_hybrid.CalcHybridPropagationLoss(cbsd_lat, cbsd_lon, 10, rx_lat, rx_lng, 1.5, False, rel, freq_mhz, 'SUBURBAN') return res