Example #1
0
    def _calc_transmit_power(SNR_dB, N0_dBm, cell_radius, path_loss_obj):
        """
        Calculates the required transmit power (in linear scale) to
        achieve the desired mean SNR value at the cell border.

        This method calculates the path loss at the cell border and
        then finds the transmit power that gives the desired mean SNR
        at the cell border.

        Parameters
        ----------
        SNR_dB : float
            SNR value (in dB)
        N0_dBm : float
            Noise power (in dBm)
        cell_radius : float
            Cell radius (in Km)
        path_loss_obj : Path Loss object
            Object of a pathloss class used to calculate the path loss (see
            `comm.pathloss`.

        Returns
        -------
        transmit_power : float
            Desired transmit power (in linear scale).
        """
        # Path loss (in linear scale) from the cell center to
        path_loss_border = path_loss_obj.calc_path_loss(cell_radius)
        snr = dB2Linear(SNR_dB)
        pt = snr * dBm2Linear(N0_dBm) / path_loss_border
        return pt
Example #2
0
    def _calc_transmit_power(SNR_dB, N0_dBm, cell_radius, path_loss_obj):
        """
        Calculates the required transmit power (in linear scale) to
        achieve the desired mean SNR value at the cell border.

        This method calculates the path loss at the cell border and
        then finds the transmit power that gives the desired mean SNR
        at the cell border.

        Parameters
        ----------
        SNR_dB : float
            SNR value (in dB)
        N0_dBm : float
            Noise power (in dBm)
        cell_radius : float
            Cell radius (in Km)
        path_loss_obj : Path Loss object
            Object of a pathloss class used to calculate the path loss (see
            `comm.pathloss`.

        Returns
        -------
        transmit_power : float
            Desired transmit power (in linear scale).
        """
        # Path loss (in linear scale) from the cell center to
        path_loss_border = path_loss_obj.calc_path_loss(cell_radius)
        snr = dB2Linear(SNR_dB)
        pt = snr * dBm2Linear(N0_dBm) / path_loss_border
        return pt
Example #3
0
    def _on_simulate_current_params_start(self, current_params):
        # IMPORTANT: Re-seed the channel and the noise RandomState
        # objects. Without this, when you perform the simulation in
        # parallel (call the simulate_in_parallel method(from the
        # SimulationRunner class) you will get the same channel samples and
        # noise for all parallel process.
        self.multiUserChannel.re_seed()

        if current_params['scenario'] == 'NoPathLoss':
            self.noise_var = 1.0
            self.multiUserChannel.noise_var = self.noise_var
        else:
            self.noise_var = dBm2Linear(self.params['N0'])
            self.multiUserChannel.noise_var = self.noise_var

        self.ia_solver.max_iterations = current_params['max_iterations']

        # Parameter choosing the stream selection method. The value can be
        # either 'greedy' or 'brute'. The value 'none' is also accepted, in
        # which case no stream selection is performed.
        alg = current_params['stream_sel_method']
        # Create the 'top' IA solver object: either "greedy" or the "brute
        # force" depending on the value of the 'stream_sel_method'
        # parameter. This object will use the basic IA solver object.  Note
        # that if 'stream_sel_method' is equal to 'none' then no IA
        # top object will be used and self.ia_top_object is set to
        # self.ia_solver so that we run the regular IA algorithm.
        if alg == 'greedy':
            self.ia_top_object = algorithms.GreedStreamIASolver(self.ia_solver)
        elif alg == 'brute':
            self.ia_top_object = algorithms.BruteForceStreamIASolver(
                self.ia_solver)
        elif alg == 'none':
            # For the no stream selection case the IA top object will be
            # the same as the IA basic object
            self.ia_top_object = self.ia_solver
        else:
            raise ValueError(
                "Invalid stream selection method: '{0}'".format(alg))
Example #4
0
    def _on_simulate_current_params_start(self, current_params):
        # IMPORTANT: Re-seed the channel and the noise RandomState
        # objects. Without this, when you perform the simulation in
        # parallel (call the simulate_in_parallel method(from the
        # SimulationRunner class) you will get the same channel samples and
        # noise for all parallel process.
        self.multiUserChannel.re_seed()

        if current_params["scenario"] == "NoPathLoss":
            self.noise_var = 1.0
            self.multiUserChannel.noise_var = self.noise_var
        else:
            self.noise_var = dBm2Linear(self.params["N0"])
            self.multiUserChannel.noise_var = self.noise_var

        self.ia_solver.max_iterations = current_params["max_iterations"]

        # Parameter choosing the stream selection method. The value can be
        # either 'greedy' or 'brute'. The value 'none' is also accepted, in
        # which case no stream selection is performed.
        alg = current_params["stream_sel_method"]
        # Create the 'top' IA solver object: either "greedy" or the "brute
        # force" depending on the value of the 'stream_sel_method'
        # parameter. This object will use the basic IA solver object.  Note
        # that if 'stream_sel_method' is equal to 'none' then no IA
        # top object will be used and self.ia_top_object is set to
        # self.ia_solver so that we run the regular IA algorithm.
        if alg == "greedy":
            self.ia_top_object = algorithms.GreedStreamIASolver(self.ia_solver)
        elif alg == "brute":
            self.ia_top_object = algorithms.BruteForceStreamIASolver(self.ia_solver)
        elif alg == "none":
            # For the no stream selection case the IA top object will be
            # the same as the IA basic object
            self.ia_top_object = self.ia_solver
        else:
            raise ValueError("Invalid stream selection method: '{0}'".format(alg))
# External Interference Parameters
Pe_dBm = -10000  # transmit power (in dBm) of the ext. interference
ext_int_rank = 1  # Rank of the external interference

# xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
rep_max = 20000  # Maximum number of repetitions for each

