Source code for hermespy.channel.fading.cost259

# -*- coding: utf-8 -*-

from __future__ import annotations
from typing import Any, Optional, Type

import numpy as np
from ruamel.yaml import SafeRepresenter, MappingNode

from hermespy.core import SerializableEnum
from .fading import MultipathFadingChannel

__author__ = "Tobias Kronauer"
__copyright__ = "Copyright 2024, Barkhausen Institut gGmbH"
__credits__ = ["Tobias Kronauer", "Jan Adler"]
__license__ = "AGPLv3"
__version__ = "1.3.0"
__maintainer__ = "Jan Adler"
__email__ = "jan.adler@barkhauseninstitut.org"
__status__ = "Prototype"


[docs] class Cost259Type(SerializableEnum): """Supported model types of the Cost256 channel model""" URBAN = 0 """Urban area""" RURAL = 1 """Rural area""" HILLY = 2 """Hilly terrain"""
[docs] class Cost259(MultipathFadingChannel): """Cost action 259 multipath fading channel model.""" yaml_tag = "COST259" __model_type: Cost259Type def __init__( self, model_type: Cost259Type = Cost259Type.URBAN, gain: float = 1.0, los_angle: Optional[float] = None, doppler_frequency: Optional[float] = None, los_doppler_frequency: Optional[float] = None, **kwargs: Any, ) -> None: """ Args: model_type (Cost259Type): The model type. gain (float, optional): Linear power gain factor a signal experiences when being propagated over this realization. :math:`1.0` by default. los_angle (float, optional): Angle phase of the line of sight component within the statistical distribution. doppler_frequency (float, optional): Doppler frequency shift of the statistical distribution. \**kwargs (Any): `MultipathFadingChannel` initialization parameters. Raises: ValueError: If `model_type` is not supported. If `los_angle` is defined in HILLY model type. """ if model_type == Cost259Type.URBAN: delays = 1e-6 * np.array( [ 0, 0.217, 0.512, 0.514, 0.517, 0.674, 0.882, 1.230, 1.287, 1.311, 1.349, 1.533, 1.535, 1.622, 1.818, 1.836, 1.884, 1.943, 2.048, 2.140, ] ) power_db = np.array( [ -5.7, -7.6, -10.1, -10.2, -10.2, -11.5, -13.4, -16.3, -16.9, -17.1, -17.4, -19.0, -19.0, -19.8, -21.5, -21.6, -22.1, -22.6, -23.5, -24.3, ] ) rice_factors = np.zeros(delays.shape) elif model_type == Cost259Type.RURAL: delays = 1e-6 * np.array( [0, 0.042, 0.101, 0.129, 0.149, 0.245, 0.312, 0.410, 0.469, 0.528] ) power_db = np.array([-5.2, -6.4, -8.4, -9.3, -10.0, -13.1, -15.3, -18.5, -20.4, -22.4]) rice_factors = np.zeros(delays.shape) elif model_type == Cost259Type.HILLY: if los_angle is not None: raise ValueError( "Model type HILLY does not support line of sight angle configuration" ) delays = 1e-6 * np.array( [ 0, 0.356, 0.441, 0.528, 0.546, 0.609, 0.625, 0.842, 0.916, 0.941, 15.0, 16.172, 16.492, 16.876, 16.882, 16.978, 17.615, 17.827, 17.849, 18.016, ] ) power_db = np.array( [ -3.6, -8.9, -10.2, -11.5, -11.8, -12.7, -13.0, -16.2, -17.3, -17.7, -17.6, -22.7, -24.1, -25.8, -25.8, -26.2, -29.0, -29.9, -30.0, -30.7, ] ) rice_factors = np.hstack([np.array([np.inf]), np.zeros(delays.size - 1)]) los_angle = np.arccos(0.7) else: raise ValueError("Requested model type not supported") self.__model_type = Cost259Type(model_type) # Convert power and normalize power_profile = 10 ** (power_db / 10) power_profile /= sum(power_profile) # Init base class with pre-defined model parameters MultipathFadingChannel.__init__( self, gain=gain, delays=delays, power_profile=power_profile, rice_factors=rice_factors, los_angle=los_angle, doppler_frequency=doppler_frequency, los_doppler_frequency=los_doppler_frequency, **kwargs, ) @property def model_type(self) -> Cost259Type: """Access the configured model type. Returns: The configured model type. """ return self.__model_type
[docs] @classmethod def to_yaml(cls: Type[Cost259], representer: SafeRepresenter, node: Cost259) -> MappingNode: """Serialize a serializable object to YAML. Args: representer (SafeRepresenter): A handle to a representer used to generate valid YAML code. The representer gets passed down the serialization tree to each node. node (Serializable): The MultipathFadingCost256 instance to be serialized. Returns: The serialized YAML node. """ blacklist = set() if node.model_type == Cost259Type.HILLY: blacklist.add("los_angle") return node._mapping_serialization_wrapper(representer, blacklist=blacklist)