def performIapForFssBlocking(fss_record, sas_uut_fad_object, sas_th_fad_objects): """Computes post IAP interference margin for FSS Blocking incumbent. FSS protection is provided over blocking pass band. Args: fss_record: A FSS record (dict). sas_uut_fad_object: FAD object from SAS UUT sas_th_fad_object: a list of FAD objects from SAS Test Harness Returns: ap_iap_ref: The post-IAP allowed interference, as a dict formatted as: {latitude : {longitude : [interference(mW/IAPBW), .., interference(mW/IAPBW)]}} where the list holds all values per channel of that protection point. """ # Actual protection threshold used for IAP - calculated by applying # a pre-defined Pre-IAP headroom (Mg) at each protection threshold(Q) fss_blocking_iap_threshold = interf.dbToLinear( THRESH_FSS_BLOCKING_DBM_PER_RBW - MARGIN_FSS_BLOCKING_DB) grants = data.getGrantObjectsFromFAD(sas_uut_fad_object, sas_th_fad_objects) # Get number of SAS num_sas = len(sas_th_fad_objects) + 1 # Get FSS T&C Flag value fss_ttc_flag = fss_record['ttc'] # Get the FSS infos fss_point, fss_info, fss_freq_range = data.getFssInfo(fss_record) fss_low_freq, fss_high_freq = fss_freq_range # FSS Passband is between 3700 and 4200 and TT&C flag is set to FALSE if (fss_low_freq >= interf.FSS_TTC_LOW_FREQ_HZ and fss_high_freq <= interf.FSS_TTC_HIGH_FREQ_HZ and fss_ttc_flag is False): raise Exception( "IAP for FSS not applied for FSS Pass band 3700 to 4200 " "and TT&C flag set to false, please check the inputs.") logging.debug('$$$$ Calling FSS blocking Protection $$$$') # 5MHz channelization is not required for Blocking protection protection_channels = [(interf.CBRS_LOW_FREQ_HZ, fss_low_freq)] iap_interfs = iapPointConstraint(fss_point, protection_channels, interf.CBRS_LOW_FREQ_HZ, fss_low_freq, grants, fss_info, None, None, fss_blocking_iap_threshold, data.ProtectedEntityType.FSS_BLOCKING) ap_iap_ref = calculatePostIapAggregateInterference( interf.dbToLinear(THRESH_FSS_BLOCKING_DBM_PER_RBW), num_sas, iap_interfs) return ap_iap_ref
def performIapForFssCochannel(fss_record, sas_uut_fad_object, sas_th_fad_objects): """Computes post IAP interference margin for FSS Co-channel incumbent. FSS protection is provided over co-channel pass band. Args: fss_record: A FSS record (dict). sas_uut_fad_object: A FAD object from SAS UUT sas_th_fad_object: A list of FAD objects from SAS Test Harness Returns: ap_iap_ref: The post-IAP allowed interference, as a dict formatted as: {latitude : {longitude : [interference(mW/IAPBW), .., interference(mW/IAPBW)]}} where the list holds all values per channel of that protection point. """ fss_cochannel_thresh_q = THRESH_FSS_CO_CHANNEL_DBM_PER_IAPBW # Actual protection threshold used for IAP - calculated by applying # a pre-defined Pre-IAP headroom (Mg) at each protection threshold(Q) fss_cochannel_iap_threshold = interf.dbToLinear(fss_cochannel_thresh_q - MARGIN_FSS_CO_CHANNEL_DB) grants = data.getGrantObjectsFromFAD(sas_uut_fad_object, sas_th_fad_objects) # Get number of SAS num_sas = len(sas_th_fad_objects) + 1 # Get the FSS infos fss_point, fss_info, fss_freq_range = data.getFssInfo(fss_record) fss_low_freq, fss_high_freq = fss_freq_range # Get channels for co-channel CBSDs if fss_high_freq < interf.CBRS_HIGH_FREQ_HZ: raise ValueError( 'FSS high frequency should not be less than CBRS high frequency(Hz)' ) protection_channels = interf.getProtectedChannels(fss_low_freq, interf.CBRS_HIGH_FREQ_HZ) # FSS Co-channel algorithm logging.debug('$$$$ Calling FSS co-channel Protection $$$$') iap_interfs = iapPointConstraint(fss_point, protection_channels, fss_low_freq, interf.CBRS_HIGH_FREQ_HZ, grants, fss_info, None, None, fss_cochannel_iap_threshold, data.ProtectedEntityType.FSS_CO_CHANNEL) ap_iap_ref = calculatePostIapAggregateInterference( interf.dbToLinear(fss_cochannel_thresh_q), num_sas, iap_interfs) return ap_iap_ref
def SetGrantsFromFad(self, sas_uut_fad, sas_th_fads): """Sets the list of grants. Args: sas_uut_fad: The FAD object of SAS UUT, or None if none. sas_th_fads: A list of FAD objects of other SAS test harness, or None if none. """ # Manages the possibility of None for the FADs. if sas_uut_fad is None: sas_uut_fad = _EmptyFad() if sas_th_fads is None: sas_th_fads = [] # TODO(sbdt): optim = pre-filtering of grants in global DPA neighborhood. self._grants = data.getGrantObjectsFromFAD(sas_uut_fad, sas_th_fads) self.ResetLists() self._has_th_grants = self._DetectIfPeerSas()
def performIapForEsc(esc_record, sas_uut_fad_object, sas_th_fad_objects): """Computes post IAP interference margin for ESC. IAP algorithm is run over ESC passband 3550-3660MHz for Category A CBSDs and 3550-3680MHz for Category B CBSDs. Args: esc_record: An ESC record (dict of schema |EscSensorRecord|). sas_uut_fad_object: FAD object from SAS UUT sas_th_fad_objects: A list of FAD objects from SAS Test Harness Returns: ap_iap_ref: The post-IAP allowed interference, as a dict formatted as: {latitude : {longitude : [interference(mW/IAPBW), .., interference(mW/IAPBW)]}} where the list holds all values per channel of that protection point. """ esc_thresh_q = THRESH_ESC_DBM_PER_IAPBW # Actual protection threshold used for IAP - calculated by applying # a pre-defined Pre-IAP headroom (Mg) at each protection threshold(Q) esc_iap_threshold = interf.dbToLinear(esc_thresh_q - MARGIN_ESC_DB) grants = data.getGrantObjectsFromFAD(sas_uut_fad_object, sas_th_fad_objects) # Get number of SAS num_sas = len(sas_th_fad_objects) + 1 # Get the ESC infos protection_point, esc_antenna_info = data.getEscInfo(esc_record) # Get ESC passband 3550-3680 MHz protection channels protection_channels = interf.getProtectedChannels(interf.ESC_LOW_FREQ_HZ, interf.ESC_HIGH_FREQ_HZ) logging.debug('$$$$ Calling ESC Protection $$$$') # ESC algorithm iap_interfs = iapPointConstraint(protection_point, protection_channels, interf.ESC_LOW_FREQ_HZ, interf.ESC_HIGH_FREQ_HZ, grants, None, esc_antenna_info, None, esc_iap_threshold, data.ProtectedEntityType.ESC) ap_iap_ref = calculatePostIapAggregateInterference( interf.dbToLinear(esc_thresh_q), num_sas, iap_interfs) return ap_iap_ref
def performIapForPpa(ppa_record, sas_uut_fad_object, sas_th_fad_objects, pal_records): """Computes post IAP interference margin for PPA incumbents. Routine to get protection points within PPA protection area and perform IAP algorithm on each protection point. Args: ppa_record: A PPA record dict. sas_uut_fad_object: A FAD object from SAS UUT. sas_th_fad_object: A list of FAD objects from SAS Test Harness pal_records: PAL records associated with a PPA protection area Returns: ap_iap_ref: The post-IAP allowed interference, as a dict formatted as: {latitude : {longitude : [interference(mW/IAPBW), .., interference(mW/IAPBW)]}} where the list holds all values per channel of that protection point. """ ppa_thresh_q = THRESH_PPA_DBM_PER_IAPBW # Actual protection threshold used for IAP - calculated by applying # a pre-defined Pre-IAP headroom (Mg) at each protection threshold(Q) ppa_iap_threshold = interf.dbToLinear(ppa_thresh_q - MARGIN_PPA_DB) grants = data.getGrantObjectsFromFAD(sas_uut_fad_object, sas_th_fad_objects, ppa_record) # Get number of SAS num_sas = len(sas_th_fad_objects) + 1 logging.debug('$$$$ Getting GRID points for PPA Protection Area $$$$') # Get Fine Grid Points for a PPA protection area protection_points = utils.GridPolygon( ppa_record['zone']['features'][0]['geometry'], PPA_GRID_RES_ARCSEC) # Get the region type of the PPA protection area ppa_region = ppa_record['ppaInfo']['ppaRegionType'] # Find the PAL records for the PAL_IDs defined in PPA records ppa_pal_ids = ppa_record['ppaInfo']['palId'] matching_pal_records = [ pr for pr in pal_records if pr['palId'] == ppa_pal_ids[0] ] if not matching_pal_records: raise ValueError('No matching PAL record, please check input') pal_record = matching_pal_records[0] # Get the frequencies from the PAL records ppa_freq_range = pal_record['channelAssignment']['primaryAssignment'] ppa_low_freq = ppa_freq_range['lowFrequency'] ppa_high_freq = ppa_freq_range['highFrequency'] # Get channels over which area incumbent needs partial/full protection protection_channels = interf.getProtectedChannels(ppa_low_freq, ppa_high_freq) # Apply IAP for each protection constraint with a pool of parallel # processes. logging.debug('$$$$ Calling PPA Protection $$$$') iapPoint = partial(iapPointConstraint, channels=protection_channels, low_freq=ppa_low_freq, high_freq=ppa_high_freq, grants=grants, fss_info=None, esc_antenna_info=None, region_type=ppa_region, threshold=ppa_iap_threshold, protection_ent_type=data.ProtectedEntityType.PPA_AREA) pool = mpool.Pool() iap_interfs = pool.map(iapPoint, protection_points) ap_iap_ref = calculatePostIapAggregateInterference( interf.dbToLinear(ppa_thresh_q), num_sas, iap_interfs) return ap_iap_ref
def performIapForGwpz(gwpz_record, sas_uut_fad_object, sas_th_fad_objects): """Computes post IAP interference margin for GWPZ incumbents. Routine to get protection points within GWPZ protection area and perform IAP algorithm on each protection point. Args: gwpz_record: A GWPZ record dict. sas_uut_fad_object: FAD object from SAS UUT sas_th_fad_objects: A list of FAD objects from SAS Test Harness Returns: ap_iap_ref: The post-IAP allowed interference, as a dict formatted as: {latitude : {longitude : [interference(mW/IAPBW), .., interference(mW/IAPBW)]}} where the list holds all values per channel of that protection point. """ gwpz_thresh_q = THRESH_GWPZ_DBM_PER_IAPBW # Actual protection threshold used for IAP - calculated by applying # a pre-defined Pre-IAP headroom (Mg) at each protection threshold(Q) gwpz_iap_threshold = interf.dbToLinear(gwpz_thresh_q - MARGIN_GWPZ_DB) grants = data.getGrantObjectsFromFAD(sas_uut_fad_object, sas_th_fad_objects) # Get number of SAS num_sas = len(sas_th_fad_objects) + 1 logging.debug('$$$$ Getting GRID points for GWPZ Protection Area $$$$') # Get Fine Grid Points for a GWPZ protection area protection_points = utils.GridPolygon( gwpz_record['zone']['features'][0]['geometry'], GWPZ_GRID_RES_ARCSEC) gwpz_freq_range = gwpz_record['record']['deploymentParam'][0]\ ['operationParam']['operationFrequencyRange'] gwpz_low_freq = gwpz_freq_range['lowFrequency'] gwpz_high_freq = gwpz_freq_range['highFrequency'] gwpz_region = gwpz_record['landCategory'] # Get channels over which area incumbent needs partial/full protection protection_channels = interf.getProtectedChannels(gwpz_low_freq, gwpz_high_freq) logging.debug('$$$$ Calling GWPZ Protection $$$$') iapPoint = partial(iapPointConstraint, channels=protection_channels, low_freq=gwpz_low_freq, high_freq=gwpz_high_freq, grants=grants, fss_info=None, esc_antenna_info=None, region_type=gwpz_region, threshold=gwpz_iap_threshold, protection_ent_type=data.ProtectedEntityType.GWPZ_AREA) pool = mpool.Pool() iap_interfs = pool.map(iapPoint, protection_points) ap_iap_ref = calculatePostIapAggregateInterference( interf.dbToLinear(gwpz_thresh_q), num_sas, iap_interfs) return ap_iap_ref