pbar = progressbar.ProgressbarText(rep_max, message="Simulating for SNR: {0}".format(SNR_dB))

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxx Dependent parameters (don't change these) xxxxxxxxxxxx
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Path loss (in linear scale) from the cell center to
path_loss_border = path_loss_obj.calc_path_loss(cell_radius)
noise_var = conversion.dBm2Linear(N0_dBm)
snr = conversion.dB2Linear(SNR_dB)
transmit_power = snr * noise_var / path_loss_border
# External interference power
pe = conversion.dBm2Linear(Pe_dBm)

# Cell Grid
cell_grid = cell.Grid()
cell_grid.create_clusters(num_clusters, num_cells, cell_radius)
# noinspection PyProtectedMember
cluster0 = cell_grid._clusters[0]
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# xxxxxxxxxx Create the scenario xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
def perform_simulation_SINR_heatmap(scenario_params, power_params):  # pylint: disable=R0914
    """
    Perform the simulation.
    """
    # xxxxxxxxxx Simulation Scenario Configuration xxxxxxxxxxxxxxxxxxxxxxxx
    # The size of the side of each square room
    side_length = scenario_params["side_length"]
    # How much (in dB) is lost for each wall teh signal has to pass
    single_wall_loss_dB = scenario_params["single_wall_loss_dB"]

    # Square of 12 x 12 square rooms
    num_rooms_per_side = scenario_params["num_rooms_per_side"]
    # Total number of rooms in the grid
    num_rooms = num_rooms_per_side ** 2

    # 1 means 1 ap every room. 2 means 1 ap every 2 rooms and so on. Valid
    # values are: 1, 2, 4 and 9.
    ap_decimation = scenario_params["ap_decimation"]
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Simulation Power Configuration xxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Transmit power of each access point
    Pt_dBm = power_params["Pt_dBm"]
    noise_power_dBm = power_params["noise_power_dBm"]

    Pt = dBm2Linear(Pt_dBm)  # 20 dBm transmit power
    noise_var = dBm2Linear(noise_power_dBm)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Discretization of the possible positions xxxxxxxxxxxxxxxxx
    num_discrete_positions_per_room = 15  # Number of discrete positions
    step = 1.0 / num_discrete_positions_per_room
    aux = np.linspace(-(1.0 - step), (1.0 - step), num_discrete_positions_per_room)
    aux = np.meshgrid(aux, aux, indexing="ij")
    user_relative_positions = aux[1] + 1j * aux[0][::-1]
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the positions of all rooms xxxxxxxxxxxxxxxxxxxxx
    room_positions = calc_room_positions_square(side_length, num_rooms)
    room_positions.shape = (num_rooms_per_side, num_rooms_per_side)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Create the path loss object xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    pl_3gpp_obj = pathloss.PathLoss3GPP1()
    pl_free_space_obj = pathloss.PathLossFreeSpace()
    pl_3gpp_obj.handle_small_distances_bool = True
    pl_free_space_obj.handle_small_distances_bool = True
    pl_metis_ps7_obj = pathloss.PathLossMetisPS7()
    pl_metis_ps7_obj.handle_small_distances_bool = True
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxx Add one user in each discrete position of each room xxxxxxxxxx
    user_relative_positions2 = user_relative_positions * side_length / 2.0
    user_positions = (
        room_positions[:, :, np.newaxis, np.newaxis] + user_relative_positions2[np.newaxis, np.newaxis, :, :]
    )
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx AP Allocation xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # 1 AP in each room
    ap_positions = get_ap_positions(room_positions, ap_decimation)
    num_aps = ap_positions.size
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate distances: each user to each AP xxxxxxxxxxxxxxxx
    # Dimension: (romm_row, room_c, user_row, user_col, num_APs)
    dists_m = np.abs(user_positions[:, :, :, :, np.newaxis] - ap_positions.reshape([1, 1, 1, 1, -1]))
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate AP association xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Determine with which AP each user is associated with.
    # Each user will associate with the CLOSEST access point.
    ap_assoc = np.argmin(dists_m, axis=-1)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate wall losses xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # We want to calculate the number walls from each room to the rooms
    # which have an access point.
    # Dimension is (num_rooms, num_aps)
    num_walls = calc_num_walls(side_length, room_positions, ap_positions)
    # Reshape it to (num_rooms_per_side, num_rooms_per_side, 1, 1, num_aps)
    num_walls_extended = num_walls.reshape([num_rooms_per_side, num_rooms_per_side, 1, 1, num_aps])
    # And finally broadcast the (1, 1) dimensions to the number of users
    # per room. This will make num_walls_extended have the same dimension
    # as dists_m.
    num_walls_extended, _ = np.broadcast_arrays(num_walls_extended, dists_m)

    wall_losses_dB = num_walls_extended * single_wall_loss_dB
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the path losses xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # The METIS PS7 path loss model require distance values in meters,
    # while the others are in Kms. All distances were calculates in meters
    # and, therefore, we divide the distance in by 1000 for 3GPP and free
    # space.
    pl_3gpp = pl_3gpp_obj.calc_path_loss(dists_m / 1000.0)
    pl_free_space = pl_free_space_obj.calc_path_loss(dists_m / 1000.0)
    pl_nothing = np.ones(
        [
            num_rooms_per_side,
            num_rooms_per_side,
            num_discrete_positions_per_room,
            num_discrete_positions_per_room,
            num_aps,
        ],
        dtype=float,
    )

    # We need to know the number of walls the signal must pass to reach the
    # receiver to calculate the path loss for the METIS PS7 model.
    pl_metis_ps7 = pl_metis_ps7_obj.calc_path_loss(dists_m, num_walls=num_walls_extended)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the SINRs for each path loss model xxxxxxxxxxxxx
    sinr_array_pl_nothing_dB = simulate_for_a_given_ap_assoc(pl_nothing, ap_assoc, wall_losses_dB, Pt, noise_var)

    sinr_array_pl_3gpp_dB = simulate_for_a_given_ap_assoc(pl_3gpp, ap_assoc, wall_losses_dB, Pt, noise_var)

    sinr_array_pl_free_space_dB = simulate_for_a_given_ap_assoc(pl_free_space, ap_assoc, wall_losses_dB, Pt, noise_var)

    sinr_array_pl_metis_ps7_dB = simulate_for_a_given_ap_assoc(pl_metis_ps7, ap_assoc, wall_losses_dB, Pt, noise_var)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    out = (sinr_array_pl_nothing_dB, sinr_array_pl_3gpp_dB, sinr_array_pl_free_space_dB, sinr_array_pl_metis_ps7_dB)
    return out
Example #7
0
    def __init__(self, read_command_line_args=True, save_parsed_file=False):
        default_config_file = 'bd_config_file.txt'

        # xxxxxxxxxx Simulation Parameters Specification xxxxxxxxxxxxxxxxxx
        spec = """[Grid]
        cell_radius=float(min=0.01, default=1.0)
        num_cells=integer(min=3,default=3)
        num_clusters=integer(min=1,default=1)

        [Scenario]
        NSymbs=integer(min=10, max=1000000, default=500)
        SNR=real_numpy_array(min=-50, max=100, default=0:3:31)
        Pe_dBm=real_numpy_array(min=-50, max=100, default=[-10. 0. 10.])
        Nr=integer(default=2)
        Nt=integer(default=2)
        N0=float(default=-116.4)
        ext_int_rank=integer(min=1,default=1)
        user_positioning_method=option("Random", 'Symmetric Far Away', default="Symmetric Far Away")

        [Modulation]
        M=integer(min=4, max=512, default=4)
        modulator=option('QPSK', 'PSK', 'QAM', 'BPSK', default="PSK")
        packet_length=integer(min=1,default=60)

        [General]
        rep_max=integer(min=1, default=5000)
        unpacked_parameters=string_list(default=list('SNR','Pe_dBm'))

        """.split("\n")
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Initialize parameters configuration xxxxxxxxxxxxxxxxxx
        # Among other things, this will create the self.params object with
        # the simulation parameters read from the config file.
        SimulationRunner.__init__(
            self,
            default_config_file=default_config_file,
            config_spec=spec,
            read_command_line_args=read_command_line_args,
            save_parsed_file=save_parsed_file)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Channel Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        self.path_loss_obj = pathloss.PathLoss3GPP1()
        self.multiuser_channel = multiuser.MultiUserChannelMatrixExtInt()
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx RandomState objects seeds xxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # This is only useful to reproduce a simulation for debugging
        # purposed
        channel_seed = None  # 22522
        self.noise_seed = None  # 4445
        self.data_gen_seed = np.random.randint(10000)  # 2105
        ext_data_gen_seed = None  # 6114
        #
        self.multiuser_channel.set_channel_seed(channel_seed)
        self.multiuser_channel.set_noise_seed(self.noise_seed)
        self.data_RS = np.random.RandomState(self.data_gen_seed)
        self.ext_data_RS = np.random.RandomState(ext_data_gen_seed)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Creates the modulator object xxxxxxxxxxxxxxxxxxxxxxxxx
        M = self.params['M']
        modulator_options = {
            'PSK': fundamental.PSK,
            'QPSK': fundamental.QPSK,
            'QAM': fundamental.QAM,
            'BPSK': fundamental.BPSK
        }
        self.modulator = modulator_options[self.params['modulator']](M)
        ":type: fundamental.PSK | fundamental.QPSK | fundamental.QAM | fundamental.BPSK"

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Maximum number of repetitions for each unpacked parameters set
        # self.params self.results
        self.rep_max = self.params['rep_max']

        # # max_bit_errors is used in the _keep_going method to stop the
        # # simulation earlier if possible. We stop the simulation if the
        # # accumulated number of bit errors becomes greater then 5% of the
        # # total number of simulated bits
        # self.max_bit_errors = self.rep_max * NSymbs * 5. / 100.

        self.progressbar_message = "SNR: {SNR}, Pe_dBm: {Pe_dBm}"

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # xxxxxxxxxx Dependent parameters (don't change these) xxxxxxxxxxxx
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # These two will be set in the _on_simulate_current_params_start
        # method
        self.pe = 0

        # Path loss (in linear scale) from the cell center to
        # self.path_loss_border = self.path_loss_obj.calc_path_loss(
        #     self.cell_radius)

        # Cell Grid
        self.cell_grid = cell.Grid()
        self.cell_grid.create_clusters(self.params['num_clusters'],
                                       self.params['num_cells'],
                                       self.params['cell_radius'])
        self.noise_var = dBm2Linear(self.params['N0'])
        self.multiuser_channel.noise_var = self.noise_var

        # This can be either 'screen' or 'file'. If it is 'file' then the
        # progressbar will write the progress to a file with appropriated
        # filename
        self.progress_output_type = 'screen'
Example #8
0
    def _on_simulate_current_params_start(self, current_params):
        """This method is called once for each combination of transmit
        parameters.
        """
        # pylint: disable=W0201

        # IMPORTANT: Re-seed the channel and the noise RandomState
        # objects. Without this, when you perform the simulation in
        # parallel (call the simulate_in_parallel method(from the
        # SimulationRunner class) you will get the same channel samples and
        # noise for all parallel process.
        self.multiuser_channel.re_seed()

        # xxxxx Calculates the transmit power at each base station. xxxxxxx
        # Because this value does not change in the different iterations of
        # _run_simulation, but only when the parameters change the
        # calculation is performed here in the
        # _on_simulate_current_params_start.
        transmit_power = BDSimulationRunner._calc_transmit_power(
            current_params['SNR'], current_params['N0'],
            current_params['cell_radius'], self.path_loss_obj)

        # External interference power
        self.pe = dBm2Linear(current_params['Pe_dBm'])

        # xxxxx Create the BD object with the None metric xxxxxxxxxxxxxxxxx
        self.bd_obj_None = EnhancedBD(current_params['num_cells'],
                                      transmit_power, self.noise_var, self.pe)
        self.bd_obj_None.set_ext_int_handling_metric(
            "None", {
                'modulator': self.modulator,
                'packet_length': current_params['packet_length'],
                'num_streams': 1
            })
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with the Naive metric xxxxxxxxxxxxxxxx
        self.bd_obj_naive = EnhancedBD(current_params['num_cells'],
                                       transmit_power, self.noise_var, self.pe)
        self.bd_obj_naive.set_ext_int_handling_metric(
            "naive", {
                'modulator': self.modulator,
                'packet_length': current_params['packet_length'],
                'num_streams': 1
            })
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with the fixed metric xxxxxxxxxxxxxxxx
        self.bd_obj_fixed = EnhancedBD(current_params['num_cells'],
                                       transmit_power, self.noise_var, self.pe)
        self.bd_obj_fixed.set_ext_int_handling_metric(
            "fixed", {
                'modulator': self.modulator,
                'packet_length': current_params['packet_length'],
                'num_streams': 1
            })
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with the capacity metric xxxxxxxxxxxxx
        self.bd_obj_capacity = EnhancedBD(current_params['num_cells'],
                                          transmit_power, self.noise_var,
                                          self.pe)
        self.bd_obj_capacity.set_ext_int_handling_metric(
            "capacity", {
                'modulator': self.modulator,
                'packet_length': current_params['packet_length'],
                'num_streams': 1
            })
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xx Create the BD object with the effective_throughput metric xxxx
        self.bd_obj_effec_throughput = EnhancedBD(current_params['num_cells'],
                                                  transmit_power,
                                                  self.noise_var, self.pe)
        self.bd_obj_effec_throughput.set_ext_int_handling_metric(
            "effective_throughput", {
                'modulator': self.modulator,
                'packet_length': current_params['packet_length'],
                'num_streams': 1
            })
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with whitening xxxxxxxxxxxxxxxxxxxxxxx
        self.bd_obj_whitening = WhiteningBD(current_params['num_cells'],
                                            transmit_power, self.noise_var,
                                            self.pe)
def perform_simulation(
        scenario_params,  # pylint: disable=R0914
        power_params,
        plot_results_bool=True):
    """
    Run the simulation.
    """
    # xxxxxxxxxx Simulation Scenario Configuration xxxxxxxxxxxxxxxxxxxxxxxx
    # The size of the side of each square room
    side_length = scenario_params['side_length']
    # How much (in dB) is lost for each wall teh signal has to pass
    single_wall_loss_dB = scenario_params['single_wall_loss_dB']

    # Square of 12 x 12 square rooms
    num_rooms_per_side = scenario_params['num_rooms_per_side']
    # Total number of rooms in the grid
    num_rooms = num_rooms_per_side**2

    # 1 means 1 ap every room. 2 means 1 ap every 2 rooms and so on. Valid
    # values are: 1, 2, 4 and 9.
    ap_decimation = scenario_params['ap_decimation']
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Simulation Power Configuration xxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Transmit power of each access point
    Pt_dBm = power_params['Pt_dBm']
    noise_power_dBm = power_params['noise_power_dBm']

    Pt = dBm2Linear(Pt_dBm)  # 20 dBm transmit power
    noise_var = dBm2Linear(noise_power_dBm)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the positions of all rooms xxxxxxxxxxxxxxxxxxxxx
    room_positions = calc_room_positions_square(side_length, num_rooms)
    room_positions.shape = (num_rooms_per_side, num_rooms_per_side)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Create the path loss object xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    pl_metis_ps7_obj = pathloss.PathLossMetisPS7()
    pl_metis_ps7_obj.handle_small_distances_bool = True
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Add users in random positions in the 2D grid xxxxxxxxxxxxx
    num_users = 100  # We will create this many users in the 2D grid
    users_positions = (num_rooms_per_side * side_length *
                       (np.random.random_sample(num_users) +
                        1j * np.random.random_sample(num_users) - 0.5 - 0.5j))
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx AP Allocation xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # 1 AP in each room
    ap_positions = get_ap_positions(room_positions, ap_decimation)
    num_aps = ap_positions.size
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate distances: each user to each AP xxxxxxxxxxxxxxxx
    # Dimension: (num_users, num_APs)
    dists_m = np.abs(users_positions[:, np.newaxis] -
                     ap_positions[np.newaxis, :])
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxx Calculate AP association xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # INPUTS
    # Find in which room each user is
    users_rooms = np.argmin(np.abs(
        room_positions.reshape([-1, 1]) - users_positions[np.newaxis, :]),
                            axis=0)

    # Number of walls from each room to each other room
    num_walls_all_rooms = calc_num_walls(side_length, room_positions,
                                         ap_positions)
    # Number of walls from each room that has at least one user to each
    # room with an AP
    num_walls_rooms_with_users = num_walls_all_rooms[users_rooms]

    # Path loss from each user to each AP (no matter if it will be a
    # transmitting AP or not, since we still have to perform the AP
    # association)
    pl_all = pl_metis_ps7_obj.calc_path_loss(
        dists_m, num_walls=num_walls_rooms_with_users)

    # Calculate wall losses from each user to each AP (no matter if it will
    # be a transmitting AP or not, since we still have to perform the AP
    # association)
    wall_losses_dB_all = num_walls_rooms_with_users * single_wall_loss_dB

    # Calculate path loss plus wall losses (we multiply the linear values)
    # from each user to each AP (no matter if it will be a transmitting AP
    # or not, since we still have to perform the AP association)
    pl_all_plus_wl = pl_all * dB2Linear(-wall_losses_dB_all)

    # OUTPUTS
    # Determine with which AP each user is associated with.
    # Each user will associate with the CLOSEST access point.
    ap_assoc = find_ap_assoc_best_channel(pl_all_plus_wl)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Find which Access Points should stay on xxxxxxxxxxxxxxxxxx
    # Indexes of the active APs
    transmitting_aps, users_count = np.unique(ap_assoc, return_counts=True)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the SINRs for each path loss model xxxxxxxxxxxxx
    # Take the path loss plus wall losses only for the transmitting aps
    pl_all_plus_wall_losses_tx_aps = pl_all_plus_wl.take(transmitting_aps,
                                                         axis=1)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the SINRs and capacity xxxxxxxxxxxxxxxxxxxxxxxxx
    sinr_array_pl_metis_ps7_dB, capacity_metis_ps7 \
        = simulate_for_a_given_ap_assoc(
            pl_all_plus_wall_losses_tx_aps, ap_assoc,
            transmitting_aps, Pt, noise_var)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxx Plot the results xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    if plot_results_bool is True:
        print(("\nMin/Mean/Max SINR value (METIS PS7):"
               "\n    {0}\n    {1}\n    {2}").format(
                   sinr_array_pl_metis_ps7_dB.min(),
                   sinr_array_pl_metis_ps7_dB.mean(),
                   sinr_array_pl_metis_ps7_dB.max()))

        print(("\nMin/Mean/Max Capacity value (METIS PS7):"
               "\n    {0}\n    {1}\n    {2}").format(capacity_metis_ps7.min(),
                                                     capacity_metis_ps7.mean(),
                                                     capacity_metis_ps7.max()))

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # xxxxxxxxxxxxxxx Plot the results xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Create a mask for the active APs
        transmitting_aps_mask = np.zeros(num_aps, dtype=bool)
        transmitting_aps_mask[transmitting_aps] = True

        # Save how many users are associated with each AP
        users_per_ap = np.zeros(num_aps, dtype=int)
        users_per_ap[transmitting_aps_mask] = users_count

        # xxxxxxxxxx Plot all rooms and users xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        all_rooms = [
            shapes.Rectangle(pos - side_length / 2. - side_length * 1j / 2.,
                             pos + side_length / 2. + side_length * 1j / 2.)
            for pos in room_positions.flatten()
        ]

        # Plot all Rooms and save the axis where they were plotted
        plt.figure(figsize=(10, 10))
        gs = gridspec.GridSpec(2, 1, height_ratios=[4, 1])
        # ax1 is where we will plot everything
        ax1 = plt.subplot(gs[0])
        ax1.set_xlabel("Position X coordinate")
        ax1.set_ylabel("Position Y coordinate")
        ax1.set_title("Plot of all Rooms")
        ax1.set_ylim([-60, 60])
        ax1.set_xlim([-60, 60])
        ax1 = plot_all_rooms(all_rooms, ax1)
        ax1.hold(True)

        # ax2 will be used for annotations
        ax2 = plt.subplot(gs[1])
        plt.setp(ax2.get_xticklabels(), visible=False)
        plt.setp(ax2.get_yticklabels(), visible=False)
        ax2.set_ylim([0, 10])
        ax2.set_xlim([0, 10])
        details = ax2.text(5,
                           5,
                           'Details',
                           verticalalignment='center',
                           horizontalalignment='center',
                           family='monospace')

        # Set the an array with colors for the access points. Transmitting APs
        # will be blue, while inactive APs will be gray
        ap_colors = np.empty(ap_positions.shape, dtype='U4')
        ap_colors[transmitting_aps_mask] = 'b'
        ap_colors[np.logical_not(transmitting_aps_mask)] = 'gray'

        # Plot the access points. We set linewidth to 0.0 so that there is no
        # border. We set the size ('s' keyword) to 50 to make it larger. The
        # colors are set according to the ap_colors array.
        # Note that we set a 5 points tolerance for the pick event.
        aps_plt = ax1.scatter(ap_positions.real,
                              ap_positions.imag,
                              marker='^',
                              c=ap_colors,
                              linewidths=0.1,
                              s=50,
                              picker=3)

        # Plot the users
        # Note that we set a 5 points tolerance for the pick event.
        users_plt = ax1.scatter(users_positions.real,
                                users_positions.imag,
                                marker='*',
                                c='r',
                                linewidth=0.1,
                                s=50,
                                picker=3)

        # xxxxxxxxxx Define a function to call for the pick_event Circle used
        # to select an AP. We will set its visibility to False here. When an AP
        # is selected, we move this circle to its position and set its
        # visibility to True.
        selected_ap_circle = ax1.plot([0], [0],
                                      'o',
                                      ms=12,
                                      alpha=0.4,
                                      color='yellow',
                                      visible=False)[0]

        # Define the callback function for the pick event
        def on_pick(event):
            """Callback for the pick event in the matplotlib plot."""
            # We will reset users colors on each pick
            users_colors = np.empty(ap_assoc.size, dtype='U1')
            users_colors[:] = 'r'

            # Index of the point clicked
            ind = event.ind[0]

            if event.artist == aps_plt:
                # Disable the circle in the AP
                selected_ap_circle.set_visible(False)

                if ind not in ap_assoc:
                    # Text information for the disabled AP
                    text = "AP {0} (Disabled)".format(ind)
                else:
                    # Text information for the selected AP
                    text = "AP {0} with {1} user(s)\nTotal throughput: {2:7.4f}"
                    text = text.format(
                        ind, users_per_ap[ind],
                        np.sum(capacity_metis_ps7[ap_assoc == ind]))

                    # Change the colors of the users associated with the
                    # current AP to green
                    users_colors[ap_assoc == ind] = 'g'

            elif event.artist == users_plt:
                # Text information for the selected user
                text = "User {0}\n    SINR: {1:7.4f}\nCapacity: {2:7.4f}".format(
                    ind, sinr_array_pl_metis_ps7_dB[ind],
                    capacity_metis_ps7[ind])

                # If there other users are associated with the same AP of the
                # current user
                if users_per_ap[ap_assoc[ind]] > 1:
                    text = "{0}\nShares AP with {1} other user(s)".format(
                        text, users_per_ap[ap_assoc[ind]] - 1)

                users_AP = ap_assoc[ind]
                # Plot a yellow circle in the user's AP
                ap_pos = ap_positions[users_AP]
                # CHange the collor of other users in the same AP to green and
                # the current user to cyan
                users_colors[ap_assoc == users_AP] = 'g'
                users_colors[ind] = 'c'

                selected_ap_circle.set_visible(True)
                selected_ap_circle.set_data([ap_pos.real], [ap_pos.imag])

            # Set users colors
            users_plt.set_color(users_colors)

            # Set the details text
            details.set_text(text)
            ax1.figure.canvas.draw()

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # Connect the on_pick function with the pick event
        ax1.figure.canvas.mpl_connect('pick_event', on_pick)

        plt.show()
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxx Return the results xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    return sinr_array_pl_metis_ps7_dB, capacity_metis_ps7
def perform_simulation_SINR_heatmap(
        scenario_params,  # pylint: disable=R0914
        power_params):
    """
    Perform the simulation.

    Parameters
    ----------
    scenario_params : dict
        Dictionary with the scenario parameters.
    power_params : dict
        Dictionary with the power related parameters.

    Returns
    -------
    tuple[np.ndarray]
        Tuple with 4 numpy arrays with the results.
    """
    # xxxxxxxxxx Simulation Scenario Configuration xxxxxxxxxxxxxxxxxxxxxxxx
    # The size of the side of each square room
    side_length = scenario_params['side_length']
    # How much (in dB) is lost for each wall teh signal has to pass
    single_wall_loss_dB = scenario_params['single_wall_loss_dB']

    # Square of 12 x 12 square rooms
    num_rooms_per_side = scenario_params['num_rooms_per_side']
    # Total number of rooms in the grid
    num_rooms = num_rooms_per_side**2

    # 1 means 1 ap every room. 2 means 1 ap every 2 rooms and so on. Valid
    # values are: 1, 2, 4 and 9.
    ap_decimation = scenario_params['ap_decimation']
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Simulation Power Configuration xxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Transmit power of each access point
    Pt_dBm = power_params['Pt_dBm']
    noise_power_dBm = power_params['noise_power_dBm']

    Pt = dBm2Linear(Pt_dBm)  # 20 dBm transmit power
    noise_var = dBm2Linear(noise_power_dBm)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Discretization of the possible positions xxxxxxxxxxxxxxxxx
    num_discrete_positions_per_room = 15  # Number of discrete positions
    step = 1. / num_discrete_positions_per_room
    aux = np.linspace(-(1. - step), (1. - step),
                      num_discrete_positions_per_room)
    aux = np.meshgrid(aux, aux, indexing='ij')
    ":type: np.ndarray"
    user_relative_positions = aux[1] + 1j * aux[0][::-1]
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the positions of all rooms xxxxxxxxxxxxxxxxxxxxx
    room_positions = calc_room_positions_square(side_length, num_rooms)
    room_positions.shape = (num_rooms_per_side, num_rooms_per_side)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Create the path loss object xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    pl_3gpp_obj = pathloss.PathLoss3GPP1()
    pl_free_space_obj = pathloss.PathLossFreeSpace()
    pl_3gpp_obj.handle_small_distances_bool = True
    pl_free_space_obj.handle_small_distances_bool = True
    pl_metis_ps7_obj = pathloss.PathLossMetisPS7()
    pl_metis_ps7_obj.handle_small_distances_bool = True
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxx Add one user in each discrete position of each room xxxxxxxxxx
    user_relative_positions2 = user_relative_positions * side_length / 2.
    user_positions = (room_positions[:, :, np.newaxis, np.newaxis] +
                      user_relative_positions2[np.newaxis, np.newaxis, :, :])
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx AP Allocation xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # 1 AP in each room
    ap_positions = get_ap_positions(room_positions, ap_decimation)
    num_aps = ap_positions.size
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate distances: each user to each AP xxxxxxxxxxxxxxxx
    # Dimension: (room_row, room_c, user_row, user_col, num_APs)
    dists_m = np.abs(user_positions[:, :, :, :, np.newaxis] -
                     ap_positions.reshape([1, 1, 1, 1, -1]))
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate AP association xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Determine with which AP each user is associated with.
    # Each user will associate with the CLOSEST access point.
    ap_assoc = np.argmin(dists_m, axis=-1)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate wall losses xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # We want to calculate the number walls from each room to the rooms
    # which have an access point.
    # Dimension is (num_rooms, num_aps)
    num_walls = calc_num_walls(side_length, room_positions, ap_positions)
    # Reshape it to (num_rooms_per_side, num_rooms_per_side, 1, 1, num_aps)
    num_walls_extended = num_walls.reshape(
        [num_rooms_per_side, num_rooms_per_side, 1, 1, num_aps])
    # And finally broadcast the (1, 1) dimensions to the number of users
    # per room. This will make num_walls_extended have the same dimension
    # as dists_m.
    num_walls_extended, _ = np.broadcast_arrays(num_walls_extended, dists_m)

    wall_losses_dB = num_walls_extended * single_wall_loss_dB
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the path losses xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # The METIS PS7 path loss model require distance values in meters,
    # while the others are in Kms. All distances were calculates in meters
    # and, therefore, we divide the distance in by 1000 for 3GPP and free
    # space.
    pl_3gpp = pl_3gpp_obj.calc_path_loss(dists_m / 1000.)
    pl_free_space = pl_free_space_obj.calc_path_loss(dists_m / 1000.)
    pl_nothing = np.ones([
        num_rooms_per_side, num_rooms_per_side,
        num_discrete_positions_per_room, num_discrete_positions_per_room,
        num_aps
    ],
                         dtype=float)

    # We need to know the number of walls the signal must pass to reach the
    # receiver to calculate the path loss for the METIS PS7 model.
    pl_metis_ps7 = pl_metis_ps7_obj.calc_path_loss(
        dists_m, num_walls=num_walls_extended)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the SINRs for each path loss model xxxxxxxxxxxxx
    sinr_array_pl_nothing_dB = simulate_for_a_given_ap_assoc(
        pl_nothing, ap_assoc, wall_losses_dB, Pt, noise_var)

    sinr_array_pl_3gpp_dB = simulate_for_a_given_ap_assoc(
        pl_3gpp, ap_assoc, wall_losses_dB, Pt, noise_var)

    sinr_array_pl_free_space_dB = simulate_for_a_given_ap_assoc(
        pl_free_space, ap_assoc, wall_losses_dB, Pt, noise_var)

    sinr_array_pl_metis_ps7_dB = simulate_for_a_given_ap_assoc(
        pl_metis_ps7, ap_assoc, wall_losses_dB, Pt, noise_var)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    out = (sinr_array_pl_nothing_dB, sinr_array_pl_3gpp_dB,
           sinr_array_pl_free_space_dB, sinr_array_pl_metis_ps7_dB)
    return out
Example #11
0
# External Interference Parameters
Pe_dBm = -10000  # transmit power (in dBm) of the ext. interference
ext_int_rank = 1  # Rank of the external interference

# xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
rep_max = 20000  # Maximum number of repetitions for each

pbar = progressbar.ProgressbarText(
    rep_max, message="Simulating for SNR: {0}".format(SNR_dB))

# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxx Dependent parameters (don't change these) xxxxxxxxxxxx
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Path loss (in linear scale) from the cell center to
path_loss_border = path_loss_obj.calc_path_loss(cell_radius)
noise_var = conversion.dBm2Linear(N0_dBm)
snr = conversion.dB2Linear(SNR_dB)
transmit_power = snr * noise_var / path_loss_border
# External interference power
pe = conversion.dBm2Linear(Pe_dBm)

# Cell Grid
cell_grid = cell.Grid()
cell_grid.create_clusters(num_clusters, num_cells, cell_radius)
# noinspection PyProtectedMember
cluster0 = cell_grid._clusters[0]
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# xxxxxxxxxx Create the scenario xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Example #12
0
 def test_dBm2Linear(self):
     self.assertAlmostEqual(conversion.dBm2Linear(60), 1000.0)
def perform_simulation(scenario_params, power_params, plot_results_bool=True):  # pylint: disable=R0914
    """
    Run the simulation.
    """
    # xxxxxxxxxx Simulation Scenario Configuration xxxxxxxxxxxxxxxxxxxxxxxx
    # The size of the side of each square room
    side_length = scenario_params["side_length"]
    # How much (in dB) is lost for each wall teh signal has to pass
    single_wall_loss_dB = scenario_params["single_wall_loss_dB"]

    # Square of 12 x 12 square rooms
    num_rooms_per_side = scenario_params["num_rooms_per_side"]
    # Total number of rooms in the grid
    num_rooms = num_rooms_per_side ** 2

    # 1 means 1 ap every room. 2 means 1 ap every 2 rooms and so on. Valid
    # values are: 1, 2, 4 and 9.
    ap_decimation = scenario_params["ap_decimation"]
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Simulation Power Configuration xxxxxxxxxxxxxxxxxxxxxxxxxxx
    # Transmit power of each access point
    Pt_dBm = power_params["Pt_dBm"]
    noise_power_dBm = power_params["noise_power_dBm"]

    Pt = dBm2Linear(Pt_dBm)  # 20 dBm transmit power
    noise_var = dBm2Linear(noise_power_dBm)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the positions of all rooms xxxxxxxxxxxxxxxxxxxxx
    room_positions = calc_room_positions_square(side_length, num_rooms)
    room_positions.shape = (num_rooms_per_side, num_rooms_per_side)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Create the path loss object xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    pl_metis_ps7_obj = pathloss.PathLossMetisPS7()
    pl_metis_ps7_obj.handle_small_distances_bool = True
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Add users in random positions in the 2D grid xxxxxxxxxxxxx
    num_users = 100  # We will create this many users in the 2D grid
    users_positions = (
        num_rooms_per_side
        * side_length
        * (np.random.random_sample(num_users) + 1j * np.random.random_sample(num_users) - 0.5 - 0.5j)
    )
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx AP Allocation xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # 1 AP in each room
    ap_positions = get_ap_positions(room_positions, ap_decimation)
    num_aps = ap_positions.size
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate distances: each user to each AP xxxxxxxxxxxxxxxx
    # Dimension: (num_users, num_APs)
    dists_m = np.abs(users_positions[:, np.newaxis] - ap_positions[np.newaxis, :])
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxx Calculate AP association xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # INPUTS
    # Find in which room each user is
    users_rooms = np.argmin(np.abs(room_positions.reshape([-1, 1]) - users_positions[np.newaxis, :]), axis=0)

    # Number of walls from each room to each other room
    num_walls_all_rooms = calc_num_walls(side_length, room_positions, ap_positions)
    # Number of walls from each room that has at least one user to each
    # room with an AP
    num_walls_rooms_with_users = num_walls_all_rooms[users_rooms]

    # Path loss from each user to each AP (no matter if it will be a
    # transmitting AP or not, since we still have to perform the AP
    # association)
    pl_all = pl_metis_ps7_obj.calc_path_loss(dists_m, num_walls=num_walls_rooms_with_users)

    # Calculate wall losses from each user to each AP (no matter if it will
    # be a transmitting AP or not, since we still have to perform the AP
    # association)
    wall_losses_dB_all = num_walls_rooms_with_users * single_wall_loss_dB

    # Calculate path loss plus wall losses (we multiply the linear values)
    # from each user to each AP (no matter if it will be a transmitting AP
    # or not, since we still have to perform the AP association)
    pl_all_plus_wl = pl_all * dB2Linear(-wall_losses_dB_all)

    # OUTPUTS
    # Determine with which AP each user is associated with.
    # Each user will associate with the CLOSEST access point.
    ap_assoc = find_ap_assoc_best_channel(pl_all_plus_wl)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Find which Access Points should stay on xxxxxxxxxxxxxxxxxx
    # Indexes of the active APs
    transmitting_aps, users_count = np.unique(ap_assoc, return_counts=True)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the SINRs for each path loss model xxxxxxxxxxxxx
    # Take the path loss plus wall losses only for the transmitting aps
    pl_all_plus_wall_losses_tx_aps = pl_all_plus_wl.take(transmitting_aps, axis=1)
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxx Calculate the SINRs and capacity xxxxxxxxxxxxxxxxxxxxxxxxx
    sinr_array_pl_metis_ps7_dB, capacity_metis_ps7 = simulate_for_a_given_ap_assoc(
        pl_all_plus_wall_losses_tx_aps, ap_assoc, transmitting_aps, Pt, noise_var
    )
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxx Plot the results xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    if plot_results_bool is True:
        print(
            ("\nMin/Mean/Max SINR value (METIS PS7):" "\n    {0}\n    {1}\n    {2}").format(
                sinr_array_pl_metis_ps7_dB.min(), sinr_array_pl_metis_ps7_dB.mean(), sinr_array_pl_metis_ps7_dB.max()
            )
        )

        print(
            ("\nMin/Mean/Max Capacity value (METIS PS7):" "\n    {0}\n    {1}\n    {2}").format(
                capacity_metis_ps7.min(), capacity_metis_ps7.mean(), capacity_metis_ps7.max()
            )
        )

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # xxxxxxxxxxxxxxx Plot the results xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Create a mask for the active APs
        transmitting_aps_mask = np.zeros(num_aps, dtype=bool)
        transmitting_aps_mask[transmitting_aps] = True

        # Save how many users are associated with each AP
        users_per_ap = np.zeros(num_aps, dtype=int)
        users_per_ap[transmitting_aps_mask] = users_count

        # xxxxxxxxxx Plot all rooms and users xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        all_rooms = [
            shapes.Rectangle(
                pos - side_length / 2.0 - side_length * 1j / 2.0, pos + side_length / 2.0 + side_length * 1j / 2.0
            )
            for pos in room_positions.flatten()
        ]

        # Plot all Rooms and save the axis where they were plotted
        plt.figure(figsize=(10, 10))
        gs = gridspec.GridSpec(2, 1, height_ratios=[4, 1])
        # ax1 is where we will plot everything
        ax1 = plt.subplot(gs[0])
        ax1.set_xlabel("Position X coordinate")
        ax1.set_ylabel("Position Y coordinate")
        ax1.set_title("Plot of all Rooms")
        ax1.set_ylim([-60, 60])
        ax1.set_xlim([-60, 60])
        ax1 = plot_all_rooms(all_rooms, ax1)
        ax1.hold(True)

        # ax2 will be used for annotations
        ax2 = plt.subplot(gs[1])
        plt.setp(ax2.get_xticklabels(), visible=False)
        plt.setp(ax2.get_yticklabels(), visible=False)
        ax2.set_ylim([0, 10])
        ax2.set_xlim([0, 10])
        details = ax2.text(
            5, 5, "Details", verticalalignment="center", horizontalalignment="center", family="monospace"
        )

        # Set the an array with colors for the access points. Transmitting APs
        # will be blue, while inactive APs will be gray
        ap_colors = np.empty(ap_positions.shape, dtype="U4")
        ap_colors[transmitting_aps_mask] = "b"
        ap_colors[np.logical_not(transmitting_aps_mask)] = "gray"

        # Plot the access points. We set linewidth to 0.0 so that there is no
        # border. We set the size ('s' keyword) to 50 to make it larger. The
        # colors are set according to the ap_colors array.
        # Note that we set a 5 points tolerance for the pick event.
        aps_plt = ax1.scatter(
            ap_positions.real, ap_positions.imag, marker="^", c=ap_colors, linewidths=0.1, s=50, picker=3
        )

        # Plot the users
        # Note that we set a 5 points tolerance for the pick event.
        users_plt = ax1.scatter(
            users_positions.real, users_positions.imag, marker="*", c="r", linewidth=0.1, s=50, picker=3
        )

        # xxxxxxxxxx Define a function to call for the pick_event Circle used
        # to select an AP. We will set its visibility to False here. When an AP
        # is selected, we move this circle to its position and set its
        # visibility to True.
        selected_ap_circle = ax1.plot([0], [0], "o", ms=12, alpha=0.4, color="yellow", visible=False)[0]

        # Define the callback function for the pick event
        def on_pick(event):
            """Callback for the pick event in the matplotlib plot."""
            # We will reset users colors on each pick
            users_colors = np.empty(ap_assoc.size, dtype="U1")
            users_colors[:] = "r"

            # Index of the point clicked
            ind = event.ind[0]

            if event.artist == aps_plt:
                # Disable the circle in the AP
                selected_ap_circle.set_visible(False)

                if ind not in ap_assoc:
                    # Text information for the disabled AP
                    text = "AP {0} (Disabled)".format(ind)
                else:
                    # Text information for the selected AP
                    text = "AP {0} with {1} user(s)\nTotal throughput: {2:7.4f}"
                    text = text.format(ind, users_per_ap[ind], np.sum(capacity_metis_ps7[ap_assoc == ind]))

                    # Change the colors of the users associated with the
                    # current AP to green
                    users_colors[ap_assoc == ind] = "g"

            elif event.artist == users_plt:
                # Text information for the selected user
                text = "User {0}\n    SINR: {1:7.4f}\nCapacity: {2:7.4f}".format(
                    ind, sinr_array_pl_metis_ps7_dB[ind], capacity_metis_ps7[ind]
                )

                # If there other users are associated with the same AP of the
                # current user
                if users_per_ap[ap_assoc[ind]] > 1:
                    text = "{0}\nShares AP with {1} other user(s)".format(text, users_per_ap[ap_assoc[ind]] - 1)

                users_AP = ap_assoc[ind]
                # Plot a yellow circle in the user's AP
                ap_pos = ap_positions[users_AP]
                # CHange the collor of other users in the same AP to green and
                # the current user to cyan
                users_colors[ap_assoc == users_AP] = "g"
                users_colors[ind] = "c"

                selected_ap_circle.set_visible(True)
                selected_ap_circle.set_data([ap_pos.real], [ap_pos.imag])

            # Set users colors
            users_plt.set_color(users_colors)

            # Set the details text
            details.set_text(text)
            ax1.figure.canvas.draw()

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # Connect the on_pick function with the pick event
        ax1.figure.canvas.mpl_connect("pick_event", on_pick)

        plt.show()
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxx Return the results xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    return sinr_array_pl_metis_ps7_dB, capacity_metis_ps7
Example #14
0
    def __init__(self, read_command_line_args=True, save_parsed_file=False):
        default_config_file = 'bd_config_file.txt'

        # xxxxxxxxxx Simulation Parameters Specification xxxxxxxxxxxxxxxxxx
        spec = """[Grid]
        cell_radius=float(min=0.01, default=1.0)
        num_cells=integer(min=3,default=3)
        num_clusters=integer(min=1,default=1)

        [Scenario]
        NSymbs=integer(min=10, max=1000000, default=500)
        SNR=real_numpy_array(min=-50, max=100, default=0:3:31)
        Pe_dBm=real_numpy_array(min=-50, max=100, default=[-10. 0. 10.])
        Nr=integer(default=2)
        Nt=integer(default=2)
        N0=float(default=-116.4)
        ext_int_rank=integer(min=1,default=1)
        user_positioning_method=option("Random", 'Symmetric Far Away', default="Symmetric Far Away")

        [Modulation]
        M=integer(min=4, max=512, default=4)
        modulator=option('QPSK', 'PSK', 'QAM', 'BPSK', default="PSK")
        packet_length=integer(min=1,default=60)

        [General]
        rep_max=integer(min=1, default=5000)
        unpacked_parameters=string_list(default=list('SNR','Pe_dBm'))

        """.split("\n")
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Initialize parameters configuration xxxxxxxxxxxxxxxxxx
        # Among other things, this will create the self.params object with
        # the simulation parameters read from the config file.
        SimulationRunner.__init__(
            self,
            default_config_file=default_config_file,
            config_spec=spec,
            read_command_line_args=read_command_line_args,
            save_parsed_file=save_parsed_file)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Channel Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        self.path_loss_obj = pathloss.PathLoss3GPP1()
        self.multiuser_channel = multiuser.MultiUserChannelMatrixExtInt()
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx RandomState objects seeds xxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # This is only useful to reproduce a simulation for debugging
        # purposed
        channel_seed = None  # 22522
        self.noise_seed = None  # 4445
        self.data_gen_seed = np.random.randint(10000)  # 2105
        ext_data_gen_seed = None  # 6114
        #
        self.multiuser_channel.set_channel_seed(channel_seed)
        self.multiuser_channel.set_noise_seed(self.noise_seed)
        self.data_RS = np.random.RandomState(self.data_gen_seed)
        self.ext_data_RS = np.random.RandomState(ext_data_gen_seed)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx Creates the modulator object xxxxxxxxxxxxxxxxxxxxxxxxx
        M = self.params['M']
        modulator_options = {'PSK': fundamental.PSK,
                             'QPSK': fundamental.QPSK,
                             'QAM': fundamental.QAM,
                             'BPSK': fundamental.BPSK}
        self.modulator = modulator_options[self.params['modulator']](M)
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxxxxxxx General Parameters xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # Maximum number of repetitions for each unpacked parameters set
        # self.params self.results
        self.rep_max = self.params['rep_max']

        # # max_bit_errors is used in the _keep_going method to stop the
        # # simulation earlier if possible. We stop the simulation if the
        # # accumulated number of bit errors becomes greater then 5% of the
        # # total number of simulated bits
        # self.max_bit_errors = self.rep_max * NSymbs * 5. / 100.

        self.progressbar_message = "SNR: {SNR}, Pe_dBm: {Pe_dBm}"

        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # xxxxxxxxxx Dependent parameters (don't change these) xxxxxxxxxxxx
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        # These two will be set in the _on_simulate_current_params_start
        # method
        self.pe = 0

        # Path loss (in linear scale) from the cell center to
        # self.path_loss_border = self.path_loss_obj.calc_path_loss(
        #     self.cell_radius)

        # Cell Grid
        self.cell_grid = cell.Grid()
        self.cell_grid.create_clusters(self.params['num_clusters'],
                                       self.params['num_cells'],
                                       self.params['cell_radius'])
        self.noise_var = dBm2Linear(self.params['N0'])
        self.multiuser_channel.noise_var = self.noise_var

        # This can be either 'screen' or 'file'. If it is 'file' then the
        # progressbar will write the progress to a file with appropriated
        # filename
        self.progress_output_type = 'screen'
Example #15
0
    def _on_simulate_current_params_start(self, current_params):
        """This method is called once for each combination of transmit
        parameters.
        """
        # pylint: disable=W0201

        # IMPORTANT: Re-seed the channel and the noise RandomState
        # objects. Without this, when you perform the simulation in
        # parallel (call the simulate_in_parallel method(from the
        # SimulationRunner class) you will get the same channel samples and
        # noise for all parallel process.
        self.multiuser_channel.re_seed()

        # xxxxx Calculates the transmit power at each base station. xxxxxxx
        # Because this value does not change in the different iterations of
        # _run_simulation, but only when the parameters change the
        # calculation is performed here in the
        # _on_simulate_current_params_start.
        transmit_power = BDSimulationRunner._calc_transmit_power(
            current_params['SNR'],
            current_params['N0'],
            current_params['cell_radius'],
            self.path_loss_obj)

        # External interference power
        self.pe = dBm2Linear(current_params['Pe_dBm'])

        # xxxxx Create the BD object with the None metric xxxxxxxxxxxxxxxxx
        self.bd_obj_None = EnhancedBD(current_params['num_cells'],
                                      transmit_power,
                                      self.noise_var,
                                      self.pe)
        self.bd_obj_None.set_ext_int_handling_metric(
            "None",
            {'modulator': self.modulator,
             'packet_length': current_params['packet_length'],
             'num_streams': 1})
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with the Naive metric xxxxxxxxxxxxxxxx
        self.bd_obj_naive = EnhancedBD(current_params['num_cells'],
                                       transmit_power,
                                       self.noise_var,
                                       self.pe)
        self.bd_obj_naive.set_ext_int_handling_metric(
            "naive",
            {'modulator': self.modulator,
             'packet_length': current_params['packet_length'],
             'num_streams': 1})
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with the fixed metric xxxxxxxxxxxxxxxx
        self.bd_obj_fixed = EnhancedBD(current_params['num_cells'],
                                       transmit_power,
                                       self.noise_var,
                                       self.pe)
        self.bd_obj_fixed.set_ext_int_handling_metric(
            "fixed",
            {'modulator': self.modulator,
             'packet_length': current_params['packet_length'],
             'num_streams': 1})
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with the capacity metric xxxxxxxxxxxxx
        self.bd_obj_capacity = EnhancedBD(current_params['num_cells'],
                                          transmit_power,
                                          self.noise_var,
                                          self.pe)
        self.bd_obj_capacity.set_ext_int_handling_metric(
            "capacity",
            {'modulator': self.modulator,
             'packet_length': current_params['packet_length'],
             'num_streams': 1})
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xx Create the BD object with the effective_throughput metric xxxx
        self.bd_obj_effec_throughput = EnhancedBD(
            current_params['num_cells'],
            transmit_power,
            self.noise_var,
            self.pe)
        self.bd_obj_effec_throughput.set_ext_int_handling_metric(
            "effective_throughput",
            {'modulator': self.modulator,
             'packet_length': current_params['packet_length'],
             'num_streams': 1})
        # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

        # xxxxx Create the BD object with whitening xxxxxxxxxxxxxxxxxxxxxxx
        self.bd_obj_whitening = WhiteningBD(current_params['num_cells'],
                                            transmit_power,
                                            self.noise_var,
                                            self.pe)
Example #16
0
 def test_dBm2Linear(self):
     self.assertAlmostEqual(conversion.dBm2Linear(60),
                            1000.0)