diff --git a/doc/changelog.d/6068.added.md b/doc/changelog.d/6068.added.md new file mode 100644 index 00000000000..3cf7ced4918 --- /dev/null +++ b/doc/changelog.d/6068.added.md @@ -0,0 +1 @@ +Support new EmitCom API for 25R2, add node classes for all EMIT node types \ No newline at end of file diff --git a/doc/changelog.d/6225.added.md b/doc/changelog.d/6225.added.md new file mode 100644 index 00000000000..004ec17df01 --- /dev/null +++ b/doc/changelog.d/6225.added.md @@ -0,0 +1 @@ +add EmitterNode \ No newline at end of file diff --git a/src/ansys/aedt/core/emit.py b/src/ansys/aedt/core/emit.py index 71045b35f51..11604bd51cf 100644 --- a/src/ansys/aedt/core/emit.py +++ b/src/ansys/aedt/core/emit.py @@ -185,12 +185,6 @@ def __init__( self.__emit_api_enabled = True - # set the default units here to make sure the EmitApi level - # stays synced with pyaedt - unit_types = ["Power", "Frequency", "Length", "Time", "Voltage", "Data Rate", "Resistance"] - unit_values = ["dBm", "MHz", "meter", "ns", "mV", "bps", "Ohm"] - self.set_units(unit_types, unit_values) - def _init_from_design(self, *args, **kwargs): self.__init__(*args, **kwargs) diff --git a/src/ansys/aedt/core/emit_core/__init__.py b/src/ansys/aedt/core/emit_core/__init__.py index 1bd5357b690..8b1dc570b08 100644 --- a/src/ansys/aedt/core/emit_core/__init__.py +++ b/src/ansys/aedt/core/emit_core/__init__.py @@ -55,37 +55,68 @@ def emit_api_python(): def _init_enums(aedt_version): - ResultType.EMI = emit_api_python().result_type().emi - ResultType.DESENSE = emit_api_python().result_type().desense - ResultType.SENSITIVITY = emit_api_python().result_type().sensitivity - ResultType.POWER_AT_RX = emit_api_python().result_type().powerAtRx - - TxRxMode.TX = emit_api_python().tx_rx_mode().tx - TxRxMode.RX = emit_api_python().tx_rx_mode().rx - TxRxMode.BOTH = emit_api_python().tx_rx_mode().both - - InterfererType.TRANSMITTERS = emit_api_python().interferer_type().transmitters - InterfererType.EMITTERS = emit_api_python().interferer_type().emitters - InterfererType.TRANSMITTERS_AND_EMITTERS = emit_api_python().interferer_type().transmitters_and_emitters - - UnitType.POWER = emit_api_python().unit_type().power - UnitType.FREQUENCY = emit_api_python().unit_type().frequency - UnitType.LENGTH = emit_api_python().unit_type().length - UnitType.TIME = emit_api_python().unit_type().time - UnitType.VOLTAGE = emit_api_python().unit_type().voltage - UnitType.DATA_RATE = emit_api_python().unit_type().dataRate - UnitType.RESISTANCE = emit_api_python().unit_type().resistance - numeric_version = int(aedt_version[-3:]) - if numeric_version >= 241: - emi_cat_filter = emit_api_python().emi_category_filter() - EmiCategoryFilter.IN_CHANNEL_TX_FUNDAMENTAL = emi_cat_filter.in_channel_tx_fundamental - EmiCategoryFilter.IN_CHANNEL_TX_HARMONIC_SPURIOUS = emi_cat_filter.in_channel_tx_harmonic_spurious - EmiCategoryFilter.IN_CHANNEL_TX_INTERMOD = emi_cat_filter.in_channel_tx_intermod - EmiCategoryFilter.IN_CHANNEL_TX_BROADBAND = emi_cat_filter.in_channel_tx_broadband - EmiCategoryFilter.OUT_OF_CHANNEL_TX_FUNDAMENTAL = emi_cat_filter.out_of_channel_tx_fundamental - EmiCategoryFilter.OUT_OF_CHANNEL_TX_HARMONIC_SPURIOUS = emi_cat_filter.out_of_channel_tx_harmonic_spurious - EmiCategoryFilter.OUT_OF_CHANNEL_TX_INTERMOD = emi_cat_filter.out_of_channel_tx_intermod + + if numeric_version > 251: + ResultType.EMI = emit_api_python().result_type().emi + ResultType.DESENSE = emit_api_python().result_type().desense + ResultType.SENSITIVITY = emit_api_python().result_type().sensitivity + ResultType.POWER_AT_RX = emit_api_python().result_type().powerAtRx + + TxRxMode.TX = emit_api_python().tx_rx_mode().tx + TxRxMode.RX = emit_api_python().tx_rx_mode().rx + TxRxMode.BOTH = emit_api_python().tx_rx_mode().both + + InterfererType.TRANSMITTERS = emit_api_python().interferer_type().transmitters + InterfererType.EMITTERS = emit_api_python().interferer_type().emitters + InterfererType.TRANSMITTERS_AND_EMITTERS = emit_api_python().interferer_type().transmitters_and_emitters + + UnitType.POWER = emit_api_python().unit_type().power + UnitType.FREQUENCY = emit_api_python().unit_type().frequency + UnitType.LENGTH = emit_api_python().unit_type().length + UnitType.TIME = emit_api_python().unit_type().time + UnitType.VOLTAGE = emit_api_python().unit_type().voltage + UnitType.DATA_RATE = emit_api_python().unit_type().dataRate + UnitType.RESISTANCE = emit_api_python().unit_type().resistance + + EmiCategoryFilter.IN_CHANNEL_TX_FUNDAMENTAL = 0 + EmiCategoryFilter.IN_CHANNEL_TX_HARMONIC_SPURIOUS = 1 + EmiCategoryFilter.IN_CHANNEL_TX_INTERMOD = 2 + EmiCategoryFilter.IN_CHANNEL_TX_BROADBAND = 3 + EmiCategoryFilter.OUT_OF_CHANNEL_TX_FUNDAMENTAL = 4 + EmiCategoryFilter.OUT_OF_CHANNEL_TX_HARMONIC_SPURIOUS = 5 + EmiCategoryFilter.OUT_OF_CHANNEL_TX_INTERMOD = 6 + else: + ResultType.EMI = emit_api_python().result_type().emi + ResultType.DESENSE = emit_api_python().result_type().desense + ResultType.SENSITIVITY = emit_api_python().result_type().sensitivity + ResultType.POWER_AT_RX = emit_api_python().result_type().powerAtRx + + TxRxMode.TX = emit_api_python().tx_rx_mode().tx + TxRxMode.RX = emit_api_python().tx_rx_mode().rx + TxRxMode.BOTH = emit_api_python().tx_rx_mode().both + + InterfererType.TRANSMITTERS = emit_api_python().interferer_type().transmitters + InterfererType.EMITTERS = emit_api_python().interferer_type().emitters + InterfererType.TRANSMITTERS_AND_EMITTERS = emit_api_python().interferer_type().transmitters_and_emitters + + UnitType.POWER = emit_api_python().unit_type().power + UnitType.FREQUENCY = emit_api_python().unit_type().frequency + UnitType.LENGTH = emit_api_python().unit_type().length + UnitType.TIME = emit_api_python().unit_type().time + UnitType.VOLTAGE = emit_api_python().unit_type().voltage + UnitType.DATA_RATE = emit_api_python().unit_type().dataRate + UnitType.RESISTANCE = emit_api_python().unit_type().resistance + + if numeric_version >= 241: + emi_cat_filter = emit_api_python().emi_category_filter() + EmiCategoryFilter.IN_CHANNEL_TX_FUNDAMENTAL = emi_cat_filter.in_channel_tx_fundamental + EmiCategoryFilter.IN_CHANNEL_TX_HARMONIC_SPURIOUS = emi_cat_filter.in_channel_tx_harmonic_spurious + EmiCategoryFilter.IN_CHANNEL_TX_INTERMOD = emi_cat_filter.in_channel_tx_intermod + EmiCategoryFilter.IN_CHANNEL_TX_BROADBAND = emi_cat_filter.in_channel_tx_broadband + EmiCategoryFilter.OUT_OF_CHANNEL_TX_FUNDAMENTAL = emi_cat_filter.out_of_channel_tx_fundamental + EmiCategoryFilter.OUT_OF_CHANNEL_TX_HARMONIC_SPURIOUS = emi_cat_filter.out_of_channel_tx_harmonic_spurious + EmiCategoryFilter.OUT_OF_CHANNEL_TX_INTERMOD = emi_cat_filter.out_of_channel_tx_intermod # need this as a function so that it can be set diff --git a/src/ansys/aedt/core/emit_core/emit_constants.py b/src/ansys/aedt/core/emit_core/emit_constants.py index 08315e27803..0c978253070 100644 --- a/src/ansys/aedt/core/emit_core/emit_constants.py +++ b/src/ansys/aedt/core/emit_core/emit_constants.py @@ -76,14 +76,109 @@ class UnitType(MutableEnum): EMIT_VALID_UNITS = { "Power": ["mW", "W", "kW", "dBm", "dBW"], "Frequency": ["Hz", "kHz", "MHz", "GHz", "THz"], - "Length": ["pm", "nm", "um", "mm", "cm", "dm", "meter", "km", "mil", "in", "ft", "yd", "mile"], + "Length": ["pm", "nm", "um", "mm", "cm", "dm", "meter", "meters", "km", "mil", "in", "ft", "yd", "mile"], "Time": ["ps", "ns", "us", "ms", "s"], - "Voltage": ["mV", "V"], + "Voltage": ["nV", "uV", "mV", "V", "kV", "MegV"], "Data Rate": ["bps", "kbps", "Mbps", "Gbps"], "Resistance": ["uOhm", "mOhm", "Ohm", "kOhm", "megOhm", "GOhm"], } """Valid units for each unit type.""" +EMIT_INTERNAL_UNITS = { + "Power": "dBm", + "Freq": "Hz", + "Length": "meter", + "Time": "s", + "Voltage": "V", + "Data Rate": "bps", + "Resistance": "ohm", +} +"""Default units for each unit type.""" + +EMIT_TO_AEDT_UNITS = { + "picometers": "pm", + "nanometers": "nm", + "micrometers": "um", + "millimeters": "mm", + "centimeters": "cm", + "decimeters": "dm", + "meters": "meter", + "kilometers": "km", + "inches": "in", + "mils": "mil", + "feet": "ft", + "yards": "yd", + "miles": "mile", + "hertz": "Hz", + "kilohertz": "kHz", + "megahertz": "MHz", + "gigahertz": "GHz", + "terahertz": "THz", + "picoseconds": "ps", + "nanoseconds": "ns", + "microseconds": "us", + "milliseconds": "ms", + "seconds": "s", + "microohms": "uOhm", + "milliohms": "mOhm", + "ohms": "ohm", + "kiloohms": "kOhm", + "megaohms": "megohm", + "gigaohms": "GOhm", + "dBm": "dBm", + "dBW": "dBW", + "watts": "W", + "milliwatts": "mW", + "kilowatts": "kW", + "nanovolts": "nV", + "microvolts": "uV", + "millivolts": "mV", + "volts": "V", + "kilovolts": "kV", + "megavolts": "MegV", + "bps": "bps", + "kbps": "kbps", + "Mbps": "Mbps", + "Gbps": "Gbps", +} + + +def data_rate_conv(value: float, units: str, to_internal: bool = True): + """Converts the data rate to (from) the internal units from the + specified units. + + Args: + value (float): numeric value of the data rate + units (str): units to convert to (from) + to_internal (bool, optional): Converts from the specified units + to the internal units OR from the internal units to the + specified units. Defaults to True. + + Returns: + value: data rate converted to/from the internal units + """ + if units not in ("bps", "kbps", "Mbps", "Gbps"): + raise ValueError(f"{units} are not valid units for data rate.") + if to_internal: + if units == "bps": + mult = 1.0 + elif units == "kbps": + mult = 1e-3 + elif units == "Mbps": + mult = 1e-6 + elif units == "Gbps": + mult = 1e-9 + else: + if units == "bps": + mult = 1.0 + elif units == "kbps": + mult = 1e3 + elif units == "Mbps": + mult = 1e6 + elif units == "Gbps": + mult = 1e9 + return value * mult + def emit_unit_type_string_to_enum(unit_string): EMIT_UNIT_TYPE_STRING_TO_ENUM = { @@ -98,6 +193,19 @@ def emit_unit_type_string_to_enum(unit_string): return EMIT_UNIT_TYPE_STRING_TO_ENUM[unit_string] +def emi_cat_enum_to_string(emi_cat_enum): + EMI_CAT_ENUM_TO_STR = { + EmiCategoryFilter.IN_CHANNEL_TX_FUNDAMENTAL: "In-Channel Tx Fundamental", + EmiCategoryFilter.IN_CHANNEL_TX_HARMONIC_SPURIOUS: "In-Channel Tx Harmonic/Spurious", + EmiCategoryFilter.IN_CHANNEL_TX_INTERMOD: "In-Channel Intermod", + EmiCategoryFilter.IN_CHANNEL_TX_BROADBAND: "In-Channel Broadband", + EmiCategoryFilter.OUT_OF_CHANNEL_TX_FUNDAMENTAL: "Out-of-Channel Tx Fundamental", + EmiCategoryFilter.OUT_OF_CHANNEL_TX_HARMONIC_SPURIOUS: "Out-of-Channel Tx Harmonic/Spurious", + EmiCategoryFilter.OUT_OF_CHANNEL_TX_INTERMOD: "Out-of-Channel Intermod", + } + return EMI_CAT_ENUM_TO_STR[emi_cat_enum] + + class EmiCategoryFilter(MutableEnum): IN_CHANNEL_TX_FUNDAMENTAL = None IN_CHANNEL_TX_HARMONIC_SPURIOUS = None diff --git a/src/ansys/aedt/core/emit_core/nodes/emit_node.py b/src/ansys/aedt/core/emit_core/nodes/emit_node.py new file mode 100644 index 00000000000..24f7cd12635 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/emit_node.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +import warnings + +from ansys.aedt.core.emit_core.emit_constants import EMIT_INTERNAL_UNITS +from ansys.aedt.core.emit_core.emit_constants import EMIT_VALID_UNITS +from ansys.aedt.core.emit_core.emit_constants import data_rate_conv +import ansys.aedt.core.generic.constants as consts + + +class EmitNode: + # meant to only be used as a parent class + def __init__(self, emit_obj, result_id, node_id): + self._emit_obj = emit_obj + self._oDesign = emit_obj.odesign + self._oRevisionData = self._oDesign.GetModule("EmitCom") + self._result_id = result_id + self._node_id = node_id + self._valid = True + self._is_component = False + + def __eq__(self, other): + return (self._result_id == other._result_id) and (self._node_id == other._node_id) + + @staticmethod + def props_to_dict(props): + """Converts a list of key/value pairs to a dictionary. + + Args: + props (List[str]): List of strings. Each string + is a key/value pair in the form: 'key=value' + + Returns: + dict: properties returned as a dictionary + """ + result = {} + for prop in props: + split_prop = prop.split("=") + if split_prop[1].find("|") != -1: + result[split_prop[0]] = split_prop[1].split("|") + result[split_prop[0]] = split_prop[1] + return result + + @property + def valid(self): + """Is false if this object has been detached from its EMIT node.""" + return self._valid + + @property + def name(self) -> str: + """Returns the name of the node. + + Returns: + str: name of the node. + """ + return self._get_property("Name") + + @property + def type(self) -> str: + """Returns the type of the node. + + Returns: + str: type of the node. + """ + return self._get_property("Type") + + @property + def _parent(self): + """Returns the parent node for this node. + + Returns: + EmitNode: parent node for the current node. + """ + parent_id = 1 + parent_node = self._get_node(parent_id) + return parent_node + + @property + def properties(self): + """Get's the node's properties. + + Returns: + Dict: dictionary of the node's properties. The display name + of each property as the key. + """ + props = self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, True) + props = self.props_to_dict(props) + return props + + @property + def node_warnings(self): + """Returns any warnings that the node might have. + + Returns: + str: Warning(s) for the node. + """ + node_warnings = "" + try: + node_warnings = self._get_property("Warnings") + except Exception: + warnings.warn( + f"Unable to get the warnings for node: {self.name}.", + UserWarning, + ) + return node_warnings + + @property + def allowed_child_types(self): + """A list of child types that can be added to this node. + + Returns: + list[str]: A list of child types that can be added to this node. + """ + return self._oRevisionData.GetAllowedChildTypes(self._result_id, self._node_id) + + def _get_node(self, node_id: int): + """Gets a node for this node's revision with the given id. + + Parameters + ---------- + node_id: int + id of node to construct. + + Returns + ------- + node: EmitNode + The node. + + Examples + -------- + >>> new_node = node._get_node(node_id) + """ + from ansys.aedt.core.emit_core.nodes import generated + + props = self._oRevisionData.GetEmitNodeProperties(self._result_id, node_id, True) + props = self.props_to_dict(props) + node_type = props["Type"] + + prefix = "" if self._result_id == 0 else "ReadOnly" + + node = None + try: + type_class = getattr(generated, f"{prefix}{node_type}") + node = type_class(self._emit_obj, self._result_id, node_id) + except AttributeError: + node = EmitNode(self._emit_obj, self._result_id, node_id) + return node + + @property + def children(self): + """A list of nodes that are children of the current node. + + Returns: + list[EmitNode]: list of child nodes that are children + of the current node. + """ + child_names = self._oRevisionData.GetChildNodeNames(self._result_id, self._node_id) + child_ids = [self._oRevisionData.GetChildNodeID(self._result_id, self._node_id, name) for name in child_names] + child_nodes = [self._get_node(child_id) for child_id in child_ids] + return child_nodes + + def _get_property(self, prop): + """Returns the value of the specified property. + + Args: + prop (str): the name of the property to extract for this node. + The name should match the value displayed in the UI. + + Returns: + str or list[str]: the value of the property. + """ + props = self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, True) + kv_pairs = [prop.split("=") for prop in props] + selected_kv_pairs = [kv for kv in kv_pairs if kv[0] == prop] + if len(selected_kv_pairs) != 1: + return "" + + selected_kv_pair = selected_kv_pairs[0] + val = selected_kv_pair[1] + + if val.find("|") != -1: + return val.split("|") + else: + return val + + def _set_property(self, prop, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"{prop}={value}"], True) + + def _string_to_value_units(self, value): + """Given a value with units specified, this function + will separate the units string from the decimal value. + + Args: + value (str): string containing both the decimal value + and the units used. + + Raises: + ValueError: throws an error if the units can't be determined. + + Returns: + dec_val: decimal value of the specified property. + units: units specified with the property. + """ + # see if we can split it based on a space between number + # and units + vals = value.split(" ") + if len(vals) == 2: + dec_val = float(vals[0]) + units = vals[1].strip() + return dec_val, units + # no space before units, so find the first letter + for i, char in enumerate(value): + if char.isalpha(): + dec_val = float(value[:i]) + units = value[i:] + return dec_val, units + raise ValueError(f"{value} are not valid units for this property.") + + def _convert_to_internal_units(self, value: float | str, unit_system: str) -> float: + """Takes a value and converts to internal EMIT units + used for internally storing the values. + + Args: + value (float | str): the specified value. If a float is specified, + then global unit settings are applied. If a string is specified, + then this function will split the value from the units and verify + that valid units are given. + unit_system (str): type of units. (e.g. FrequencyUnit, PowerUnit, etc) + + Returns: + converted_value (float): value in EMIT internal units (SI units where applicable). + + Examples: + val = self._convert_to_default_units(25, "FrequencyUnits") + val2 = self._convert_to_default_units("10 W", "PowerUnits") + """ + if isinstance(value, float) or isinstance(value, int): + # unitless, so assume SI Units + units = consts.SI_UNITS[unit_system] + else: + value, units = self._string_to_value_units(value) + # verify the units are valid for the specified type + if units not in EMIT_VALID_UNITS[unit_system]: + raise ValueError(f"{units} are not valid units for this property.") + + if unit_system == "Data Rate": + converted_value = data_rate_conv(value, units, True) + else: + converted_value = consts.unit_converter(value, unit_system, units, EMIT_INTERNAL_UNITS[unit_system]) + return converted_value + + def _convert_from_internal_units(self, value: float, unit_system: str) -> float: + """Takes a value and converts from internal EMIT units to + SI Units + + Args: + value (float): the specified value. + unit_system (str): type of units. (e.g. Freq, Power, etc) + + Returns: + converted_value (float): value in SI units. + """ + # get the SI units + units = consts.SI_UNITS[unit_system] + if unit_system == "Data Rate": + converted_value = data_rate_conv(value, units, False) + else: + converted_value = consts.unit_converter(value, unit_system, EMIT_INTERNAL_UNITS[unit_system], units) + return converted_value + + def _delete(self): + """Deletes the current node (component).""" + if self.get_is_component(): + self._oRevisionData.DeleteEmitComponent(self._result_id, self._node_id) + else: + self._oRevisionData.DeleteEmitNode(self._result_id, self._node_id) + + def _rename(self, requested_name): + """Renames the node/component. + + Args: + requested_name (str): New name for the node/component. + + Raises: + ValueError: Error if the node is read-only and cannot be renamed. + + Returns: + str: new name of the node/component. Note that it may be different + than requested_name if a node/component already exists with + requested_name. + """ + new_name = None + if self.get_is_component(): + if self._result_id > 0: + raise ValueError("This node is read-only for kept results.") + self._emit_obj.oeditor.RenameComponent(self.name, requested_name) + new_name = requested_name + else: + new_name = self._oRevisionData.RenameEmitNode(self._result_id, self._node_id, requested_name) + + return new_name + + def _duplicate(self, new_name): + # TODO (maybe needs to be custom?) + pass + + def _import(self, file_path, import_type): + """Imports a file into an Emit node creating a child node for the + imported data where necessary. + + Args: + file_path (str): Fullpath to the file to import. + import_type (str): Type of import desired. Options are: CsvFile, + TxMeasurement, RxMeasurement, SpectralData, TouchstoneCoupling, CAD + """ + self._oRevisionData.EmitNodeImport(self._result_id, self._node_id, file_path, import_type) + + def _export_model(self, file_path): + """Exports an Emit node's model to a file. Currently limited + to plot trace nodes and the exporting of csv files. + + Args: + file_path (str): Fullpath to export the data to. + """ + self._oRevisionData.EmitExportModel(self._result_id, self._node_id, file_path) + + def get_is_component(self): + """Returns true if the node is also a component. + + Returns: + bool: True if the node is a component. False otherwise. + """ + return self._is_component + + def _get_child_node_id(self, child_name): + """Returns the node ID for the specified child node. + + Args: + child_name (str): shortname of the desired child node. + + Returns: + int: unique ID assigned to the child node. + """ + return self._oRevisionData.GetChildNodeID(self._result_id, self._node_id, child_name) + + def _get_table_data(self): + """Returns a nested with the node's table data. + + Returns: + list[list]: the node's table data. + """ + rows = self._oRevisionData.GetTableData(self._result_id, self._node_id) + nested_list = [col.split(" ") for col in rows] + return nested_list + + def _set_table_data(self, nested_list): + """Sets the table data for the node. + + Args: + nested_list (list[list]): data to populate the table with. + """ + rows = [col.join(" ") for col in nested_list] + self._oRevisionData.SetTableData(self._result_id, self._node_id, rows) + + def _add_child_node(self, child_type, child_name=None): + """Creates a child node of the given type and name. + + Args: + child_type (EmitNode): type of child node to create + child_name (str, optional): Optional name to use for the + child node. If None, the default name for the node type + will be used. + + Raises: + ValueError: error if the specified child type is not allowed + for the current node. + + Returns: + int: unique node ID given to the created child node. + """ + if not child_name: + child_name = f"New {child_type}" + + new_id = None + if child_type not in self.allowed_child_types: + raise ValueError( + f"Child type {child_type} is not allowed for this node. Allowed types are: {self.allowed_child_types}" + ) + try: + new_id = self._oRevisionData.CreateEmitNode(self._result_id, self._node_id, child_name, child_type) + except Exception as e: + print(f"Failed to add child node of type {child_type} to node {self.name}. Error: {e}") + return new_id diff --git a/src/ansys/aedt/core/emit_core/nodes/emitter_node.py b/src/ansys/aedt/core/emit_core/nodes/emitter_node.py new file mode 100644 index 00000000000..71234bbc24c --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/emitter_node.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode +from ansys.aedt.core.emit_core.nodes.generated.antenna_node import AntennaNode +from ansys.aedt.core.emit_core.nodes.generated.radio_node import RadioNode + + +class EmitterNode(RadioNode, AntennaNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/__init__.py b/src/ansys/aedt/core/emit_core/nodes/generated/__init__.py new file mode 100644 index 00000000000..6918f1bd9ac --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/__init__.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from .amplifier import Amplifier +from .antenna_node import AntennaNode +from .antenna_passband import AntennaPassband +from .band import Band +from .band_folder import BandFolder +from .band_trace_node import BandTraceNode +from .cable import Cable +from .cad_node import CADNode +from .categories_view_node import CategoriesViewNode +from .circulator import Circulator +from .coupling_link_node import CouplingLinkNode +from .coupling_trace_node import CouplingTraceNode +from .couplings_node import CouplingsNode +from .custom_coupling_node import CustomCouplingNode +from .emi_plot_marker_node import EmiPlotMarkerNode +from .emit_scene_node import EmitSceneNode +from .emitter_node import EmitterNode +from .erceg_coupling_node import ErcegCouplingNode +from .filter import Filter +from .five_g_channel_model import FiveGChannelModel +from .hata_coupling_node import HataCouplingNode +from .indoor_propagation_coupling_node import IndoorPropagationCouplingNode +from .isolator import Isolator +from .log_distance_coupling_node import LogDistanceCouplingNode +from .mplex_band_trace_node import MPlexBandTraceNode +from .multiplexer import Multiplexer +from .multiplexer_band import MultiplexerBand +from .outboard_trace_node import OutboardTraceNode +from .parametric_coupling_trace_node import ParametricCouplingTraceNode +from .plot_marker_node import PlotMarkerNode +from .plot_node import PlotNode +from .power_divider import PowerDivider +from .power_trace_node import PowerTraceNode +from .profile_trace_node import ProfileTraceNode +from .propagation_loss_coupling_node import PropagationLossCouplingNode +from .radio_node import RadioNode +from .read_only_amplifier import ReadOnlyAmplifier +from .read_only_antenna_node import ReadOnlyAntennaNode +from .read_only_antenna_passband import ReadOnlyAntennaPassband +from .read_only_band import ReadOnlyBand +from .read_only_band_folder import ReadOnlyBandFolder +from .read_only_cable import ReadOnlyCable +from .read_only_cad_node import ReadOnlyCADNode +from .read_only_circulator import ReadOnlyCirculator +from .read_only_coupling_link_node import ReadOnlyCouplingLinkNode +from .read_only_couplings_node import ReadOnlyCouplingsNode +from .read_only_custom_coupling_node import ReadOnlyCustomCouplingNode +from .read_only_emit_scene_node import ReadOnlyEmitSceneNode +from .read_only_erceg_coupling_node import ReadOnlyErcegCouplingNode +from .read_only_filter import ReadOnlyFilter +from .read_only_five_g_channel_model import ReadOnlyFiveGChannelModel +from .read_only_hata_coupling_node import ReadOnlyHataCouplingNode +from .read_only_indoor_propagation_coupling_node import ReadOnlyIndoorPropagationCouplingNode +from .read_only_isolator import ReadOnlyIsolator +from .read_only_log_distance_coupling_node import ReadOnlyLogDistanceCouplingNode +from .read_only_multiplexer import ReadOnlyMultiplexer +from .read_only_multiplexer_band import ReadOnlyMultiplexerBand +from .read_only_power_divider import ReadOnlyPowerDivider +from .read_only_propagation_loss_coupling_node import ReadOnlyPropagationLossCouplingNode +from .read_only_radio_node import ReadOnlyRadioNode +from .read_only_rx_meas_node import ReadOnlyRxMeasNode +from .read_only_rx_mixer_product_node import ReadOnlyRxMixerProductNode +from .read_only_rx_saturation_node import ReadOnlyRxSaturationNode +from .read_only_rx_selectivity_node import ReadOnlyRxSelectivityNode +from .read_only_rx_spur_node import ReadOnlyRxSpurNode +from .read_only_rx_susceptibility_prof_node import ReadOnlyRxSusceptibilityProfNode +from .read_only_sampling_node import ReadOnlySamplingNode +from .read_only_scene_group_node import ReadOnlySceneGroupNode +from .read_only_solution_coupling_node import ReadOnlySolutionCouplingNode +from .read_only_solutions_node import ReadOnlySolutionsNode +from .read_only_terminator import ReadOnlyTerminator +from .read_only_touchstone_coupling_node import ReadOnlyTouchstoneCouplingNode +from .read_only_tr_switch import ReadOnlyTR_Switch +from .read_only_two_ray_path_loss_coupling_node import ReadOnlyTwoRayPathLossCouplingNode +from .read_only_tx_bb_emission_node import ReadOnlyTxBbEmissionNode +from .read_only_tx_harmonic_node import ReadOnlyTxHarmonicNode +from .read_only_tx_meas_node import ReadOnlyTxMeasNode +from .read_only_tx_nb_emission_node import ReadOnlyTxNbEmissionNode +from .read_only_tx_spectral_prof_emitter_node import ReadOnlyTxSpectralProfEmitterNode +from .read_only_tx_spectral_prof_node import ReadOnlyTxSpectralProfNode +from .read_only_tx_spur_node import ReadOnlyTxSpurNode +from .read_only_walfisch_coupling_node import ReadOnlyWalfischCouplingNode +from .read_only_waveform import ReadOnlyWaveform +from .result_plot_node import ResultPlotNode +from .rx_meas_node import RxMeasNode +from .rx_mixer_product_node import RxMixerProductNode +from .rx_saturation_node import RxSaturationNode +from .rx_selectivity_node import RxSelectivityNode +from .rx_spur_node import RxSpurNode +from .rx_susceptibility_prof_node import RxSusceptibilityProfNode +from .sampling_node import SamplingNode +from .scene_group_node import SceneGroupNode +from .selectivity_trace_node import SelectivityTraceNode +from .solution_coupling_node import SolutionCouplingNode +from .solutions_node import SolutionsNode +from .spur_trace_node import SpurTraceNode +from .terminator import Terminator +from .test_noise_trace_node import TestNoiseTraceNode +from .top_level_simulation import TopLevelSimulation +from .touchstone_coupling_node import TouchstoneCouplingNode +from .tr_switch import TR_Switch +from .tr_switch_trace_node import TRSwitchTraceNode +from .tunable_trace_node import TunableTraceNode +from .two_ray_path_loss_coupling_node import TwoRayPathLossCouplingNode +from .two_tone_trace_node import TwoToneTraceNode +from .tx_bb_emission_node import TxBbEmissionNode +from .tx_harmonic_node import TxHarmonicNode +from .tx_meas_node import TxMeasNode +from .tx_nb_emission_node import TxNbEmissionNode +from .tx_spectral_prof_emitter_node import TxSpectralProfEmitterNode +from .tx_spectral_prof_node import TxSpectralProfNode +from .tx_spur_node import TxSpurNode +from .walfisch_coupling_node import WalfischCouplingNode +from .waveform import Waveform + +__all__ = [ + "Amplifier", + "AntennaNode", + "AntennaPassband", + "Band", + "BandFolder", + "BandTraceNode", + "CADNode", + "Cable", + "CategoriesViewNode", + "Circulator", + "CouplingLinkNode", + "CouplingTraceNode", + "CouplingsNode", + "CustomCouplingNode", + "EmiPlotMarkerNode", + "EmitSceneNode", + "EmitterNode", + "ErcegCouplingNode", + "Filter", + "FiveGChannelModel", + "HataCouplingNode", + "IndoorPropagationCouplingNode", + "Isolator", + "LogDistanceCouplingNode", + "MPlexBandTraceNode", + "Multiplexer", + "MultiplexerBand", + "OutboardTraceNode", + "ParametricCouplingTraceNode", + "PlotMarkerNode", + "PlotNode", + "PowerDivider", + "PowerTraceNode", + "ProfileTraceNode", + "PropagationLossCouplingNode", + "RadioNode", + "ResultPlotNode", + "RxMeasNode", + "RxMixerProductNode", + "RxSaturationNode", + "RxSelectivityNode", + "RxSpurNode", + "RxSusceptibilityProfNode", + "SamplingNode", + "SceneGroupNode", + "SelectivityTraceNode", + "SolutionCouplingNode", + "SolutionsNode", + "SpurTraceNode", + "TR_Switch", + "TRSwitchTraceNode", + "Terminator", + "TestNoiseTraceNode", + "TopLevelSimulation", + "TouchstoneCouplingNode", + "TunableTraceNode", + "TwoRayPathLossCouplingNode", + "TwoToneTraceNode", + "TxBbEmissionNode", + "TxHarmonicNode", + "TxMeasNode", + "TxNbEmissionNode", + "TxSpectralProfEmitterNode", + "TxSpectralProfNode", + "TxSpurNode", + "WalfischCouplingNode", + "Waveform", + "ReadOnlyAmplifier", + "ReadOnlyAntennaNode", + "ReadOnlyAntennaPassband", + "ReadOnlyBand", + "ReadOnlyBandFolder", + "ReadOnlyCADNode", + "ReadOnlyCable", + "ReadOnlyCirculator", + "ReadOnlyCouplingLinkNode", + "ReadOnlyCouplingsNode", + "ReadOnlyCustomCouplingNode", + "ReadOnlyEmitSceneNode", + "ReadOnlyErcegCouplingNode", + "ReadOnlyFilter", + "ReadOnlyFiveGChannelModel", + "ReadOnlyHataCouplingNode", + "ReadOnlyIndoorPropagationCouplingNode", + "ReadOnlyIsolator", + "ReadOnlyLogDistanceCouplingNode", + "ReadOnlyMultiplexer", + "ReadOnlyMultiplexerBand", + "ReadOnlyPowerDivider", + "ReadOnlyPropagationLossCouplingNode", + "ReadOnlyRadioNode", + "ReadOnlyRxMeasNode", + "ReadOnlyRxMixerProductNode", + "ReadOnlyRxSaturationNode", + "ReadOnlyRxSelectivityNode", + "ReadOnlyRxSpurNode", + "ReadOnlyRxSusceptibilityProfNode", + "ReadOnlySamplingNode", + "ReadOnlySceneGroupNode", + "ReadOnlySolutionCouplingNode", + "ReadOnlySolutionsNode", + "ReadOnlyTR_Switch", + "ReadOnlyTerminator", + "ReadOnlyTouchstoneCouplingNode", + "ReadOnlyTwoRayPathLossCouplingNode", + "ReadOnlyTxBbEmissionNode", + "ReadOnlyTxHarmonicNode", + "ReadOnlyTxMeasNode", + "ReadOnlyTxNbEmissionNode", + "ReadOnlyTxSpectralProfEmitterNode", + "ReadOnlyTxSpectralProfNode", + "ReadOnlyTxSpurNode", + "ReadOnlyWalfischCouplingNode", + "ReadOnlyWaveform", +] diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/amplifier.py b/src/ansys/aedt/core/emit_core/nodes/generated/amplifier.py new file mode 100644 index 00000000000..a2b80a1a794 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/amplifier.py @@ -0,0 +1,237 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Amplifier(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class AmplifierTypeOption(Enum): + TRANSMIT_AMPLIFIER = "Transmit Amplifier" + RECEIVE_AMPLIFIER = "Receive Amplifier" + + @property + def amplifier_type(self) -> AmplifierTypeOption: + """Configures the amplifier as a Tx or Rx amplifier.""" + val = self._get_property("Amplifier Type") + val = self.AmplifierTypeOption[val.upper()] + return val + + @amplifier_type.setter + def amplifier_type(self, value: AmplifierTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Amplifier Type={value.value}"]) + + @property + def gain(self) -> float: + """Amplifier in-band gain. + + Value should be between 0 and 100. + """ + val = self._get_property("Gain") + return float(val) + + @gain.setter + def gain(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Gain={value}"]) + + @property + def center_frequency(self) -> float: + """Center frequency of amplifiers operational bandwidth. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Center Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @center_frequency.setter + def center_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Center Frequency={value}"]) + + @property + def bandwidth(self) -> float: + """Frequency region where the gain applies. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Bandwidth") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @bandwidth.setter + def bandwidth(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bandwidth={value}"]) + + @property + def noise_figure(self) -> float: + """Amplifier noise figure. + + Value should be between 0 and 100. + """ + val = self._get_property("Noise Figure") + return float(val) + + @noise_figure.setter + def noise_figure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Figure={value}"]) + + @property + def saturation_level(self) -> float: + """Saturation level. + + Value should be between -200 and 200. + """ + val = self._get_property("Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @saturation_level.setter + def saturation_level(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Saturation Level={value}"]) + + @property + def p1_db_point_ref_input(self) -> float: + """Incoming signals > this value saturate the amplifier. + + Value should be between -200 and 200. + """ + val = self._get_property("P1-dB Point, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @p1_db_point_ref_input.setter + def p1_db_point_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"P1-dB Point, Ref. Input={value}"]) + + @property + def ip3_ref_input(self) -> float: + """3rd order intercept point. + + Value should be between -200 and 200. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @ip3_ref_input.setter + def ip3_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"IP3, Ref. Input={value}"]) + + @property + def shape_factor(self) -> float: + """Ratio defining the selectivity of the amplifier. + + Value should be between 1 and 100. + """ + val = self._get_property("Shape Factor") + return float(val) + + @shape_factor.setter + def shape_factor(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Shape Factor={value}"]) + + @property + def reverse_isolation(self) -> float: + """Amplifier reverse isolation. + + Value should be between 0 and 200. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @reverse_isolation.setter + def reverse_isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Reverse Isolation={value}"]) + + @property + def max_intermod_order(self) -> int: + """Maximum order of intermods to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) + + @max_intermod_order.setter + def max_intermod_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Intermod Order={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/antenna_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/antenna_node.py new file mode 100644 index 00000000000..cc198a0a33f --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/antenna_node.py @@ -0,0 +1,912 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class AntennaNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def add_antenna_passband(self): + """Add a New Passband to this Antenna""" + return self._add_child_node("Antenna Passband") + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def tags(self) -> str: + """Space delimited list of tags for coupling selections.""" + val = self._get_property("Tags") + return val + + @tags.setter + def tags(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tags={value}"]) + + @property + def show_relative_coordinates(self) -> bool: + """Show Relative Coordinates. + + Show antenna position and orientation in parent-node coords (False) or + relative to placement coords (True). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Relative Coordinates") + return val == true + + @show_relative_coordinates.setter + def show_relative_coordinates(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Show Relative Coordinates={value}"] + ) + + @property + def position(self): + """Set position of the antenna in parent-node coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Position") + return val + + @position.setter + def position(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position={value}"]) + + @property + def relative_position(self): + """Set position of the antenna relative to placement coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Relative Position") + return val + + @relative_position.setter + def relative_position(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Relative Position={value}"]) + + class OrientationModeOption(Enum): + ROLL_PITCH_YAW = "Roll-Pitch-Yaw" + AZ_EL_TWIST = "Az-El-Twist" + + @property + def orientation_mode(self) -> OrientationModeOption: + """Orientation Mode. + + Select the convention (order of rotations) for configuring orientation. + """ + val = self._get_property("Orientation Mode") + val = self.OrientationModeOption[val.upper()] + return val + + @orientation_mode.setter + def orientation_mode(self, value: OrientationModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation Mode={value.value}"]) + + @property + def orientation(self): + """Set orientation of the antenna relative to parent-node coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Orientation") + return val + + @orientation.setter + def orientation(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation={value}"]) + + @property + def relative_orientation(self): + """Set orientation of the antenna relative to placement coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Relative Orientation") + return val + + @relative_orientation.setter + def relative_orientation(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Relative Orientation={value}"]) + + @property + def position_defined(self) -> bool: + """Toggles on/off the ability to define a position for the antenna. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Position Defined") + return val == true + + @position_defined.setter + def position_defined(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position Defined={value}"]) + + @property + def antenna_temperature(self) -> float: + """Antenna noise temperature. + + Value should be between 0 and 100000. + """ + val = self._get_property("Antenna Temperature") + return float(val) + + @antenna_temperature.setter + def antenna_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna Temperature={value}"]) + + @property + def type(self): + """Defines the type of antenna.""" + val = self._get_property("Type") + return val + + @type.setter + def type(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value}"]) + + @property + def antenna_file(self) -> str: + """Antenna File.""" + val = self._get_property("Antenna File") + return val + + @antenna_file.setter + def antenna_file(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna File={value}"]) + + @property + def project_name(self) -> str: + """Name of imported HFSS Antenna project. + + Value should be a full file path. + """ + val = self._get_property("Project Name") + return val + + @project_name.setter + def project_name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Project Name={value}"]) + + @property + def peak_gain(self) -> float: + """Set peak gain of antenna (dBi). + + Value should be between -200 and 200. + """ + val = self._get_property("Peak Gain") + return float(val) + + @peak_gain.setter + def peak_gain(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Peak Gain={value}"]) + + class BoresightOption(Enum): + XAXIS = "+X Axis" + YAXIS = "+Y Axis" + ZAXIS = "+Z Axis" + + @property + def boresight(self) -> BoresightOption: + """Select peak beam direction in local coordinates.""" + val = self._get_property("Boresight") + val = self.BoresightOption[val.upper()] + return val + + @boresight.setter + def boresight(self, value: BoresightOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Boresight={value.value}"]) + + @property + def vertical_beamwidth(self) -> float: + """Set half-power beamwidth in local-coordinates elevation plane. + + Value should be between 0.1 and 360. + """ + val = self._get_property("Vertical Beamwidth") + return float(val) + + @vertical_beamwidth.setter + def vertical_beamwidth(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Vertical Beamwidth={value}"]) + + @property + def horizontal_beamwidth(self) -> float: + """Set half-power beamwidth in local-coordinates azimuth plane. + + Value should be between 0.1 and 360. + """ + val = self._get_property("Horizontal Beamwidth") + return float(val) + + @horizontal_beamwidth.setter + def horizontal_beamwidth(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Horizontal Beamwidth={value}"]) + + @property + def extra_sidelobe(self) -> bool: + """Toggle (on/off) option to define two sidelobe levels. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Extra Sidelobe") + return val == true + + @extra_sidelobe.setter + def extra_sidelobe(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Extra Sidelobe={value}"]) + + @property + def first_sidelobe_level(self) -> float: + """First Sidelobe Level. + + Set reduction in the gain of Directive Beam antenna for first sidelobe + level. + + Value should be between 0 and 200. + """ + val = self._get_property("First Sidelobe Level") + return float(val) + + @first_sidelobe_level.setter + def first_sidelobe_level(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"First Sidelobe Level={value}"]) + + @property + def first_sidelobe_vert_bw(self) -> float: + """Set beamwidth of first sidelobe beam in theta direction. + + Value should be between 0.1 and 360. + """ + val = self._get_property("First Sidelobe Vert. BW") + return float(val) + + @first_sidelobe_vert_bw.setter + def first_sidelobe_vert_bw(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"First Sidelobe Vert. BW={value}"]) + + @property + def first_sidelobe_hor_bw(self) -> float: + """Set beamwidth of first sidelobe beam in phi direction. + + Value should be between 0.1 and 360. + """ + val = self._get_property("First Sidelobe Hor. BW") + return float(val) + + @first_sidelobe_hor_bw.setter + def first_sidelobe_hor_bw(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"First Sidelobe Hor. BW={value}"]) + + @property + def outerbacklobe_level(self) -> float: + """Outer/Backlobe Level. + + Set reduction in gain of Directive Beam antenna for outer/backlobe + level. + + Value should be between 0 and 200. + """ + val = self._get_property("Outer/Backlobe Level") + return float(val) + + @outerbacklobe_level.setter + def outerbacklobe_level(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Outer/Backlobe Level={value}"]) + + @property + def resonant_frequency(self) -> float: + """Resonant Frequency. + + Set first resonant frequency of wire dipole, monopole, or parametric + antenna. + + Value should be between 1.0 and 1e13. + """ + val = self._get_property("Resonant Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @resonant_frequency.setter + def resonant_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Resonant Frequency={value}"]) + + @property + def slot_length(self) -> float: + """Set slot length of parametric slot. + + Value should be greater than 1e-6. + """ + val = self._get_property("Slot Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @slot_length.setter + def slot_length(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Slot Length={value}"]) + + @property + def mouth_width(self) -> float: + """Set mouth width (along local y-axis) of the horn antenna. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Mouth Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @mouth_width.setter + def mouth_width(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mouth Width={value}"]) + + @property + def mouth_height(self) -> float: + """Set mouth height (along local x-axis) of the horn antenna. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Mouth Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @mouth_height.setter + def mouth_height(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mouth Height={value}"]) + + @property + def waveguide_width(self) -> float: + """Waveguide Width. + + Set waveguide width (along local y-axis) where flared horn walls meet + the feed, determines cut-off frequency. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Waveguide Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @waveguide_width.setter + def waveguide_width(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Waveguide Width={value}"]) + + @property + def width_flare_half_angle(self) -> float: + """Width Flare Half-angle. + + Set half-angle (degrees) of flared horn walls measured in local yz-plane + from boresight (z) axis to either wall. + + Value should be between 1 and 89.9. + """ + val = self._get_property("Width Flare Half-angle") + return float(val) + + @width_flare_half_angle.setter + def width_flare_half_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Width Flare Half-angle={value}"]) + + @property + def height_flare_half_angle(self) -> float: + """Height Flare Half-angle. + + Set half-angle (degrees) of flared horn walls measured in local xz-plane + from boresight (z) axis to either wall. + + Value should be between 1 and 89.9. + """ + val = self._get_property("Height Flare Half-angle") + return float(val) + + @height_flare_half_angle.setter + def height_flare_half_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Height Flare Half-angle={value}"]) + + @property + def mouth_diameter(self) -> float: + """Set aperture (mouth) diameter of horn antenna. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Mouth Diameter") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @mouth_diameter.setter + def mouth_diameter(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mouth Diameter={value}"]) + + @property + def flare_half_angle(self) -> float: + """Flare Half-angle. + + Set half-angle (degrees) of conical horn wall measured from boresight + (z). + + Value should be between 1 and 89.9. + """ + val = self._get_property("Flare Half-angle") + return float(val) + + @flare_half_angle.setter + def flare_half_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Flare Half-angle={value}"]) + + @property + def vswr(self) -> float: + """VSWR. + + The Voltage Standing Wave Ratio (VSWR) due to the impedance mismatch + between the antenna and the RF System (or outboard component). + + Value should be between 1 and 100. + """ + val = self._get_property("VSWR") + return float(val) + + @vswr.setter + def vswr(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"VSWR={value}"]) + + class AntennaPolarizationOption(Enum): + VERTICAL = "Vertical" + HORIZONTAL = "Horizontal" + RHCP = "RHCP" + LHCP = "LHCP" + + @property + def antenna_polarization(self) -> AntennaPolarizationOption: + """Choose local-coordinates polarization along boresight.""" + val = self._get_property("Antenna Polarization") + val = self.AntennaPolarizationOption[val.upper()] + return val + + @antenna_polarization.setter + def antenna_polarization(self, value: AntennaPolarizationOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Antenna Polarization={value.value}"] + ) + + class CrossDipoleModeOption(Enum): + FREESTANDING = "Freestanding" + OVER_GROUND_PLANE = "Over Ground Plane" + + @property + def cross_dipole_mode(self) -> CrossDipoleModeOption: + """Choose the Cross Dipole type.""" + val = self._get_property("Cross Dipole Mode") + val = self.CrossDipoleModeOption[val.upper()] + return val + + @cross_dipole_mode.setter + def cross_dipole_mode(self, value: CrossDipoleModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Cross Dipole Mode={value.value}"]) + + class CrossDipolePolarizationOption(Enum): + RHCP = "RHCP" + LHCP = "LHCP" + + @property + def cross_dipole_polarization(self) -> CrossDipolePolarizationOption: + """Choose local-coordinates polarization along boresight.""" + val = self._get_property("Cross Dipole Polarization") + val = self.CrossDipolePolarizationOption[val.upper()] + return val + + @cross_dipole_polarization.setter + def cross_dipole_polarization(self, value: CrossDipolePolarizationOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Cross Dipole Polarization={value.value}"] + ) + + @property + def override_height(self) -> bool: + """Override Height. + + Ignores the default placement of quarter design wavelength over the + ground plane. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Override Height") + return val == true + + @override_height.setter + def override_height(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Override Height={value}"]) + + @property + def offset_height(self) -> float: + """Offset Height. + + Sets the offset height for the current sources above the ground plane. + + Value should be greater than 0. + """ + val = self._get_property("Offset Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @offset_height.setter + def offset_height(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Offset Height={value}"]) + + @property + def auto_height_offset(self) -> bool: + """Auto Height Offset. + + Switch on to automatically place slot current at sub-wavelength offset + height above ground plane. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Auto Height Offset") + return val == true + + @auto_height_offset.setter + def auto_height_offset(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Auto Height Offset={value}"]) + + @property + def conform__adjust_antenna(self) -> bool: + """Toggle (on/off) conformal adjustment for array antenna elements. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Conform / Adjust Antenna") + return val == true + + @conform__adjust_antenna.setter + def conform__adjust_antenna(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Conform / Adjust Antenna={value}"]) + + @property + def element_offset(self): + """Element Offset. + + Set vector for shifting element positions in antenna local coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Element Offset") + return val + + @element_offset.setter + def element_offset(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Element Offset={value}"]) + + class ConformtoPlatformOption(Enum): + NONE = "None" + ALONG_NORMAL = "Along Normal" + PERPENDICULAR_TO_PLANE = "Perpendicular to Plane" + + @property + def conform_to_platform(self) -> ConformtoPlatformOption: + """Select method of automated conforming applied after Element Offset.""" + val = self._get_property("Conform to Platform") + val = self.ConformtoPlatformOption[val.upper()] + return val + + @conform_to_platform.setter + def conform_to_platform(self, value: ConformtoPlatformOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Conform to Platform={value.value}"] + ) + + class ReferencePlaneOption(Enum): + XY_PLANE = "XY Plane" + YZ_PLANE = "YZ Plane" + ZX_PLANE = "ZX Plane" + + @property + def reference_plane(self) -> ReferencePlaneOption: + """Select reference plane for determining original element heights.""" + val = self._get_property("Reference Plane") + val = self.ReferencePlaneOption[val.upper()] + return val + + @reference_plane.setter + def reference_plane(self, value: ReferencePlaneOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Reference Plane={value.value}"]) + + @property + def conform_element_orientation(self) -> bool: + """Conform Element Orientation. + + Toggle (on/off) re-orientation of elements to conform to curved + placement surface. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Conform Element Orientation") + return val == true + + @conform_element_orientation.setter + def conform_element_orientation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Conform Element Orientation={value}"] + ) + + @property + def show_axes(self) -> bool: + """Toggle (on/off) display of antenna coordinate axes in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Axes") + return val == true + + @show_axes.setter + def show_axes(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Axes={value}"]) + + @property + def show_icon(self) -> bool: + """Toggle (on/off) display of antenna marker (cone) in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Icon") + return val == true + + @show_icon.setter + def show_icon(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Icon={value}"]) + + @property + def size(self) -> float: + """Adjust relative size of antenna marker (cone) in 3-D window. + + Value should be between 0.001 and 1. + """ + val = self._get_property("Size") + return float(val) + + @size.setter + def size(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Size={value}"]) + + @property + def color(self): + """Set color of antenna marker (cone) in 3-D window. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @color.setter + def color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Color={value}"]) + + @property + def el_sample_interval(self) -> float: + """Space between elevation-angle samples of pattern.""" + val = self._get_property("El Sample Interval") + return float(val) + + @property + def az_sample_interval(self) -> float: + """Space between azimuth-angle samples of pattern.""" + val = self._get_property("Az Sample Interval") + return float(val) + + @property + def has_frequency_domain(self) -> bool: + """False if antenna can be used at any frequency. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Has Frequency Domain") + return val == true + + @property + def frequency_domain(self): + """Frequency sample(s) defining antenna.""" + val = self._get_property("Frequency Domain") + return val + + @property + def number_of_electric_sources(self) -> int: + """Number of freestanding electric current sources defining antenna.""" + val = self._get_property("Number of Electric Sources") + return int(val) + + @property + def number_of_magnetic_sources(self) -> int: + """Number of freestanding magnetic current sources defining antenna.""" + val = self._get_property("Number of Magnetic Sources") + return int(val) + + @property + def number_of_imaged_electric_sources(self) -> int: + """Number of Imaged Electric Sources. + + Number of imaged, half-space radiating electric current sources defining + antenna. + """ + val = self._get_property("Number of Imaged Electric Sources") + return int(val) + + @property + def number_of_imaged_magnetic_sources(self) -> int: + """Number of Imaged Magnetic Sources. + + Number of imaged, half-space radiating magnetic current sources defining + antenna. + """ + val = self._get_property("Number of Imaged Magnetic Sources") + return int(val) + + @property + def waveguide_height(self) -> float: + """Waveguide Height. + + Implied waveguide height (along local x-axis) where the flared horn + walls meet the feed. + """ + val = self._get_property("Waveguide Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def waveguide_cutoff_frequency(self) -> float: + """Implied lowest operating frequency of pyramidal horn antenna.""" + val = self._get_property("Waveguide Cutoff Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def aperture_cutoff_frequency(self) -> float: + """Implied lowest operating frequency of conical horn antenna.""" + val = self._get_property("Aperture Cutoff Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class SWEModeTruncationOption(Enum): + DYNAMIC = "Dynamic" + FIXED_CUSTOM = "Fixed (Custom)" + NONE = "None" + + @property + def swe_mode_truncation(self) -> SWEModeTruncationOption: + """SWE Mode Truncation. + + Select the method for stability-enhancing truncation of spherical wave + expansion terms. + """ + val = self._get_property("SWE Mode Truncation") + val = self.SWEModeTruncationOption[val.upper()] + return val + + @swe_mode_truncation.setter + def swe_mode_truncation(self, value: SWEModeTruncationOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"SWE Mode Truncation={value.value}"] + ) + + @property + def max_n_index(self) -> int: + """Set maximum allowed index N for spherical wave expansion terms. + + Value should be greater than 1. + """ + val = self._get_property("Max N Index") + return int(val) + + @max_n_index.setter + def max_n_index(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max N Index={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + @property + def show_composite_passband(self) -> bool: + """Show plot instead of 3D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Composite Passband") + return val == true + + @show_composite_passband.setter + def show_composite_passband(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Composite Passband={value}"]) + + @property + def use_phase_center(self) -> bool: + """Use the phase center defined in the HFSS design. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Phase Center") + return val == true + + @use_phase_center.setter + def use_phase_center(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use Phase Center={value}"]) + + @property + def coordinate_systems(self) -> str: + """Coordinate Systems. + + Specifies the coordinate system for the phase center of this antenna. + """ + val = self._get_property("Coordinate Systems") + return val + + @property + def phasecenterposition(self): + """Set position of the antennas linked coordinate system. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("PhaseCenterPosition") + return val + + @property + def phasecenterorientation(self): + """Set orientation of the antennas linked coordinate system. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("PhaseCenterOrientation") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/antenna_passband.py b/src/ansys/aedt/core/emit_core/nodes/generated/antenna_passband.py new file mode 100644 index 00000000000..48ea986c691 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/antenna_passband.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class AntennaPassband(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + @property + def passband_loss(self) -> float: + """Passband loss. + + Value should be between 0 and 100. + """ + val = self._get_property("Passband Loss") + return float(val) + + @passband_loss.setter + def passband_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Passband Loss={value}"]) + + @property + def out_of_band_attenuation(self) -> float: + """Out of band antenna loss. + + Value should be between 0 and 200. + """ + val = self._get_property("Out of Band Attenuation") + return float(val) + + @out_of_band_attenuation.setter + def out_of_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Out of Band Attenuation={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/band.py b/src/ansys/aedt/core/emit_core/nodes/generated/band.py new file mode 100644 index 00000000000..6f1529efb0b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/band.py @@ -0,0 +1,599 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Band(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + @property + def port(self): + """Radio Port associated with this Band.""" + val = self._get_property("Port") + return val + + @port.setter + def port(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port={value}"]) + + @property + def use_dd_1494_mode(self) -> bool: + """Uses DD-1494 parameters to define the Tx/Rx spectrum. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use DD-1494 Mode") + return val == true + + @use_dd_1494_mode.setter + def use_dd_1494_mode(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use DD-1494 Mode={value}"]) + + @property + def use_emission_designator(self) -> bool: + """Use Emission Designator. + + Uses the Emission Designator to define the bandwidth and modulation. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Emission Designator") + return val == true + + @use_emission_designator.setter + def use_emission_designator(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use Emission Designator={value}"]) + + @property + def emission_designator(self) -> str: + """Emission Designator. + + Enter the Emission Designator to define the bandwidth and modulation. + """ + val = self._get_property("Emission Designator") + return val + + @emission_designator.setter + def emission_designator(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Emission Designator={value}"]) + + @property + def emission_designator_ch_bw(self) -> float: + """Channel Bandwidth based off the emission designator.""" + val = self._get_property("Emission Designator Ch. BW") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def emit_modulation_type(self) -> str: + """Modulation based off the emission designator.""" + val = self._get_property("EMIT Modulation Type") + return val + + @property + def override_emission_designator_bw(self) -> bool: + """Override Emission Designator BW. + + Enables the 3 dB channel bandwidth to equal a value < emission + designator bandwidth. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Override Emission Designator BW") + return val == true + + @override_emission_designator_bw.setter + def override_emission_designator_bw(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Override Emission Designator BW={value}"] + ) + + @property + def channel_bandwidth(self) -> float: + """Channel Bandwidth. + + Value should be greater than 1. + """ + val = self._get_property("Channel Bandwidth") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @channel_bandwidth.setter + def channel_bandwidth(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Channel Bandwidth={value}"]) + + class ModulationOption(Enum): + GENERIC = "Generic" + AM = "AM" + LSB = "LSB" + USB = "USB" + FM = "FM" + FSK = "FSK" + MSK = "MSK" + PSK = "PSK" + QAM = "QAM" + APSK = "APSK" + RADAR = "Radar" + + @property + def modulation(self) -> ModulationOption: + """Modulation used for the transmitted/received signal.""" + val = self._get_property("Modulation") + val = self.ModulationOption[val.upper()] + return val + + @modulation.setter + def modulation(self, value: ModulationOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Modulation={value.value}"]) + + @property + def max_modulating_freq(self) -> float: + """Maximum modulating frequency: helps determine spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Max Modulating Freq.") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @max_modulating_freq.setter + def max_modulating_freq(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Modulating Freq.={value}"]) + + @property + def modulation_index(self) -> float: + """AM modulation index: helps determine spectral profile. + + Value should be between 0.01 and 1. + """ + val = self._get_property("Modulation Index") + return float(val) + + @modulation_index.setter + def modulation_index(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Modulation Index={value}"]) + + @property + def freq_deviation(self) -> float: + """Frequency deviation: helps determine spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Freq. Deviation") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @freq_deviation.setter + def freq_deviation(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Freq. Deviation={value}"]) + + @property + def bit_rate(self) -> float: + """Maximum bit rate: helps determine width of spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Bit Rate") + val = self._convert_from_internal_units(float(val), "Data Rate") + return float(val) + + @bit_rate.setter + def bit_rate(self, value: float | str): + value = self._convert_to_internal_units(value, "Data Rate") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bit Rate={value}"]) + + @property + def sidelobes(self) -> int: + """Number of sidelobes in spectral profile. + + Value should be greater than 0. + """ + val = self._get_property("Sidelobes") + return int(val) + + @sidelobes.setter + def sidelobes(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Sidelobes={value}"]) + + @property + def freq_deviation(self) -> float: + """FSK frequency deviation: helps determine spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Freq. Deviation ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @freq_deviation.setter + def freq_deviation(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Freq. Deviation ={value}"]) + + class PSKTypeOption(Enum): + BPSK = "BPSK" + QPSK = "QPSK" + PSK_8 = "PSK-8" + PSK_16 = "PSK-16" + PSK_32 = "PSK-32" + PSK_64 = "PSK-64" + + @property + def psk_type(self) -> PSKTypeOption: + """PSK modulation order: helps determine spectral profile.""" + val = self._get_property("PSK Type") + val = self.PSKTypeOption[val.upper()] + return val + + @psk_type.setter + def psk_type(self, value: PSKTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"PSK Type={value.value}"]) + + class FSKTypeOption(Enum): + FSK_2 = "FSK-2" + FSK_4 = "FSK-4" + FSK_8 = "FSK-8" + + @property + def fsk_type(self) -> FSKTypeOption: + """FSK modulation order: helps determine spectral profile.""" + val = self._get_property("FSK Type") + val = self.FSKTypeOption[val.upper()] + return val + + @fsk_type.setter + def fsk_type(self, value: FSKTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"FSK Type={value.value}"]) + + class QAMTypeOption(Enum): + QAM_4 = "QAM-4" + QAM_16 = "QAM-16" + QAM_64 = "QAM-64" + QAM_256 = "QAM-256" + QAM_1024 = "QAM-1024" + + @property + def qam_type(self) -> QAMTypeOption: + """QAM modulation order: helps determine spectral profile.""" + val = self._get_property("QAM Type") + val = self.QAMTypeOption[val.upper()] + return val + + @qam_type.setter + def qam_type(self, value: QAMTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"QAM Type={value.value}"]) + + class APSKTypeOption(Enum): + APSK_4 = "APSK-4" + APSK_16 = "APSK-16" + APSK_64 = "APSK-64" + APSK_256 = "APSK-256" + APSK_1024 = "APSK-1024" + + @property + def apsk_type(self) -> APSKTypeOption: + """APSK modulation order: helps determine spectral profile.""" + val = self._get_property("APSK Type") + val = self.APSKTypeOption[val.upper()] + return val + + @apsk_type.setter + def apsk_type(self, value: APSKTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"APSK Type={value.value}"]) + + @property + def start_frequency(self) -> float: + """First frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @start_frequency.setter + def start_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Start Frequency={value}"]) + + @property + def stop_frequency(self) -> float: + """Last frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @stop_frequency.setter + def stop_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop Frequency={value}"]) + + @property + def channel_spacing(self) -> float: + """Spacing between channels within this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Channel Spacing") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @channel_spacing.setter + def channel_spacing(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Channel Spacing={value}"]) + + @property + def tx_offset(self) -> float: + """Frequency offset between Tx and Rx channels. + + Value should be less than 100e9. + """ + val = self._get_property("Tx Offset") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @tx_offset.setter + def tx_offset(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tx Offset={value}"]) + + class RadarTypeOption(Enum): + CW = "CW" + FM_CW = "FM-CW" + FM_PULSE = "FM Pulse" + NON_FM_PULSE = "Non-FM Pulse" + PHASE_CODED = "Phase Coded" + + @property + def radar_type(self) -> RadarTypeOption: + """Radar type: helps determine spectral profile.""" + val = self._get_property("Radar Type") + val = self.RadarTypeOption[val.upper()] + return val + + @radar_type.setter + def radar_type(self, value: RadarTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Radar Type={value.value}"]) + + @property + def hopping_radar(self) -> bool: + """True for hopping radars; false otherwise. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Hopping Radar") + return val == true + + @hopping_radar.setter + def hopping_radar(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Hopping Radar={value}"]) + + @property + def post_october_2020_procurement(self) -> bool: + """Post October 2020 Procurement. + + Procurement date: helps determine spectral profile, particularly the + roll-off. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Post October 2020 Procurement") + return val == true + + @post_october_2020_procurement.setter + def post_october_2020_procurement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Post October 2020 Procurement={value}"] + ) + + @property + def hop_range_min_freq(self) -> float: + """Sets the minimum frequency of the hopping range. + + Value should be between 1.0 and 100.0e9. + """ + val = self._get_property("Hop Range Min Freq") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @hop_range_min_freq.setter + def hop_range_min_freq(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Hop Range Min Freq={value}"]) + + @property + def hop_range_max_freq(self) -> float: + """Sets the maximum frequency of the hopping range. + + Value should be between 1.0 and 100.0e9. + """ + val = self._get_property("Hop Range Max Freq") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @hop_range_max_freq.setter + def hop_range_max_freq(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Hop Range Max Freq={value}"]) + + @property + def pulse_duration(self) -> float: + """Pulse duration. + + Value should be greater than 0.0. + """ + val = self._get_property("Pulse Duration") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @pulse_duration.setter + def pulse_duration(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pulse Duration={value}"]) + + @property + def pulse_rise_time(self) -> float: + """Pulse rise time. + + Value should be greater than 0.0. + """ + val = self._get_property("Pulse Rise Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @pulse_rise_time.setter + def pulse_rise_time(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pulse Rise Time={value}"]) + + @property + def pulse_fall_time(self) -> float: + """Pulse fall time. + + Value should be greater than 0.0. + """ + val = self._get_property("Pulse Fall Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @pulse_fall_time.setter + def pulse_fall_time(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pulse Fall Time={value}"]) + + @property + def pulse_repetition_rate(self) -> float: + """Pulse repetition rate [pulses/sec]. + + Value should be greater than 1.0. + """ + val = self._get_property("Pulse Repetition Rate") + return float(val) + + @pulse_repetition_rate.setter + def pulse_repetition_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pulse Repetition Rate={value}"]) + + @property + def number_of_chips(self) -> float: + """Total number of chips (subpulses) contained in the pulse. + + Value should be greater than 1.0. + """ + val = self._get_property("Number of Chips") + return float(val) + + @number_of_chips.setter + def number_of_chips(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Number of Chips={value}"]) + + @property + def pulse_compression_ratio(self) -> float: + """Pulse compression ratio. + + Value should be greater than 1.0. + """ + val = self._get_property("Pulse Compression Ratio") + return float(val) + + @pulse_compression_ratio.setter + def pulse_compression_ratio(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pulse Compression Ratio={value}"]) + + @property + def fm_chirp_period(self) -> float: + """FM Chirp period for the FM/CW radar. + + Value should be greater than 0.0. + """ + val = self._get_property("FM Chirp Period") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @fm_chirp_period.setter + def fm_chirp_period(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"FM Chirp Period={value}"]) + + @property + def fm_freq_deviation(self) -> float: + """FM Freq Deviation. + + Total frequency deviation for the carrier frequency for the FM/CW radar. + + Value should be between 1 and 100e9. + """ + val = self._get_property("FM Freq Deviation") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @fm_freq_deviation.setter + def fm_freq_deviation(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"FM Freq Deviation={value}"]) + + @property + def fm_freq_dev_bandwidth(self) -> float: + """FM Freq Dev Bandwidth. + + Bandwidth of freq deviation for FM modulated pulsed waveform (total freq + shift during pulse duration). + + Value should be between 1 and 100e9. + """ + val = self._get_property("FM Freq Dev Bandwidth") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @fm_freq_dev_bandwidth.setter + def fm_freq_dev_bandwidth(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"FM Freq Dev Bandwidth={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/band_folder.py b/src/ansys/aedt/core/emit_core/nodes/generated/band_folder.py new file mode 100644 index 00000000000..528817256e3 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/band_folder.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class BandFolder(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def add_band(self): + """Create a New Band""" + return self._add_child_node("Band") + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/band_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/band_trace_node.py new file mode 100644 index 00000000000..4c4f65840aa --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/band_trace_node.py @@ -0,0 +1,265 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class BandTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + class TxorRxOption(Enum): + TX = "Tx" + RX = "Rx" + + @property + def tx_or_rx(self) -> TxorRxOption: + """Specifies whether the trace is a Tx or Rx channel.""" + val = self._get_property("Tx or Rx") + val = self.TxorRxOption[val.upper()] + return val + + @tx_or_rx.setter + def tx_or_rx(self, value: TxorRxOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tx or Rx={value.value}"]) + + @property + def channel_frequency(self): + """Select band channel frequency to display.""" + val = self._get_property("Channel Frequency") + return val + + @channel_frequency.setter + def channel_frequency(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Channel Frequency={value}"]) + + @property + def transmit_frequency(self) -> float: + """Transmit Frequency. + + The actual transmit frequency (i.e., the Channel Frequency plus the Tx + Offset). + """ + val = self._get_property("Transmit Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/cable.py b/src/ansys/aedt/core/emit_core/nodes/generated/cable.py new file mode 100644 index 00000000000..199bcf38831 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/cable.py @@ -0,0 +1,177 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Cable(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_FILE = "By File" + CONSTANT_LOSS = "Constant Loss" + COAXIAL_CABLE = "Coaxial Cable" + + @property + def type(self) -> TypeOption: + """Type. + + Type of cable to use. Options include: By File (measured or simulated), + Constant Loss, or Coaxial Cable. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + @property + def length(self) -> float: + """Length of cable. + + Value should be between 0 and 500. + """ + val = self._get_property("Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @length.setter + def length(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Length={value}"]) + + @property + def loss_per_length(self) -> float: + """Cable loss per unit length (dB/meter). + + Value should be between 0 and 20. + """ + val = self._get_property("Loss Per Length") + return float(val) + + @loss_per_length.setter + def loss_per_length(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Loss Per Length={value}"]) + + @property + def measurement_length(self) -> float: + """Length of the cable used for the measurements. + + Value should be between 0 and 500. + """ + val = self._get_property("Measurement Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @measurement_length.setter + def measurement_length(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Measurement Length={value}"]) + + @property + def resistive_loss_constant(self) -> float: + """Coaxial cable resistive loss constant. + + Value should be between 0 and 2. + """ + val = self._get_property("Resistive Loss Constant") + return float(val) + + @resistive_loss_constant.setter + def resistive_loss_constant(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Resistive Loss Constant={value}"]) + + @property + def dielectric_loss_constant(self) -> float: + """Coaxial cable dielectric loss constant. + + Value should be between 0 and 1. + """ + val = self._get_property("Dielectric Loss Constant") + return float(val) + + @dielectric_loss_constant.setter + def dielectric_loss_constant(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Dielectric Loss Constant={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/cad_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/cad_node.py new file mode 100644 index 00000000000..1cbfade403d --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/cad_node.py @@ -0,0 +1,622 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class CADNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def file(self) -> str: + """Name of the imported CAD file. + + Value should be a full file path. + """ + val = self._get_property("File") + return val + + class ModelTypeOption(Enum): + PLATE = "Plate" + BOX = "Box" + DIHEDRAL = "Dihedral" + TRIHEDRAL = "Trihedral" + CYLINDER = "Cylinder" + TAPERED_CYLINDER = "Tapered Cylinder" + CONE = "Cone" + SPHERE = "Sphere" + ELLIPSOID = "Ellipsoid" + CIRCULAR_PLATE = "Circular Plate" + PARABOLA = "Parabola" + PRISM = "Prism" + TAPERED_PRISM = "Tapered Prism" + TOPHAT = "Tophat" + + @property + def model_type(self) -> ModelTypeOption: + """Select type of parametric model to create.""" + val = self._get_property("Model Type") + val = self.ModelTypeOption[val.upper()] + return val + + @model_type.setter + def model_type(self, value: ModelTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Model Type={value.value}"]) + + @property + def length(self) -> float: + """Length of the model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @length.setter + def length(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Length={value}"]) + + @property + def width(self) -> float: + """Width of the model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @width.setter + def width(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Width={value}"]) + + @property + def height(self) -> float: + """Height of the model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @height.setter + def height(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Height={value}"]) + + @property + def angle(self) -> float: + """Angle (deg) between the plates. + + Value should be between 0.0 and 360.0. + """ + val = self._get_property("Angle") + return float(val) + + @angle.setter + def angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Angle={value}"]) + + @property + def top_side(self) -> float: + """Side of the top of a equilateral triangular cylinder model. + + Value should be greater than 0.0. + """ + val = self._get_property("Top Side") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @top_side.setter + def top_side(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Top Side={value}"]) + + @property + def top_radius(self) -> float: + """Radius of the top of a tapered cylinder model. + + Value should be greater than 0.0. + """ + val = self._get_property("Top Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @top_radius.setter + def top_radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Top Radius={value}"]) + + @property + def side(self) -> float: + """Side of the equilateral triangular cylinder. + + Value should be greater than 0.000001. + """ + val = self._get_property("Side") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @side.setter + def side(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Side={value}"]) + + @property + def radius(self) -> float: + """Radius of the sphere or cylinder. + + Value should be greater than 0.000001. + """ + val = self._get_property("Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @radius.setter + def radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Radius={value}"]) + + @property + def base_radius(self) -> float: + """Radius of the base of a tophat model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Base Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @base_radius.setter + def base_radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Base Radius={value}"]) + + @property + def center_radius(self) -> float: + """Radius of the raised portion of a tophat model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Center Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @center_radius.setter + def center_radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Center Radius={value}"]) + + @property + def x_axis_ellipsoid_radius(self) -> float: + """Ellipsoid semi-principal radius for the X axis. + + Value should be greater than 0.000001. + """ + val = self._get_property("X Axis Ellipsoid Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @x_axis_ellipsoid_radius.setter + def x_axis_ellipsoid_radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"X Axis Ellipsoid Radius={value}"]) + + @property + def y_axis_ellipsoid_radius(self) -> float: + """Ellipsoid semi-principal radius for the Y axis. + + Value should be greater than 0.000001. + """ + val = self._get_property("Y Axis Ellipsoid Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @y_axis_ellipsoid_radius.setter + def y_axis_ellipsoid_radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y Axis Ellipsoid Radius={value}"]) + + @property + def z_axis_ellipsoid_radius(self) -> float: + """Ellipsoid semi-principal radius for the Z axis. + + Value should be greater than 0.000001. + """ + val = self._get_property("Z Axis Ellipsoid Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @z_axis_ellipsoid_radius.setter + def z_axis_ellipsoid_radius(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Z Axis Ellipsoid Radius={value}"]) + + @property + def focal_length(self) -> float: + """Focal length of a parabolic reflector (f = 1/4a where y=ax^2). + + Value should be greater than 0.000001. + """ + val = self._get_property("Focal Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @focal_length.setter + def focal_length(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Focal Length={value}"]) + + @property + def offset(self) -> float: + """Offset of parabolic reflector.""" + val = self._get_property("Offset") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @offset.setter + def offset(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Offset={value}"]) + + @property + def x_direction_taper(self) -> float: + """X Direction Taper. + + Amount (%) that the prism tapers in the X dimension from one end to the + other. + + Value should be greater than 0.0. + """ + val = self._get_property("X Direction Taper") + return float(val) + + @x_direction_taper.setter + def x_direction_taper(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"X Direction Taper={value}"]) + + @property + def y_direction_taper(self) -> float: + """Y Direction Taper. + + Amount (%) that the prism tapers in the Y dimension from one end to the + other. + + Value should be greater than 0.0. + """ + val = self._get_property("Y Direction Taper") + return float(val) + + @y_direction_taper.setter + def y_direction_taper(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y Direction Taper={value}"]) + + @property + def prism_direction(self): + """Prism Direction. + + Direction vector between the center of the base and center of the top. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Prism Direction") + return val + + @prism_direction.setter + def prism_direction(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Prism Direction={value}"]) + + @property + def closed_top(self) -> bool: + """Control whether the top of the model is closed. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Closed Top") + return val == true + + @closed_top.setter + def closed_top(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Closed Top={value}"]) + + @property + def closed_base(self) -> bool: + """Control whether the base of the model is closed. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Closed Base") + return val == true + + @closed_base.setter + def closed_base(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Closed Base={value}"]) + + @property + def mesh_density(self) -> int: + """Mesh Density. + + Unitless mesh density parameter where higher value improves mesh + smoothness. + + Value should be between 1 and 100. + """ + val = self._get_property("Mesh Density") + return int(val) + + @mesh_density.setter + def mesh_density(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mesh Density={value}"]) + + @property + def use_symmetric_mesh(self) -> bool: + """Use Symmetric Mesh. + + Convert quads to a symmetric triangle mesh by adding a center point (4 + triangles per quad instead of 2). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Symmetric Mesh") + return val == true + + @use_symmetric_mesh.setter + def use_symmetric_mesh(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use Symmetric Mesh={value}"]) + + class MeshOptionOption(Enum): + IMPROVED = "Improved" + LEGACY = "Legacy" + + @property + def mesh_option(self) -> MeshOptionOption: + """Select from different meshing options.""" + val = self._get_property("Mesh Option") + val = self.MeshOptionOption[val.upper()] + return val + + @mesh_option.setter + def mesh_option(self, value: MeshOptionOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mesh Option={value.value}"]) + + @property + def coating_index(self) -> int: + """Coating index for the parametric model primitive. + + Value should be between 0 and 100000. + """ + val = self._get_property("Coating Index") + return int(val) + + @coating_index.setter + def coating_index(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Coating Index={value}"]) + + @property + def show_relative_coordinates(self) -> bool: + """Show Relative Coordinates. + + Show CAD model node position and orientation in parent-node coords + (False) or relative to placement coords (True). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Relative Coordinates") + return val == true + + @show_relative_coordinates.setter + def show_relative_coordinates(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Show Relative Coordinates={value}"] + ) + + @property + def position(self): + """Set position of the CAD node in parent-node coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Position") + return val + + @position.setter + def position(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position={value}"]) + + @property + def relative_position(self): + """Relative Position. + + Set position of the CAD model node relative to placement coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Relative Position") + return val + + @relative_position.setter + def relative_position(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Relative Position={value}"]) + + class OrientationModeOption(Enum): + ROLL_PITCH_YAW = "Roll-Pitch-Yaw" + AZ_EL_TWIST = "Az-El-Twist" + + @property + def orientation_mode(self) -> OrientationModeOption: + """Orientation Mode. + + Select the convention (order of rotations) for configuring orientation. + """ + val = self._get_property("Orientation Mode") + val = self.OrientationModeOption[val.upper()] + return val + + @orientation_mode.setter + def orientation_mode(self, value: OrientationModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation Mode={value.value}"]) + + @property + def orientation(self): + """Set orientation of the CAD node in parent-node coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Orientation") + return val + + @orientation.setter + def orientation(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation={value}"]) + + @property + def relative_orientation(self): + """Relative Orientation. + + Set orientation of the CAD model node relative to placement coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Relative Orientation") + return val + + @relative_orientation.setter + def relative_orientation(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Relative Orientation={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of CAD model in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + class RenderModeOption(Enum): + FLAT_SHADED = "Flat-Shaded" + WIRE_FRAME = "Wire-Frame" + HIDDEN_WIRE_FRAME = "Hidden Wire-Frame" + OUTLINE = "Outline" + + @property + def render_mode(self) -> RenderModeOption: + """Select drawing style for surfaces.""" + val = self._get_property("Render Mode") + val = self.RenderModeOption[val.upper()] + return val + + @render_mode.setter + def render_mode(self, value: RenderModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Render Mode={value.value}"]) + + @property + def show_axes(self) -> bool: + """Toggle (on/off) display of CAD model coordinate axes in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Axes") + return val == true + + @show_axes.setter + def show_axes(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Axes={value}"]) + + @property + def min(self): + """Minimum x,y,z extents of CAD model in local coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Min") + return val + + @property + def max(self): + """Maximum x,y,z extents of CAD model in local coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Max") + return val + + @property + def number_of_surfaces(self) -> int: + """Number of surfaces in the model.""" + val = self._get_property("Number of Surfaces") + return int(val) + + @property + def color(self): + """Defines the CAD nodes color. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @color.setter + def color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Color={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/categories_view_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/categories_view_node.py new file mode 100644 index 00000000000..f6c5ee604ce --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/categories_view_node.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class CategoriesViewNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/circulator.py b/src/ansys/aedt/core/emit_core/nodes/generated/circulator.py new file mode 100644 index 00000000000..c4bdad21819 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/circulator.py @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Circulator(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the Isolator/Circulator. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_FILE = "By File" + PARAMETRIC = "Parametric" + + @property + def type(self) -> TypeOption: + """Type. + + Type of circulator model to use. Options include: By File (measured or + simulated) or Parametric. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + class Port1LocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_1_location(self) -> Port1LocationOption: + """Defines the orientation of the circulator.""" + val = self._get_property("Port 1 Location") + val = self.Port1LocationOption[val.upper()] + return val + + @port_1_location.setter + def port_1_location(self, value: Port1LocationOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port 1 Location={value.value}"]) + + @property + def insertion_loss(self) -> float: + """Circulator in-band loss in forward direction. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @insertion_loss.setter + def insertion_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Insertion Loss={value}"]) + + @property + def finite_reverse_isolation(self) -> bool: + """Finite Reverse Isolation. + + Use a finite reverse isolation. If disabled, the circulator model is + ideal (infinite reverse isolation). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Reverse Isolation") + return val == true + + @finite_reverse_isolation.setter + def finite_reverse_isolation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Reverse Isolation={value}"]) + + @property + def reverse_isolation(self) -> float: + """Circulator reverse isolation (i.e., loss in the reverse direction). + + Value should be between 0 and 100. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @reverse_isolation.setter + def reverse_isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Reverse Isolation={value}"]) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the circulator model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @finite_bandwidth.setter + def finite_bandwidth(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Bandwidth={value}"]) + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @out_of_band_attenuation.setter + def out_of_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Out-of-band Attenuation={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/coupling_link_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/coupling_link_node.py new file mode 100644 index 00000000000..e405be54839 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/coupling_link_node.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class CouplingLinkNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling link. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def ports(self): + """Maps each port in the link to an antenna in the project.""" + val = self._get_property("Ports") + return val + + @ports.setter + def ports(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Ports={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/coupling_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/coupling_trace_node.py new file mode 100644 index 00000000000..b28364b1819 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/coupling_trace_node.py @@ -0,0 +1,353 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class CouplingTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def transmitter(self) -> EmitNode: + """Transmitter.""" + val = self._get_property("Transmitter") + return val + + @transmitter.setter + def transmitter(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Transmitter={value}"]) + + @property + def receiver(self) -> EmitNode: + """Receiver.""" + val = self._get_property("Receiver") + return val + + @receiver.setter + def receiver(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Receiver={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) + + @property + def highlight_regions(self) -> bool: + """If true, regions of the trace are highlighted. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Highlight Regions") + return val == true + + @highlight_regions.setter + def highlight_regions(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Highlight Regions={value}"]) + + @property + def show_region_labels(self) -> bool: + """If true, regions of the trace are labelled. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Region Labels") + return val == true + + @show_region_labels.setter + def show_region_labels(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Region Labels={value}"]) + + @property + def font(self): + """Specify font used for the label. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Font") + return val + + @font.setter + def font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Font={value}"]) + + @property + def color(self): + """Specify color of the label text. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @color.setter + def color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Color={value}"]) + + @property + def background_color(self): + """Set color of the label text background. + + Color should be in RGBA form: #AARRGGBB. + """ + val = self._get_property("Background Color") + return val + + @background_color.setter + def background_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Background Color={value}"]) + + @property + def border(self) -> bool: + """Display a border around the label text. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Border") + return val == true + + @border.setter + def border(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border={value}"]) + + @property + def border_width(self) -> int: + """Set the width of the border around the label text. + + Value should be between 1 and 20. + """ + val = self._get_property("Border Width") + return int(val) + + @border_width.setter + def border_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border Width={value}"]) + + @property + def border_color(self): + """Set color of the border around the label text. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Border Color") + return val + + @border_color.setter + def border_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border Color={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/couplings_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/couplings_node.py new file mode 100644 index 00000000000..38cd126aa1d --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/couplings_node.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class CouplingsNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def import_touchstone(self, file_name): + """Open an Existing S-Matrix Data File""" + return self._import(file_name, "TouchstoneCoupling") + + def add_custom_coupling(self): + """Add a new node to define custom coupling between antennas""" + return self._add_child_node("Custom Coupling") + + def add_path_loss_coupling(self): + """Add a new node to define path loss coupling between antennas""" + return self._add_child_node("Path Loss Coupling") + + def add_two_ray_path_loss_coupling(self): + """Add a new node to define two ray ground reflection coupling between antennas""" + return self._add_child_node("Two Ray Path Loss Coupling") + + def add_log_distance_coupling(self): + """Add a new node to define coupling between antennas using the Log Distance model""" + return self._add_child_node("Log Distance Coupling") + + def add_hata_coupling(self): + """Add a new node to define coupling between antennas using the Hata COST 231 model""" + return self._add_child_node("Hata Coupling") + + def add_walfisch_ikegami_coupling(self): + """Add a new node to define coupling between antennas using the Walfisch-Ikegami model""" + return self._add_child_node("Walfisch-Ikegami Coupling") + + def add_erceg_coupling(self): + """Add a new node to define coupling between antennas using the Erceg coupling model""" + return self._add_child_node("Erceg Coupling") + + def add_indoor_propagation_coupling(self): + """Add a new node to define coupling between antennas using the ITU Indoor Propagation model""" + return self._add_child_node("Indoor Propagation Coupling") + + def add_5g_channel_model_coupling(self): + """Add a new node to define coupling between antennas using the 5G channel coupling model""" + return self._add_child_node("5G Channel Model Coupling") + + @property + def minimum_allowed_coupling(self) -> float: + """Minimum Allowed Coupling. + + Global minimum allowed coupling value. All computed coupling within this + project will be >= this value. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Minimum Allowed Coupling") + return float(val) + + @minimum_allowed_coupling.setter + def minimum_allowed_coupling(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Minimum Allowed Coupling={value}"]) + + @property + def global_default_coupling(self) -> float: + """Default antenna-to-antenna coupling loss value. + + Value should be between -1000 and 0. + """ + val = self._get_property("Global Default Coupling") + return float(val) + + @global_default_coupling.setter + def global_default_coupling(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Global Default Coupling={value}"]) + + @property + def antenna_tags(self) -> str: + """All tags currently used by all antennas in the project.""" + val = self._get_property("Antenna Tags") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/custom_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/custom_coupling_node.py new file mode 100644 index 00000000000..7291baf4541 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/custom_coupling_node.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class CustomCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def table_data(self): + """Table. + Table consists of 2 columns. + Frequency: + Value should be between 1.0 and 100.0e9. + Value (dB): + Value should be between -1000.0 and 0.0. + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @antenna_a.setter + def antenna_a(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna A={value}"]) + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @antenna_b.setter + def antenna_b(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna B={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/emi_plot_marker_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/emi_plot_marker_node.py new file mode 100644 index 00000000000..826c7abaff2 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/emi_plot_marker_node.py @@ -0,0 +1,373 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class EmiPlotMarkerNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def visible(self) -> bool: + """Toggle (on/off) this marker. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def attached(self): + """Attached. + + Attach marker to a fixed X-Y point on the plot (True), or to a fixed + point on the plot window (False). + """ + val = self._get_property("Attached") + return val + + @attached.setter + def attached(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Attached={value}"]) + + @property + def position_x(self) -> float: + """Position of the marker on the X-axis (frequency axis).""" + val = self._get_property("Position X") + return float(val) + + @property + def position_y(self) -> float: + """Position of the marker on the Y-axis (result axis).""" + val = self._get_property("Position Y") + return float(val) + + @property + def floating_label(self) -> bool: + """Floating Label. + + Allow marker label to be positioned at a fixed point on the plot window + (the marker symbol remains fixed to the specified X-Y point). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Floating Label") + return val == true + + @floating_label.setter + def floating_label(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Floating Label={value}"]) + + @property + def position_from_left(self) -> float: + """Position from Left. + + Set position of label from left to right as a percentage of the width of + the plot window. + + Value should be between 0 and 100. + """ + val = self._get_property("Position from Left") + return float(val) + + @position_from_left.setter + def position_from_left(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position from Left={value}"]) + + @property + def position_from_top(self) -> float: + """Position from Top. + + Set position of label from top to bottom as a percentage of the height + of the plot window. + + Value should be between 0 and 100. + """ + val = self._get_property("Position from Top") + return float(val) + + @position_from_top.setter + def position_from_top(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position from Top={value}"]) + + @property + def text(self) -> str: + """Set the text of the label.""" + val = self._get_property("Text") + return val + + @text.setter + def text(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Text={value}"]) + + class HorizontalPositionOption(Enum): + LEFT = "Left" + RIGHT = "Right" + CENTER = "Center" + + @property + def horizontal_position(self) -> HorizontalPositionOption: + """Specify horizontal position of the label as compared to the symbol.""" + val = self._get_property("Horizontal Position") + val = self.HorizontalPositionOption[val.upper()] + return val + + @horizontal_position.setter + def horizontal_position(self, value: HorizontalPositionOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Horizontal Position={value.value}"] + ) + + class VerticalPositionOption(Enum): + TOP = "Top" + BOTTOM = "Bottom" + CENTER = "Center" + + @property + def vertical_position(self) -> VerticalPositionOption: + """Specify vertical position of the label as compared to the symbol.""" + val = self._get_property("Vertical Position") + val = self.VerticalPositionOption[val.upper()] + return val + + @vertical_position.setter + def vertical_position(self, value: VerticalPositionOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Vertical Position={value.value}"]) + + class TextAlignmentOption(Enum): + LEFT = "Left" + RIGHT = "Right" + CENTER = "Center" + + @property + def text_alignment(self) -> TextAlignmentOption: + """Specify justification applied to multi-line text.""" + val = self._get_property("Text Alignment") + val = self.TextAlignmentOption[val.upper()] + return val + + @text_alignment.setter + def text_alignment(self, value: TextAlignmentOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Text Alignment={value.value}"]) + + @property + def font(self): + """Specify font used for the label. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Font") + return val + + @font.setter + def font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Font={value}"]) + + @property + def color(self): + """Specify color of the label text. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @color.setter + def color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Color={value}"]) + + @property + def background_color(self): + """Set color of the label text background. + + Color should be in RGBA form: #AARRGGBB. + """ + val = self._get_property("Background Color") + return val + + @background_color.setter + def background_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Background Color={value}"]) + + @property + def border(self) -> bool: + """Display a border around the label text. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Border") + return val == true + + @border.setter + def border(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border={value}"]) + + @property + def border_width(self) -> int: + """Set the width of the border around the label text. + + Value should be between 1 and 20. + """ + val = self._get_property("Border Width") + return int(val) + + @border_width.setter + def border_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border Width={value}"]) + + @property + def border_color(self): + """Set color of the border around the label text. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Border Color") + return val + + @border_color.setter + def border_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + ARROW = "Arrow" + + @property + def symbol(self) -> SymbolOption: + """Specify symbol displayed next to the label.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def arrow_direction(self) -> int: + """Set direction of the arrow; zero degrees is up. + + Value should be between -360 and 360. + """ + val = self._get_property("Arrow Direction") + return int(val) + + @arrow_direction.setter + def arrow_direction(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Arrow Direction={value}"]) + + @property + def symbol_size(self) -> int: + """Set size of the symbol used for this marker. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Set color of the symbol used for this marker. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def filled(self) -> bool: + """Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Filled") + return val == true + + @filled.setter + def filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/emit_scene_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/emit_scene_node.py new file mode 100644 index 00000000000..66aecf33bc8 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/emit_scene_node.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class EmitSceneNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def add_group(self): + """Add a new scene group""" + return self._add_child_node("Group") + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class GroundPlaneNormalOption(Enum): + X_AXIS = "X Axis" + Y_AXIS = "Y Axis" + Z_AXIS = "Z Axis" + + @property + def ground_plane_normal(self) -> GroundPlaneNormalOption: + """Specifies the axis of the normal to the ground plane.""" + val = self._get_property("Ground Plane Normal") + val = self.GroundPlaneNormalOption[val.upper()] + return val + + @ground_plane_normal.setter + def ground_plane_normal(self, value: GroundPlaneNormalOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Ground Plane Normal={value.value}"] + ) + + @property + def gp_position_along_normal(self) -> float: + """GP Position Along Normal. + + Offset of ground plane in direction normal to the ground planes + orientation. + """ + val = self._get_property("GP Position Along Normal") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @gp_position_along_normal.setter + def gp_position_along_normal(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"GP Position Along Normal={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/emitter_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/emitter_node.py new file mode 100644 index 00000000000..28807963674 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/emitter_node.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from typing import cast + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode +from ansys.aedt.core.emit_core.nodes.generated import AntennaNode +from ansys.aedt.core.emit_core.nodes.generated import RadioNode +from ansys.aedt.core.emit_core.nodes.generated import Waveform + + +class EmitterNode(EmitNode): + """ + Provides the EmitterNode object. + + Parameters + ---------- + emit_obj : emit_obj object + EMIT design object representing the project. + result_id : int + Unique ID associated with the Revision. For the Current Revision + the ID = 0 + node_id : int + Unique ID associated with the node. + + >>> aedtapp.results = Results() + >>> revision = aedtapp.results.analyze() + >>> receivers = revision.get_receiver_names() + """ + + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + self._radio_node = RadioNode(emit_obj, result_id, node_id) + + # create_component code provides the radio_id, but we also + # need to get the antenna ID. We can get this by traversing + # the SceneNode children and finding the antenna with the + # same name as the Radio + scene_node_id = self._oRevisionData.GetTopLevelNodeID(result_id, "Scene") + antennas = self._oRevisionData.GetChildNodeNames(result_id, scene_node_id, "AntennaNode", True) + for ant in antennas: + if ant == self._radio_node.name: + ant_id = self._oRevisionData.GetChildNodeID(result_id, scene_node_id, ant) + self._antenna_node = AntennaNode(emit_obj, result_id, ant_id) + + def get_radio(self) -> RadioNode: + """Get the radio associated with this Emitter. + + Returns + ------- + radio_node: RadioNode + Node representing the radio of this Emitter + + Examples + -------- + >>> node = emitter.get_radio() + """ + return self._radio_node + + def get_antenna(self) -> AntennaNode: + """Get the antenna associated with this Emitter. + + Returns + ------- + antenna_node: AntennaNode + Node representing the antenna of this Emitter + + Examples + -------- + >>> node = emitter.get_antenna() + """ + return self._antenna_node + + def get_waveforms(self) -> list[Waveform]: + """Get the waveform nodes for the Emitter. + + Returns + ------- + waveforms: list[Waveform] + list of waveform nodes defined for the Emitter. + + Examples + -------- + >>> waveforms = emitter.get_waveforms() + """ + radio = self.get_radio() + radio_children = radio.children + waveforms = [] + # check for folders and recurse them if needed + for child in radio_children: + if child.type == "BandFolder": + grandchildren = child.children + for grandchild in grandchildren: + # don't allow nested folders, so can add these + # directly to the waveform list + waveforms.append(cast(Waveform, grandchild)) + elif child.type == "Band": + waveforms.append(cast(Waveform, child)) + return waveforms diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/erceg_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/erceg_coupling_node.py new file mode 100644 index 00000000000..cde48706460 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/erceg_coupling_node.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ErcegCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @base_antenna.setter + def base_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Base Antenna={value}"]) + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @mobile_antenna.setter + def mobile_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mobile Antenna={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + class TerrainCategoryOption(Enum): + TYPE_A = "Type A" + TYPE_B = "Type B" + TYPE_C = "Type C" + + @property + def terrain_category(self) -> TerrainCategoryOption: + """Specify the terrain category type for the Erceg model.""" + val = self._get_property("Terrain Category") + val = self.TerrainCategoryOption[val.upper()] + return val + + @terrain_category.setter + def terrain_category(self, value: TerrainCategoryOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Terrain Category={value.value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/filter.py b/src/ansys/aedt/core/emit_core/nodes/generated/filter.py new file mode 100644 index 00000000000..488f1627073 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/filter.py @@ -0,0 +1,374 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Filter(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_FILE = "By File" + LOW_PASS = "Low Pass" + HIGH_PASS = "High Pass" + BAND_PASS = "Band Pass" + BAND_STOP = "Band Stop" + TUNABLE_BANDPASS = "Tunable Bandpass" + TUNABLE_BANDSTOP = "Tunable Bandstop" + + @property + def type(self) -> TypeOption: + """Type. + + Type of filter to define. The filter can be defined by file (measured or + simulated data) or using one of EMIT's parametric models. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + @property + def insertion_loss(self) -> float: + """Filter pass band loss. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @insertion_loss.setter + def insertion_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Insertion Loss={value}"]) + + @property + def stop_band_attenuation(self) -> float: + """Filter stop band loss (attenuation). + + Value should be less than 200. + """ + val = self._get_property("Stop band Attenuation") + return float(val) + + @stop_band_attenuation.setter + def stop_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop band Attenuation={value}"]) + + @property + def max_pass_band(self) -> float: + """Maximum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @max_pass_band.setter + def max_pass_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Pass Band={value}"]) + + @property + def min_stop_band(self) -> float: + """Minimum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @min_stop_band.setter + def min_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Min Stop Band={value}"]) + + @property + def max_stop_band(self) -> float: + """Maximum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @max_stop_band.setter + def max_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Stop Band={value}"]) + + @property + def min_pass_band(self) -> float: + """Minimum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @min_pass_band.setter + def min_pass_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Min Pass Band={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff ={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band ={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band ={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff ={value}"]) + + @property + def lowest_tuned_frequency(self) -> float: + """Lowest tuned frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lowest Tuned Frequency ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lowest_tuned_frequency.setter + def lowest_tuned_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lowest Tuned Frequency ={value}"]) + + @property + def highest_tuned_frequency(self) -> float: + """Highest tuned frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Highest Tuned Frequency ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @highest_tuned_frequency.setter + def highest_tuned_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Highest Tuned Frequency ={value}"]) + + @property + def percent_bandwidth(self) -> float: + """Tunable filter 3-dB bandwidth. + + Value should be between 0.001 and 100. + """ + val = self._get_property("Percent Bandwidth") + return float(val) + + @percent_bandwidth.setter + def percent_bandwidth(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Percent Bandwidth={value}"]) + + @property + def shape_factor(self) -> float: + """Ratio defining the filter rolloff. + + Value should be between 1 and 100. + """ + val = self._get_property("Shape Factor") + return float(val) + + @shape_factor.setter + def shape_factor(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Shape Factor={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/five_g_channel_model.py b/src/ansys/aedt/core/emit_core/nodes/generated/five_g_channel_model.py new file mode 100644 index 00000000000..49685eacd29 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/five_g_channel_model.py @@ -0,0 +1,388 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class FiveGChannelModel(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @base_antenna.setter + def base_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Base Antenna={value}"]) + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @mobile_antenna.setter + def mobile_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mobile Antenna={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + class EnvironmentOption(Enum): + URBAN_MICROCELL = "Urban Microcell" + URBAN_MACROCELL = "Urban Macrocell" + RURAL_MACROCELL = "Rural Macrocell" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment for the 5G channel model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @environment.setter + def environment(self, value: EnvironmentOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Environment={value.value}"]) + + @property + def los(self) -> bool: + """True if the operating environment is line-of-sight. + + Value should be 'true' or 'false'. + """ + val = self._get_property("LOS") + return val == true + + @los.setter + def los(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"LOS={value}"]) + + @property + def include_bpl(self) -> bool: + """Includes building penetration loss if true. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include BPL") + return val == true + + @include_bpl.setter + def include_bpl(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include BPL={value}"]) + + class NYUBPLModelOption(Enum): + LOW_LOSS_MODEL = "Low-loss model" + HIGH_LOSS_MODEL = "High-loss model" + + @property + def nyu_bpl_model(self) -> NYUBPLModelOption: + """Specify the NYU Building Penetration Loss model.""" + val = self._get_property("NYU BPL Model") + val = self.NYUBPLModelOption[val.upper()] + return val + + @nyu_bpl_model.setter + def nyu_bpl_model(self, value: NYUBPLModelOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"NYU BPL Model={value.value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/hata_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/hata_coupling_node.py new file mode 100644 index 00000000000..18f8496f624 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/hata_coupling_node.py @@ -0,0 +1,348 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class HataCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @base_antenna.setter + def base_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Base Antenna={value}"]) + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @mobile_antenna.setter + def mobile_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mobile Antenna={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + class EnvironmentOption(Enum): + LARGE_CITY = "Large City" + SMALLMEDIUM_CITY = "Small/Medium City" + SUBURBAN = "Suburban" + RURAL = "Rural" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment type for the Hata model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @environment.setter + def environment(self, value: EnvironmentOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Environment={value.value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/indoor_propagation_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/indoor_propagation_coupling_node.py new file mode 100644 index 00000000000..07d322e8385 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/indoor_propagation_coupling_node.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class IndoorPropagationCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def table_data(self): + """Table. + Table consists of 3 columns. + Frequency: + Value should be between 1.0 and 100.0e9. + Power Loss Coefficient: + Value should be between 0.0 and 100.0. + Floor Penetration Loss (dB): + Value should be between 0.0 and 1000.0. + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @antenna_a.setter + def antenna_a(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna A={value}"]) + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @antenna_b.setter + def antenna_b(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna B={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + class BuildingTypeOption(Enum): + RESIDENTIAL_APARTMENT = "Residential Apartment" + RESIDENTIAL_HOUSE = "Residential House" + OFFICE_BUILDING = "Office Building" + COMMERCIAL_BUILDING = "Commercial Building" + CUSTOM_BUILDING = "Custom Building" + + @property + def building_type(self) -> BuildingTypeOption: + """Specify the building type for the Indoor Propagation model.""" + val = self._get_property("Building Type") + val = self.BuildingTypeOption[val.upper()] + return val + + @building_type.setter + def building_type(self, value: BuildingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Building Type={value.value}"]) + + @property + def number_of_floors(self) -> int: + """The number of floors separating the antennas. + + Value should be between 1 and 3. + """ + val = self._get_property("Number of Floors") + return int(val) + + @number_of_floors.setter + def number_of_floors(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Number of Floors={value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/isolator.py b/src/ansys/aedt/core/emit_core/nodes/generated/isolator.py new file mode 100644 index 00000000000..944835b1274 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/isolator.py @@ -0,0 +1,253 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Isolator(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_FILE = "By File" + PARAMETRIC = "Parametric" + + @property + def type(self) -> TypeOption: + """Type. + + Type of isolator model to use. Options include: By File (measured or + simulated) or Parametric. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + class Port1LocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_1_location(self) -> Port1LocationOption: + """Defines the orientation of the isolator.""" + val = self._get_property("Port 1 Location") + val = self.Port1LocationOption[val.upper()] + return val + + @port_1_location.setter + def port_1_location(self, value: Port1LocationOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port 1 Location={value.value}"]) + + @property + def insertion_loss(self) -> float: + """Isolator in-band loss in forward direction. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @insertion_loss.setter + def insertion_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Insertion Loss={value}"]) + + @property + def finite_reverse_isolation(self) -> bool: + """Finite Reverse Isolation. + + Use a finite reverse isolation. If disabled, the isolator model is + ideal (infinite reverse isolation). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Reverse Isolation") + return val == true + + @finite_reverse_isolation.setter + def finite_reverse_isolation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Reverse Isolation={value}"]) + + @property + def reverse_isolation(self) -> float: + """Isolator reverse isolation (i.e., loss in the reverse direction). + + Value should be between 0 and 100. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @reverse_isolation.setter + def reverse_isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Reverse Isolation={value}"]) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the isolator model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @finite_bandwidth.setter + def finite_bandwidth(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Bandwidth={value}"]) + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @out_of_band_attenuation.setter + def out_of_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Out-of-band Attenuation={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/log_distance_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/log_distance_coupling_node.py new file mode 100644 index 00000000000..e167b77669b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/log_distance_coupling_node.py @@ -0,0 +1,364 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class LogDistanceCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @antenna_a.setter + def antenna_a(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna A={value}"]) + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @antenna_b.setter + def antenna_b(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna B={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + class EnvironmentOption(Enum): + FREE_SPACE = "Free Space" + URBAN = "Urban" + SHADOWED_URBAN = "Shadowed Urban" + BUILDING_LINE_OF_SIGHT = "Building Line of Sight" + BUILDING_OBSTRUCTED = "Building Obstructed" + FACTORY_OBSTRUCTED = "Factory Obstructed" + CUSTOM = "Custom" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment type for the Log Distance model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @environment.setter + def environment(self, value: EnvironmentOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Environment={value.value}"]) + + @property + def path_loss_exponent(self) -> float: + """Path Loss Exponent. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Path Loss Exponent") + return float(val) + + @path_loss_exponent.setter + def path_loss_exponent(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Path Loss Exponent={value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/mplex_band_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/mplex_band_trace_node.py new file mode 100644 index 00000000000..38ac1746877 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/mplex_band_trace_node.py @@ -0,0 +1,243 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class MPlexBandTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + class PowerDirectionOption(Enum): + INTO_COMMON_PORTOUT_OF_COMMON_PORT = "Into Common Port|Out of Common Port" + + @property + def power_direction(self) -> PowerDirectionOption: + """Power Direction.""" + val = self._get_property("Power Direction") + val = self.PowerDirectionOption[val.upper()] + return val + + @power_direction.setter + def power_direction(self, value: PowerDirectionOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Power Direction={value.value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/multiplexer.py b/src/ansys/aedt/core/emit_core/nodes/generated/multiplexer.py new file mode 100644 index 00000000000..5c794fd04e3 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/multiplexer.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Multiplexer(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def add_multiplexer_pass_band(self): + """Add a New Multiplexer Band to this Multiplexer""" + return self._add_child_node("Multiplexer Pass Band") + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the multiplexer. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_PASS_BAND = "By Pass Band" + BY_FILE = "By File" + + @property + def type(self) -> TypeOption: + """Type. + + Type of multiplexer model. Options include: By File (one measured or + simulated file for the device) or By Pass Band (parametric or file-based + definition for each pass band). + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + class Port1LocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_1_location(self) -> Port1LocationOption: + """Defines the orientation of the multiplexer.""" + val = self._get_property("Port 1 Location") + val = self.Port1LocationOption[val.upper()] + return val + + @port_1_location.setter + def port_1_location(self, value: Port1LocationOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port 1 Location={value.value}"]) + + @property + def flip_ports_vertically(self) -> bool: + """Reverses the port order on the multi-port side of the multiplexer. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Flip Ports Vertically") + return val == true + + @flip_ports_vertically.setter + def flip_ports_vertically(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Flip Ports Vertically={value}"]) + + @property + def ports(self): + """Assigns the child port nodes to the multiplexers ports.""" + val = self._get_property("Ports") + return val + + @ports.setter + def ports(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Ports={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/multiplexer_band.py b/src/ansys/aedt/core/emit_core/nodes/generated/multiplexer_band.py new file mode 100644 index 00000000000..eb4777a6e88 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/multiplexer_band.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class MultiplexerBand(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + class TypeOption(Enum): + BY_FILE = "By File" + LOW_PASS = "Low Pass" + HIGH_PASS = "High Pass" + BAND_PASS = "Band Pass" + + @property + def type(self) -> TypeOption: + """Type. + + Type of multiplexer pass band to define. The pass band can be defined by + file (measured or simulated data) or using one of EMIT's parametric + models. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + @property + def filename(self) -> str: + """Name of file defining the multiplexer band. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def insertion_loss(self) -> float: + """Multiplexer pass band insertion loss. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @insertion_loss.setter + def insertion_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Insertion Loss={value}"]) + + @property + def stop_band_attenuation(self) -> float: + """Stop-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Stop band Attenuation") + return float(val) + + @stop_band_attenuation.setter + def stop_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop band Attenuation={value}"]) + + @property + def max_pass_band(self) -> float: + """Maximum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @max_pass_band.setter + def max_pass_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Pass Band={value}"]) + + @property + def min_stop_band(self) -> float: + """Minimum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @min_stop_band.setter + def min_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Min Stop Band={value}"]) + + @property + def max_stop_band(self) -> float: + """Maximum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @max_stop_band.setter + def max_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Stop Band={value}"]) + + @property + def min_pass_band(self) -> float: + """Minimum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @min_pass_band.setter + def min_pass_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Min Pass Band={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/outboard_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/outboard_trace_node.py new file mode 100644 index 00000000000..4223d62d111 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/outboard_trace_node.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class OutboardTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def input_port(self) -> int: + """Specifies input port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Input Port") + return int(val) + + @input_port.setter + def input_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Input Port={value}"]) + + @property + def output_port(self) -> int: + """Specifies output port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Output Port") + return int(val) + + @output_port.setter + def output_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Output Port={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/parametric_coupling_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/parametric_coupling_trace_node.py new file mode 100644 index 00000000000..6761a31e52b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/parametric_coupling_trace_node.py @@ -0,0 +1,249 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ParametricCouplingTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def antenna_a(self) -> EmitNode: + """Antenna A.""" + val = self._get_property("Antenna A") + return val + + @antenna_a.setter + def antenna_a(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna A={value}"]) + + @property + def antenna_b(self) -> EmitNode: + """Antenna B.""" + val = self._get_property("Antenna B") + return val + + @antenna_b.setter + def antenna_b(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna B={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/plot_marker_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/plot_marker_node.py new file mode 100644 index 00000000000..372889120a6 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/plot_marker_node.py @@ -0,0 +1,383 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class PlotMarkerNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def visible(self) -> bool: + """Toggle (on/off) this marker. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def attached(self) -> bool: + """Attached. + + Attach marker to a fixed X-Y point on the plot (True), or to a fixed + point on the plot window (False). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Attached") + return val == true + + @attached.setter + def attached(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Attached={value}"]) + + @property + def position_x(self) -> float: + """Position of the marker on the X-axis (frequency axis).""" + val = self._get_property("Position X") + return float(val) + + @position_x.setter + def position_x(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position X={value}"]) + + @property + def position_y(self) -> float: + """Position of the marker on the Y-axis (result axis).""" + val = self._get_property("Position Y") + return float(val) + + @position_y.setter + def position_y(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position Y={value}"]) + + @property + def floating_label(self) -> bool: + """Floating Label. + + Allow marker label to be positioned at a fixed point on the plot window + (the marker symbol remains fixed to the specified X-Y point). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Floating Label") + return val == true + + @floating_label.setter + def floating_label(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Floating Label={value}"]) + + @property + def position_from_left(self) -> float: + """Position from Left. + + Set position of label from left to right as a percentage of the width of + the plot window. + + Value should be between 0 and 100. + """ + val = self._get_property("Position from Left") + return float(val) + + @position_from_left.setter + def position_from_left(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position from Left={value}"]) + + @property + def position_from_top(self) -> float: + """Position from Top. + + Set position of label from top to bottom as a percentage of the height + of the plot window. + + Value should be between 0 and 100. + """ + val = self._get_property("Position from Top") + return float(val) + + @position_from_top.setter + def position_from_top(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position from Top={value}"]) + + @property + def text(self) -> str: + """Set the text of the label.""" + val = self._get_property("Text") + return val + + @text.setter + def text(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Text={value}"]) + + class HorizontalPositionOption(Enum): + LEFT = "Left" + RIGHT = "Right" + CENTER = "Center" + + @property + def horizontal_position(self) -> HorizontalPositionOption: + """Specify horizontal position of the label as compared to the symbol.""" + val = self._get_property("Horizontal Position") + val = self.HorizontalPositionOption[val.upper()] + return val + + @horizontal_position.setter + def horizontal_position(self, value: HorizontalPositionOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Horizontal Position={value.value}"] + ) + + class VerticalPositionOption(Enum): + TOP = "Top" + BOTTOM = "Bottom" + CENTER = "Center" + + @property + def vertical_position(self) -> VerticalPositionOption: + """Specify vertical position of the label as compared to the symbol.""" + val = self._get_property("Vertical Position") + val = self.VerticalPositionOption[val.upper()] + return val + + @vertical_position.setter + def vertical_position(self, value: VerticalPositionOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Vertical Position={value.value}"]) + + class TextAlignmentOption(Enum): + LEFT = "Left" + RIGHT = "Right" + CENTER = "Center" + + @property + def text_alignment(self) -> TextAlignmentOption: + """Specify justification applied to multi-line text.""" + val = self._get_property("Text Alignment") + val = self.TextAlignmentOption[val.upper()] + return val + + @text_alignment.setter + def text_alignment(self, value: TextAlignmentOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Text Alignment={value.value}"]) + + @property + def font(self): + """Specify font used for the label. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Font") + return val + + @font.setter + def font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Font={value}"]) + + @property + def color(self): + """Specify color of the label text. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @color.setter + def color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Color={value}"]) + + @property + def background_color(self): + """Set color of the label text background. + + Color should be in RGBA form: #AARRGGBB. + """ + val = self._get_property("Background Color") + return val + + @background_color.setter + def background_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Background Color={value}"]) + + @property + def border(self) -> bool: + """Display a border around the label text. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Border") + return val == true + + @border.setter + def border(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border={value}"]) + + @property + def border_width(self) -> int: + """Set the width of the border around the label text. + + Value should be between 1 and 20. + """ + val = self._get_property("Border Width") + return int(val) + + @border_width.setter + def border_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border Width={value}"]) + + @property + def border_color(self): + """Set color of the border around the label text. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Border Color") + return val + + @border_color.setter + def border_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Border Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + ARROW = "Arrow" + + @property + def symbol(self) -> SymbolOption: + """Specify symbol displayed next to the label.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def arrow_direction(self) -> int: + """Set direction of the arrow; zero degrees is up. + + Value should be between -360 and 360. + """ + val = self._get_property("Arrow Direction") + return int(val) + + @arrow_direction.setter + def arrow_direction(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Arrow Direction={value}"]) + + @property + def symbol_size(self) -> int: + """Set size of the symbol used for this marker. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Set color of the symbol used for this marker. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def filled(self) -> bool: + """Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Filled") + return val == true + + @filled.setter + def filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/plot_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/plot_node.py new file mode 100644 index 00000000000..2ef37b1b57c --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/plot_node.py @@ -0,0 +1,443 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class PlotNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def add_marker(self): + """Add an icon and/or label to this plot""" + return self._add_child_node("Plot Marker") + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def title(self) -> str: + """Enter title at the top of the plot, room will be made for it.""" + val = self._get_property("Title") + return val + + @title.setter + def title(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Title={value}"]) + + @property + def title_font(self): + """Configure title font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Title Font") + return val + + @title_font.setter + def title_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Title Font={value}"]) + + @property + def show_legend(self) -> bool: + """Toggle (on/off) display of plot legend. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Legend") + return val == true + + @show_legend.setter + def show_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Legend={value}"]) + + @property + def legend_font(self): + """Configure legend font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Legend Font") + return val + + @legend_font.setter + def legend_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Legend Font={value}"]) + + @property + def display_cad_overlay(self) -> bool: + """Toggle on/off overlay of CAD model in plot. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Display CAD Overlay") + return val == true + + @display_cad_overlay.setter + def display_cad_overlay(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Display CAD Overlay={value}"]) + + @property + def opacity(self) -> float: + """Adjust opacity of CAD model overlay: 0 Transparent - 1 Opaque. + + Value should be between 0 and 100. + """ + val = self._get_property("Opacity") + return float(val) + + @opacity.setter + def opacity(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Opacity={value}"]) + + @property + def vertical_offset(self) -> float: + """Adjust vertical position of CAD model overlay.""" + val = self._get_property("Vertical Offset") + return float(val) + + @vertical_offset.setter + def vertical_offset(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Vertical Offset={value}"]) + + @property + def range_axis_rotation(self) -> float: + """Range Axis Rotation. + + Adjust view angle for CAD model overlay by rotating it about plot + horizontal axis. + + Value should be between -180 and 180. + """ + val = self._get_property("Range Axis Rotation") + return float(val) + + @range_axis_rotation.setter + def range_axis_rotation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Range Axis Rotation={value}"]) + + @property + def lock_axes(self) -> bool: + """Lock Axes. + + Allow or prevent changing of axes when displayed plot traces are + updated. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Lock Axes") + return val == true + + @lock_axes.setter + def lock_axes(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lock Axes={value}"]) + + @property + def x_axis_min(self) -> float: + """Set lower extent of horizontal axis.""" + val = self._get_property("X-axis Min") + return float(val) + + @x_axis_min.setter + def x_axis_min(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"X-axis Min={value}"]) + + @property + def x_axis_max(self) -> float: + """Set upper extent of horizontal axis.""" + val = self._get_property("X-axis Max") + return float(val) + + @x_axis_max.setter + def x_axis_max(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"X-axis Max={value}"]) + + @property + def y_axis_min(self) -> float: + """Set lower extent of vertical axis.""" + val = self._get_property("Y-axis Min") + return float(val) + + @y_axis_min.setter + def y_axis_min(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y-axis Min={value}"]) + + @property + def y_axis_max(self) -> float: + """Set upper extent of vertical axis.""" + val = self._get_property("Y-axis Max") + return float(val) + + @y_axis_max.setter + def y_axis_max(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y-axis Max={value}"]) + + @property + def y_axis_range(self) -> float: + """Y-axis Range. + + Adjust dB span of vertical axis, makes corresponding adjustment in + Y-axis Min. + + Value should be greater than 0. + """ + val = self._get_property("Y-axis Range") + return float(val) + + @y_axis_range.setter + def y_axis_range(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y-axis Range={value}"]) + + @property + def max_major_ticks_x(self) -> int: + """Max Major Ticks X. + + Set maximum number of major tick-mark intervals along horizontal axis. + + Value should be between 1 and 30. + """ + val = self._get_property("Max Major Ticks X") + return int(val) + + @max_major_ticks_x.setter + def max_major_ticks_x(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Major Ticks X={value}"]) + + @property + def max_minor_ticks_x(self) -> int: + """Max Minor Ticks X. + + Set maximum number of minor tick-mark intervals between major ticks + along horizontal axis. + + Value should be between 0 and 100. + """ + val = self._get_property("Max Minor Ticks X") + return int(val) + + @max_minor_ticks_x.setter + def max_minor_ticks_x(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Minor Ticks X={value}"]) + + @property + def max_major_ticks_y(self) -> int: + """Max Major Ticks Y. + + Set maximum number of major tick-mark intervals along vertical axis. + + Value should be between 1 and 30. + """ + val = self._get_property("Max Major Ticks Y") + return int(val) + + @max_major_ticks_y.setter + def max_major_ticks_y(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Major Ticks Y={value}"]) + + @property + def max_minor_ticks_y(self) -> int: + """Max Minor Ticks Y. + + Set maximum number of minor tick-mark intervals between major ticks + along vertical axis. + + Value should be between 0 and 100. + """ + val = self._get_property("Max Minor Ticks Y") + return int(val) + + @max_minor_ticks_y.setter + def max_minor_ticks_y(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Minor Ticks Y={value}"]) + + @property + def axis_label_font(self): + """Configure axis text labels font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Axis Label Font") + return val + + @axis_label_font.setter + def axis_label_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Axis Label Font={value}"]) + + @property + def axis_tick_label_font(self): + """Configure axis tick numeric labels font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Axis Tick Label Font") + return val + + @axis_tick_label_font.setter + def axis_tick_label_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Axis Tick Label Font={value}"]) + + class MajorGridLineStyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def major_grid_line_style(self) -> MajorGridLineStyleOption: + """Select line style of major-tick grid lines.""" + val = self._get_property("Major Grid Line Style") + val = self.MajorGridLineStyleOption[val.upper()] + return val + + @major_grid_line_style.setter + def major_grid_line_style(self, value: MajorGridLineStyleOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Major Grid Line Style={value.value}"] + ) + + @property + def major_grid_color(self): + """Set color of major-tick grid lines. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Major Grid Color") + return val + + @major_grid_color.setter + def major_grid_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Major Grid Color={value}"]) + + class MinorGridLineStyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def minor_grid_line_style(self) -> MinorGridLineStyleOption: + """Select line style of minor-tick grid lines.""" + val = self._get_property("Minor Grid Line Style") + val = self.MinorGridLineStyleOption[val.upper()] + return val + + @minor_grid_line_style.setter + def minor_grid_line_style(self, value: MinorGridLineStyleOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Minor Grid Line Style={value.value}"] + ) + + @property + def minor_grid_color(self): + """Set color of minor-tick grid lines. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Minor Grid Color") + return val + + @minor_grid_color.setter + def minor_grid_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Minor Grid Color={value}"]) + + @property + def background_color(self): + """Set background color of entire plot. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Background Color") + return val + + @background_color.setter + def background_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Background Color={value}"]) + + class BBPowerforPlotsUnitOption(Enum): + HERTZ = "hertz" + KILOHERTZ = "kilohertz" + MEGAHERTZ = "megahertz" + GIGAHERTZ = "gigahertz" + + @property + def bb_power_for_plots_unit(self) -> BBPowerforPlotsUnitOption: + """Units to use for plotting broadband power densities.""" + val = self._get_property("BB Power for Plots Unit") + val = self.BBPowerforPlotsUnitOption[val.upper()] + return val + + @bb_power_for_plots_unit.setter + def bb_power_for_plots_unit(self, value: BBPowerforPlotsUnitOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"BB Power for Plots Unit={value.value}"] + ) + + @property + def bb_power_bandwidth(self) -> float: + """Resolution bandwidth for broadband power. + + Value should be between 1.0 and 100e9. + """ + val = self._get_property("BB Power Bandwidth") + val = self._convert_from_internal_units(float(val), "") + return float(val) + + @bb_power_bandwidth.setter + def bb_power_bandwidth(self, value: float | str): + value = self._convert_to_internal_units(value, "") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"BB Power Bandwidth={value}"]) + + @property + def log_scale(self) -> bool: + """Toggles on/off using a log scale for the X-Axis. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Log Scale") + return val == true + + @log_scale.setter + def log_scale(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Log Scale={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/power_divider.py b/src/ansys/aedt/core/emit_core/nodes/generated/power_divider.py new file mode 100644 index 00000000000..2aa6f1ae4b8 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/power_divider.py @@ -0,0 +1,259 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class PowerDivider(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the Power Divider. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_FILE = "By File" + P3_DB = "P3 dB" + RESISTIVE = "Resistive" + + @property + def type(self) -> TypeOption: + """Type. + + Type of Power Divider model to use. Options include: By File (measured + or simulated), 3 dB (parametric), and Resistive (parametric). + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + class OrientationOption(Enum): + DIVIDER = "Divider" + COMBINER = "Combiner" + + @property + def orientation(self) -> OrientationOption: + """Defines the orientation of the Power Divider.""" + val = self._get_property("Orientation") + val = self.OrientationOption[val.upper()] + return val + + @orientation.setter + def orientation(self, value: OrientationOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation={value.value}"]) + + @property + def insertion_loss_above_ideal(self) -> float: + """Insertion Loss Above Ideal. + + Additional loss beyond the ideal insertion loss. The ideal insertion + loss is 3 dB for the 3 dB Divider and 6 dB for the Resistive Divider. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss Above Ideal") + return float(val) + + @insertion_loss_above_ideal.setter + def insertion_loss_above_ideal(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Insertion Loss Above Ideal={value}"] + ) + + @property + def finite_isolation(self) -> bool: + """Finite Isolation. + + Use a finite isolation between output ports. If disabled, the Power + Divider isolation is ideal (infinite isolation between output ports). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Isolation") + return val == true + + @finite_isolation.setter + def finite_isolation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Isolation={value}"]) + + @property + def isolation(self) -> float: + """Power Divider isolation between output ports. + + Value should be between 0 and 100. + """ + val = self._get_property("Isolation") + return float(val) + + @isolation.setter + def isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Isolation={value}"]) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the Power Divider model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @finite_bandwidth.setter + def finite_bandwidth(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Bandwidth={value}"]) + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @out_of_band_attenuation.setter + def out_of_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Out-of-band Attenuation={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/power_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/power_trace_node.py new file mode 100644 index 00000000000..f7be3575e08 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/power_trace_node.py @@ -0,0 +1,247 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class PowerTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + class DirectionOption(Enum): + AWAY_FROM_TX = "Away From Tx" + TOWARD_TX = "Toward Tx" + + @property + def direction(self) -> DirectionOption: + """Direction. + + Direction of power flow (towards or away from the transmitter) to plot. + """ + val = self._get_property("Direction") + val = self.DirectionOption[val.upper()] + return val + + @direction.setter + def direction(self, value: DirectionOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Direction={value.value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/profile_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/profile_trace_node.py new file mode 100644 index 00000000000..b8844eb9555 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/profile_trace_node.py @@ -0,0 +1,229 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ProfileTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/propagation_loss_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/propagation_loss_coupling_node.py new file mode 100644 index 00000000000..975ee34ad1d --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/propagation_loss_coupling_node.py @@ -0,0 +1,331 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class PropagationLossCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @antenna_a.setter + def antenna_a(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna A={value}"]) + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @antenna_b.setter + def antenna_b(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna B={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/radio_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/radio_node.py new file mode 100644 index 00000000000..10124fcd1ad --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/radio_node.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RadioNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def add_band(self): + """Create a New Band""" + return self._add_child_node("Band") + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def table_data(self): + """Table. + Table consists of 2 columns. + Name: + + Type: + + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_amplifier.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_amplifier.py new file mode 100644 index 00000000000..e0126f43ca9 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_amplifier.py @@ -0,0 +1,164 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyAmplifier(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class AmplifierTypeOption(Enum): + TRANSMIT_AMPLIFIER = "Transmit Amplifier" + RECEIVE_AMPLIFIER = "Receive Amplifier" + + @property + def amplifier_type(self) -> AmplifierTypeOption: + """Configures the amplifier as a Tx or Rx amplifier.""" + val = self._get_property("Amplifier Type") + val = self.AmplifierTypeOption[val.upper()] + return val + + @property + def gain(self) -> float: + """Amplifier in-band gain. + + Value should be between 0 and 100. + """ + val = self._get_property("Gain") + return float(val) + + @property + def center_frequency(self) -> float: + """Center frequency of amplifiers operational bandwidth. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Center Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def bandwidth(self) -> float: + """Frequency region where the gain applies. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Bandwidth") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def noise_figure(self) -> float: + """Amplifier noise figure. + + Value should be between 0 and 100. + """ + val = self._get_property("Noise Figure") + return float(val) + + @property + def saturation_level(self) -> float: + """Saturation level. + + Value should be between -200 and 200. + """ + val = self._get_property("Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def p1_db_point_ref_input(self) -> float: + """Incoming signals > this value saturate the amplifier. + + Value should be between -200 and 200. + """ + val = self._get_property("P1-dB Point, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def ip3_ref_input(self) -> float: + """3rd order intercept point. + + Value should be between -200 and 200. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def shape_factor(self) -> float: + """Ratio defining the selectivity of the amplifier. + + Value should be between 1 and 100. + """ + val = self._get_property("Shape Factor") + return float(val) + + @property + def reverse_isolation(self) -> float: + """Amplifier reverse isolation. + + Value should be between 0 and 200. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @property + def max_intermod_order(self) -> int: + """Maximum order of intermods to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_antenna_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_antenna_node.py new file mode 100644 index 00000000000..2a41c8cff95 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_antenna_node.py @@ -0,0 +1,673 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyAntennaNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def tags(self) -> str: + """Space delimited list of tags for coupling selections.""" + val = self._get_property("Tags") + return val + + @property + def show_relative_coordinates(self) -> bool: + """Show Relative Coordinates. + + Show antenna position and orientation in parent-node coords (False) or + relative to placement coords (True). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Relative Coordinates") + return val == true + + @property + def position(self): + """Set position of the antenna in parent-node coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Position") + return val + + @property + def relative_position(self): + """Set position of the antenna relative to placement coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Relative Position") + return val + + class OrientationModeOption(Enum): + ROLL_PITCH_YAW = "Roll-Pitch-Yaw" + AZ_EL_TWIST = "Az-El-Twist" + + @property + def orientation_mode(self) -> OrientationModeOption: + """Orientation Mode. + + Select the convention (order of rotations) for configuring orientation. + """ + val = self._get_property("Orientation Mode") + val = self.OrientationModeOption[val.upper()] + return val + + @property + def orientation(self): + """Set orientation of the antenna relative to parent-node coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Orientation") + return val + + @property + def relative_orientation(self): + """Set orientation of the antenna relative to placement coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Relative Orientation") + return val + + @property + def position_defined(self) -> bool: + """Toggles on/off the ability to define a position for the antenna. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Position Defined") + return val == true + + @property + def antenna_temperature(self) -> float: + """Antenna noise temperature. + + Value should be between 0 and 100000. + """ + val = self._get_property("Antenna Temperature") + return float(val) + + @property + def type(self): + """Defines the type of antenna.""" + val = self._get_property("Type") + return val + + @property + def antenna_file(self) -> str: + """Antenna File.""" + val = self._get_property("Antenna File") + return val + + @property + def project_name(self) -> str: + """Name of imported HFSS Antenna project. + + Value should be a full file path. + """ + val = self._get_property("Project Name") + return val + + @property + def peak_gain(self) -> float: + """Set peak gain of antenna (dBi). + + Value should be between -200 and 200. + """ + val = self._get_property("Peak Gain") + return float(val) + + class BoresightOption(Enum): + XAXIS = "+X Axis" + YAXIS = "+Y Axis" + ZAXIS = "+Z Axis" + + @property + def boresight(self) -> BoresightOption: + """Select peak beam direction in local coordinates.""" + val = self._get_property("Boresight") + val = self.BoresightOption[val.upper()] + return val + + @property + def vertical_beamwidth(self) -> float: + """Set half-power beamwidth in local-coordinates elevation plane. + + Value should be between 0.1 and 360. + """ + val = self._get_property("Vertical Beamwidth") + return float(val) + + @property + def horizontal_beamwidth(self) -> float: + """Set half-power beamwidth in local-coordinates azimuth plane. + + Value should be between 0.1 and 360. + """ + val = self._get_property("Horizontal Beamwidth") + return float(val) + + @property + def extra_sidelobe(self) -> bool: + """Toggle (on/off) option to define two sidelobe levels. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Extra Sidelobe") + return val == true + + @property + def first_sidelobe_level(self) -> float: + """First Sidelobe Level. + + Set reduction in the gain of Directive Beam antenna for first sidelobe + level. + + Value should be between 0 and 200. + """ + val = self._get_property("First Sidelobe Level") + return float(val) + + @property + def first_sidelobe_vert_bw(self) -> float: + """Set beamwidth of first sidelobe beam in theta direction. + + Value should be between 0.1 and 360. + """ + val = self._get_property("First Sidelobe Vert. BW") + return float(val) + + @property + def first_sidelobe_hor_bw(self) -> float: + """Set beamwidth of first sidelobe beam in phi direction. + + Value should be between 0.1 and 360. + """ + val = self._get_property("First Sidelobe Hor. BW") + return float(val) + + @property + def outerbacklobe_level(self) -> float: + """Outer/Backlobe Level. + + Set reduction in gain of Directive Beam antenna for outer/backlobe + level. + + Value should be between 0 and 200. + """ + val = self._get_property("Outer/Backlobe Level") + return float(val) + + @property + def resonant_frequency(self) -> float: + """Resonant Frequency. + + Set first resonant frequency of wire dipole, monopole, or parametric + antenna. + + Value should be between 1.0 and 1e13. + """ + val = self._get_property("Resonant Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def slot_length(self) -> float: + """Set slot length of parametric slot. + + Value should be greater than 1e-6. + """ + val = self._get_property("Slot Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def mouth_width(self) -> float: + """Set mouth width (along local y-axis) of the horn antenna. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Mouth Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def mouth_height(self) -> float: + """Set mouth height (along local x-axis) of the horn antenna. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Mouth Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def waveguide_width(self) -> float: + """Waveguide Width. + + Set waveguide width (along local y-axis) where flared horn walls meet + the feed, determines cut-off frequency. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Waveguide Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def width_flare_half_angle(self) -> float: + """Width Flare Half-angle. + + Set half-angle (degrees) of flared horn walls measured in local yz-plane + from boresight (z) axis to either wall. + + Value should be between 1 and 89.9. + """ + val = self._get_property("Width Flare Half-angle") + return float(val) + + @property + def height_flare_half_angle(self) -> float: + """Height Flare Half-angle. + + Set half-angle (degrees) of flared horn walls measured in local xz-plane + from boresight (z) axis to either wall. + + Value should be between 1 and 89.9. + """ + val = self._get_property("Height Flare Half-angle") + return float(val) + + @property + def mouth_diameter(self) -> float: + """Set aperture (mouth) diameter of horn antenna. + + Value should be between 1e-6 and 100. + """ + val = self._get_property("Mouth Diameter") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def flare_half_angle(self) -> float: + """Flare Half-angle. + + Set half-angle (degrees) of conical horn wall measured from boresight + (z). + + Value should be between 1 and 89.9. + """ + val = self._get_property("Flare Half-angle") + return float(val) + + @property + def vswr(self) -> float: + """VSWR. + + The Voltage Standing Wave Ratio (VSWR) due to the impedance mismatch + between the antenna and the RF System (or outboard component). + + Value should be between 1 and 100. + """ + val = self._get_property("VSWR") + return float(val) + + class AntennaPolarizationOption(Enum): + VERTICAL = "Vertical" + HORIZONTAL = "Horizontal" + RHCP = "RHCP" + LHCP = "LHCP" + + @property + def antenna_polarization(self) -> AntennaPolarizationOption: + """Choose local-coordinates polarization along boresight.""" + val = self._get_property("Antenna Polarization") + val = self.AntennaPolarizationOption[val.upper()] + return val + + class CrossDipoleModeOption(Enum): + FREESTANDING = "Freestanding" + OVER_GROUND_PLANE = "Over Ground Plane" + + @property + def cross_dipole_mode(self) -> CrossDipoleModeOption: + """Choose the Cross Dipole type.""" + val = self._get_property("Cross Dipole Mode") + val = self.CrossDipoleModeOption[val.upper()] + return val + + class CrossDipolePolarizationOption(Enum): + RHCP = "RHCP" + LHCP = "LHCP" + + @property + def cross_dipole_polarization(self) -> CrossDipolePolarizationOption: + """Choose local-coordinates polarization along boresight.""" + val = self._get_property("Cross Dipole Polarization") + val = self.CrossDipolePolarizationOption[val.upper()] + return val + + @property + def override_height(self) -> bool: + """Override Height. + + Ignores the default placement of quarter design wavelength over the + ground plane. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Override Height") + return val == true + + @property + def offset_height(self) -> float: + """Offset Height. + + Sets the offset height for the current sources above the ground plane. + + Value should be greater than 0. + """ + val = self._get_property("Offset Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def auto_height_offset(self) -> bool: + """Auto Height Offset. + + Switch on to automatically place slot current at sub-wavelength offset + height above ground plane. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Auto Height Offset") + return val == true + + @property + def conform__adjust_antenna(self) -> bool: + """Toggle (on/off) conformal adjustment for array antenna elements. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Conform / Adjust Antenna") + return val == true + + @property + def element_offset(self): + """Element Offset. + + Set vector for shifting element positions in antenna local coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Element Offset") + return val + + class ConformtoPlatformOption(Enum): + NONE = "None" + ALONG_NORMAL = "Along Normal" + PERPENDICULAR_TO_PLANE = "Perpendicular to Plane" + + @property + def conform_to_platform(self) -> ConformtoPlatformOption: + """Select method of automated conforming applied after Element Offset.""" + val = self._get_property("Conform to Platform") + val = self.ConformtoPlatformOption[val.upper()] + return val + + class ReferencePlaneOption(Enum): + XY_PLANE = "XY Plane" + YZ_PLANE = "YZ Plane" + ZX_PLANE = "ZX Plane" + + @property + def reference_plane(self) -> ReferencePlaneOption: + """Select reference plane for determining original element heights.""" + val = self._get_property("Reference Plane") + val = self.ReferencePlaneOption[val.upper()] + return val + + @property + def conform_element_orientation(self) -> bool: + """Conform Element Orientation. + + Toggle (on/off) re-orientation of elements to conform to curved + placement surface. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Conform Element Orientation") + return val == true + + @property + def show_axes(self) -> bool: + """Toggle (on/off) display of antenna coordinate axes in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Axes") + return val == true + + @property + def show_icon(self) -> bool: + """Toggle (on/off) display of antenna marker (cone) in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Icon") + return val == true + + @property + def size(self) -> float: + """Adjust relative size of antenna marker (cone) in 3-D window. + + Value should be between 0.001 and 1. + """ + val = self._get_property("Size") + return float(val) + + @property + def color(self): + """Set color of antenna marker (cone) in 3-D window. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @property + def el_sample_interval(self) -> float: + """Space between elevation-angle samples of pattern.""" + val = self._get_property("El Sample Interval") + return float(val) + + @property + def az_sample_interval(self) -> float: + """Space between azimuth-angle samples of pattern.""" + val = self._get_property("Az Sample Interval") + return float(val) + + @property + def has_frequency_domain(self) -> bool: + """False if antenna can be used at any frequency. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Has Frequency Domain") + return val == true + + @property + def frequency_domain(self): + """Frequency sample(s) defining antenna.""" + val = self._get_property("Frequency Domain") + return val + + @property + def number_of_electric_sources(self) -> int: + """Number of freestanding electric current sources defining antenna.""" + val = self._get_property("Number of Electric Sources") + return int(val) + + @property + def number_of_magnetic_sources(self) -> int: + """Number of freestanding magnetic current sources defining antenna.""" + val = self._get_property("Number of Magnetic Sources") + return int(val) + + @property + def number_of_imaged_electric_sources(self) -> int: + """Number of Imaged Electric Sources. + + Number of imaged, half-space radiating electric current sources defining + antenna. + """ + val = self._get_property("Number of Imaged Electric Sources") + return int(val) + + @property + def number_of_imaged_magnetic_sources(self) -> int: + """Number of Imaged Magnetic Sources. + + Number of imaged, half-space radiating magnetic current sources defining + antenna. + """ + val = self._get_property("Number of Imaged Magnetic Sources") + return int(val) + + @property + def waveguide_height(self) -> float: + """Waveguide Height. + + Implied waveguide height (along local x-axis) where the flared horn + walls meet the feed. + """ + val = self._get_property("Waveguide Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def waveguide_cutoff_frequency(self) -> float: + """Implied lowest operating frequency of pyramidal horn antenna.""" + val = self._get_property("Waveguide Cutoff Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def aperture_cutoff_frequency(self) -> float: + """Implied lowest operating frequency of conical horn antenna.""" + val = self._get_property("Aperture Cutoff Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class SWEModeTruncationOption(Enum): + DYNAMIC = "Dynamic" + FIXED_CUSTOM = "Fixed (Custom)" + NONE = "None" + + @property + def swe_mode_truncation(self) -> SWEModeTruncationOption: + """SWE Mode Truncation. + + Select the method for stability-enhancing truncation of spherical wave + expansion terms. + """ + val = self._get_property("SWE Mode Truncation") + val = self.SWEModeTruncationOption[val.upper()] + return val + + @property + def max_n_index(self) -> int: + """Set maximum allowed index N for spherical wave expansion terms. + + Value should be greater than 1. + """ + val = self._get_property("Max N Index") + return int(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @property + def show_composite_passband(self) -> bool: + """Show plot instead of 3D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Composite Passband") + return val == true + + @property + def use_phase_center(self) -> bool: + """Use the phase center defined in the HFSS design. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Phase Center") + return val == true + + @property + def coordinate_systems(self) -> str: + """Coordinate Systems. + + Specifies the coordinate system for the phase center of this antenna. + """ + val = self._get_property("Coordinate Systems") + return val + + @property + def phasecenterposition(self): + """Set position of the antennas linked coordinate system. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("PhaseCenterPosition") + return val + + @property + def phasecenterorientation(self): + """Set orientation of the antennas linked coordinate system. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("PhaseCenterOrientation") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_antenna_passband.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_antenna_passband.py new file mode 100644 index 00000000000..04539f1f495 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_antenna_passband.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyAntennaPassband(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def passband_loss(self) -> float: + """Passband loss. + + Value should be between 0 and 100. + """ + val = self._get_property("Passband Loss") + return float(val) + + @property + def out_of_band_attenuation(self) -> float: + """Out of band antenna loss. + + Value should be between 0 and 200. + """ + val = self._get_property("Out of Band Attenuation") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_band.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_band.py new file mode 100644 index 00000000000..c138d107919 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_band.py @@ -0,0 +1,429 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyBand(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def port(self): + """Radio Port associated with this Band.""" + val = self._get_property("Port") + return val + + @property + def use_dd_1494_mode(self) -> bool: + """Uses DD-1494 parameters to define the Tx/Rx spectrum. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use DD-1494 Mode") + return val == true + + @property + def use_emission_designator(self) -> bool: + """Use Emission Designator. + + Uses the Emission Designator to define the bandwidth and modulation. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Emission Designator") + return val == true + + @property + def emission_designator(self) -> str: + """Emission Designator. + + Enter the Emission Designator to define the bandwidth and modulation. + """ + val = self._get_property("Emission Designator") + return val + + @property + def emission_designator_ch_bw(self) -> float: + """Channel Bandwidth based off the emission designator.""" + val = self._get_property("Emission Designator Ch. BW") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def emit_modulation_type(self) -> str: + """Modulation based off the emission designator.""" + val = self._get_property("EMIT Modulation Type") + return val + + @property + def override_emission_designator_bw(self) -> bool: + """Override Emission Designator BW. + + Enables the 3 dB channel bandwidth to equal a value < emission + designator bandwidth. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Override Emission Designator BW") + return val == true + + @property + def channel_bandwidth(self) -> float: + """Channel Bandwidth. + + Value should be greater than 1. + """ + val = self._get_property("Channel Bandwidth") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class ModulationOption(Enum): + GENERIC = "Generic" + AM = "AM" + LSB = "LSB" + USB = "USB" + FM = "FM" + FSK = "FSK" + MSK = "MSK" + PSK = "PSK" + QAM = "QAM" + APSK = "APSK" + RADAR = "Radar" + + @property + def modulation(self) -> ModulationOption: + """Modulation used for the transmitted/received signal.""" + val = self._get_property("Modulation") + val = self.ModulationOption[val.upper()] + return val + + @property + def max_modulating_freq(self) -> float: + """Maximum modulating frequency: helps determine spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Max Modulating Freq.") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def modulation_index(self) -> float: + """AM modulation index: helps determine spectral profile. + + Value should be between 0.01 and 1. + """ + val = self._get_property("Modulation Index") + return float(val) + + @property + def freq_deviation(self) -> float: + """Frequency deviation: helps determine spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Freq. Deviation") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def bit_rate(self) -> float: + """Maximum bit rate: helps determine width of spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Bit Rate") + val = self._convert_from_internal_units(float(val), "Data Rate") + return float(val) + + @property + def sidelobes(self) -> int: + """Number of sidelobes in spectral profile. + + Value should be greater than 0. + """ + val = self._get_property("Sidelobes") + return int(val) + + @property + def freq_deviation(self) -> float: + """FSK frequency deviation: helps determine spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Freq. Deviation ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class PSKTypeOption(Enum): + BPSK = "BPSK" + QPSK = "QPSK" + PSK_8 = "PSK-8" + PSK_16 = "PSK-16" + PSK_32 = "PSK-32" + PSK_64 = "PSK-64" + + @property + def psk_type(self) -> PSKTypeOption: + """PSK modulation order: helps determine spectral profile.""" + val = self._get_property("PSK Type") + val = self.PSKTypeOption[val.upper()] + return val + + class FSKTypeOption(Enum): + FSK_2 = "FSK-2" + FSK_4 = "FSK-4" + FSK_8 = "FSK-8" + + @property + def fsk_type(self) -> FSKTypeOption: + """FSK modulation order: helps determine spectral profile.""" + val = self._get_property("FSK Type") + val = self.FSKTypeOption[val.upper()] + return val + + class QAMTypeOption(Enum): + QAM_4 = "QAM-4" + QAM_16 = "QAM-16" + QAM_64 = "QAM-64" + QAM_256 = "QAM-256" + QAM_1024 = "QAM-1024" + + @property + def qam_type(self) -> QAMTypeOption: + """QAM modulation order: helps determine spectral profile.""" + val = self._get_property("QAM Type") + val = self.QAMTypeOption[val.upper()] + return val + + class APSKTypeOption(Enum): + APSK_4 = "APSK-4" + APSK_16 = "APSK-16" + APSK_64 = "APSK-64" + APSK_256 = "APSK-256" + APSK_1024 = "APSK-1024" + + @property + def apsk_type(self) -> APSKTypeOption: + """APSK modulation order: helps determine spectral profile.""" + val = self._get_property("APSK Type") + val = self.APSKTypeOption[val.upper()] + return val + + @property + def start_frequency(self) -> float: + """First frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def stop_frequency(self) -> float: + """Last frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def channel_spacing(self) -> float: + """Spacing between channels within this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Channel Spacing") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def tx_offset(self) -> float: + """Frequency offset between Tx and Rx channels. + + Value should be less than 100e9. + """ + val = self._get_property("Tx Offset") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class RadarTypeOption(Enum): + CW = "CW" + FM_CW = "FM-CW" + FM_PULSE = "FM Pulse" + NON_FM_PULSE = "Non-FM Pulse" + PHASE_CODED = "Phase Coded" + + @property + def radar_type(self) -> RadarTypeOption: + """Radar type: helps determine spectral profile.""" + val = self._get_property("Radar Type") + val = self.RadarTypeOption[val.upper()] + return val + + @property + def hopping_radar(self) -> bool: + """True for hopping radars; false otherwise. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Hopping Radar") + return val == true + + @property + def post_october_2020_procurement(self) -> bool: + """Post October 2020 Procurement. + + Procurement date: helps determine spectral profile, particularly the + roll-off. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Post October 2020 Procurement") + return val == true + + @property + def hop_range_min_freq(self) -> float: + """Sets the minimum frequency of the hopping range. + + Value should be between 1.0 and 100.0e9. + """ + val = self._get_property("Hop Range Min Freq") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def hop_range_max_freq(self) -> float: + """Sets the maximum frequency of the hopping range. + + Value should be between 1.0 and 100.0e9. + """ + val = self._get_property("Hop Range Max Freq") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def pulse_duration(self) -> float: + """Pulse duration. + + Value should be greater than 0.0. + """ + val = self._get_property("Pulse Duration") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @property + def pulse_rise_time(self) -> float: + """Pulse rise time. + + Value should be greater than 0.0. + """ + val = self._get_property("Pulse Rise Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @property + def pulse_fall_time(self) -> float: + """Pulse fall time. + + Value should be greater than 0.0. + """ + val = self._get_property("Pulse Fall Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @property + def pulse_repetition_rate(self) -> float: + """Pulse repetition rate [pulses/sec]. + + Value should be greater than 1.0. + """ + val = self._get_property("Pulse Repetition Rate") + return float(val) + + @property + def number_of_chips(self) -> float: + """Total number of chips (subpulses) contained in the pulse. + + Value should be greater than 1.0. + """ + val = self._get_property("Number of Chips") + return float(val) + + @property + def pulse_compression_ratio(self) -> float: + """Pulse compression ratio. + + Value should be greater than 1.0. + """ + val = self._get_property("Pulse Compression Ratio") + return float(val) + + @property + def fm_chirp_period(self) -> float: + """FM Chirp period for the FM/CW radar. + + Value should be greater than 0.0. + """ + val = self._get_property("FM Chirp Period") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @property + def fm_freq_deviation(self) -> float: + """FM Freq Deviation. + + Total frequency deviation for the carrier frequency for the FM/CW radar. + + Value should be between 1 and 100e9. + """ + val = self._get_property("FM Freq Deviation") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def fm_freq_dev_bandwidth(self) -> float: + """FM Freq Dev Bandwidth. + + Bandwidth of freq deviation for FM modulated pulsed waveform (total freq + shift during pulse duration). + + Value should be between 1 and 100e9. + """ + val = self._get_property("FM Freq Dev Bandwidth") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_band_folder.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_band_folder.py new file mode 100644 index 00000000000..6aa83ad1ada --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_band_folder.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyBandFolder(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_cable.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_cable.py new file mode 100644 index 00000000000..05cb690a00d --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_cable.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyCable(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_FILE = "By File" + CONSTANT_LOSS = "Constant Loss" + COAXIAL_CABLE = "Coaxial Cable" + + @property + def type(self) -> TypeOption: + """Type. + + Type of cable to use. Options include: By File (measured or simulated), + Constant Loss, or Coaxial Cable. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @property + def length(self) -> float: + """Length of cable. + + Value should be between 0 and 500. + """ + val = self._get_property("Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def loss_per_length(self) -> float: + """Cable loss per unit length (dB/meter). + + Value should be between 0 and 20. + """ + val = self._get_property("Loss Per Length") + return float(val) + + @property + def measurement_length(self) -> float: + """Length of the cable used for the measurements. + + Value should be between 0 and 500. + """ + val = self._get_property("Measurement Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def resistive_loss_constant(self) -> float: + """Coaxial cable resistive loss constant. + + Value should be between 0 and 2. + """ + val = self._get_property("Resistive Loss Constant") + return float(val) + + @property + def dielectric_loss_constant(self) -> float: + """Coaxial cable dielectric loss constant. + + Value should be between 0 and 1. + """ + val = self._get_property("Dielectric Loss Constant") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_cad_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_cad_node.py new file mode 100644 index 00000000000..d34ebed2290 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_cad_node.py @@ -0,0 +1,450 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyCADNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def file(self) -> str: + """Name of the imported CAD file. + + Value should be a full file path. + """ + val = self._get_property("File") + return val + + class ModelTypeOption(Enum): + PLATE = "Plate" + BOX = "Box" + DIHEDRAL = "Dihedral" + TRIHEDRAL = "Trihedral" + CYLINDER = "Cylinder" + TAPERED_CYLINDER = "Tapered Cylinder" + CONE = "Cone" + SPHERE = "Sphere" + ELLIPSOID = "Ellipsoid" + CIRCULAR_PLATE = "Circular Plate" + PARABOLA = "Parabola" + PRISM = "Prism" + TAPERED_PRISM = "Tapered Prism" + TOPHAT = "Tophat" + + @property + def model_type(self) -> ModelTypeOption: + """Select type of parametric model to create.""" + val = self._get_property("Model Type") + val = self.ModelTypeOption[val.upper()] + return val + + @property + def length(self) -> float: + """Length of the model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def width(self) -> float: + """Width of the model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def height(self) -> float: + """Height of the model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def angle(self) -> float: + """Angle (deg) between the plates. + + Value should be between 0.0 and 360.0. + """ + val = self._get_property("Angle") + return float(val) + + @property + def top_side(self) -> float: + """Side of the top of a equilateral triangular cylinder model. + + Value should be greater than 0.0. + """ + val = self._get_property("Top Side") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def top_radius(self) -> float: + """Radius of the top of a tapered cylinder model. + + Value should be greater than 0.0. + """ + val = self._get_property("Top Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def side(self) -> float: + """Side of the equilateral triangular cylinder. + + Value should be greater than 0.000001. + """ + val = self._get_property("Side") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def radius(self) -> float: + """Radius of the sphere or cylinder. + + Value should be greater than 0.000001. + """ + val = self._get_property("Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def base_radius(self) -> float: + """Radius of the base of a tophat model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Base Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def center_radius(self) -> float: + """Radius of the raised portion of a tophat model. + + Value should be greater than 0.000001. + """ + val = self._get_property("Center Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def x_axis_ellipsoid_radius(self) -> float: + """Ellipsoid semi-principal radius for the X axis. + + Value should be greater than 0.000001. + """ + val = self._get_property("X Axis Ellipsoid Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def y_axis_ellipsoid_radius(self) -> float: + """Ellipsoid semi-principal radius for the Y axis. + + Value should be greater than 0.000001. + """ + val = self._get_property("Y Axis Ellipsoid Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def z_axis_ellipsoid_radius(self) -> float: + """Ellipsoid semi-principal radius for the Z axis. + + Value should be greater than 0.000001. + """ + val = self._get_property("Z Axis Ellipsoid Radius") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def focal_length(self) -> float: + """Focal length of a parabolic reflector (f = 1/4a where y=ax^2). + + Value should be greater than 0.000001. + """ + val = self._get_property("Focal Length") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def offset(self) -> float: + """Offset of parabolic reflector.""" + val = self._get_property("Offset") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def x_direction_taper(self) -> float: + """X Direction Taper. + + Amount (%) that the prism tapers in the X dimension from one end to the + other. + + Value should be greater than 0.0. + """ + val = self._get_property("X Direction Taper") + return float(val) + + @property + def y_direction_taper(self) -> float: + """Y Direction Taper. + + Amount (%) that the prism tapers in the Y dimension from one end to the + other. + + Value should be greater than 0.0. + """ + val = self._get_property("Y Direction Taper") + return float(val) + + @property + def prism_direction(self): + """Prism Direction. + + Direction vector between the center of the base and center of the top. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Prism Direction") + return val + + @property + def closed_top(self) -> bool: + """Control whether the top of the model is closed. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Closed Top") + return val == true + + @property + def closed_base(self) -> bool: + """Control whether the base of the model is closed. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Closed Base") + return val == true + + @property + def mesh_density(self) -> int: + """Mesh Density. + + Unitless mesh density parameter where higher value improves mesh + smoothness. + + Value should be between 1 and 100. + """ + val = self._get_property("Mesh Density") + return int(val) + + @property + def use_symmetric_mesh(self) -> bool: + """Use Symmetric Mesh. + + Convert quads to a symmetric triangle mesh by adding a center point (4 + triangles per quad instead of 2). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Symmetric Mesh") + return val == true + + class MeshOptionOption(Enum): + IMPROVED = "Improved" + LEGACY = "Legacy" + + @property + def mesh_option(self) -> MeshOptionOption: + """Select from different meshing options.""" + val = self._get_property("Mesh Option") + val = self.MeshOptionOption[val.upper()] + return val + + @property + def coating_index(self) -> int: + """Coating index for the parametric model primitive. + + Value should be between 0 and 100000. + """ + val = self._get_property("Coating Index") + return int(val) + + @property + def show_relative_coordinates(self) -> bool: + """Show Relative Coordinates. + + Show CAD model node position and orientation in parent-node coords + (False) or relative to placement coords (True). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Relative Coordinates") + return val == true + + @property + def position(self): + """Set position of the CAD node in parent-node coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Position") + return val + + @property + def relative_position(self): + """Relative Position. + + Set position of the CAD model node relative to placement coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Relative Position") + return val + + class OrientationModeOption(Enum): + ROLL_PITCH_YAW = "Roll-Pitch-Yaw" + AZ_EL_TWIST = "Az-El-Twist" + + @property + def orientation_mode(self) -> OrientationModeOption: + """Orientation Mode. + + Select the convention (order of rotations) for configuring orientation. + """ + val = self._get_property("Orientation Mode") + val = self.OrientationModeOption[val.upper()] + return val + + @property + def orientation(self): + """Set orientation of the CAD node in parent-node coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Orientation") + return val + + @property + def relative_orientation(self): + """Relative Orientation. + + Set orientation of the CAD model node relative to placement coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Relative Orientation") + return val + + @property + def visible(self) -> bool: + """Toggle (on/off) display of CAD model in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + class RenderModeOption(Enum): + FLAT_SHADED = "Flat-Shaded" + WIRE_FRAME = "Wire-Frame" + HIDDEN_WIRE_FRAME = "Hidden Wire-Frame" + OUTLINE = "Outline" + + @property + def render_mode(self) -> RenderModeOption: + """Select drawing style for surfaces.""" + val = self._get_property("Render Mode") + val = self.RenderModeOption[val.upper()] + return val + + @property + def show_axes(self) -> bool: + """Toggle (on/off) display of CAD model coordinate axes in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Axes") + return val == true + + @property + def min(self): + """Minimum x,y,z extents of CAD model in local coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Min") + return val + + @property + def max(self): + """Maximum x,y,z extents of CAD model in local coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Max") + return val + + @property + def number_of_surfaces(self) -> int: + """Number of surfaces in the model.""" + val = self._get_property("Number of Surfaces") + return int(val) + + @property + def color(self): + """Defines the CAD nodes color. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Color") + return val + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_circulator.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_circulator.py new file mode 100644 index 00000000000..d2445060b36 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_circulator.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyCirculator(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the Isolator/Circulator. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_FILE = "By File" + PARAMETRIC = "Parametric" + + @property + def type(self) -> TypeOption: + """Type. + + Type of circulator model to use. Options include: By File (measured or + simulated) or Parametric. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + class Port1LocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_1_location(self) -> Port1LocationOption: + """Defines the orientation of the circulator.""" + val = self._get_property("Port 1 Location") + val = self.Port1LocationOption[val.upper()] + return val + + @property + def insertion_loss(self) -> float: + """Circulator in-band loss in forward direction. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @property + def finite_reverse_isolation(self) -> bool: + """Finite Reverse Isolation. + + Use a finite reverse isolation. If disabled, the circulator model is + ideal (infinite reverse isolation). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Reverse Isolation") + return val == true + + @property + def reverse_isolation(self) -> float: + """Circulator reverse isolation (i.e., loss in the reverse direction). + + Value should be between 0 and 100. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the circulator model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_coupling_link_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_coupling_link_node.py new file mode 100644 index 00000000000..401179dff60 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_coupling_link_node.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyCouplingLinkNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling link. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def ports(self): + """Maps each port in the link to an antenna in the project.""" + val = self._get_property("Ports") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_couplings_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_couplings_node.py new file mode 100644 index 00000000000..c40b4bc14c9 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_couplings_node.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyCouplingsNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def minimum_allowed_coupling(self) -> float: + """Minimum Allowed Coupling. + + Global minimum allowed coupling value. All computed coupling within this + project will be >= this value. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Minimum Allowed Coupling") + return float(val) + + @property + def global_default_coupling(self) -> float: + """Default antenna-to-antenna coupling loss value. + + Value should be between -1000 and 0. + """ + val = self._get_property("Global Default Coupling") + return float(val) + + @property + def antenna_tags(self) -> str: + """All tags currently used by all antennas in the project.""" + val = self._get_property("Antenna Tags") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_custom_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_custom_coupling_node.py new file mode 100644 index 00000000000..02ff63002ce --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_custom_coupling_node.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyCustomCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 2 columns. + Frequency: + Value should be between 1.0 and 100.0e9. + Value (dB): + Value should be between -1000.0 and 0.0. + """ + return self._get_table_data() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_emit_scene_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_emit_scene_node.py new file mode 100644 index 00000000000..7b7fe4af8de --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_emit_scene_node.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyEmitSceneNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class GroundPlaneNormalOption(Enum): + X_AXIS = "X Axis" + Y_AXIS = "Y Axis" + Z_AXIS = "Z Axis" + + @property + def ground_plane_normal(self) -> GroundPlaneNormalOption: + """Specifies the axis of the normal to the ground plane.""" + val = self._get_property("Ground Plane Normal") + val = self.GroundPlaneNormalOption[val.upper()] + return val + + @property + def gp_position_along_normal(self) -> float: + """GP Position Along Normal. + + Offset of ground plane in direction normal to the ground planes + orientation. + """ + val = self._get_property("GP Position Along Normal") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_erceg_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_erceg_coupling_node.py new file mode 100644 index 00000000000..d3ab8cef208 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_erceg_coupling_node.py @@ -0,0 +1,247 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyErcegCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + class TerrainCategoryOption(Enum): + TYPE_A = "Type A" + TYPE_B = "Type B" + TYPE_C = "Type C" + + @property + def terrain_category(self) -> TerrainCategoryOption: + """Specify the terrain category type for the Erceg model.""" + val = self._get_property("Terrain Category") + val = self.TerrainCategoryOption[val.upper()] + return val + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_filter.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_filter.py new file mode 100644 index 00000000000..8098a709c80 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_filter.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyFilter(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_FILE = "By File" + LOW_PASS = "Low Pass" + HIGH_PASS = "High Pass" + BAND_PASS = "Band Pass" + BAND_STOP = "Band Stop" + TUNABLE_BANDPASS = "Tunable Bandpass" + TUNABLE_BANDSTOP = "Tunable Bandstop" + + @property + def type(self) -> TypeOption: + """Type. + + Type of filter to define. The filter can be defined by file (measured or + simulated data) or using one of EMIT's parametric models. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @property + def insertion_loss(self) -> float: + """Filter pass band loss. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @property + def stop_band_attenuation(self) -> float: + """Filter stop band loss (attenuation). + + Value should be less than 200. + """ + val = self._get_property("Stop band Attenuation") + return float(val) + + @property + def max_pass_band(self) -> float: + """Maximum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def min_stop_band(self) -> float: + """Minimum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def max_stop_band(self) -> float: + """Maximum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def min_pass_band(self) -> float: + """Minimum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lowest_tuned_frequency(self) -> float: + """Lowest tuned frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lowest Tuned Frequency ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def highest_tuned_frequency(self) -> float: + """Highest tuned frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Highest Tuned Frequency ") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def percent_bandwidth(self) -> float: + """Tunable filter 3-dB bandwidth. + + Value should be between 0.001 and 100. + """ + val = self._get_property("Percent Bandwidth") + return float(val) + + @property + def shape_factor(self) -> float: + """Ratio defining the filter rolloff. + + Value should be between 1 and 100. + """ + val = self._get_property("Shape Factor") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_five_g_channel_model.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_five_g_channel_model.py new file mode 100644 index 00000000000..105bb5c2abe --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_five_g_channel_model.py @@ -0,0 +1,276 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyFiveGChannelModel(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + class EnvironmentOption(Enum): + URBAN_MICROCELL = "Urban Microcell" + URBAN_MACROCELL = "Urban Macrocell" + RURAL_MACROCELL = "Rural Macrocell" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment for the 5G channel model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @property + def los(self) -> bool: + """True if the operating environment is line-of-sight. + + Value should be 'true' or 'false'. + """ + val = self._get_property("LOS") + return val == true + + @property + def include_bpl(self) -> bool: + """Includes building penetration loss if true. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include BPL") + return val == true + + class NYUBPLModelOption(Enum): + LOW_LOSS_MODEL = "Low-loss model" + HIGH_LOSS_MODEL = "High-loss model" + + @property + def nyu_bpl_model(self) -> NYUBPLModelOption: + """Specify the NYU Building Penetration Loss model.""" + val = self._get_property("NYU BPL Model") + val = self.NYUBPLModelOption[val.upper()] + return val + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_hata_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_hata_coupling_node.py new file mode 100644 index 00000000000..39ffc5ef454 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_hata_coupling_node.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyHataCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + class EnvironmentOption(Enum): + LARGE_CITY = "Large City" + SMALLMEDIUM_CITY = "Small/Medium City" + SUBURBAN = "Suburban" + RURAL = "Rural" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment type for the Hata model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_indoor_propagation_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_indoor_propagation_coupling_node.py new file mode 100644 index 00000000000..dc6a231564d --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_indoor_propagation_coupling_node.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyIndoorPropagationCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 3 columns. + Frequency: + Value should be between 1.0 and 100.0e9. + Power Loss Coefficient: + Value should be between 0.0 and 100.0. + Floor Penetration Loss (dB): + Value should be between 0.0 and 1000.0. + """ + return self._get_table_data() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + class BuildingTypeOption(Enum): + RESIDENTIAL_APARTMENT = "Residential Apartment" + RESIDENTIAL_HOUSE = "Residential House" + OFFICE_BUILDING = "Office Building" + COMMERCIAL_BUILDING = "Commercial Building" + CUSTOM_BUILDING = "Custom Building" + + @property + def building_type(self) -> BuildingTypeOption: + """Specify the building type for the Indoor Propagation model.""" + val = self._get_property("Building Type") + val = self.BuildingTypeOption[val.upper()] + return val + + @property + def number_of_floors(self) -> int: + """The number of floors separating the antennas. + + Value should be between 1 and 3. + """ + val = self._get_property("Number of Floors") + return int(val) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_isolator.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_isolator.py new file mode 100644 index 00000000000..3b813d84762 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_isolator.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyIsolator(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_FILE = "By File" + PARAMETRIC = "Parametric" + + @property + def type(self) -> TypeOption: + """Type. + + Type of isolator model to use. Options include: By File (measured or + simulated) or Parametric. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + class Port1LocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_1_location(self) -> Port1LocationOption: + """Defines the orientation of the isolator.""" + val = self._get_property("Port 1 Location") + val = self.Port1LocationOption[val.upper()] + return val + + @property + def insertion_loss(self) -> float: + """Isolator in-band loss in forward direction. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @property + def finite_reverse_isolation(self) -> bool: + """Finite Reverse Isolation. + + Use a finite reverse isolation. If disabled, the isolator model is + ideal (infinite reverse isolation). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Reverse Isolation") + return val == true + + @property + def reverse_isolation(self) -> float: + """Isolator reverse isolation (i.e., loss in the reverse direction). + + Value should be between 0 and 100. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the isolator model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_log_distance_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_log_distance_coupling_node.py new file mode 100644 index 00000000000..704241244d6 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_log_distance_coupling_node.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyLogDistanceCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + class EnvironmentOption(Enum): + FREE_SPACE = "Free Space" + URBAN = "Urban" + SHADOWED_URBAN = "Shadowed Urban" + BUILDING_LINE_OF_SIGHT = "Building Line of Sight" + BUILDING_OBSTRUCTED = "Building Obstructed" + FACTORY_OBSTRUCTED = "Factory Obstructed" + CUSTOM = "Custom" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment type for the Log Distance model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @property + def path_loss_exponent(self) -> float: + """Path Loss Exponent. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Path Loss Exponent") + return float(val) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_multiplexer.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_multiplexer.py new file mode 100644 index 00000000000..7fa1bfe3ebd --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_multiplexer.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyMultiplexer(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the multiplexer. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_PASS_BAND = "By Pass Band" + BY_FILE = "By File" + + @property + def type(self) -> TypeOption: + """Type. + + Type of multiplexer model. Options include: By File (one measured or + simulated file for the device) or By Pass Band (parametric or file-based + definition for each pass band). + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + class Port1LocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_1_location(self) -> Port1LocationOption: + """Defines the orientation of the multiplexer.""" + val = self._get_property("Port 1 Location") + val = self.Port1LocationOption[val.upper()] + return val + + @property + def flip_ports_vertically(self) -> bool: + """Reverses the port order on the multi-port side of the multiplexer. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Flip Ports Vertically") + return val == true + + @property + def ports(self): + """Assigns the child port nodes to the multiplexers ports.""" + val = self._get_property("Ports") + return val + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_multiplexer_band.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_multiplexer_band.py new file mode 100644 index 00000000000..d288092aafb --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_multiplexer_band.py @@ -0,0 +1,170 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyMultiplexerBand(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + class TypeOption(Enum): + BY_FILE = "By File" + LOW_PASS = "Low Pass" + HIGH_PASS = "High Pass" + BAND_PASS = "Band Pass" + + @property + def type(self) -> TypeOption: + """Type. + + Type of multiplexer pass band to define. The pass band can be defined by + file (measured or simulated data) or using one of EMIT's parametric + models. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @property + def filename(self) -> str: + """Name of file defining the multiplexer band. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def insertion_loss(self) -> float: + """Multiplexer pass band insertion loss. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @property + def stop_band_attenuation(self) -> float: + """Stop-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Stop band Attenuation") + return float(val) + + @property + def max_pass_band(self) -> float: + """Maximum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def min_stop_band(self) -> float: + """Minimum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def max_stop_band(self) -> float: + """Maximum stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Max Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def min_pass_band(self) -> float: + """Minimum pass band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Min Pass Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_power_divider.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_power_divider.py new file mode 100644 index 00000000000..8cd25bcbf1b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_power_divider.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyPowerDivider(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the Power Divider. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_FILE = "By File" + P3_DB = "P3 dB" + RESISTIVE = "Resistive" + + @property + def type(self) -> TypeOption: + """Type. + + Type of Power Divider model to use. Options include: By File (measured + or simulated), 3 dB (parametric), and Resistive (parametric). + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + class OrientationOption(Enum): + DIVIDER = "Divider" + COMBINER = "Combiner" + + @property + def orientation(self) -> OrientationOption: + """Defines the orientation of the Power Divider.""" + val = self._get_property("Orientation") + val = self.OrientationOption[val.upper()] + return val + + @property + def insertion_loss_above_ideal(self) -> float: + """Insertion Loss Above Ideal. + + Additional loss beyond the ideal insertion loss. The ideal insertion + loss is 3 dB for the 3 dB Divider and 6 dB for the Resistive Divider. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss Above Ideal") + return float(val) + + @property + def finite_isolation(self) -> bool: + """Finite Isolation. + + Use a finite isolation between output ports. If disabled, the Power + Divider isolation is ideal (infinite isolation between output ports). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Isolation") + return val == true + + @property + def isolation(self) -> float: + """Power Divider isolation between output ports. + + Value should be between 0 and 100. + """ + val = self._get_property("Isolation") + return float(val) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the Power Divider model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_propagation_loss_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_propagation_loss_coupling_node.py new file mode 100644 index 00000000000..368e1feba46 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_propagation_loss_coupling_node.py @@ -0,0 +1,235 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyPropagationLossCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_radio_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_radio_node.py new file mode 100644 index 00000000000..73a1b526d89 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_radio_node.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRadioNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 2 columns. + Name: + + Type: + + """ + return self._get_table_data() + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_meas_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_meas_node.py new file mode 100644 index 00000000000..661a8626ebc --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_meas_node.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRxMeasNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("File") + return val + + @property + def source_file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("Source File") + return val + + @property + def receive_frequency(self) -> float: + """Channel associated with the measurement file.""" + val = self._get_property("Receive Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class MeasurementModeOption(Enum): + AUDIO_SINAD = "Audio SINAD" + DIGITAL_BER = "Digital BER" + GPS_CNR = "GPS CNR" + + @property + def measurement_mode(self) -> MeasurementModeOption: + """Defines the mode for the receiver measurement.""" + val = self._get_property("Measurement Mode") + val = self.MeasurementModeOption[val.upper()] + return val + + @property + def sinad_threshold(self) -> float: + """SINAD Threshold used for the receiver measurements. + + Value should be between 5 and 20. + """ + val = self._get_property("SINAD Threshold") + return float(val) + + @property + def gps_cnr_threshold(self) -> float: + """GPS CNR Threshold used for the receiver measurements. + + Value should be between 15 and 30. + """ + val = self._get_property("GPS CNR Threshold") + return float(val) + + @property + def ber_threshold(self) -> float: + """BER Threshold used for the receiver measurements. + + Value should be between -12 and -1. + """ + val = self._get_property("BER Threshold") + return float(val) + + @property + def default_intended_power(self) -> bool: + """Specify the intended signal. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Default Intended Power") + return val == true + + @property + def intended_signal_power(self) -> float: + """Specify the power level of the intended signal. + + Value should be between -140 and -50. + """ + val = self._get_property("Intended Signal Power") + return float(val) + + @property + def freq_deviation(self) -> float: + """Specify the frequency deviation of the intended signal. + + Value should be between 1000 and 200000. + """ + val = self._get_property("Freq. Deviation") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def modulation_depth(self) -> float: + """Specify the modulation depth of the intended signal. + + Value should be between 10 and 100. + """ + val = self._get_property("Modulation Depth") + return float(val) + + @property + def measure_selectivity(self) -> bool: + """Enable/disable the measurement of the receiver's selectivity. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Measure Selectivity") + return val == true + + @property + def measure_mixer_products(self) -> bool: + """Enable/disable the measurement of the receiver's mixer products. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Measure Mixer Products") + return val == true + + @property + def max_rf_order(self) -> int: + """Max RF Order of the mixer products to measure. + + Value should be greater than 1. + """ + val = self._get_property("Max RF Order") + return int(val) + + @property + def max_lo_order(self) -> int: + """Max LO Order of the mixer products to measure. + + Value should be greater than 1. + """ + val = self._get_property("Max LO Order") + return int(val) + + @property + def include_if(self) -> bool: + """Enable/disable the measurement of the IF channel. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include IF") + return val == true + + @property + def measure_saturation(self) -> bool: + """Enable/disable measurement of the receiver's saturation level. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Measure Saturation") + return val == true + + @property + def use_ams_limits(self) -> bool: + """Allow AMS to determine the limits for measuring saturation. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use AMS Limits") + return val == true + + @property + def start_frequency(self) -> float: + """Starting frequency for the measurement sweep. + + Value should be greater than 1e6. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def stop_frequency(self) -> float: + """Stopping frequency for the measurement sweep. + + Value should be less than 6e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def samples(self) -> int: + """Number of measurement samples for each frequency. + + Value should be between 2 and 100. + """ + val = self._get_property("Samples") + return int(val) + + @property + def exclude_mixer_products_below_noise(self) -> bool: + """Include/Exclude Mixer Products below the noise. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Exclude Mixer Products Below Noise") + return val == true diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_mixer_product_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_mixer_product_node.py new file mode 100644 index 00000000000..46ef817aefb --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_mixer_product_node.py @@ -0,0 +1,200 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRxMixerProductNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + class MixerProductTaperOption(Enum): + CONSTANT = "Constant" + MIL_STD_461G = "MIL-STD-461G" + DUFF_MODEL = "Duff Model" + + @property + def mixer_product_taper(self) -> MixerProductTaperOption: + """Taper for setting amplitude of mixer products.""" + val = self._get_property("Mixer Product Taper") + val = self.MixerProductTaperOption[val.upper()] + return val + + @property + def mixer_product_susceptibility(self) -> float: + """Mixer product amplitudes (relative to the in-band susceptibility). + + Value should be between -200 and 200. + """ + val = self._get_property("Mixer Product Susceptibility") + return float(val) + + @property + def spurious_rejection(self) -> float: + """Mixer product amplitudes (relative to the in-band susceptibility). + + Value should be between -200 and 200. + """ + val = self._get_property("Spurious Rejection") + return float(val) + + @property + def minimum_tuning_frequency(self) -> float: + """Minimum tuning frequency of Rx's local oscillator. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Minimum Tuning Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def maximum_tuning_frequency(self) -> float: + """Maximum tuning frequency of Rx's local oscillator. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Maximum Tuning Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def mixer_product_slope(self) -> float: + """Mixer Product Slope. + + Rate of decrease for amplitude of Rx's local oscillator harmonics + (dB/decade). + + Value should be between 0 and 100. + """ + val = self._get_property("Mixer Product Slope") + return float(val) + + @property + def mixer_product_intercept(self) -> float: + """Mixer product intercept (dBc). + + Value should be between 0 and 100. + """ + val = self._get_property("Mixer Product Intercept") + return float(val) + + @property + def bandwidth_80_db(self) -> float: + """Bandwidth 80 dB. + + Bandwidth where Rx's susceptibility envelope is 80 dB above in-band + susceptibility level. + + Value should be greater than 1. + """ + val = self._get_property("Bandwidth 80 dB") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def image_rejection(self) -> float: + """Image frequency amplitude (relative to the in-band susceptibility). + + Value should be between -200 and 200. + """ + val = self._get_property("Image Rejection") + return float(val) + + @property + def maximum_rf_harmonic_order(self) -> int: + """Maximum order of RF frequency. + + Value should be between 1 and 100. + """ + val = self._get_property("Maximum RF Harmonic Order") + return int(val) + + @property + def maximum_lo_harmonic_order(self) -> int: + """Maximum order of the LO frequency. + + Value should be between 1 and 100. + """ + val = self._get_property("Maximum LO Harmonic Order") + return int(val) + + class MixingModeOption(Enum): + LO_ABOVE_TUNED_RF_FREQUENCY = "LO Above Tuned (RF) Frequency" + LO_BELOW_TUNED_RF_FREQUENCY = "LO Below Tuned (RF) Frequency" + LO_ABOVEBELOW_TUNED_RF_FREQUENCY = "LO Above/Below Tuned (RF) Frequency" + + @property + def mixing_mode(self) -> MixingModeOption: + """Specifies whether the IF frequency is > or < RF channel frequency.""" + val = self._get_property("Mixing Mode") + val = self.MixingModeOption[val.upper()] + return val + + @property + def first_if_frequency(self): + """Intermediate frequency for Rx's 1st conversion stage. + + Value should be a mathematical expression. + """ + val = self._get_property("First IF Frequency") + return val + + @property + def rf_transition_frequency(self) -> float: + """RF Frequency Transition point.""" + val = self._get_property("RF Transition Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class UseHighLOOption(Enum): + ABOVE_TRANSITION_FREQUENCY = "Above Transition Frequency" + BELOW_TRANSITION_FREQUENCY = "Below Transition Frequency" + + @property + def use_high_lo(self) -> UseHighLOOption: + """Use High LO above/below the transition frequency.""" + val = self._get_property("Use High LO") + val = self.UseHighLOOption[val.upper()] + return val + + class MixerProductTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def mixer_product_table_units(self) -> MixerProductTableUnitsOption: + """Specifies the units for the Mixer Products.""" + val = self._get_property("Mixer Product Table Units") + val = self.MixerProductTableUnitsOption[val.upper()] + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_saturation_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_saturation_node.py new file mode 100644 index 00000000000..45328a8b5fe --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_saturation_node.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRxSaturationNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_selectivity_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_selectivity_node.py new file mode 100644 index 00000000000..3c671091caf --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_selectivity_node.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRxSelectivityNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def use_arithmetic_mean(self) -> bool: + """Use Arithmetic Mean. + + Uses arithmetic mean to center bandwidths about the tuned channel + frequency. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Arithmetic Mean") + return val == true diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_spur_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_spur_node.py new file mode 100644 index 00000000000..2b6d8f043ea --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_spur_node.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRxSpurNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 3 columns. + Frequency (MHz): + Value should be a mathematical expression. + Bandwidth: + Value should be greater than 1.0. + Power: + Value should be between -200.0 and 150.0. + """ + return self._get_table_data() + + class SpurTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def spur_table_units(self) -> SpurTableUnitsOption: + """Specifies the units for the Spurs.""" + val = self._get_property("Spur Table Units") + val = self.SpurTableUnitsOption[val.upper()] + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_susceptibility_prof_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_susceptibility_prof_node.py new file mode 100644 index 00000000000..0e7ee87cfd9 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_rx_susceptibility_prof_node.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyRxSusceptibilityProfNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + class SensitivityUnitsOption(Enum): + DBM = "dBm" + DBUV = "dBuV" + MILLIWATTS = "milliwatts" + MICROVOLTS = "microvolts" + + @property + def sensitivity_units(self) -> SensitivityUnitsOption: + """Units to use for the Rx Sensitivity.""" + val = self._get_property("Sensitivity Units") + val = self.SensitivityUnitsOption[val.upper()] + return val + + @property + def min_receive_signal_pwr(self) -> float: + """Received signal power level at the Rx's antenna terminal. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Min. Receive Signal Pwr") + return float(val) + + @property + def snr_at_rx_signal_pwr(self) -> float: + """SNR at Rx Signal Pwr. + + Signal-to-Noise Ratio (dB) at specified received signal power at the + Rx's antenna terminal. + + Value should be between -1000 and 1000. + """ + val = self._get_property("SNR at Rx Signal Pwr") + return float(val) + + @property + def processing_gain(self) -> float: + """Rx processing gain (dB) of (optional) despreader. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Processing Gain") + return float(val) + + @property + def apply_pg_to_narrowband_only(self) -> bool: + """Apply PG to Narrowband Only. + + Processing gain captures the despreading effect and applies to NB + signals only (not BB noise) when enabled. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Apply PG to Narrowband Only") + return val == true + + @property + def saturation_level(self) -> float: + """Rx input saturation level. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def rx_noise_figure(self) -> float: + """Rx noise figure (dB). + + Value should be between 0 and 1000. + """ + val = self._get_property("Rx Noise Figure") + return float(val) + + @property + def receiver_sensitivity(self) -> float: + """Rx minimum sensitivity level (dBm). + + Value should be between -1000 and 1000. + """ + val = self._get_property("Receiver Sensitivity") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def snrsinad_at_sensitivity(self) -> float: + """SNR or SINAD at the specified sensitivity level. + + Value should be between -1000 and 1000. + """ + val = self._get_property("SNR/SINAD at Sensitivity") + return float(val) + + @property + def perform_rx_intermod_analysis(self) -> bool: + """Performs a non-linear intermod analysis for the Rx. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Perform Rx Intermod Analysis") + return val == true + + @property + def amplifier_saturation_level(self) -> float: + """Internal Rx Amplifier's Saturation Level. + + Value should be between -200 and 200. + """ + val = self._get_property("Amplifier Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def p1_db_point_ref_input(self) -> float: + """P1-dB Point, Ref. Input. + + Rx's 1 dB Compression Point - total power > P1dB saturates the receiver. + + Value should be between -1000 and 1000. + """ + val = self._get_property("P1-dB Point, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def ip3_ref_input(self) -> float: + """Internal Rx Amplifier's 3rd order intercept point. + + Value should be between -1000 and 1000. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def max_intermod_order(self) -> int: + """Internal Rx Amplifier's maximum intermod order to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_sampling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_sampling_node.py new file mode 100644 index 00000000000..cf28cff7483 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_sampling_node.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlySamplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 2 columns. + Min: + Value should be greater than 1.0. + Max: + Value should be greater than 1.0. + """ + return self._get_table_data() + + class SamplingTypeOption(Enum): + SAMPLE_ALL_CHANNELS_IN_RANGES = "Sample All Channels in Range(s)" + RANDOM_SAMPLING = "Random Sampling" + UNIFORM_SAMPLING = "Uniform Sampling" + + @property + def sampling_type(self) -> SamplingTypeOption: + """Sampling to apply to this configuration.""" + val = self._get_property("Sampling Type") + val = self.SamplingTypeOption[val.upper()] + return val + + @property + def specify_percentage(self) -> bool: + """Specify Percentage. + + Specify the number of channels to simulate via a percentage of the total + available band channels. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Specify Percentage") + return val == true + + @property + def percentage_of_channels(self) -> float: + """Percentage of the Band Channels to simulate. + + Value should be between 1 and 100. + """ + val = self._get_property("Percentage of Channels") + return float(val) + + @property + def max__channelsrangeband(self) -> int: + """Maximum number of Band Channels to simulate. + + Value should be between 1 and 100000. + """ + val = self._get_property("Max # Channels/Range/Band") + return int(val) + + @property + def seed(self) -> int: + """Seed for random channel generator. + + Value should be greater than 0. + """ + val = self._get_property("Seed") + return int(val) + + @property + def total_tx_channels(self) -> int: + """Total Tx Channels. + + Total number of transmit channels this configuration is capable of + operating on. + """ + val = self._get_property("Total Tx Channels") + return int(val) + + @property + def total_rx_channels(self) -> int: + """Total Rx Channels. + + Total number of receive channels this configuration is capable of + operating on. + """ + val = self._get_property("Total Rx Channels") + return int(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_scene_group_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_scene_group_node.py new file mode 100644 index 00000000000..435d080210b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_scene_group_node.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlySceneGroupNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def show_relative_coordinates(self) -> bool: + """Show Relative Coordinates. + + Show Scene Group position and orientation in parent-node coords (False) + or relative to placement coords (True). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Relative Coordinates") + return val == true + + @property + def position(self): + """Set position of the Scene Group in parent-node coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Position") + return val + + @property + def relative_position(self): + """Set position of the Scene Group relative to placement coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Relative Position") + return val + + class OrientationModeOption(Enum): + ROLL_PITCH_YAW = "Roll-Pitch-Yaw" + AZ_EL_TWIST = "Az-El-Twist" + + @property + def orientation_mode(self) -> OrientationModeOption: + """Orientation Mode. + + Select the convention (order of rotations) for configuring orientation. + """ + val = self._get_property("Orientation Mode") + val = self.OrientationModeOption[val.upper()] + return val + + @property + def orientation(self): + """Orientation. + + Set orientation of the Scene Group relative to parent-node coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Orientation") + return val + + @property + def relative_orientation(self): + """Relative Orientation. + + Set orientation of the Scene Group relative to placement coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Relative Orientation") + return val + + @property + def show_axes(self) -> bool: + """Show Axes. + + Toggle (on/off) display of Scene Group coordinate axes in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Axes") + return val == true + + @property + def box_color(self): + """Set color of the bounding box of the Scene Group. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Box Color") + return val + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_solution_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_solution_coupling_node.py new file mode 100644 index 00000000000..47e5437003c --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_solution_coupling_node.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlySolutionCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled. + + Enable/Disable coupling (A sweep disabled in HFSS/Layout cannot be + enabled in EMIT). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_solutions_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_solutions_node.py new file mode 100644 index 00000000000..1875416ba75 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_solutions_node.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlySolutionsNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled. + + Enable/Disable coupling (A setup disabled in HFSS/Layout cannot be + enabled in EMIT). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_terminator.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_terminator.py new file mode 100644 index 00000000000..745328179c4 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_terminator.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTerminator(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the Terminator. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TypeOption(Enum): + BY_FILE = "By File" + PARAMETRIC = "Parametric" + + @property + def type(self) -> TypeOption: + """Type. + + Type of terminator model to use. Options include: By File (measured or + simulated) or Parametric. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + class PortLocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_location(self) -> PortLocationOption: + """Defines the orientation of the terminator.""" + val = self._get_property("Port Location") + val = self.PortLocationOption[val.upper()] + return val + + @property + def vswr(self) -> float: + """VSWR. + + The Voltage Standing Wave Ratio (VSWR) due to the impedance mismatch + between the terminator and the connected component (RF System, Antenna, + etc). + + Value should be between 1.0 and 100. + """ + val = self._get_property("VSWR") + return float(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_touchstone_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_touchstone_coupling_node.py new file mode 100644 index 00000000000..816565b7415 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_touchstone_coupling_node.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTouchstoneCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @property + def filename(self) -> str: + """Name of file with coupling data. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def savant_matched_coupling_file(self) -> str: + """Coupling data generated by Savant and exported as a matched file.""" + val = self._get_property("Savant Matched Coupling File") + return val + + @property + def enable_em_isolation(self) -> bool: + """Enables/disables EM isolation. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable EM Isolation") + return val == true + + @property + def port_antenna_assignment(self): + """Maps each port in the coupling file to an antenna in the project.""" + val = self._get_property("Port-Antenna Assignment") + return val + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tr_switch.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tr_switch.py new file mode 100644 index 00000000000..ce7e802635b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tr_switch.py @@ -0,0 +1,171 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTR_Switch(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + class TxPortOption(Enum): + PORT_1 = "Port 1" + PORT_2 = "Port 2" + + @property + def tx_port(self) -> TxPortOption: + """Specifies which port on the TR Switch is part of the Tx path.""" + val = self._get_property("Tx Port") + val = self.TxPortOption[val.upper()] + return val + + class CommonPortLocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def common_port_location(self) -> CommonPortLocationOption: + """Defines the orientation of the tr switch.""" + val = self._get_property("Common Port Location") + val = self.CommonPortLocationOption[val.upper()] + return val + + @property + def insertion_loss(self) -> float: + """TR Switch in-band loss in forward direction. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @property + def finite_isolation(self) -> bool: + """Finite Isolation. + + Use a finite isolation. If disabled, the tr switch model is ideal + (infinite isolation). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Isolation") + return val == true + + @property + def isolation(self) -> float: + """TR Switch reverse isolation (i.e., loss between the Tx/Rx ports). + + Value should be between 0 and 100. + """ + val = self._get_property("Isolation") + return float(val) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the tr switch model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_two_ray_path_loss_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_two_ray_path_loss_coupling_node.py new file mode 100644 index 00000000000..e13f31e2b97 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_two_ray_path_loss_coupling_node.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTwoRayPathLossCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @property + def ground_reflection_coeff(self) -> float: + """The ground reflection coefficient. + + Value should be between -100 and 100. + """ + val = self._get_property("Ground Reflection Coeff.") + return float(val) + + @property + def pointspeak(self) -> int: + """Points/Peak. + + Number of points used to model each peak in frequency vs loss curve. + + Value should be between 3 and 100. + """ + val = self._get_property("Points/Peak") + return int(val) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_bb_emission_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_bb_emission_node.py new file mode 100644 index 00000000000..1afedfdae73 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_bb_emission_node.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxBbEmissionNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Tx Broadband Noise Profile Table. + Table consists of 2 columns. + Frequency (MHz): + Value should be a mathematical expression. + Amplitude (dBm/Hz): + Value should be between -200.0 and 150.0. + """ + return self._get_table_data() + + class NoiseBehaviorOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE_BANDWIDTH = "Relative (Bandwidth)" + RELATIVE_OFFSET = "Relative (Offset)" + EQUATION = "Equation" + + @property + def noise_behavior(self) -> NoiseBehaviorOption: + """Specifies the behavior of the parametric noise profile.""" + val = self._get_property("Noise Behavior") + val = self.NoiseBehaviorOption[val.upper()] + return val + + @property + def use_log_linear_interpolation(self) -> bool: + """Use Log-Linear Interpolation. + + If true, linear interpolation in the log domain is used. If false, + linear interpolation in the linear domain is used. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Log-Linear Interpolation") + return val == true diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_harmonic_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_harmonic_node.py new file mode 100644 index 00000000000..1930d67407b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_harmonic_node.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxHarmonicNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + class HarmonicTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def harmonic_table_units(self) -> HarmonicTableUnitsOption: + """Specifies the units for the Harmonics.""" + val = self._get_property("Harmonic Table Units") + val = self.HarmonicTableUnitsOption[val.upper()] + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_meas_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_meas_node.py new file mode 100644 index 00000000000..c0634ca21b1 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_meas_node.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxMeasNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("File") + return val + + @property + def source_file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("Source File") + return val + + @property + def transmit_frequency(self) -> float: + """Channel associated with the measurement file.""" + val = self._get_property("Transmit Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def use_ams_limits(self) -> bool: + """Allow AMS to define the frequency limits for the measurements. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use AMS Limits") + return val == true + + @property + def start_frequency(self) -> float: + """Starting frequency for the measurement sweep. + + Value should be greater than 1e6. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def stop_frequency(self) -> float: + """Stopping frequency for the measurement sweep. + + Value should be less than 6e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def exclude_harmonics_below_noise(self) -> bool: + """Include/Exclude Harmonics below the noise. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Exclude Harmonics Below Noise") + return val == true diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_nb_emission_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_nb_emission_node.py new file mode 100644 index 00000000000..4eb1e749b64 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_nb_emission_node.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxNbEmissionNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + class NarrowbandBehaviorOption(Enum): + ABSOLUTE_FREQS_AND_POWER = "Absolute Freqs and Power" + RELATIVE_FREQS_AND_ATTENUATION = "Relative Freqs and Attenuation" + + @property + def narrowband_behavior(self) -> NarrowbandBehaviorOption: + """Specifies the behavior of the parametric narrowband emissions mask.""" + val = self._get_property("Narrowband Behavior") + val = self.NarrowbandBehaviorOption[val.upper()] + return val + + @property + def measurement_frequency(self) -> float: + """Measurement frequency for the absolute freq/amp pairs.""" + val = self._get_property("Measurement Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spectral_prof_emitter_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spectral_prof_emitter_node.py new file mode 100644 index 00000000000..68c521ec488 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spectral_prof_emitter_node.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxSpectralProfEmitterNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def output_voltage_peak(self) -> float: + """Output High Voltage Level: maximum voltage of the digital signal.""" + val = self._get_property("Output Voltage Peak") + val = self._convert_from_internal_units(float(val), "Voltage") + return float(val) + + @property + def include_phase_noise(self) -> bool: + """Include oscillator phase noise in Tx spectral profile. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Phase Noise") + return val == true + + @property + def tx_broadband_noise(self) -> float: + """Transmitters broadband noise level. + + Value should be less than 1000. + """ + val = self._get_property("Tx Broadband Noise") + return float(val) + + @property + def perform_tx_intermod_analysis(self) -> bool: + """Performs a non-linear intermod analysis for the Tx. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Perform Tx Intermod Analysis") + return val == true + + @property + def internal_amp_gain(self) -> float: + """Internal Tx Amplifier's Gain. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Internal Amp Gain") + return float(val) + + @property + def noise_figure(self) -> float: + """Internal Tx Amplifier's noise figure. + + Value should be between 0 and 50. + """ + val = self._get_property("Noise Figure") + return float(val) + + @property + def amplifier_saturation_level(self) -> float: + """Internal Tx Amplifier's Saturation Level. + + Value should be between -200 and 200. + """ + val = self._get_property("Amplifier Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def p1_db_point_ref_input(self) -> float: + """P1-dB Point, Ref. Input . + + Internal Tx Amplifier's 1 dB Compression Point - total power > P1dB + saturates the internal Tx amplifier. + + Value should be between -200 and 200. + """ + val = self._get_property("P1-dB Point, Ref. Input ") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def ip3_ref_input(self) -> float: + """Internal Tx Amplifier's 3rd order intercept point. + + Value should be between -200 and 200. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def reverse_isolation(self) -> float: + """Internal Tx Amplifier's Reverse Isolation. + + Value should be between -200 and 200. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @property + def max_intermod_order(self) -> int: + """Internal Tx Amplifier's maximum intermod order to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spectral_prof_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spectral_prof_node.py new file mode 100644 index 00000000000..379afee1a05 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spectral_prof_node.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxSpectralProfNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + class SpectrumTypeOption(Enum): + NARROWBAND__BROADBAND = "Narrowband & Broadband" + BROADBAND_ONLY = "Broadband Only" + + @property + def spectrum_type(self) -> SpectrumTypeOption: + """Specifies EMI Margins to calculate.""" + val = self._get_property("Spectrum Type") + val = self.SpectrumTypeOption[val.upper()] + return val + + class TxPowerOption(Enum): + PEAK_POWER = "Peak Power" + AVERAGE_POWER = "Average Power" + + @property + def tx_power(self) -> TxPowerOption: + """Method used to specify the power.""" + val = self._get_property("Tx Power") + val = self.TxPowerOption[val.upper()] + return val + + @property + def peak_power(self) -> float: + """Tx's carrier frequency peak power. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Peak Power") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def average_power(self) -> float: + """Tx's fundamental level specified by average power. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Average Power") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def include_phase_noise(self) -> bool: + """Include oscillator phase noise in Tx spectral profile. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Phase Noise") + return val == true + + @property + def tx_broadband_noise(self) -> float: + """Transmitters broadband noise level. + + Value should be less than 1000. + """ + val = self._get_property("Tx Broadband Noise") + return float(val) + + class HarmonicTaperOption(Enum): + CONSTANT = "Constant" + MIL_STD_461G = "MIL-STD-461G" + MIL_STD_461G_NAVY = "MIL-STD-461G Navy" + DUFF_MODEL = "Duff Model" + + @property + def harmonic_taper(self) -> HarmonicTaperOption: + """Taper type used to set amplitude of harmonics.""" + val = self._get_property("Harmonic Taper") + val = self.HarmonicTaperOption[val.upper()] + return val + + @property + def harmonic_amplitude(self) -> float: + """Amplitude (relative to the carrier power) of harmonics. + + Value should be between -1000 and 0. + """ + val = self._get_property("Harmonic Amplitude") + return float(val) + + @property + def harmonic_slope(self) -> float: + """Rate of decrease for harmonics' amplitudes (dB/decade). + + Value should be between -1000 and 0. + """ + val = self._get_property("Harmonic Slope") + return float(val) + + @property + def harmonic_intercept(self) -> float: + """Amplitude intercept at the fundamental (dBc). + + Value should be between -1000 and 0. + """ + val = self._get_property("Harmonic Intercept") + return float(val) + + @property + def enable_harmonic_bw_expansion(self) -> bool: + """Enable Harmonic BW Expansion. + + If (True), bandwidth of harmonics increases proportional to the harmonic + number. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Harmonic BW Expansion") + return val == true + + @property + def number_of_harmonics(self) -> int: + """Maximum number of harmonics modeled. + + Value should be between 1 and 1000. + """ + val = self._get_property("Number of Harmonics") + return int(val) + + @property + def second_harmonic_level(self) -> float: + """Amplitude (relative to the carrier power) of the 2nd harmonic. + + Value should be between -1000 and 0. + """ + val = self._get_property("Second Harmonic Level") + return float(val) + + @property + def third_harmonic_level(self) -> float: + """Amplitude (relative to the carrier power) of the 3rd harmonic. + + Value should be between -1000 and 0. + """ + val = self._get_property("Third Harmonic Level") + return float(val) + + @property + def other_harmonic_levels(self) -> float: + """Other Harmonic Levels. + + Amplitude (relative to the carrier power) of the higher order harmonics. + + Value should be between -1000 and 0. + """ + val = self._get_property("Other Harmonic Levels") + return float(val) + + @property + def perform_tx_intermod_analysis(self) -> bool: + """Performs a non-linear intermod analysis for the Tx. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Perform Tx Intermod Analysis") + return val == true + + @property + def internal_amp_gain(self) -> float: + """Internal Tx Amplifier's Gain. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Internal Amp Gain") + return float(val) + + @property + def noise_figure(self) -> float: + """Internal Tx Amplifier's noise figure. + + Value should be between 0 and 50. + """ + val = self._get_property("Noise Figure") + return float(val) + + @property + def amplifier_saturation_level(self) -> float: + """Internal Tx Amplifier's Saturation Level. + + Value should be between -200 and 200. + """ + val = self._get_property("Amplifier Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def p1_db_point_ref_input(self) -> float: + """P1-dB Point, Ref. Input . + + Internal Tx Amplifier's 1 dB Compression Point - total power > P1dB + saturates the internal Tx amplifier. + + Value should be between -200 and 200. + """ + val = self._get_property("P1-dB Point, Ref. Input ") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def ip3_ref_input(self) -> float: + """Internal Tx Amplifier's 3rd order intercept point. + + Value should be between -200 and 200. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @property + def reverse_isolation(self) -> float: + """Internal Tx Amplifier's Reverse Isolation. + + Value should be between -200 and 200. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @property + def max_intermod_order(self) -> int: + """Internal Tx Amplifier's maximum intermod order to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spur_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spur_node.py new file mode 100644 index 00000000000..16b1e9d70cd --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_tx_spur_node.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyTxSpurNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 3 columns. + Frequency (MHz): + Value should be a mathematical expression. + Bandwidth: + Value should be greater than 1.0. + Power: + Value should be between -200.0 and 150.0. + """ + return self._get_table_data() + + class SpurTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def spur_table_units(self) -> SpurTableUnitsOption: + """Specifies the units for the Spurs.""" + val = self._get_property("Spur Table Units") + val = self.SpurTableUnitsOption[val.upper()] + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_walfisch_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_walfisch_coupling_node.py new file mode 100644 index 00000000000..bc1124dcc0f --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_walfisch_coupling_node.py @@ -0,0 +1,296 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyWalfischCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + class PathLossTypeOption(Enum): + LOS_URBAN_CANYON = "LOS (Urban Canyon)" + NLOS = "NLOS" + + @property + def path_loss_type(self) -> PathLossTypeOption: + """Specify LOS vs NLOS for the Walfisch-Ikegami model.""" + val = self._get_property("Path Loss Type") + val = self.PathLossTypeOption[val.upper()] + return val + + class EnvironmentOption(Enum): + DENSE_METRO = "Dense Metro" + SMALLMEDIUM_CITY_OR_SUBURBAN = "Small/Medium City or Suburban" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment type for the Walfisch model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @property + def roof_height(self) -> float: + """The height of the building where the antenna is located. + + Value should be between 0 and 100. + """ + val = self._get_property("Roof Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def distance_between_buildings(self) -> float: + """The distance between two buildings. + + Value should be between 0 and 100. + """ + val = self._get_property("Distance Between Buildings") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def street_width(self) -> float: + """Width of the street. + + Value should be between 0 and 100. + """ + val = self._get_property("Street Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @property + def incidence_angle(self) -> float: + """Angle between the street orientation and direction of incidence. + + Value should be between 0 and 90. + """ + val = self._get_property("Incidence Angle") + return float(val) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/read_only_waveform.py b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_waveform.py new file mode 100644 index 00000000000..ef9e488bfca --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/read_only_waveform.py @@ -0,0 +1,313 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ReadOnlyWaveform(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def port(self): + """Radio Port associated with this Band.""" + val = self._get_property("Port") + return val + + class WaveformOption(Enum): + PERIODIC_CLOCK = "Periodic Clock" + SPREAD_SPECTRUM_CLOCK = "Spread Spectrum Clock" + PRBS = "PRBS" + PRBS_PERIODIC = "PRBS (Periodic)" + IMPORTED = "Imported" + + @property + def waveform(self) -> WaveformOption: + """Modulation used for the transmitted/received signal.""" + val = self._get_property("Waveform") + val = self.WaveformOption[val.upper()] + return val + + @property + def start_frequency(self) -> float: + """First frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def stop_frequency(self) -> float: + """Last frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def channel_spacing(self) -> float: + """Spacing between channels within this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Channel Spacing") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def clock_duty_cycle(self) -> float: + """Clock signals duty cycle. + + Value should be between 0.001 and 1.0. + """ + val = self._get_property("Clock Duty Cycle") + return float(val) + + @property + def clock_risefall_time(self) -> float: + """Clock signals rise/fall time. + + Value should be greater than 0.0. + """ + val = self._get_property("Clock Rise/Fall Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + class SpreadingTypeOption(Enum): + LOW_SPREAD = "Low Spread" + CENTER_SPREAD = "Center Spread" + HIGH_SPREAD = "High Spread" + + @property + def spreading_type(self) -> SpreadingTypeOption: + """Type of spreading employed by the Spread Spectrum Clock.""" + val = self._get_property("Spreading Type") + val = self.SpreadingTypeOption[val.upper()] + return val + + @property + def spread_percentage(self) -> float: + """Peak-to-peak spread percentage. + + Value should be between 0 and 100. + """ + val = self._get_property("Spread Percentage") + return float(val) + + @property + def imported_spectrum(self) -> str: + """Imported Spectrum.""" + val = self._get_property("Imported Spectrum") + return val + + @property + def raw_data_format(self) -> str: + """Format of the imported raw data.""" + val = self._get_property("Raw Data Format") + return val + + @property + def system_impedance(self) -> float: + """System impedance for the imported data. + + Value should be between 0.0 and 1.0e6. + """ + val = self._get_property("System Impedance") + val = self._convert_from_internal_units(float(val), "Resistance") + return float(val) + + @property + def advanced_extraction_params(self) -> bool: + """Show/hide advanced extraction params. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Advanced Extraction Params") + return val == true + + @property + def nb_window_size(self) -> float: + """NB Window Size. + + Window size for computing the moving average during narrowband signal + detection. + + Value should be greater than 3. + """ + val = self._get_property("NB Window Size") + return float(val) + + @property + def bb_smoothing_factor(self) -> float: + """BB Smoothing Factor. + + Reduces the number of frequency points used for the broadband noise. + + Value should be greater than 1. + """ + val = self._get_property("BB Smoothing Factor") + return float(val) + + @property + def nb_detector_threshold(self) -> float: + """Narrowband Detector threshold standard deviation. + + Value should be between 2 and 10. + """ + val = self._get_property("NB Detector Threshold") + return float(val) + + class AlgorithmOption(Enum): + FFT = "FFT" + FOURIER_TRANSFORM = "Fourier Transform" + + @property + def algorithm(self) -> AlgorithmOption: + """Algorithm used to transform the imported time domain spectrum.""" + val = self._get_property("Algorithm") + val = self.AlgorithmOption[val.upper()] + return val + + @property + def start_time(self) -> float: + """Initial time of the imported spectrum. + + Value should be greater than 0.0. + """ + val = self._get_property("Start Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @property + def stop_time(self) -> float: + """Final time of the imported time domain spectrum.""" + val = self._get_property("Stop Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @property + def max_frequency(self) -> float: + """Frequency cutoff of the imported time domain spectrum. + + Value should be between 1.0 and 100.0e9. + """ + val = self._get_property("Max Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class WindowTypeOption(Enum): + RECTANGULAR = "Rectangular" + BARTLETT = "Bartlett" + BLACKMAN = "Blackman" + HAMMING = "Hamming" + HANNING = "Hanning" + KAISER = "Kaiser" + LANZCOS = "Lanzcos" + WELCH = "Welch" + WEBER = "Weber" + + @property + def window_type(self) -> WindowTypeOption: + """Windowing scheme used for importing time domain spectrum.""" + val = self._get_property("Window Type") + val = self.WindowTypeOption[val.upper()] + return val + + @property + def kaiser_parameter(self) -> float: + """Shape factor applied to the transform. + + Value should be greater than 0.0. + """ + val = self._get_property("Kaiser Parameter") + return float(val) + + @property + def adjust_coherent_gain(self) -> bool: + """Shape factor applied to the transform. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adjust Coherent Gain") + return val == true + + @property + def data_rate(self) -> float: + """Maximum data rate: helps determine shape of spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Data Rate") + val = self._convert_from_internal_units(float(val), "Data Rate") + return float(val) + + @property + def num_of_bits(self) -> int: + """Length of the Pseudo Random Binary Sequence. + + Value should be between 1 and 1000. + """ + val = self._get_property("Num of Bits") + return int(val) + + @property + def use_envelope(self) -> bool: + """Model the waveform as a worst case envelope. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Envelope") + return val == true + + @property + def min_ptsnull(self) -> int: + """Minimum number of points to use between each null frequency. + + Value should be between 2 and 50. + """ + val = self._get_property("Min Pts/Null") + return int(val) + + @property + def delay_skew(self) -> float: + """Delay Skew of the differential signal pairs. + + Value should be greater than 0.0. + """ + val = self._get_property("Delay Skew") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/result_plot_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/result_plot_node.py new file mode 100644 index 00000000000..b0247071c0a --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/result_plot_node.py @@ -0,0 +1,444 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class ResultPlotNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def add_marker(self): + """Add an icon and/or label to this plot""" + return self._add_child_node("Plot Marker") + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + @property + def title(self) -> str: + """Enter title at the top of the plot, room will be made for it.""" + val = self._get_property("Title") + return val + + @title.setter + def title(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Title={value}"]) + + @property + def title_font(self): + """Configure title font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Title Font") + return val + + @title_font.setter + def title_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Title Font={value}"]) + + @property + def show_legend(self) -> bool: + """Toggle (on/off) display of plot legend. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Legend") + return val == true + + @show_legend.setter + def show_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Legend={value}"]) + + @property + def legend_font(self): + """Configure legend font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Legend Font") + return val + + @legend_font.setter + def legend_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Legend Font={value}"]) + + @property + def show_emi_thresholds(self) -> bool: + """Toggles on/off visibility of the EMI Thresholds. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show EMI Thresholds") + return val == true + + @show_emi_thresholds.setter + def show_emi_thresholds(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show EMI Thresholds={value}"]) + + @property + def display_cad_overlay(self) -> bool: + """Toggle on/off overlay of CAD model in plot. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Display CAD Overlay") + return val == true + + @display_cad_overlay.setter + def display_cad_overlay(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Display CAD Overlay={value}"]) + + @property + def opacity(self) -> float: + """Adjust opacity of CAD model overlay: 0 Transparent - 1 Opaque. + + Value should be between 0 and 100. + """ + val = self._get_property("Opacity") + return float(val) + + @opacity.setter + def opacity(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Opacity={value}"]) + + @property + def vertical_offset(self) -> float: + """Adjust vertical position of CAD model overlay.""" + val = self._get_property("Vertical Offset") + return float(val) + + @vertical_offset.setter + def vertical_offset(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Vertical Offset={value}"]) + + @property + def range_axis_rotation(self) -> float: + """Range Axis Rotation. + + Adjust view angle for CAD model overlay by rotating it about plot + horizontal axis. + + Value should be between -180 and 180. + """ + val = self._get_property("Range Axis Rotation") + return float(val) + + @range_axis_rotation.setter + def range_axis_rotation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Range Axis Rotation={value}"]) + + @property + def lock_axes(self) -> bool: + """Lock Axes. + + Allow or prevent changing of axes when displayed plot traces are + updated. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Lock Axes") + return val == true + + @lock_axes.setter + def lock_axes(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lock Axes={value}"]) + + @property + def x_axis_min(self) -> float: + """Set lower extent of horizontal axis.""" + val = self._get_property("X-axis Min") + return float(val) + + @x_axis_min.setter + def x_axis_min(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"X-axis Min={value}"]) + + @property + def x_axis_max(self) -> float: + """Set upper extent of horizontal axis.""" + val = self._get_property("X-axis Max") + return float(val) + + @x_axis_max.setter + def x_axis_max(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"X-axis Max={value}"]) + + @property + def y_axis_min(self) -> float: + """Set lower extent of vertical axis.""" + val = self._get_property("Y-axis Min") + return float(val) + + @y_axis_min.setter + def y_axis_min(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y-axis Min={value}"]) + + @property + def y_axis_max(self) -> float: + """Set upper extent of vertical axis.""" + val = self._get_property("Y-axis Max") + return float(val) + + @y_axis_max.setter + def y_axis_max(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y-axis Max={value}"]) + + @property + def y_axis_range(self) -> float: + """Y-axis Range. + + Adjust dB span of vertical axis, makes corresponding adjustment in + Y-axis Min. + + Value should be greater than 0. + """ + val = self._get_property("Y-axis Range") + return float(val) + + @y_axis_range.setter + def y_axis_range(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Y-axis Range={value}"]) + + @property + def max_major_ticks_x(self) -> int: + """Max Major Ticks X. + + Set maximum number of major tick-mark intervals along horizontal axis. + + Value should be between 1 and 30. + """ + val = self._get_property("Max Major Ticks X") + return int(val) + + @max_major_ticks_x.setter + def max_major_ticks_x(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Major Ticks X={value}"]) + + @property + def max_minor_ticks_x(self) -> int: + """Max Minor Ticks X. + + Set maximum number of minor tick-mark intervals between major ticks + along horizontal axis. + + Value should be between 0 and 100. + """ + val = self._get_property("Max Minor Ticks X") + return int(val) + + @max_minor_ticks_x.setter + def max_minor_ticks_x(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Minor Ticks X={value}"]) + + @property + def max_major_ticks_y(self) -> int: + """Max Major Ticks Y. + + Set maximum number of major tick-mark intervals along vertical axis. + + Value should be between 1 and 30. + """ + val = self._get_property("Max Major Ticks Y") + return int(val) + + @max_major_ticks_y.setter + def max_major_ticks_y(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Major Ticks Y={value}"]) + + @property + def max_minor_ticks_y(self) -> int: + """Max Minor Ticks Y. + + Set maximum number of minor tick-mark intervals between major ticks + along vertical axis. + + Value should be between 0 and 100. + """ + val = self._get_property("Max Minor Ticks Y") + return int(val) + + @max_minor_ticks_y.setter + def max_minor_ticks_y(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Minor Ticks Y={value}"]) + + @property + def axis_label_font(self): + """Configure axis text labels font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Axis Label Font") + return val + + @axis_label_font.setter + def axis_label_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Axis Label Font={value}"]) + + @property + def axis_tick_label_font(self): + """Configure axis tick numeric labels font family, typeface, and size. + + Value formated like 'Sans Serif,10,-1,5,50,0,0,0,0,0'. + """ + val = self._get_property("Axis Tick Label Font") + return val + + @axis_tick_label_font.setter + def axis_tick_label_font(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Axis Tick Label Font={value}"]) + + class MajorGridLineStyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def major_grid_line_style(self) -> MajorGridLineStyleOption: + """Select line style of major-tick grid lines.""" + val = self._get_property("Major Grid Line Style") + val = self.MajorGridLineStyleOption[val.upper()] + return val + + @major_grid_line_style.setter + def major_grid_line_style(self, value: MajorGridLineStyleOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Major Grid Line Style={value.value}"] + ) + + @property + def major_grid_color(self): + """Set color of major-tick grid lines. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Major Grid Color") + return val + + @major_grid_color.setter + def major_grid_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Major Grid Color={value}"]) + + class MinorGridLineStyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def minor_grid_line_style(self) -> MinorGridLineStyleOption: + """Select line style of minor-tick grid lines.""" + val = self._get_property("Minor Grid Line Style") + val = self.MinorGridLineStyleOption[val.upper()] + return val + + @minor_grid_line_style.setter + def minor_grid_line_style(self, value: MinorGridLineStyleOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Minor Grid Line Style={value.value}"] + ) + + @property + def minor_grid_color(self): + """Set color of minor-tick grid lines. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Minor Grid Color") + return val + + @minor_grid_color.setter + def minor_grid_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Minor Grid Color={value}"]) + + @property + def background_color(self): + """Set background color of entire plot. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Background Color") + return val + + @background_color.setter + def background_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Background Color={value}"]) + + class BBPowerforPlotsUnitOption(Enum): + HERTZ = "hertz" + KILOHERTZ = "kilohertz" + MEGAHERTZ = "megahertz" + GIGAHERTZ = "gigahertz" + + @property + def bb_power_for_plots_unit(self) -> BBPowerforPlotsUnitOption: + """Units to use for plotting broadband power densities.""" + val = self._get_property("BB Power for Plots Unit") + val = self.BBPowerforPlotsUnitOption[val.upper()] + return val + + @bb_power_for_plots_unit.setter + def bb_power_for_plots_unit(self, value: BBPowerforPlotsUnitOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"BB Power for Plots Unit={value.value}"] + ) + + @property + def bb_power_bandwidth(self) -> float: + """Resolution bandwidth for broadband power. + + Value should be between 1.0 and 100e9. + """ + val = self._get_property("BB Power Bandwidth") + val = self._convert_from_internal_units(float(val), "") + return float(val) + + @bb_power_bandwidth.setter + def bb_power_bandwidth(self, value: float | str): + value = self._convert_to_internal_units(value, "") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"BB Power Bandwidth={value}"]) + + @property + def log_scale(self) -> bool: + """Toggles on/off using a log scale for the X-Axis. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Log Scale") + return val == true + + @log_scale.setter + def log_scale(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Log Scale={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/rx_meas_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/rx_meas_node.py new file mode 100644 index 00000000000..bb7327a4654 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/rx_meas_node.py @@ -0,0 +1,339 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RxMeasNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("File") + return val + + @property + def source_file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("Source File") + return val + + @property + def receive_frequency(self) -> float: + """Channel associated with the measurement file.""" + val = self._get_property("Receive Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + class MeasurementModeOption(Enum): + AUDIO_SINAD = "Audio SINAD" + DIGITAL_BER = "Digital BER" + GPS_CNR = "GPS CNR" + + @property + def measurement_mode(self) -> MeasurementModeOption: + """Defines the mode for the receiver measurement.""" + val = self._get_property("Measurement Mode") + val = self.MeasurementModeOption[val.upper()] + return val + + @measurement_mode.setter + def measurement_mode(self, value: MeasurementModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Measurement Mode={value.value}"]) + + @property + def sinad_threshold(self) -> float: + """SINAD Threshold used for the receiver measurements. + + Value should be between 5 and 20. + """ + val = self._get_property("SINAD Threshold") + return float(val) + + @sinad_threshold.setter + def sinad_threshold(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"SINAD Threshold={value}"]) + + @property + def gps_cnr_threshold(self) -> float: + """GPS CNR Threshold used for the receiver measurements. + + Value should be between 15 and 30. + """ + val = self._get_property("GPS CNR Threshold") + return float(val) + + @gps_cnr_threshold.setter + def gps_cnr_threshold(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"GPS CNR Threshold={value}"]) + + @property + def ber_threshold(self) -> float: + """BER Threshold used for the receiver measurements. + + Value should be between -12 and -1. + """ + val = self._get_property("BER Threshold") + return float(val) + + @ber_threshold.setter + def ber_threshold(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"BER Threshold={value}"]) + + @property + def default_intended_power(self) -> bool: + """Specify the intended signal. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Default Intended Power") + return val == true + + @default_intended_power.setter + def default_intended_power(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Default Intended Power={value}"]) + + @property + def intended_signal_power(self) -> float: + """Specify the power level of the intended signal. + + Value should be between -140 and -50. + """ + val = self._get_property("Intended Signal Power") + return float(val) + + @intended_signal_power.setter + def intended_signal_power(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Intended Signal Power={value}"]) + + @property + def freq_deviation(self) -> float: + """Specify the frequency deviation of the intended signal. + + Value should be between 1000 and 200000. + """ + val = self._get_property("Freq. Deviation") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @freq_deviation.setter + def freq_deviation(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Freq. Deviation={value}"]) + + @property + def modulation_depth(self) -> float: + """Specify the modulation depth of the intended signal. + + Value should be between 10 and 100. + """ + val = self._get_property("Modulation Depth") + return float(val) + + @modulation_depth.setter + def modulation_depth(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Modulation Depth={value}"]) + + @property + def measure_selectivity(self) -> bool: + """Enable/disable the measurement of the receiver's selectivity. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Measure Selectivity") + return val == true + + @measure_selectivity.setter + def measure_selectivity(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Measure Selectivity={value}"]) + + @property + def measure_mixer_products(self) -> bool: + """Enable/disable the measurement of the receiver's mixer products. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Measure Mixer Products") + return val == true + + @measure_mixer_products.setter + def measure_mixer_products(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Measure Mixer Products={value}"]) + + @property + def max_rf_order(self) -> int: + """Max RF Order of the mixer products to measure. + + Value should be greater than 1. + """ + val = self._get_property("Max RF Order") + return int(val) + + @max_rf_order.setter + def max_rf_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max RF Order={value}"]) + + @property + def max_lo_order(self) -> int: + """Max LO Order of the mixer products to measure. + + Value should be greater than 1. + """ + val = self._get_property("Max LO Order") + return int(val) + + @max_lo_order.setter + def max_lo_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max LO Order={value}"]) + + @property + def include_if(self) -> bool: + """Enable/disable the measurement of the IF channel. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include IF") + return val == true + + @include_if.setter + def include_if(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include IF={value}"]) + + @property + def measure_saturation(self) -> bool: + """Enable/disable measurement of the receiver's saturation level. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Measure Saturation") + return val == true + + @measure_saturation.setter + def measure_saturation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Measure Saturation={value}"]) + + @property + def use_ams_limits(self) -> bool: + """Allow AMS to determine the limits for measuring saturation. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use AMS Limits") + return val == true + + @use_ams_limits.setter + def use_ams_limits(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use AMS Limits={value}"]) + + @property + def start_frequency(self) -> float: + """Starting frequency for the measurement sweep. + + Value should be greater than 1e6. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @start_frequency.setter + def start_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Start Frequency={value}"]) + + @property + def stop_frequency(self) -> float: + """Stopping frequency for the measurement sweep. + + Value should be less than 6e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @stop_frequency.setter + def stop_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop Frequency={value}"]) + + @property + def samples(self) -> int: + """Number of measurement samples for each frequency. + + Value should be between 2 and 100. + """ + val = self._get_property("Samples") + return int(val) + + @samples.setter + def samples(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Samples={value}"]) + + @property + def exclude_mixer_products_below_noise(self) -> bool: + """Include/Exclude Mixer Products below the noise. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Exclude Mixer Products Below Noise") + return val == true + + @exclude_mixer_products_below_noise.setter + def exclude_mixer_products_below_noise(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Exclude Mixer Products Below Noise={value}"] + ) + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/rx_mixer_product_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/rx_mixer_product_node.py new file mode 100644 index 00000000000..e4946d32b5b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/rx_mixer_product_node.py @@ -0,0 +1,295 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RxMixerProductNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class MixerProductTaperOption(Enum): + CONSTANT = "Constant" + MIL_STD_461G = "MIL-STD-461G" + DUFF_MODEL = "Duff Model" + + @property + def mixer_product_taper(self) -> MixerProductTaperOption: + """Taper for setting amplitude of mixer products.""" + val = self._get_property("Mixer Product Taper") + val = self.MixerProductTaperOption[val.upper()] + return val + + @mixer_product_taper.setter + def mixer_product_taper(self, value: MixerProductTaperOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Mixer Product Taper={value.value}"] + ) + + @property + def mixer_product_susceptibility(self) -> float: + """Mixer product amplitudes (relative to the in-band susceptibility). + + Value should be between -200 and 200. + """ + val = self._get_property("Mixer Product Susceptibility") + return float(val) + + @mixer_product_susceptibility.setter + def mixer_product_susceptibility(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Mixer Product Susceptibility={value}"] + ) + + @property + def spurious_rejection(self) -> float: + """Mixer product amplitudes (relative to the in-band susceptibility). + + Value should be between -200 and 200. + """ + val = self._get_property("Spurious Rejection") + return float(val) + + @spurious_rejection.setter + def spurious_rejection(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Spurious Rejection={value}"]) + + @property + def minimum_tuning_frequency(self) -> float: + """Minimum tuning frequency of Rx's local oscillator. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Minimum Tuning Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @minimum_tuning_frequency.setter + def minimum_tuning_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Minimum Tuning Frequency={value}"]) + + @property + def maximum_tuning_frequency(self) -> float: + """Maximum tuning frequency of Rx's local oscillator. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Maximum Tuning Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @maximum_tuning_frequency.setter + def maximum_tuning_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Maximum Tuning Frequency={value}"]) + + @property + def mixer_product_slope(self) -> float: + """Mixer Product Slope. + + Rate of decrease for amplitude of Rx's local oscillator harmonics + (dB/decade). + + Value should be between 0 and 100. + """ + val = self._get_property("Mixer Product Slope") + return float(val) + + @mixer_product_slope.setter + def mixer_product_slope(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mixer Product Slope={value}"]) + + @property + def mixer_product_intercept(self) -> float: + """Mixer product intercept (dBc). + + Value should be between 0 and 100. + """ + val = self._get_property("Mixer Product Intercept") + return float(val) + + @mixer_product_intercept.setter + def mixer_product_intercept(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mixer Product Intercept={value}"]) + + @property + def bandwidth_80_db(self) -> float: + """Bandwidth 80 dB. + + Bandwidth where Rx's susceptibility envelope is 80 dB above in-band + susceptibility level. + + Value should be greater than 1. + """ + val = self._get_property("Bandwidth 80 dB") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @bandwidth_80_db.setter + def bandwidth_80_db(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bandwidth 80 dB={value}"]) + + @property + def image_rejection(self) -> float: + """Image frequency amplitude (relative to the in-band susceptibility). + + Value should be between -200 and 200. + """ + val = self._get_property("Image Rejection") + return float(val) + + @image_rejection.setter + def image_rejection(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Image Rejection={value}"]) + + @property + def maximum_rf_harmonic_order(self) -> int: + """Maximum order of RF frequency. + + Value should be between 1 and 100. + """ + val = self._get_property("Maximum RF Harmonic Order") + return int(val) + + @maximum_rf_harmonic_order.setter + def maximum_rf_harmonic_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Maximum RF Harmonic Order={value}"] + ) + + @property + def maximum_lo_harmonic_order(self) -> int: + """Maximum order of the LO frequency. + + Value should be between 1 and 100. + """ + val = self._get_property("Maximum LO Harmonic Order") + return int(val) + + @maximum_lo_harmonic_order.setter + def maximum_lo_harmonic_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Maximum LO Harmonic Order={value}"] + ) + + class MixingModeOption(Enum): + LO_ABOVE_TUNED_RF_FREQUENCY = "LO Above Tuned (RF) Frequency" + LO_BELOW_TUNED_RF_FREQUENCY = "LO Below Tuned (RF) Frequency" + LO_ABOVEBELOW_TUNED_RF_FREQUENCY = "LO Above/Below Tuned (RF) Frequency" + + @property + def mixing_mode(self) -> MixingModeOption: + """Specifies whether the IF frequency is > or < RF channel frequency.""" + val = self._get_property("Mixing Mode") + val = self.MixingModeOption[val.upper()] + return val + + @mixing_mode.setter + def mixing_mode(self, value: MixingModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mixing Mode={value.value}"]) + + @property + def first_if_frequency(self): + """Intermediate frequency for Rx's 1st conversion stage. + + Value should be a mathematical expression. + """ + val = self._get_property("First IF Frequency") + return val + + @first_if_frequency.setter + def first_if_frequency(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"First IF Frequency={value}"]) + + @property + def rf_transition_frequency(self) -> float: + """RF Frequency Transition point.""" + val = self._get_property("RF Transition Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @rf_transition_frequency.setter + def rf_transition_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"RF Transition Frequency={value}"]) + + class UseHighLOOption(Enum): + ABOVE_TRANSITION_FREQUENCY = "Above Transition Frequency" + BELOW_TRANSITION_FREQUENCY = "Below Transition Frequency" + + @property + def use_high_lo(self) -> UseHighLOOption: + """Use High LO above/below the transition frequency.""" + val = self._get_property("Use High LO") + val = self.UseHighLOOption[val.upper()] + return val + + @use_high_lo.setter + def use_high_lo(self, value: UseHighLOOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use High LO={value.value}"]) + + class MixerProductTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def mixer_product_table_units(self) -> MixerProductTableUnitsOption: + """Specifies the units for the Mixer Products.""" + val = self._get_property("Mixer Product Table Units") + val = self.MixerProductTableUnitsOption[val.upper()] + return val + + @mixer_product_table_units.setter + def mixer_product_table_units(self, value: MixerProductTableUnitsOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Mixer Product Table Units={value.value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/rx_saturation_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/rx_saturation_node.py new file mode 100644 index 00000000000..62e4e8f9276 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/rx_saturation_node.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RxSaturationNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/rx_selectivity_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/rx_selectivity_node.py new file mode 100644 index 00000000000..d8949544e68 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/rx_selectivity_node.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RxSelectivityNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + @property + def use_arithmetic_mean(self) -> bool: + """Use Arithmetic Mean. + + Uses arithmetic mean to center bandwidths about the tuned channel + frequency. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Arithmetic Mean") + return val == true + + @use_arithmetic_mean.setter + def use_arithmetic_mean(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use Arithmetic Mean={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/rx_spur_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/rx_spur_node.py new file mode 100644 index 00000000000..1e94f1933ff --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/rx_spur_node.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RxSpurNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def table_data(self): + """Table. + Table consists of 3 columns. + Frequency (MHz): + Value should be a mathematical expression. + Bandwidth: + Value should be greater than 1.0. + Power: + Value should be between -200.0 and 150.0. + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class SpurTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def spur_table_units(self) -> SpurTableUnitsOption: + """Specifies the units for the Spurs.""" + val = self._get_property("Spur Table Units") + val = self.SpurTableUnitsOption[val.upper()] + return val + + @spur_table_units.setter + def spur_table_units(self, value: SpurTableUnitsOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Spur Table Units={value.value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/rx_susceptibility_prof_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/rx_susceptibility_prof_node.py new file mode 100644 index 00000000000..704f4ae6ddb --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/rx_susceptibility_prof_node.py @@ -0,0 +1,258 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class RxSusceptibilityProfNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class SensitivityUnitsOption(Enum): + DBM = "dBm" + DBUV = "dBuV" + MILLIWATTS = "milliwatts" + MICROVOLTS = "microvolts" + + @property + def sensitivity_units(self) -> SensitivityUnitsOption: + """Units to use for the Rx Sensitivity.""" + val = self._get_property("Sensitivity Units") + val = self.SensitivityUnitsOption[val.upper()] + return val + + @sensitivity_units.setter + def sensitivity_units(self, value: SensitivityUnitsOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Sensitivity Units={value.value}"]) + + @property + def min_receive_signal_pwr(self) -> float: + """Received signal power level at the Rx's antenna terminal. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Min. Receive Signal Pwr") + return float(val) + + @min_receive_signal_pwr.setter + def min_receive_signal_pwr(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Min. Receive Signal Pwr={value}"]) + + @property + def snr_at_rx_signal_pwr(self) -> float: + """SNR at Rx Signal Pwr. + + Signal-to-Noise Ratio (dB) at specified received signal power at the + Rx's antenna terminal. + + Value should be between -1000 and 1000. + """ + val = self._get_property("SNR at Rx Signal Pwr") + return float(val) + + @snr_at_rx_signal_pwr.setter + def snr_at_rx_signal_pwr(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"SNR at Rx Signal Pwr={value}"]) + + @property + def processing_gain(self) -> float: + """Rx processing gain (dB) of (optional) despreader. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Processing Gain") + return float(val) + + @processing_gain.setter + def processing_gain(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Processing Gain={value}"]) + + @property + def apply_pg_to_narrowband_only(self) -> bool: + """Apply PG to Narrowband Only. + + Processing gain captures the despreading effect and applies to NB + signals only (not BB noise) when enabled. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Apply PG to Narrowband Only") + return val == true + + @apply_pg_to_narrowband_only.setter + def apply_pg_to_narrowband_only(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Apply PG to Narrowband Only={value}"] + ) + + @property + def saturation_level(self) -> float: + """Rx input saturation level. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @saturation_level.setter + def saturation_level(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Saturation Level={value}"]) + + @property + def rx_noise_figure(self) -> float: + """Rx noise figure (dB). + + Value should be between 0 and 1000. + """ + val = self._get_property("Rx Noise Figure") + return float(val) + + @rx_noise_figure.setter + def rx_noise_figure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rx Noise Figure={value}"]) + + @property + def receiver_sensitivity(self) -> float: + """Rx minimum sensitivity level (dBm). + + Value should be between -1000 and 1000. + """ + val = self._get_property("Receiver Sensitivity") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @receiver_sensitivity.setter + def receiver_sensitivity(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Receiver Sensitivity={value}"]) + + @property + def snrsinad_at_sensitivity(self) -> float: + """SNR or SINAD at the specified sensitivity level. + + Value should be between -1000 and 1000. + """ + val = self._get_property("SNR/SINAD at Sensitivity") + return float(val) + + @snrsinad_at_sensitivity.setter + def snrsinad_at_sensitivity(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"SNR/SINAD at Sensitivity={value}"]) + + @property + def perform_rx_intermod_analysis(self) -> bool: + """Performs a non-linear intermod analysis for the Rx. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Perform Rx Intermod Analysis") + return val == true + + @perform_rx_intermod_analysis.setter + def perform_rx_intermod_analysis(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Perform Rx Intermod Analysis={value}"] + ) + + @property + def amplifier_saturation_level(self) -> float: + """Internal Rx Amplifier's Saturation Level. + + Value should be between -200 and 200. + """ + val = self._get_property("Amplifier Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplifier_saturation_level.setter + def amplifier_saturation_level(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Amplifier Saturation Level={value}"] + ) + + @property + def p1_db_point_ref_input(self) -> float: + """P1-dB Point, Ref. Input. + + Rx's 1 dB Compression Point - total power > P1dB saturates the receiver. + + Value should be between -1000 and 1000. + """ + val = self._get_property("P1-dB Point, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @p1_db_point_ref_input.setter + def p1_db_point_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"P1-dB Point, Ref. Input={value}"]) + + @property + def ip3_ref_input(self) -> float: + """Internal Rx Amplifier's 3rd order intercept point. + + Value should be between -1000 and 1000. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @ip3_ref_input.setter + def ip3_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"IP3, Ref. Input={value}"]) + + @property + def max_intermod_order(self) -> int: + """Internal Rx Amplifier's maximum intermod order to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) + + @max_intermod_order.setter + def max_intermod_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Intermod Order={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/sampling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/sampling_node.py new file mode 100644 index 00000000000..7bdb3ae30e5 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/sampling_node.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class SamplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def table_data(self): + """Table. + Table consists of 2 columns. + Min: + Value should be greater than 1.0. + Max: + Value should be greater than 1.0. + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + class SamplingTypeOption(Enum): + SAMPLE_ALL_CHANNELS_IN_RANGES = "Sample All Channels in Range(s)" + RANDOM_SAMPLING = "Random Sampling" + UNIFORM_SAMPLING = "Uniform Sampling" + + @property + def sampling_type(self) -> SamplingTypeOption: + """Sampling to apply to this configuration.""" + val = self._get_property("Sampling Type") + val = self.SamplingTypeOption[val.upper()] + return val + + @sampling_type.setter + def sampling_type(self, value: SamplingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Sampling Type={value.value}"]) + + @property + def specify_percentage(self) -> bool: + """Specify Percentage. + + Specify the number of channels to simulate via a percentage of the total + available band channels. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Specify Percentage") + return val == true + + @specify_percentage.setter + def specify_percentage(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Specify Percentage={value}"]) + + @property + def percentage_of_channels(self) -> float: + """Percentage of the Band Channels to simulate. + + Value should be between 1 and 100. + """ + val = self._get_property("Percentage of Channels") + return float(val) + + @percentage_of_channels.setter + def percentage_of_channels(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Percentage of Channels={value}"]) + + @property + def max__channelsrangeband(self) -> int: + """Maximum number of Band Channels to simulate. + + Value should be between 1 and 100000. + """ + val = self._get_property("Max # Channels/Range/Band") + return int(val) + + @max__channelsrangeband.setter + def max__channelsrangeband(self, value: int): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Max # Channels/Range/Band={value}"] + ) + + @property + def seed(self) -> int: + """Seed for random channel generator. + + Value should be greater than 0. + """ + val = self._get_property("Seed") + return int(val) + + @seed.setter + def seed(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Seed={value}"]) + + @property + def total_tx_channels(self) -> int: + """Total Tx Channels. + + Total number of transmit channels this configuration is capable of + operating on. + """ + val = self._get_property("Total Tx Channels") + return int(val) + + @property + def total_rx_channels(self) -> int: + """Total Rx Channels. + + Total number of receive channels this configuration is capable of + operating on. + """ + val = self._get_property("Total Rx Channels") + return int(val) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/scene_group_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/scene_group_node.py new file mode 100644 index 00000000000..664a425a136 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/scene_group_node.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class SceneGroupNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def add_group(self): + """Add a new scene group""" + return self._add_child_node("Group") + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def show_relative_coordinates(self) -> bool: + """Show Relative Coordinates. + + Show Scene Group position and orientation in parent-node coords (False) + or relative to placement coords (True). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Relative Coordinates") + return val == true + + @show_relative_coordinates.setter + def show_relative_coordinates(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Show Relative Coordinates={value}"] + ) + + @property + def position(self): + """Set position of the Scene Group in parent-node coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Position") + return val + + @position.setter + def position(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Position={value}"]) + + @property + def relative_position(self): + """Set position of the Scene Group relative to placement coordinates. + + Value should be x/y/z, delimited by spaces. + """ + val = self._get_property("Relative Position") + return val + + @relative_position.setter + def relative_position(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Relative Position={value}"]) + + class OrientationModeOption(Enum): + ROLL_PITCH_YAW = "Roll-Pitch-Yaw" + AZ_EL_TWIST = "Az-El-Twist" + + @property + def orientation_mode(self) -> OrientationModeOption: + """Orientation Mode. + + Select the convention (order of rotations) for configuring orientation. + """ + val = self._get_property("Orientation Mode") + val = self.OrientationModeOption[val.upper()] + return val + + @orientation_mode.setter + def orientation_mode(self, value: OrientationModeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation Mode={value.value}"]) + + @property + def orientation(self): + """Orientation. + + Set orientation of the Scene Group relative to parent-node coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Orientation") + return val + + @orientation.setter + def orientation(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Orientation={value}"]) + + @property + def relative_orientation(self): + """Relative Orientation. + + Set orientation of the Scene Group relative to placement coordinates. + + Value format is determined by 'Orientation Mode', in degrees and delimited by spaces. + """ + val = self._get_property("Relative Orientation") + return val + + @relative_orientation.setter + def relative_orientation(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Relative Orientation={value}"]) + + @property + def show_axes(self) -> bool: + """Show Axes. + + Toggle (on/off) display of Scene Group coordinate axes in 3-D window. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Show Axes") + return val == true + + @show_axes.setter + def show_axes(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Show Axes={value}"]) + + @property + def box_color(self): + """Set color of the bounding box of the Scene Group. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Box Color") + return val + + @box_color.setter + def box_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Box Color={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/selectivity_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/selectivity_trace_node.py new file mode 100644 index 00000000000..a815c8c8496 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/selectivity_trace_node.py @@ -0,0 +1,229 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class SelectivityTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/solution_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/solution_coupling_node.py new file mode 100644 index 00000000000..4b6f706b54e --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/solution_coupling_node.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class SolutionCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled. + + Enable/Disable coupling (A sweep disabled in HFSS/Layout cannot be + enabled in EMIT). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/solutions_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/solutions_node.py new file mode 100644 index 00000000000..df582638b37 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/solutions_node.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class SolutionsNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled. + + Enable/Disable coupling (A setup disabled in HFSS/Layout cannot be + enabled in EMIT). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/spur_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/spur_trace_node.py new file mode 100644 index 00000000000..bc701b69326 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/spur_trace_node.py @@ -0,0 +1,250 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class SpurTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def channel_frequency(self): + """Select band channel frequency to display.""" + val = self._get_property("Channel Frequency") + return val + + @channel_frequency.setter + def channel_frequency(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Channel Frequency={value}"]) + + @property + def transmit_frequency(self) -> float: + """Transmit Frequency. + + The actual transmit frequency (i.e., the Channel Frequency plus the Tx + Offset). + """ + val = self._get_property("Transmit Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/terminator.py b/src/ansys/aedt/core/emit_core/nodes/generated/terminator.py new file mode 100644 index 00000000000..1bb49082441 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/terminator.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Terminator(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the Terminator. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TypeOption(Enum): + BY_FILE = "By File" + PARAMETRIC = "Parametric" + + @property + def type(self) -> TypeOption: + """Type. + + Type of terminator model to use. Options include: By File (measured or + simulated) or Parametric. + """ + val = self._get_property("Type") + val = self.TypeOption[val.upper()] + return val + + @type.setter + def type(self, value: TypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Type={value.value}"]) + + class PortLocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def port_location(self) -> PortLocationOption: + """Defines the orientation of the terminator.""" + val = self._get_property("Port Location") + val = self.PortLocationOption[val.upper()] + return val + + @port_location.setter + def port_location(self, value: PortLocationOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port Location={value.value}"]) + + @property + def vswr(self) -> float: + """VSWR. + + The Voltage Standing Wave Ratio (VSWR) due to the impedance mismatch + between the terminator and the connected component (RF System, Antenna, + etc). + + Value should be between 1.0 and 100. + """ + val = self._get_property("VSWR") + return float(val) + + @vswr.setter + def vswr(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"VSWR={value}"]) + + @property + def warnings(self) -> str: + """Warning(s) for this node.""" + val = self._get_property("Warnings") + return val diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/test_noise_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/test_noise_trace_node.py new file mode 100644 index 00000000000..e3f9a47d2b9 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/test_noise_trace_node.py @@ -0,0 +1,358 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TestNoiseTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def input_port(self) -> int: + """Specifies input port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Input Port") + return int(val) + + @input_port.setter + def input_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Input Port={value}"]) + + @property + def output_port(self) -> int: + """Specifies output port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Output Port") + return int(val) + + @output_port.setter + def output_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Output Port={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) + + @property + def frequency_1(self) -> float: + """1st test tone frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Frequency 1") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @frequency_1.setter + def frequency_1(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Frequency 1={value}"]) + + @property + def amplitude_1(self) -> float: + """1st test tone amplitude. + + Value should be between -100 and 200. + """ + val = self._get_property("Amplitude 1") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplitude_1.setter + def amplitude_1(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Amplitude 1={value}"]) + + @property + def bandwidth_1(self) -> float: + """1st test tone bandwidth. + + Value should be greater than 1. + """ + val = self._get_property("Bandwidth 1") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @bandwidth_1.setter + def bandwidth_1(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bandwidth 1={value}"]) + + @property + def frequency_2(self) -> float: + """2nd test tone frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Frequency 2") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @frequency_2.setter + def frequency_2(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Frequency 2={value}"]) + + @property + def amplitude_2(self) -> float: + """2nd test tone amplitude. + + Value should be between -100 and 200. + """ + val = self._get_property("Amplitude 2") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplitude_2.setter + def amplitude_2(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Amplitude 2={value}"]) + + @property + def bandwidth_2(self) -> float: + """2nd test tone bandwidth. + + Value should be greater than 1. + """ + val = self._get_property("Bandwidth 2") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @bandwidth_2.setter + def bandwidth_2(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bandwidth 2={value}"]) + + @property + def noise_level(self) -> float: + """Broadband noise level. + + Value should be between -200 and 0. + """ + val = self._get_property("Noise Level") + return float(val) + + @noise_level.setter + def noise_level(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Level={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/top_level_simulation.py b/src/ansys/aedt/core/emit_core/nodes/generated/top_level_simulation.py new file mode 100644 index 00000000000..e54ab2654f2 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/top_level_simulation.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TopLevelSimulation(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/touchstone_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/touchstone_coupling_node.py new file mode 100644 index 00000000000..c571863c107 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/touchstone_coupling_node.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TouchstoneCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + @property + def filename(self) -> str: + """Name of file with coupling data. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def savant_matched_coupling_file(self) -> str: + """Coupling data generated by Savant and exported as a matched file.""" + val = self._get_property("Savant Matched Coupling File") + return val + + @property + def enable_em_isolation(self) -> bool: + """Enables/disables EM isolation. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable EM Isolation") + return val == true + + @enable_em_isolation.setter + def enable_em_isolation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable EM Isolation={value}"]) + + @property + def port_antenna_assignment(self): + """Maps each port in the coupling file to an antenna in the project.""" + val = self._get_property("Port-Antenna Assignment") + return val + + @port_antenna_assignment.setter + def port_antenna_assignment(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port-Antenna Assignment={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tr_switch.py b/src/ansys/aedt/core/emit_core/nodes/generated/tr_switch.py new file mode 100644 index 00000000000..979e06d145f --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tr_switch.py @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TR_Switch(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = True + EmitNode.__init__(self, emit_obj, result_id, node_id) + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def filename(self) -> str: + """Name of file defining the outboard component. + + Value should be a full file path. + """ + val = self._get_property("Filename") + return val + + @filename.setter + def filename(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Filename={value}"]) + + @property + def noise_temperature(self) -> float: + """System Noise temperature (K) of the component. + + Value should be between 0 and 1000. + """ + val = self._get_property("Noise Temperature") + return float(val) + + @noise_temperature.setter + def noise_temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Temperature={value}"]) + + @property + def notes(self) -> str: + """Expand to view/edit notes stored with the project.""" + val = self._get_property("Notes") + return val + + @notes.setter + def notes(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Notes={value}"]) + + class TxPortOption(Enum): + PORT_1 = "Port 1" + PORT_2 = "Port 2" + + @property + def tx_port(self) -> TxPortOption: + """Specifies which port on the TR Switch is part of the Tx path.""" + val = self._get_property("Tx Port") + val = self.TxPortOption[val.upper()] + return val + + @tx_port.setter + def tx_port(self, value: TxPortOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tx Port={value.value}"]) + + class CommonPortLocationOption(Enum): + RADIO_SIDE = "Radio Side" + ANTENNA_SIDE = "Antenna Side" + + @property + def common_port_location(self) -> CommonPortLocationOption: + """Defines the orientation of the tr switch.""" + val = self._get_property("Common Port Location") + val = self.CommonPortLocationOption[val.upper()] + return val + + @common_port_location.setter + def common_port_location(self, value: CommonPortLocationOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Common Port Location={value.value}"] + ) + + @property + def insertion_loss(self) -> float: + """TR Switch in-band loss in forward direction. + + Value should be between 0 and 100. + """ + val = self._get_property("Insertion Loss") + return float(val) + + @insertion_loss.setter + def insertion_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Insertion Loss={value}"]) + + @property + def finite_isolation(self) -> bool: + """Finite Isolation. + + Use a finite isolation. If disabled, the tr switch model is ideal + (infinite isolation). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Isolation") + return val == true + + @finite_isolation.setter + def finite_isolation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Isolation={value}"]) + + @property + def isolation(self) -> float: + """TR Switch reverse isolation (i.e., loss between the Tx/Rx ports). + + Value should be between 0 and 100. + """ + val = self._get_property("Isolation") + return float(val) + + @isolation.setter + def isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Isolation={value}"]) + + @property + def finite_bandwidth(self) -> bool: + """Finite Bandwidth. + + Use a finite bandwidth. If disabled, the tr switch model is ideal + (infinite bandwidth). + + Value should be 'true' or 'false'. + """ + val = self._get_property("Finite Bandwidth") + return val == true + + @finite_bandwidth.setter + def finite_bandwidth(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Finite Bandwidth={value}"]) + + @property + def out_of_band_attenuation(self) -> float: + """Out-of-band loss (attenuation). + + Value should be between 0 and 200. + """ + val = self._get_property("Out-of-band Attenuation") + return float(val) + + @out_of_band_attenuation.setter + def out_of_band_attenuation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Out-of-band Attenuation={value}"]) + + @property + def lower_stop_band(self) -> float: + """Lower stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_stop_band.setter + def lower_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Stop Band={value}"]) + + @property + def lower_cutoff(self) -> float: + """Lower cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Lower Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @lower_cutoff.setter + def lower_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Lower Cutoff={value}"]) + + @property + def higher_cutoff(self) -> float: + """Higher cutoff frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Cutoff") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_cutoff.setter + def higher_cutoff(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Cutoff={value}"]) + + @property + def higher_stop_band(self) -> float: + """Higher stop band frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Higher Stop Band") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @higher_stop_band.setter + def higher_stop_band(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Higher Stop Band={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tr_switch_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tr_switch_trace_node.py new file mode 100644 index 00000000000..3a0b6dd3578 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tr_switch_trace_node.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TRSwitchTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def input_port(self) -> int: + """Specifies input port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Input Port") + return int(val) + + @input_port.setter + def input_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Input Port={value}"]) + + @property + def output_port(self) -> int: + """Specifies output port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Output Port") + return int(val) + + @output_port.setter + def output_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Output Port={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tunable_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tunable_trace_node.py new file mode 100644 index 00000000000..8b3914c8b7f --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tunable_trace_node.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TunableTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def input_port(self) -> int: + """Specifies input port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Input Port") + return int(val) + + @input_port.setter + def input_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Input Port={value}"]) + + @property + def output_port(self) -> int: + """Specifies output port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Output Port") + return int(val) + + @output_port.setter + def output_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Output Port={value}"]) + + @property + def frequency(self) -> float: + """Tunable filter center frequency.""" + val = self._get_property("Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @frequency.setter + def frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Frequency={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/two_ray_path_loss_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/two_ray_path_loss_coupling_node.py new file mode 100644 index 00000000000..49fb44201ef --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/two_ray_path_loss_coupling_node.py @@ -0,0 +1,359 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TwoRayPathLossCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def antenna_a(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna A") + return val + + @antenna_a.setter + def antenna_a(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna A={value}"]) + + @property + def antenna_b(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Antenna B") + return val + + @antenna_b.setter + def antenna_b(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Antenna B={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + @property + def ground_reflection_coeff(self) -> float: + """The ground reflection coefficient. + + Value should be between -100 and 100. + """ + val = self._get_property("Ground Reflection Coeff.") + return float(val) + + @ground_reflection_coeff.setter + def ground_reflection_coeff(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Ground Reflection Coeff.={value}"]) + + @property + def pointspeak(self) -> int: + """Points/Peak. + + Number of points used to model each peak in frequency vs loss curve. + + Value should be between 3 and 100. + """ + val = self._get_property("Points/Peak") + return int(val) + + @pointspeak.setter + def pointspeak(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Points/Peak={value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/two_tone_trace_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/two_tone_trace_node.py new file mode 100644 index 00000000000..3e26c45e4d2 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/two_tone_trace_node.py @@ -0,0 +1,358 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TwoToneTraceNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def export_model(self, file_name): + """Save this data to a file""" + return self._export_model(file_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def input_port(self) -> int: + """Specifies input port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Input Port") + return int(val) + + @input_port.setter + def input_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Input Port={value}"]) + + @property + def output_port(self) -> int: + """Specifies output port for the plotted outboard component. + + Value should be greater than 1. + """ + val = self._get_property("Output Port") + return int(val) + + @output_port.setter + def output_port(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Output Port={value}"]) + + @property + def data_source(self): + """Data Source. + + Identifies tree node serving as data source for plot trace, click link + to find it. + """ + val = self._get_property("Data Source") + return val + + @data_source.setter + def data_source(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Source={value}"]) + + @property + def visible(self) -> bool: + """Toggle (on/off) display of this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Visible") + return val == true + + @visible.setter + def visible(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Visible={value}"]) + + @property + def custom_legend(self) -> bool: + """Enable/disable custom legend entry for this plot trace. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Custom Legend") + return val == true + + @custom_legend.setter + def custom_legend(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Legend={value}"]) + + @property + def name(self) -> str: + """Enter name of plot trace as it will appear in legend.""" + val = self._get_property("Name") + return val + + @name.setter + def name(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Name={value}"]) + + class StyleOption(Enum): + LINES = "Lines" + DOTTED = "Dotted" + DASHED = "Dashed" + DOT_DASH = "Dot-Dash" + DOT_DOT_DASH = "Dot-Dot-Dash" + NONE = "None" + + @property + def style(self) -> StyleOption: + """Specify line style of plot trace.""" + val = self._get_property("Style") + val = self.StyleOption[val.upper()] + return val + + @style.setter + def style(self, value: StyleOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Style={value.value}"]) + + @property + def line_width(self) -> int: + """Specify line width of plot trace. + + Value should be between 1 and 100. + """ + val = self._get_property("Line Width") + return int(val) + + @line_width.setter + def line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Width={value}"]) + + @property + def line_color(self): + """Specify line color of plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Line Color") + return val + + @line_color.setter + def line_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Line Color={value}"]) + + class SymbolOption(Enum): + NOSYMBOL = "NoSymbol" + ELLIPSE = "Ellipse" + RECT = "Rect" + DIAMOND = "Diamond" + TRIANGLE = "Triangle" + DTRIANGLE = "DTriangle" + LTRIANGLE = "LTriangle" + RTRIANGLE = "RTriangle" + CROSS = "Cross" + XCROSS = "XCross" + HLINE = "HLine" + VLINE = "VLine" + STAR1 = "Star1" + STAR2 = "Star2" + HEXAGON = "Hexagon" + + @property + def symbol(self) -> SymbolOption: + """Select symbol to mark points along plot trace.""" + val = self._get_property("Symbol") + val = self.SymbolOption[val.upper()] + return val + + @symbol.setter + def symbol(self, value: SymbolOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol={value.value}"]) + + @property + def symbol_size(self) -> int: + """Set size (in points) of symbols marking points along plot trace. + + Value should be between 1 and 1000. + """ + val = self._get_property("Symbol Size") + return int(val) + + @symbol_size.setter + def symbol_size(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Size={value}"]) + + @property + def symbol_color(self): + """Specify color of symbols marking points along plot trace. + + Color should be in RGB form: #RRGGBB. + """ + val = self._get_property("Symbol Color") + return val + + @symbol_color.setter + def symbol_color(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Color={value}"]) + + @property + def symbol_line_width(self) -> int: + """Set the width of the line used to draw the symbol. + + Value should be between 1 and 20. + """ + val = self._get_property("Symbol Line Width") + return int(val) + + @symbol_line_width.setter + def symbol_line_width(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Line Width={value}"]) + + @property + def symbol_filled(self) -> bool: + """Symbol Filled. + + If true, the interior of the symbol is filled - has no effect for some + symbol types. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Symbol Filled") + return val == true + + @symbol_filled.setter + def symbol_filled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Symbol Filled={value}"]) + + @property + def frequency_1(self) -> float: + """1st test tone frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Frequency 1") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @frequency_1.setter + def frequency_1(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Frequency 1={value}"]) + + @property + def amplitude_1(self) -> float: + """1st test tone amplitude. + + Value should be between -100 and 200. + """ + val = self._get_property("Amplitude 1") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplitude_1.setter + def amplitude_1(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Amplitude 1={value}"]) + + @property + def bandwidth_1(self) -> float: + """1st test tone bandwidth. + + Value should be greater than 1. + """ + val = self._get_property("Bandwidth 1") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @bandwidth_1.setter + def bandwidth_1(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bandwidth 1={value}"]) + + @property + def frequency_2(self) -> float: + """2nd test tone frequency. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Frequency 2") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @frequency_2.setter + def frequency_2(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Frequency 2={value}"]) + + @property + def amplitude_2(self) -> float: + """2nd test tone amplitude. + + Value should be between -100 and 200. + """ + val = self._get_property("Amplitude 2") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplitude_2.setter + def amplitude_2(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Amplitude 2={value}"]) + + @property + def bandwidth_2(self) -> float: + """2nd test tone bandwidth. + + Value should be greater than 1. + """ + val = self._get_property("Bandwidth 2") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @bandwidth_2.setter + def bandwidth_2(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Bandwidth 2={value}"]) + + @property + def noise_level(self) -> float: + """Broadband noise level. + + Value should be between -200 and 0. + """ + val = self._get_property("Noise Level") + return float(val) + + @noise_level.setter + def noise_level(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Level={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_bb_emission_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_bb_emission_node.py new file mode 100644 index 00000000000..c28b0bc3c27 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_bb_emission_node.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxBbEmissionNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def table_data(self): + """Tx Broadband Noise Profile Table. + Table consists of 2 columns. + Frequency (MHz): + Value should be a mathematical expression. + Amplitude (dBm/Hz): + Value should be between -200.0 and 150.0. + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class NoiseBehaviorOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE_BANDWIDTH = "Relative (Bandwidth)" + RELATIVE_OFFSET = "Relative (Offset)" + EQUATION = "Equation" + + @property + def noise_behavior(self) -> NoiseBehaviorOption: + """Specifies the behavior of the parametric noise profile.""" + val = self._get_property("Noise Behavior") + val = self.NoiseBehaviorOption[val.upper()] + return val + + @noise_behavior.setter + def noise_behavior(self, value: NoiseBehaviorOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Behavior={value.value}"]) + + @property + def use_log_linear_interpolation(self) -> bool: + """Use Log-Linear Interpolation. + + If true, linear interpolation in the log domain is used. If false, + linear interpolation in the linear domain is used. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Log-Linear Interpolation") + return val == true + + @use_log_linear_interpolation.setter + def use_log_linear_interpolation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Use Log-Linear Interpolation={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_harmonic_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_harmonic_node.py new file mode 100644 index 00000000000..8236eb8e1e6 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_harmonic_node.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxHarmonicNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class HarmonicTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def harmonic_table_units(self) -> HarmonicTableUnitsOption: + """Specifies the units for the Harmonics.""" + val = self._get_property("Harmonic Table Units") + val = self.HarmonicTableUnitsOption[val.upper()] + return val + + @harmonic_table_units.setter + def harmonic_table_units(self, value: HarmonicTableUnitsOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Harmonic Table Units={value.value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_meas_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_meas_node.py new file mode 100644 index 00000000000..4387238cb4b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_meas_node.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxMeasNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("File") + return val + + @property + def source_file(self) -> str: + """Name of the measurement source. + + Value should be a full file path. + """ + val = self._get_property("Source File") + return val + + @property + def transmit_frequency(self) -> float: + """Channel associated with the measurement file.""" + val = self._get_property("Transmit Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @property + def use_ams_limits(self) -> bool: + """Allow AMS to define the frequency limits for the measurements. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use AMS Limits") + return val == true + + @use_ams_limits.setter + def use_ams_limits(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use AMS Limits={value}"]) + + @property + def start_frequency(self) -> float: + """Starting frequency for the measurement sweep. + + Value should be greater than 1e6. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @start_frequency.setter + def start_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Start Frequency={value}"]) + + @property + def stop_frequency(self) -> float: + """Stopping frequency for the measurement sweep. + + Value should be less than 6e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @stop_frequency.setter + def stop_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop Frequency={value}"]) + + @property + def exclude_harmonics_below_noise(self) -> bool: + """Include/Exclude Harmonics below the noise. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Exclude Harmonics Below Noise") + return val == true + + @exclude_harmonics_below_noise.setter + def exclude_harmonics_below_noise(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Exclude Harmonics Below Noise={value}"] + ) + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_nb_emission_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_nb_emission_node.py new file mode 100644 index 00000000000..f60b8d4bbae --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_nb_emission_node.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxNbEmissionNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class NarrowbandBehaviorOption(Enum): + ABSOLUTE_FREQS_AND_POWER = "Absolute Freqs and Power" + RELATIVE_FREQS_AND_ATTENUATION = "Relative Freqs and Attenuation" + + @property + def narrowband_behavior(self) -> NarrowbandBehaviorOption: + """Specifies the behavior of the parametric narrowband emissions mask.""" + val = self._get_property("Narrowband Behavior") + val = self.NarrowbandBehaviorOption[val.upper()] + return val + + @narrowband_behavior.setter + def narrowband_behavior(self, value: NarrowbandBehaviorOption): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Narrowband Behavior={value.value}"] + ) + + @property + def measurement_frequency(self) -> float: + """Measurement frequency for the absolute freq/amp pairs.""" + val = self._get_property("Measurement Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @measurement_frequency.setter + def measurement_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Measurement Frequency={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_spectral_prof_emitter_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_spectral_prof_emitter_node.py new file mode 100644 index 00000000000..9220b3d596a --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_spectral_prof_emitter_node.py @@ -0,0 +1,201 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxSpectralProfEmitterNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + @property + def output_voltage_peak(self) -> float: + """Output High Voltage Level: maximum voltage of the digital signal.""" + val = self._get_property("Output Voltage Peak") + val = self._convert_from_internal_units(float(val), "Voltage") + return float(val) + + @output_voltage_peak.setter + def output_voltage_peak(self, value: float | str): + value = self._convert_to_internal_units(value, "Voltage") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Output Voltage Peak={value}"]) + + @property + def include_phase_noise(self) -> bool: + """Include oscillator phase noise in Tx spectral profile. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Phase Noise") + return val == true + + @include_phase_noise.setter + def include_phase_noise(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Phase Noise={value}"]) + + @property + def tx_broadband_noise(self) -> float: + """Transmitters broadband noise level. + + Value should be less than 1000. + """ + val = self._get_property("Tx Broadband Noise") + return float(val) + + @tx_broadband_noise.setter + def tx_broadband_noise(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tx Broadband Noise={value}"]) + + @property + def perform_tx_intermod_analysis(self) -> bool: + """Performs a non-linear intermod analysis for the Tx. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Perform Tx Intermod Analysis") + return val == true + + @perform_tx_intermod_analysis.setter + def perform_tx_intermod_analysis(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Perform Tx Intermod Analysis={value}"] + ) + + @property + def internal_amp_gain(self) -> float: + """Internal Tx Amplifier's Gain. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Internal Amp Gain") + return float(val) + + @internal_amp_gain.setter + def internal_amp_gain(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Internal Amp Gain={value}"]) + + @property + def noise_figure(self) -> float: + """Internal Tx Amplifier's noise figure. + + Value should be between 0 and 50. + """ + val = self._get_property("Noise Figure") + return float(val) + + @noise_figure.setter + def noise_figure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Figure={value}"]) + + @property + def amplifier_saturation_level(self) -> float: + """Internal Tx Amplifier's Saturation Level. + + Value should be between -200 and 200. + """ + val = self._get_property("Amplifier Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplifier_saturation_level.setter + def amplifier_saturation_level(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Amplifier Saturation Level={value}"] + ) + + @property + def p1_db_point_ref_input(self) -> float: + """P1-dB Point, Ref. Input . + + Internal Tx Amplifier's 1 dB Compression Point - total power > P1dB + saturates the internal Tx amplifier. + + Value should be between -200 and 200. + """ + val = self._get_property("P1-dB Point, Ref. Input ") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @p1_db_point_ref_input.setter + def p1_db_point_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"P1-dB Point, Ref. Input ={value}"]) + + @property + def ip3_ref_input(self) -> float: + """Internal Tx Amplifier's 3rd order intercept point. + + Value should be between -200 and 200. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @ip3_ref_input.setter + def ip3_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"IP3, Ref. Input={value}"]) + + @property + def reverse_isolation(self) -> float: + """Internal Tx Amplifier's Reverse Isolation. + + Value should be between -200 and 200. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @reverse_isolation.setter + def reverse_isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Reverse Isolation={value}"]) + + @property + def max_intermod_order(self) -> int: + """Internal Tx Amplifier's maximum intermod order to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) + + @max_intermod_order.setter + def max_intermod_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Intermod Order={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_spectral_prof_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_spectral_prof_node.py new file mode 100644 index 00000000000..1a1282c9f1b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_spectral_prof_node.py @@ -0,0 +1,379 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxSpectralProfNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class SpectrumTypeOption(Enum): + NARROWBAND__BROADBAND = "Narrowband & Broadband" + BROADBAND_ONLY = "Broadband Only" + + @property + def spectrum_type(self) -> SpectrumTypeOption: + """Specifies EMI Margins to calculate.""" + val = self._get_property("Spectrum Type") + val = self.SpectrumTypeOption[val.upper()] + return val + + @spectrum_type.setter + def spectrum_type(self, value: SpectrumTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Spectrum Type={value.value}"]) + + class TxPowerOption(Enum): + PEAK_POWER = "Peak Power" + AVERAGE_POWER = "Average Power" + + @property + def tx_power(self) -> TxPowerOption: + """Method used to specify the power.""" + val = self._get_property("Tx Power") + val = self.TxPowerOption[val.upper()] + return val + + @tx_power.setter + def tx_power(self, value: TxPowerOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tx Power={value.value}"]) + + @property + def peak_power(self) -> float: + """Tx's carrier frequency peak power. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Peak Power") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @peak_power.setter + def peak_power(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Peak Power={value}"]) + + @property + def average_power(self) -> float: + """Tx's fundamental level specified by average power. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Average Power") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @average_power.setter + def average_power(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Average Power={value}"]) + + @property + def include_phase_noise(self) -> bool: + """Include oscillator phase noise in Tx spectral profile. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Phase Noise") + return val == true + + @include_phase_noise.setter + def include_phase_noise(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Phase Noise={value}"]) + + @property + def tx_broadband_noise(self) -> float: + """Transmitters broadband noise level. + + Value should be less than 1000. + """ + val = self._get_property("Tx Broadband Noise") + return float(val) + + @tx_broadband_noise.setter + def tx_broadband_noise(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Tx Broadband Noise={value}"]) + + class HarmonicTaperOption(Enum): + CONSTANT = "Constant" + MIL_STD_461G = "MIL-STD-461G" + MIL_STD_461G_NAVY = "MIL-STD-461G Navy" + DUFF_MODEL = "Duff Model" + + @property + def harmonic_taper(self) -> HarmonicTaperOption: + """Taper type used to set amplitude of harmonics.""" + val = self._get_property("Harmonic Taper") + val = self.HarmonicTaperOption[val.upper()] + return val + + @harmonic_taper.setter + def harmonic_taper(self, value: HarmonicTaperOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Harmonic Taper={value.value}"]) + + @property + def harmonic_amplitude(self) -> float: + """Amplitude (relative to the carrier power) of harmonics. + + Value should be between -1000 and 0. + """ + val = self._get_property("Harmonic Amplitude") + return float(val) + + @harmonic_amplitude.setter + def harmonic_amplitude(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Harmonic Amplitude={value}"]) + + @property + def harmonic_slope(self) -> float: + """Rate of decrease for harmonics' amplitudes (dB/decade). + + Value should be between -1000 and 0. + """ + val = self._get_property("Harmonic Slope") + return float(val) + + @harmonic_slope.setter + def harmonic_slope(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Harmonic Slope={value}"]) + + @property + def harmonic_intercept(self) -> float: + """Amplitude intercept at the fundamental (dBc). + + Value should be between -1000 and 0. + """ + val = self._get_property("Harmonic Intercept") + return float(val) + + @harmonic_intercept.setter + def harmonic_intercept(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Harmonic Intercept={value}"]) + + @property + def enable_harmonic_bw_expansion(self) -> bool: + """Enable Harmonic BW Expansion. + + If (True), bandwidth of harmonics increases proportional to the harmonic + number. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Harmonic BW Expansion") + return val == true + + @enable_harmonic_bw_expansion.setter + def enable_harmonic_bw_expansion(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Enable Harmonic BW Expansion={value}"] + ) + + @property + def number_of_harmonics(self) -> int: + """Maximum number of harmonics modeled. + + Value should be between 1 and 1000. + """ + val = self._get_property("Number of Harmonics") + return int(val) + + @number_of_harmonics.setter + def number_of_harmonics(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Number of Harmonics={value}"]) + + @property + def second_harmonic_level(self) -> float: + """Amplitude (relative to the carrier power) of the 2nd harmonic. + + Value should be between -1000 and 0. + """ + val = self._get_property("Second Harmonic Level") + return float(val) + + @second_harmonic_level.setter + def second_harmonic_level(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Second Harmonic Level={value}"]) + + @property + def third_harmonic_level(self) -> float: + """Amplitude (relative to the carrier power) of the 3rd harmonic. + + Value should be between -1000 and 0. + """ + val = self._get_property("Third Harmonic Level") + return float(val) + + @third_harmonic_level.setter + def third_harmonic_level(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Third Harmonic Level={value}"]) + + @property + def other_harmonic_levels(self) -> float: + """Other Harmonic Levels. + + Amplitude (relative to the carrier power) of the higher order harmonics. + + Value should be between -1000 and 0. + """ + val = self._get_property("Other Harmonic Levels") + return float(val) + + @other_harmonic_levels.setter + def other_harmonic_levels(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Other Harmonic Levels={value}"]) + + @property + def perform_tx_intermod_analysis(self) -> bool: + """Performs a non-linear intermod analysis for the Tx. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Perform Tx Intermod Analysis") + return val == true + + @perform_tx_intermod_analysis.setter + def perform_tx_intermod_analysis(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Perform Tx Intermod Analysis={value}"] + ) + + @property + def internal_amp_gain(self) -> float: + """Internal Tx Amplifier's Gain. + + Value should be between -1000 and 1000. + """ + val = self._get_property("Internal Amp Gain") + return float(val) + + @internal_amp_gain.setter + def internal_amp_gain(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Internal Amp Gain={value}"]) + + @property + def noise_figure(self) -> float: + """Internal Tx Amplifier's noise figure. + + Value should be between 0 and 50. + """ + val = self._get_property("Noise Figure") + return float(val) + + @noise_figure.setter + def noise_figure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Noise Figure={value}"]) + + @property + def amplifier_saturation_level(self) -> float: + """Internal Tx Amplifier's Saturation Level. + + Value should be between -200 and 200. + """ + val = self._get_property("Amplifier Saturation Level") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @amplifier_saturation_level.setter + def amplifier_saturation_level(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Amplifier Saturation Level={value}"] + ) + + @property + def p1_db_point_ref_input(self) -> float: + """P1-dB Point, Ref. Input . + + Internal Tx Amplifier's 1 dB Compression Point - total power > P1dB + saturates the internal Tx amplifier. + + Value should be between -200 and 200. + """ + val = self._get_property("P1-dB Point, Ref. Input ") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @p1_db_point_ref_input.setter + def p1_db_point_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"P1-dB Point, Ref. Input ={value}"]) + + @property + def ip3_ref_input(self) -> float: + """Internal Tx Amplifier's 3rd order intercept point. + + Value should be between -200 and 200. + """ + val = self._get_property("IP3, Ref. Input") + val = self._convert_from_internal_units(float(val), "Power") + return float(val) + + @ip3_ref_input.setter + def ip3_ref_input(self, value: float | str): + value = self._convert_to_internal_units(value, "Power") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"IP3, Ref. Input={value}"]) + + @property + def reverse_isolation(self) -> float: + """Internal Tx Amplifier's Reverse Isolation. + + Value should be between -200 and 200. + """ + val = self._get_property("Reverse Isolation") + return float(val) + + @reverse_isolation.setter + def reverse_isolation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Reverse Isolation={value}"]) + + @property + def max_intermod_order(self) -> int: + """Internal Tx Amplifier's maximum intermod order to compute. + + Value should be between 3 and 20. + """ + val = self._get_property("Max Intermod Order") + return int(val) + + @max_intermod_order.setter + def max_intermod_order(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Intermod Order={value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/tx_spur_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/tx_spur_node.py new file mode 100644 index 00000000000..88807a7a55a --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/tx_spur_node.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class TxSpurNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def import_csv_file(self, file_name): + """Import a CSV File...""" + return self._import(file_name, "Csv") + + def delete(self): + """Delete this node""" + self._delete() + + @property + def table_data(self): + """Table. + Table consists of 3 columns. + Frequency (MHz): + Value should be a mathematical expression. + Bandwidth: + Value should be greater than 1.0. + Power: + Value should be between -200.0 and 150.0. + """ + return self._get_table_data() + + @table_data.setter + def table_data(self, value): + self._set_table_data(value) + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + class SpurTableUnitsOption(Enum): + ABSOLUTE = "Absolute" + RELATIVE = "Relative" + + @property + def spur_table_units(self) -> SpurTableUnitsOption: + """Specifies the units for the Spurs.""" + val = self._get_property("Spur Table Units") + val = self.SpurTableUnitsOption[val.upper()] + return val + + @spur_table_units.setter + def spur_table_units(self, value: SpurTableUnitsOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Spur Table Units={value.value}"]) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/walfisch_coupling_node.py b/src/ansys/aedt/core/emit_core/nodes/generated/walfisch_coupling_node.py new file mode 100644 index 00000000000..efa9d1ed585 --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/walfisch_coupling_node.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class WalfischCouplingNode(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + def rename(self, new_name: str): + """Rename this node""" + self._rename(new_name) + + def duplicate(self, new_name: str): + """Duplicate this node""" + return self._duplicate(new_name) + + def delete(self): + """Delete this node""" + self._delete() + + @property + def enabled(self) -> bool: + """Enable/Disable coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enabled") + return val == true + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enabled={value}"]) + + @property + def base_antenna(self) -> EmitNode: + """First antenna of the pair to apply the coupling values to.""" + val = self._get_property("Base Antenna") + return val + + @base_antenna.setter + def base_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Base Antenna={value}"]) + + @property + def mobile_antenna(self) -> EmitNode: + """Second antenna of the pair to apply the coupling values to.""" + val = self._get_property("Mobile Antenna") + return val + + @mobile_antenna.setter + def mobile_antenna(self, value: EmitNode): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Mobile Antenna={value}"]) + + @property + def enable_refinement(self) -> bool: + """Enables/disables refined sampling of the frequency domain. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Enable Refinement") + return val == true + + @enable_refinement.setter + def enable_refinement(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Enable Refinement={value}"]) + + @property + def adaptive_sampling(self) -> bool: + """Enables/disables adaptive refinement the frequency domain sampling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adaptive Sampling") + return val == true + + @adaptive_sampling.setter + def adaptive_sampling(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adaptive Sampling={value}"]) + + @property + def refinement_domain(self): + """Points to use when refining the frequency domain.""" + val = self._get_property("Refinement Domain") + return val + + @refinement_domain.setter + def refinement_domain(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Refinement Domain={value}"]) + + class PathLossTypeOption(Enum): + LOS_URBAN_CANYON = "LOS (Urban Canyon)" + NLOS = "NLOS" + + @property + def path_loss_type(self) -> PathLossTypeOption: + """Specify LOS vs NLOS for the Walfisch-Ikegami model.""" + val = self._get_property("Path Loss Type") + val = self.PathLossTypeOption[val.upper()] + return val + + @path_loss_type.setter + def path_loss_type(self, value: PathLossTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Path Loss Type={value.value}"]) + + class EnvironmentOption(Enum): + DENSE_METRO = "Dense Metro" + SMALLMEDIUM_CITY_OR_SUBURBAN = "Small/Medium City or Suburban" + + @property + def environment(self) -> EnvironmentOption: + """Specify the environment type for the Walfisch model.""" + val = self._get_property("Environment") + val = self.EnvironmentOption[val.upper()] + return val + + @environment.setter + def environment(self, value: EnvironmentOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Environment={value.value}"]) + + @property + def roof_height(self) -> float: + """The height of the building where the antenna is located. + + Value should be between 0 and 100. + """ + val = self._get_property("Roof Height") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @roof_height.setter + def roof_height(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Roof Height={value}"]) + + @property + def distance_between_buildings(self) -> float: + """The distance between two buildings. + + Value should be between 0 and 100. + """ + val = self._get_property("Distance Between Buildings") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @distance_between_buildings.setter + def distance_between_buildings(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Distance Between Buildings={value}"] + ) + + @property + def street_width(self) -> float: + """Width of the street. + + Value should be between 0 and 100. + """ + val = self._get_property("Street Width") + val = self._convert_from_internal_units(float(val), "Length") + return float(val) + + @street_width.setter + def street_width(self, value: float | str): + value = self._convert_to_internal_units(value, "Length") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Street Width={value}"]) + + @property + def incidence_angle(self) -> float: + """Angle between the street orientation and direction of incidence. + + Value should be between 0 and 90. + """ + val = self._get_property("Incidence Angle") + return float(val) + + @incidence_angle.setter + def incidence_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Incidence Angle={value}"]) + + @property + def custom_fading_margin(self) -> float: + """Custom Fading Margin. + + Sets a custom fading margin to be applied to all coupling defined by + this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Custom Fading Margin") + return float(val) + + @custom_fading_margin.setter + def custom_fading_margin(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Custom Fading Margin={value}"]) + + @property + def polarization_mismatch(self) -> float: + """Polarization Mismatch. + + Sets a margin for polarization mismatch to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Polarization Mismatch") + return float(val) + + @polarization_mismatch.setter + def polarization_mismatch(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Mismatch={value}"]) + + @property + def pointing_error_loss(self) -> float: + """Pointing Error Loss. + + Sets a margin for pointing error loss to be applied to all coupling + defined by this node. + + Value should be between 0 and 100. + """ + val = self._get_property("Pointing Error Loss") + return float(val) + + @pointing_error_loss.setter + def pointing_error_loss(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Pointing Error Loss={value}"]) + + class FadingTypeOption(Enum): + NONE = "None" + FAST_FADING_ONLY = "Fast Fading Only" + SHADOWING_ONLY = "Shadowing Only" + FAST_FADING_AND_SHADOWING = "Fast Fading and Shadowing" + + @property + def fading_type(self) -> FadingTypeOption: + """Specify the type of fading to include.""" + val = self._get_property("Fading Type") + val = self.FadingTypeOption[val.upper()] + return val + + @fading_type.setter + def fading_type(self, value: FadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Type={value.value}"]) + + @property + def fading_availability(self) -> float: + """Fading Availability. + + The probability that the propagation loss in dB is below its median + value plus the margin. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Fading Availability") + return float(val) + + @fading_availability.setter + def fading_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Fading Availability={value}"]) + + @property + def std_deviation(self) -> float: + """Standard deviation modeling the random amount of shadowing loss. + + Value should be between 0.0 and 100.0. + """ + val = self._get_property("Std Deviation") + return float(val) + + @std_deviation.setter + def std_deviation(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Std Deviation={value}"]) + + @property + def include_rain_attenuation(self) -> bool: + """Adds a margin for rain attenuation to the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Rain Attenuation") + return val == true + + @include_rain_attenuation.setter + def include_rain_attenuation(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Include Rain Attenuation={value}"]) + + @property + def rain_availability(self) -> float: + """Rain Availability. + + Percentage of time attenuation due to range is < computed margin (range + from 99-99.999%). + + Value should be between 99 and 99.999. + """ + val = self._get_property("Rain Availability") + return float(val) + + @rain_availability.setter + def rain_availability(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Availability={value}"]) + + @property + def rain_rate(self) -> float: + """Rain rate (mm/hr) exceeded for 0.01% of the time. + + Value should be between 0.0 and 1000.0. + """ + val = self._get_property("Rain Rate") + return float(val) + + @rain_rate.setter + def rain_rate(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Rain Rate={value}"]) + + @property + def polarization_tilt_angle(self) -> float: + """Polarization Tilt Angle. + + Polarization tilt angle of the transmitted signal relative to the + horizontal. + + Value should be between 0.0 and 180.0. + """ + val = self._get_property("Polarization Tilt Angle") + return float(val) + + @polarization_tilt_angle.setter + def polarization_tilt_angle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Polarization Tilt Angle={value}"]) + + @property + def include_atmospheric_absorption(self) -> bool: + """Include Atmospheric Absorption. + + Adds a margin for atmospheric absorption due to oxygen/water vapor to + the computed coupling. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Include Atmospheric Absorption") + return val == true + + @include_atmospheric_absorption.setter + def include_atmospheric_absorption(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Include Atmospheric Absorption={value}"] + ) + + @property + def temperature(self) -> float: + """Air temperature in degrees Celsius. + + Value should be between -273.0 and 100.0. + """ + val = self._get_property("Temperature") + return float(val) + + @temperature.setter + def temperature(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Temperature={value}"]) + + @property + def total_air_pressure(self) -> float: + """Total air pressure. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Total Air Pressure") + return float(val) + + @total_air_pressure.setter + def total_air_pressure(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Total Air Pressure={value}"]) + + @property + def water_vapor_concentration(self) -> float: + """Water vapor concentration. + + Value should be between 0.0 and 2000.0. + """ + val = self._get_property("Water Vapor Concentration") + return float(val) + + @water_vapor_concentration.setter + def water_vapor_concentration(self, value: float): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Water Vapor Concentration={value}"] + ) diff --git a/src/ansys/aedt/core/emit_core/nodes/generated/waveform.py b/src/ansys/aedt/core/emit_core/nodes/generated/waveform.py new file mode 100644 index 00000000000..ec00154860b --- /dev/null +++ b/src/ansys/aedt/core/emit_core/nodes/generated/waveform.py @@ -0,0 +1,442 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2021 - 2025 ANSYS, Inc. and/or its affiliates. +# SPDX-FileCopyrightText: 2021 - 2025 ANSYS, Inc. and /or its affiliates. +# SPDX-License-Identifier: MIT +# +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from enum import Enum + +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + + +class Waveform(EmitNode): + def __init__(self, emit_obj, result_id, node_id): + self._is_component = False + EmitNode.__init__(self, emit_obj, result_id, node_id) + + @property + def parent(self): + """The parent of this emit node.""" + return self._parent + + @property + def enabled(self) -> bool: + """Enabled state for this node.""" + return self._oRevisionData.GetEmitNodeProperties(self._result_id, self._node_id, "enabled") + + @enabled.setter + def enabled(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"enabled= + {value}"]) + + @property + def port(self): + """Radio Port associated with this Band.""" + val = self._get_property("Port") + return val + + @port.setter + def port(self, value): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Port={value}"]) + + class WaveformOption(Enum): + PERIODIC_CLOCK = "Periodic Clock" + SPREAD_SPECTRUM_CLOCK = "Spread Spectrum Clock" + PRBS = "PRBS" + PRBS_PERIODIC = "PRBS (Periodic)" + IMPORTED = "Imported" + + @property + def waveform(self) -> WaveformOption: + """Modulation used for the transmitted/received signal.""" + val = self._get_property("Waveform") + val = self.WaveformOption[val.upper()] + return val + + @waveform.setter + def waveform(self, value: WaveformOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Waveform={value.value}"]) + + @property + def start_frequency(self) -> float: + """First frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Start Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @start_frequency.setter + def start_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Start Frequency={value}"]) + + @property + def stop_frequency(self) -> float: + """Last frequency for this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Stop Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @stop_frequency.setter + def stop_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop Frequency={value}"]) + + @property + def channel_spacing(self) -> float: + """Spacing between channels within this band. + + Value should be between 1 and 100e9. + """ + val = self._get_property("Channel Spacing") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @channel_spacing.setter + def channel_spacing(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Channel Spacing={value}"]) + + @property + def clock_duty_cycle(self) -> float: + """Clock signals duty cycle. + + Value should be between 0.001 and 1.0. + """ + val = self._get_property("Clock Duty Cycle") + return float(val) + + @clock_duty_cycle.setter + def clock_duty_cycle(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Clock Duty Cycle={value}"]) + + @property + def clock_risefall_time(self) -> float: + """Clock signals rise/fall time. + + Value should be greater than 0.0. + """ + val = self._get_property("Clock Rise/Fall Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @clock_risefall_time.setter + def clock_risefall_time(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Clock Rise/Fall Time={value}"]) + + class SpreadingTypeOption(Enum): + LOW_SPREAD = "Low Spread" + CENTER_SPREAD = "Center Spread" + HIGH_SPREAD = "High Spread" + + @property + def spreading_type(self) -> SpreadingTypeOption: + """Type of spreading employed by the Spread Spectrum Clock.""" + val = self._get_property("Spreading Type") + val = self.SpreadingTypeOption[val.upper()] + return val + + @spreading_type.setter + def spreading_type(self, value: SpreadingTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Spreading Type={value.value}"]) + + @property + def spread_percentage(self) -> float: + """Peak-to-peak spread percentage. + + Value should be between 0 and 100. + """ + val = self._get_property("Spread Percentage") + return float(val) + + @spread_percentage.setter + def spread_percentage(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Spread Percentage={value}"]) + + @property + def imported_spectrum(self) -> str: + """Imported Spectrum.""" + val = self._get_property("Imported Spectrum") + return val + + @imported_spectrum.setter + def imported_spectrum(self, value: str): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Imported Spectrum={value}"]) + + @property + def raw_data_format(self) -> str: + """Format of the imported raw data.""" + val = self._get_property("Raw Data Format") + return val + + @property + def system_impedance(self) -> float: + """System impedance for the imported data. + + Value should be between 0.0 and 1.0e6. + """ + val = self._get_property("System Impedance") + val = self._convert_from_internal_units(float(val), "Resistance") + return float(val) + + @system_impedance.setter + def system_impedance(self, value: float | str): + value = self._convert_to_internal_units(value, "Resistance") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"System Impedance={value}"]) + + @property + def advanced_extraction_params(self) -> bool: + """Show/hide advanced extraction params. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Advanced Extraction Params") + return val == true + + @advanced_extraction_params.setter + def advanced_extraction_params(self, value: bool): + self._oRevisionData.SetEmitNodeProperties( + self._result_id, self._node_id, [f"Advanced Extraction Params={value}"] + ) + + @property + def nb_window_size(self) -> float: + """NB Window Size. + + Window size for computing the moving average during narrowband signal + detection. + + Value should be greater than 3. + """ + val = self._get_property("NB Window Size") + return float(val) + + @nb_window_size.setter + def nb_window_size(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"NB Window Size={value}"]) + + @property + def bb_smoothing_factor(self) -> float: + """BB Smoothing Factor. + + Reduces the number of frequency points used for the broadband noise. + + Value should be greater than 1. + """ + val = self._get_property("BB Smoothing Factor") + return float(val) + + @bb_smoothing_factor.setter + def bb_smoothing_factor(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"BB Smoothing Factor={value}"]) + + @property + def nb_detector_threshold(self) -> float: + """Narrowband Detector threshold standard deviation. + + Value should be between 2 and 10. + """ + val = self._get_property("NB Detector Threshold") + return float(val) + + @nb_detector_threshold.setter + def nb_detector_threshold(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"NB Detector Threshold={value}"]) + + class AlgorithmOption(Enum): + FFT = "FFT" + FOURIER_TRANSFORM = "Fourier Transform" + + @property + def algorithm(self) -> AlgorithmOption: + """Algorithm used to transform the imported time domain spectrum.""" + val = self._get_property("Algorithm") + val = self.AlgorithmOption[val.upper()] + return val + + @algorithm.setter + def algorithm(self, value: AlgorithmOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Algorithm={value.value}"]) + + @property + def start_time(self) -> float: + """Initial time of the imported spectrum. + + Value should be greater than 0.0. + """ + val = self._get_property("Start Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @start_time.setter + def start_time(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Start Time={value}"]) + + @property + def stop_time(self) -> float: + """Final time of the imported time domain spectrum.""" + val = self._get_property("Stop Time") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @stop_time.setter + def stop_time(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Stop Time={value}"]) + + @property + def max_frequency(self) -> float: + """Frequency cutoff of the imported time domain spectrum. + + Value should be between 1.0 and 100.0e9. + """ + val = self._get_property("Max Frequency") + val = self._convert_from_internal_units(float(val), "Freq") + return float(val) + + @max_frequency.setter + def max_frequency(self, value: float | str): + value = self._convert_to_internal_units(value, "Freq") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Max Frequency={value}"]) + + class WindowTypeOption(Enum): + RECTANGULAR = "Rectangular" + BARTLETT = "Bartlett" + BLACKMAN = "Blackman" + HAMMING = "Hamming" + HANNING = "Hanning" + KAISER = "Kaiser" + LANZCOS = "Lanzcos" + WELCH = "Welch" + WEBER = "Weber" + + @property + def window_type(self) -> WindowTypeOption: + """Windowing scheme used for importing time domain spectrum.""" + val = self._get_property("Window Type") + val = self.WindowTypeOption[val.upper()] + return val + + @window_type.setter + def window_type(self, value: WindowTypeOption): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Window Type={value.value}"]) + + @property + def kaiser_parameter(self) -> float: + """Shape factor applied to the transform. + + Value should be greater than 0.0. + """ + val = self._get_property("Kaiser Parameter") + return float(val) + + @kaiser_parameter.setter + def kaiser_parameter(self, value: float): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Kaiser Parameter={value}"]) + + @property + def adjust_coherent_gain(self) -> bool: + """Shape factor applied to the transform. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Adjust Coherent Gain") + return val == true + + @adjust_coherent_gain.setter + def adjust_coherent_gain(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Adjust Coherent Gain={value}"]) + + @property + def data_rate(self) -> float: + """Maximum data rate: helps determine shape of spectral profile. + + Value should be greater than 1. + """ + val = self._get_property("Data Rate") + val = self._convert_from_internal_units(float(val), "Data Rate") + return float(val) + + @data_rate.setter + def data_rate(self, value: float | str): + value = self._convert_to_internal_units(value, "Data Rate") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Data Rate={value}"]) + + @property + def num_of_bits(self) -> int: + """Length of the Pseudo Random Binary Sequence. + + Value should be between 1 and 1000. + """ + val = self._get_property("Num of Bits") + return int(val) + + @num_of_bits.setter + def num_of_bits(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Num of Bits={value}"]) + + @property + def use_envelope(self) -> bool: + """Model the waveform as a worst case envelope. + + Value should be 'true' or 'false'. + """ + val = self._get_property("Use Envelope") + return val == true + + @use_envelope.setter + def use_envelope(self, value: bool): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Use Envelope={value}"]) + + @property + def min_ptsnull(self) -> int: + """Minimum number of points to use between each null frequency. + + Value should be between 2 and 50. + """ + val = self._get_property("Min Pts/Null") + return int(val) + + @min_ptsnull.setter + def min_ptsnull(self, value: int): + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Min Pts/Null={value}"]) + + @property + def delay_skew(self) -> float: + """Delay Skew of the differential signal pairs. + + Value should be greater than 0.0. + """ + val = self._get_property("Delay Skew") + val = self._convert_from_internal_units(float(val), "Time") + return float(val) + + @delay_skew.setter + def delay_skew(self, value: float | str): + value = self._convert_to_internal_units(value, "Time") + self._oRevisionData.SetEmitNodeProperties(self._result_id, self._node_id, [f"Delay Skew={value}"]) diff --git a/src/ansys/aedt/core/emit_core/results/results.py b/src/ansys/aedt/core/emit_core/results/results.py index 4c7265cd16e..b80b0c371cb 100644 --- a/src/ansys/aedt/core/emit_core/results/results.py +++ b/src/ansys/aedt/core/emit_core/results/results.py @@ -79,9 +79,25 @@ def _add_revision(self, name=None): ------- ``Revision`` object that was created. """ - revision = Revision(self, self.emit_project, name) - self.revisions.append(revision) - return revision + self.aedt_version = int(self.emit_project.aedt_version_id[-3:]) + if self.aedt_version > 251 and name == None: + # Return the current revision. Only create it if it isn't already there. + current_revision = None + current_revisions = [revision for revision in self.revisions if revision.name == "Current"] + # Do we need to delete the existing Current revisions? Or can we just return it? + for revision in current_revisions: + self.delete_revision("Current") + # if len(current_revisions) > 0: + # current_revision = current_revisions[0] + # current_revision._load_revision() + # # current_revision.revision_loaded = True + current_revision = Revision(self, self.emit_project, name) + self.revisions.append(current_revision) + return current_revision + else: + revision = Revision(self, self.emit_project, name) + self.revisions.append(revision) + return revision @pyaedt_function_handler() def delete_revision(self, revision_name): @@ -100,17 +116,29 @@ def delete_revision(self, revision_name): -------- >>> aedtapp.results.delete_revision("Revision 10") """ - if revision_name in self.design.GetResultList(): - self.design.DeleteResult(revision_name) - if self.current_revision.name == revision_name and self.current_revision.revision_loaded: - self.emit_project._emit_api.close() - self.current_revision = None + self.aedt_version = int(self.emit_project.aedt_version_id[-3:]) + if self.aedt_version > 251: + if revision_name in self.design.GetKeptResultNames(): + self.design.DeleteKeptResult(revision_name) + if self.current_revision.name == revision_name and self.current_revision.revision_loaded: + self.emit_project._emit_api.close() + self.current_revision = None for rev in self.revisions: if revision_name in rev.name: self.revisions.remove(rev) break - else: - warnings.warn(f"{revision_name} does not exist") + else: + if revision_name in self.design.GetResultList(): + self.design.DeleteResult(revision_name) + if self.current_revision.name == revision_name and self.current_revision.revision_loaded: + self.emit_project._emit_api.close() + self.current_revision = None + for rev in self.revisions: + if revision_name in rev.name: + self.revisions.remove(rev) + break + else: + warnings.warn(f"{revision_name} does not exist") @staticmethod def interaction_domain(): @@ -186,11 +214,15 @@ def get_revision(self, revision_name=None): >>> interferers = rev.get_interferer_names() >>> receivers = rev.get_receiver_names() """ + self.aedt_version = int(self.emit_project.aedt_version_id[-3:]) # no revisions to load, create a new one if len(self.revisions) == 0: return self.analyze() # retrieve the latest revision if nothing specified if revision_name is None: + if self.aedt_version > 251: + return self.current_revision + # unload the current revision and load the latest self.current_revision.revision_loaded = False self.current_revision = self.revisions[-1] @@ -204,7 +236,7 @@ def get_revision(self, revision_name=None): self.current_revision._load_revision() else: # might be an old revision that was never loaded by pyaedt - aedt_result_list = self.design.GetResultList() + aedt_result_list = self.design.GetKeptResultNames() rev = [x for x in aedt_result_list if revision_name == x] if len(rev) > 0: # unload the current revision and load the specified revision @@ -229,21 +261,29 @@ def analyze(self): >>> interferers = rev.get_interferer_names() >>> receivers = rev.get_receiver_names() """ - # No revisions exist, add one - if self.current_revision is None: + self.aedt_version = int(self.emit_project.aedt_version_id[-3:]) + if self.aedt_version > 251: + if self.current_revision: + self.current_revision.revision_loaded = False + self.current_revision = self._add_revision() - # no changes since last created revision, load it - elif ( - self.revisions[-1].revision_number - == self.emit_project.desktop_class.active_design( - self.emit_project.desktop_class.active_project() - ).GetRevision() - ): - self.get_revision(self.revisions[-1].name) + return self.current_revision else: - # there are changes since the current revision was analyzed, create - # a new revision - self.current_revision.revision_loaded = False - self.current_revision = self._add_revision() + # No revisions exist, add one + if self.current_revision is None: + self.current_revision = self._add_revision() + # no changes since last created revision, load it + elif ( + self.revisions[-1].revision_number + == self.emit_project.desktop_class.active_design( + self.emit_project.desktop_class.active_project() + ).GetRevision() + ): + self.get_revision(self.revisions[-1].name) + else: + # there are changes since the current revision was analyzed, create + # a new revision + self.current_revision.revision_loaded = False + self.current_revision = self._add_revision() - return self.current_revision + return self.current_revision diff --git a/src/ansys/aedt/core/emit_core/results/revision.py b/src/ansys/aedt/core/emit_core/results/revision.py index 05188a58616..048bd3273fb 100644 --- a/src/ansys/aedt/core/emit_core/results/revision.py +++ b/src/ansys/aedt/core/emit_core/results/revision.py @@ -22,13 +22,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +import os import warnings from ansys.aedt.core.emit_core.emit_constants import EmiCategoryFilter from ansys.aedt.core.emit_core.emit_constants import InterfererType from ansys.aedt.core.emit_core.emit_constants import ResultType from ansys.aedt.core.emit_core.emit_constants import TxRxMode +from ansys.aedt.core.emit_core.nodes import generated +from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode +from ansys.aedt.core.emit_core.nodes.generated import CouplingsNode +from ansys.aedt.core.emit_core.nodes.generated import EmitSceneNode +from ansys.aedt.core.emit_core.nodes.generated import ResultPlotNode from ansys.aedt.core.generic.general_methods import pyaedt_function_handler +from ansys.aedt.core.internal.checks import min_aedt_version class Revision: @@ -42,8 +49,8 @@ class Revision: emit_obj : ``Emit`` object that this revision is associated with. name : str, optional - Name of the revision to create. The default is ``None``, in which - case the name of the current design revision is used. + Name of the revision to load . The default is ``None``, in which + case the Current revision is used. Raises ------ @@ -60,39 +67,82 @@ class Revision: """ def __init__(self, parent_results, emit_obj, name=None): - if not name: - name = emit_obj.odesign.GetCurrentResult() - if not name: - name = emit_obj.odesign.AddResult("") - else: - if name not in emit_obj.odesign.GetResultList(): - name = emit_obj.odesign.AddResult(name) - full = emit_obj.odesign.GetResultDirectory(name) + self.emit_project = emit_obj + """EMIT project.""" - self.name = name - """Name of the revision.""" + self.odesktop = emit_obj.odesktop + """Desktop object.""" - self.path = full - """Full path of the revision.""" + self.parent_results = parent_results + """Parent Results object.""" - self.emit_project = emit_obj - """EMIT project.""" + self.aedt_version = int(parent_results.emit_project.aedt_version_id[-3:]) + """AEDT version.""" + + if self.aedt_version > 251: + self._emit_com = emit_obj.odesign.GetModule("EmitCom") + + if not name: + # User didn't specify a specific revision name to load- use the Current revision + self.results_index = 0 + + self.name = "Current" + """Name of the revision.""" + + emit_obj.odesign.SaveEmitProject() + + self.path = os.path.normpath( + os.path.join( + emit_obj.project_path, + f"{emit_obj.project_name}.aedtresults", + "EmitDesign1", + "Current Project.emit", + ) + ) + """Path to the EMIT result folder for the revision.""" + else: + kept_result_names = emit_obj.odesign.GetKeptResultNames() + if not name in kept_result_names: + raise ValueError(f'Revision "{name}" does not exist in the project.') + + self.results_index = self._emit_com.GetKeptResultIndex(name) + """Index of the result for this revision.""" + + self.path = emit_obj.odesign.GetResultDirectory(name) + """Path to the EMIT result folder for the revision.""" + + self.name = name + """Name of the revision.""" + + # Get the SimulationNodeID for the specified result + # self._sim_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, "Simulation") + else: + if not name: + name = emit_obj.odesign.GetCurrentResult() + if not name: + name = emit_obj.odesign.AddResult("") + else: + if name not in emit_obj.odesign.GetResultList(): + name = emit_obj.odesign.AddResult(name) + full = emit_obj.odesign.GetResultDirectory(name) - raw_props = emit_obj.odesign.GetResultProperties(name) - key = lambda s: s.split("=", 1)[0] - val = lambda s: s.split("=", 1)[1] - props = {key(s): val(s) for s in raw_props} + self.name = name + """Name of the revision.""" - self.revision_number = int(props["Revision"]) - """Unique revision number from the EMIT design""" + self.path = full + """Full path of the revision.""" - self.timestamp = props["Timestamp"] - """Unique timestamp for the revision""" + raw_props = emit_obj.odesign.GetResultProperties(name) + key = lambda s: s.split("=", 1)[0] + val = lambda s: s.split("=", 1)[1] + props = {key(s): val(s) for s in raw_props} - self.parent_results = parent_results - """Parent Results object""" + self.revision_number = int(props["Revision"]) + """Unique revision number from the EMIT design""" + + self.timestamp = props["Timestamp"] + """Unique timestamp for the revision""" - # load the revision after creating it self.revision_loaded = False """``True`` if the revision is loaded and ``False`` if it is not.""" self._load_revision() @@ -147,6 +197,7 @@ def get_interaction(self, domain): >>> rev.get_interaction(domain) """ + # TODO: update when Domain methods are added to API self._load_revision() engine = self.emit_project._emit_api.get_engine() if domain.interferer_names and engine.max_simultaneous_interferers != len(domain.interferer_names): @@ -188,6 +239,15 @@ def run(self, domain): engine.max_simultaneous_interferers = 1 if len(domain.interferer_names) > 1: raise ValueError("Multiple interferers cannot be specified prior to AEDT version 2024 R1.") + if self.emit_project._aedt_version > "2025.1": + # check for disconnected systems and add a warning + disconnected_radios = self._get_disconnected_radios() + if len(disconnected_radios) > 0: + err_msg = ( + "Some radios are part of a system with unconnected ports or errors " + "and will not be included in the EMIT analysis: " + ", ".join(disconnected_radios) + ) + warnings.warn(err_msg) interaction = engine.run(domain) # save the project and revision self.emit_project.save_project() @@ -751,6 +811,7 @@ def set_emi_category_filter_enabled(self, category: EmiCategoryFilter, enabled: engine = self.emit_project._emit_api.get_engine() engine.set_emi_category_filter_enabled(category, enabled) + @pyaedt_function_handler def get_license_session(self): """Get a license session. @@ -769,3 +830,351 @@ def get_license_session(self): raise RuntimeError("This function is only supported in AEDT version 2024 R2 and later.") engine = self.emit_project._emit_api.get_engine() return engine.license_session() + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def _get_all_component_names(self) -> list[str]: + """Gets all component names from this revision. + + Returns + ------- + component_names: list + List of component names. + + Examples + -------- + >>> components = revision._get_all_component_names() + """ + component_names = self._emit_com.GetComponentNames(self.results_index, "") + return component_names + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def _get_all_top_level_node_ids(self) -> list[int]: + """Gets all top level node ids from this revision. + + Returns + ------- + node_ids: list + List of top level node ids. + + Examples + -------- + >>> top_level_node_ids = revision._get_all_top_level_node_ids() + """ + top_level_node_names = [ + # 'Windows-*-Configuration Diagram', + "Windows-*-Result Plot", + # 'Windows-*-EMI Margin Plot', + "Windows-*-Result Categorization", + # 'Windows-*-Plot', + # 'Windows-*-Coupling Plot', + "Windows-*-Project Tree", + "Windows-*-Properties", + # 'Windows-*-JETS Search', + "Windows-*-Antenna Coupling Matrix", + "Windows-*-Scenario Matrix", + "Windows-*-Scenario Details", + "Windows-*-Interaction Diagram", + # 'Windows-*-Link Analysis', + # 'Windows-*-Event Log', + # 'Windows-*-Library Tree', + # 'Windows-*-Python Script Window', + "RF Systems", + "Couplings", + # 'Analysis', + "Simulation", + "Scene", + ] + top_level_node_ids = [] + for name in top_level_node_names: + top_level_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, name) + top_level_node_ids.append(top_level_node_id) + return top_level_node_ids + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_all_top_level_nodes(self) -> list[EmitNode]: + """Gets all top level nodes from this revision. + + Returns + ------- + nodes: list + List of top level nodes. + + Examples + -------- + >>> top_level_nodes = revision.get_all_top_level_nodes() + """ + top_level_node_ids = self._get_all_top_level_node_ids() + top_level_nodes = [self._get_node(node_id) for node_id in top_level_node_ids] + return top_level_nodes + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_all_component_nodes(self) -> list[EmitNode]: + """Gets all component nodes from this revision. + + Returns + ------- + component_nodes: list + List of component nodes. + + Examples + -------- + >>> nodes = revision.get_all_component_nodes() + """ + component_names = self._get_all_component_names() + component_node_ids = [self._emit_com.GetComponentNodeID(self.results_index, name) for name in component_names] + component_nodes = [self._get_node(node_id) for node_id in component_node_ids] + return component_nodes + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_component_node(self, comp_name: str) -> EmitNode | None: + """Get the specified component from this revision. + + Parameters + ---------- + comp_name: str + name of the component to return. + + Returns + ------- + component_node: EmitNode + Node representing the specified component. + + Examples + -------- + >>> node = revision.get_component_node("GPS Radio") + """ + component_nodes = self.get_all_component_nodes() + for comp in component_nodes: + if comp.name == comp_name: + return comp + warnings.warn(f"{comp_name} not found.") + return None + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def _get_all_node_ids(self) -> list[int]: + """Gets all node ids from this revision. + + Returns + ------- + node_ids: list + List of node ids. + + Examples + -------- + >>> node_ids = revision._get_all_node_ids() + """ + node_ids = [] + node_ids_to_search = [] + + top_level_node_ids = self._get_all_top_level_node_ids() + node_ids_to_search.extend(top_level_node_ids) + + component_names = self._get_all_component_names() + component_node_ids = [self._emit_com.GetComponentNodeID(self.results_index, name) for name in component_names] + node_ids_to_search.extend(component_node_ids) + + while len(node_ids_to_search) > 0: + node_id_to_search = node_ids_to_search.pop() + if node_id_to_search not in node_ids: + node_ids.append(node_id_to_search) + + child_names = self._emit_com.GetChildNodeNames(self.results_index, node_id_to_search) + child_ids = [ + self._emit_com.GetChildNodeID(self.results_index, node_id_to_search, name) for name in child_names + ] + if len(child_ids) > 0: + node_ids_to_search.extend(child_ids) + + return node_ids + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def _get_node(self, node_id: int) -> EmitNode | None: + """Gets a node for this revision with the given id. + + Parameters + ---------- + node_id: int + node_id of node to construct. + + Returns + ------- + node: EmitNode + The node. + + Examples + -------- + >>> node = revision._get_node(node_id) + """ + props = self._emit_com.GetEmitNodeProperties(self.results_index, node_id, True) + props = EmitNode.props_to_dict(props) + node_type = props["Type"] + + prefix = "" if self.results_index == 0 else "ReadOnly" + + node = None + try: + if node_type == "RadioNode" and props["IsEmitter"] == "true": + type_class = getattr(generated, f"{prefix}EmitterNode") + node = type_class(self.emit_project, self.results_index, node_id) + else: + type_class = getattr(generated, f"{prefix}{node_type}") + node = type_class(self.emit_project, self.results_index, node_id) + except AttributeError: + node = EmitNode(self.emit_project, self.results_index, node_id) + return node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_all_nodes(self) -> list[EmitNode]: + """Gets all nodes for this revision. + + Returns + ------- + nodes: list + List of all nodes from this revision. + + Examples + -------- + >>> nodes = revision.get_all_nodes() + """ + ids = self._get_all_node_ids() + nodes = [self._get_node(id) for id in ids] + return nodes + + # Methods to get specific top level nodes + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_scene_node(self) -> EmitSceneNode: + """Gets the Scene node for this revision. + + Returns + ------- + node: EmitSceneNode + The Scene node for this revision. + + Examples + -------- + >>> scene_node = revision.get_scene_node() + """ + scene_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, "Scene") + scene_node = self._get_node(scene_node_id) + return scene_node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_coupling_data_node(self) -> CouplingsNode: + """Gets the Coupling Data node for this revision. + + Returns + ------- + node: CouplingsNode + The Coupling Data node for this revision. + + Examples + -------- + >>> coupling_data_node = revision.get_coupling_data_node() + """ + coupling_data_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, "Couplings") + coupling_data_node = self._get_node(coupling_data_node_id) + return coupling_data_node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_simulation_node(self) -> EmitNode: + """Gets the Simulation node for this revision. + + Returns + ------- + node: EmitNode + The Simulation node for this revision. + + Examples + -------- + >>> simulation_node = revision.get_simulation_node() + """ + simulation_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, "Simulation") + simulation_node = self._get_node(simulation_node_id) + return simulation_node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_preferences_node(self) -> EmitNode: + """Gets the Preferences node for this revision. + + Returns + ------- + node: EmitNode + The Preferences node for this revision. + + Examples + -------- + >>> preferences_node = revision.get_preferences_node() + """ + preferences_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, "Preferences") + preferences_node = self._get_node(preferences_node_id) + return preferences_node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_result_plot_node(self) -> ResultPlotNode: + """Gets the Result Plot node for this revision. + + Returns + ------- + node: ResultPlotNode + The Result Plot node for this revision. + + Examples + -------- + >>> result_plot_node = revision.get_result_plot_node() + """ + result_plot_node_id = self._emit_com.GetTopLevelNodeID(self.results_index, "Windows-*-Result Plot") + result_plot_node = self._get_node(result_plot_node_id) + return result_plot_node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def get_result_categorization_node(self) -> EmitNode: + """Gets the Result Categorization node for this revision. + + Returns + ------- + node: EmitNode + The Result Categorization node for this revision. + + Examples + -------- + >>> result_categorization_node = revision.get_result_categorization_node() + """ + result_categorization_node_id = self._emit_com.GetTopLevelNodeID( + self.results_index, "Windows-*-Result Categorization" + ) + result_categorization_node = self._get_node(result_categorization_node_id) + return result_categorization_node + + @pyaedt_function_handler + @min_aedt_version("2025.2") + def _get_disconnected_radios(self) -> list[str]: + """Gets a list of disconnected radios for this revision. + + Returns + ------- + list: str + All radios in the revision that are not connected to an antenna. A radio + is only considered "disconnected" if any of the components' ports in its + chain are left open. + """ + rf_systems_id = self._emit_com.GetTopLevelNodeID(self.results_index, "RF Systems") + sys_names = self._emit_com.GetChildNodeNames(self.results_index, rf_systems_id) + if "Disconnected Components" in sys_names: + dis_comp_id = self._emit_com.GetChildNodeID(self.results_index, rf_systems_id, "Disconnected Components") + radios_id = self._emit_com.GetChildNodeID(self.results_index, dis_comp_id, "Radios") + return self._emit_com.GetChildNodeNames(0, radios_id) + return [] diff --git a/src/ansys/aedt/core/modeler/circuits/primitives_emit.py b/src/ansys/aedt/core/modeler/circuits/primitives_emit.py index a4bf25c7792..ab034f98d43 100644 --- a/src/ansys/aedt/core/modeler/circuits/primitives_emit.py +++ b/src/ansys/aedt/core/modeler/circuits/primitives_emit.py @@ -409,9 +409,6 @@ def __init__(self, components, component_name): self.root_prop_node = None """Root node of the component.""" - self.units = components._parent.get_units() - """Units for the component.""" - @property def composed_name(self): """Component name. Needed for compatibility.""" @@ -707,7 +704,7 @@ def get_position(self, units=""): # Check the units specified are a valid EMIT length if not units or units not in emit_consts.EMIT_VALID_UNITS["Length"]: - units = self.units["Length"] + units = "meter" position = ( consts.unit_converter(float(parts[0]), "Length", "meter", units), consts.unit_converter(float(parts[1]), "Length", "meter", units), @@ -779,14 +776,14 @@ def band_start_frequency(self, band_node, units=""): ---------- band_node : Instance of the band node. units : str, optional - If ``None`` specified, global units are used. + If ``None`` specified, SI units (Hz) are used. Returns ------- Float Start frequency of the band node.""" if not units or units not in emit_consts.EMIT_VALID_UNITS["Frequency"]: - units = self.units["Frequency"] + units = "Hz" return consts.unit_converter(float(band_node.props["StartFrequency"]), "Freq", "Hz", units) def band_stop_frequency(self, band_node, units=""): @@ -796,14 +793,14 @@ def band_stop_frequency(self, band_node, units=""): ---------- band_node : Instance of the band node. units : str, optional - If ``None`` specified, global units are used. + If ``None`` specified, SI units (Hz) are used. Returns ------- Float Stop frequency of the band node.""" if not units or units not in emit_consts.EMIT_VALID_UNITS["Frequency"]: - units = self.units["Frequency"] + units = "Hz" return consts.unit_converter(float(band_node.props["StopFrequency"]), "Freq", "Hz", units) def set_band_start_frequency(self, band_node, band_start_freq, units=""): @@ -896,54 +893,6 @@ def set_band_stop_frequency(self, band_node, band_stop_freq, units=""): prop_list = {"StopFrequency": freq_string} band_node._set_prop_value(prop_list) - # def duplicate_band(self, band_node_to_duplicate): - # """ - # [Incomplete 10/19/2023] - # Parameters - # ---------- - # band_node_to_duplicate - # - # Returns - # ------- - # - # """ - # # append number to the name of the band to duplicate. - # print('Duplicating...') - # - # - # # return band node - # def convert_channels_to_multi_bands(self, band_node): - # """ - # [Incomplete 10/19/2023] - # Parameters - # ---------- - # band_node - # - # Returns - # ------- - # - # """ - # # get the channels. Say returns 10 channels in the band_node - # # Name = r.bands()[0].children[0].props['Name'] - # # band_node.props['Name'] - # # Start = r.bands()[0].props['StartFrequency'] - # band_start_frequency = float(band_node.props['StartFrequency']) - # # Stop = r.bands()[0].props['StopFrequency'] - # band_stop_frequency = float(band_node.props['StopFrequency']) - # # Spacing = r.bands()[0].props['ChannelSpacing'] - # channel_spacing = float(band_node.props['ChannelSpacing']) - # # for each channel - # # 1) create a band (duplicate original one) - # # 2) set band start and stop frequencies - # for channel in list(range(int(band_start_frequency), int(band_stop_frequency), int(channel_spacing))): - # baby_band_start = channel - # baby_band_stop = channel+channel_spacing - # baby_band_node = self.duplicate_band(band_node) # return band name or some handle to it - # self.set_band_start_frequency(baby_band_node, baby_band_start) - # self.set_band_stop_frequency(baby_band_node, baby_band_stop) - # # set start and stop freq for that band name - # # to be - def band_channel_bandwidth(self, band_node, units=""): """Get the channel bandwidth of the band node. @@ -951,14 +900,14 @@ def band_channel_bandwidth(self, band_node, units=""): ---------- band_node : Instance of the band node. units : str, optional - If ``None`` specified, global units are used. + If ``None`` specified, SI units (Hz) are used. Returns ------- Float Channel bandwidth of the band node.""" if not units or units not in emit_consts.EMIT_VALID_UNITS["Frequency"]: - units = self.units["Frequency"] + units = "Hz" return consts.unit_converter(float(band_node.props["ChannelBandwidth"]), "Freq", "Hz", units) def band_tx_power(self, band_node, units=""): @@ -968,14 +917,15 @@ def band_tx_power(self, band_node, units=""): ---------- band_node : Instance of the band node. units : str - Units to use for the tx power. + Units to use for the tx power. If none specified, + SI units (W) are used Returns ------- Float Transmit power of the band node.""" if not units or units not in emit_consts.EMIT_VALID_UNITS["Power"]: - units = self.units["Power"] + units = "W" for child in band_node.children: if child.props["Type"] == "TxSpectralProfNode": return consts.unit_converter(float(child.props["FundamentalAmplitude"]), "Power", "dBm", units) @@ -1104,7 +1054,7 @@ def set_band_power_level(self, power, units=""): power : float Peak amplitude of the fundamental [dBm]. units : str, optional - Units of the input power. If None specified, global units are used. + Units of the input power. If None specified, SI units (W) are used. Return ------ @@ -1114,7 +1064,7 @@ def set_band_power_level(self, power, units=""): raise TypeError(f"{self.node_name} must be a band.") # Need to store power in dBm if not units or units not in emit_consts.EMIT_VALID_UNITS["Power"]: - units = self.parent_component.units["Power"] + units = "W" power_string = f'{consts.unit_converter(power, "Power", units, "dBm")}' prop_list = {"FundamentalAmplitude": power_string} for child in self.children: @@ -1129,7 +1079,7 @@ def get_band_power_level(self, units=""): Parameters ---------- units : str, optional - Units to use for the power. If None specified, global units are used. + Units to use for the power. If None specified, SI units (W) are used. Return ------ @@ -1140,7 +1090,7 @@ def get_band_power_level(self, units=""): raise TypeError(f"{self.node_name} must be a band.") # Power is stored in dBm, convert to desired units if not units or units not in emit_consts.EMIT_VALID_UNITS["Power"]: - units = self.parent_component.units["Power"] + units = "W" for child in self.children: if child.props["Type"] == "TxSpectralProfNode": power = child.props["FundamentalAmplitude"] diff --git a/tests/system/solvers/test_26_emit.py b/tests/system/solvers/test_26_emit.py index 54e0baca9d2..d19fa38a8d4 100644 --- a/tests/system/solvers/test_26_emit.py +++ b/tests/system/solvers/test_26_emit.py @@ -22,10 +22,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from enum import Enum +import inspect + # Import required modules import os import sys import tempfile +import types from ansys.aedt.core.generic import constants as consts from ansys.aedt.core.generic.general_methods import is_linux @@ -44,6 +48,10 @@ from ansys.aedt.core.emit_core.emit_constants import InterfererType from ansys.aedt.core.emit_core.emit_constants import ResultType from ansys.aedt.core.emit_core.emit_constants import TxRxMode + from ansys.aedt.core.emit_core.nodes import generated + from ansys.aedt.core.emit_core.nodes.emit_node import EmitNode + from ansys.aedt.core.emit_core.nodes.generated import * + from ansys.aedt.core.emit_core.results.revision import Revision from ansys.aedt.core.modeler.circuits.primitives_emit import EmitAntennaComponent from ansys.aedt.core.modeler.circuits.primitives_emit import EmitComponent from ansys.aedt.core.modeler.circuits.primitives_emit import EmitComponents @@ -225,7 +233,7 @@ def test_04_radio_component(self, add_app): power = band.get_band_power_level("mW") assert power == 10000.0 # test frequency unit conversions - start_freq = radio.band_start_frequency(band) + start_freq = radio.band_start_frequency(band, "MHz") assert start_freq == 100.0 start_freq = radio.band_start_frequency(band, "Hz") assert start_freq == 100000000.0 @@ -275,7 +283,7 @@ def test_04_radio_component(self, add_app): assert "Frequency should be within 1Hz to 100 GHz." in str(e) # test power unit conversions - band_power = radio.band_tx_power(band) + band_power = radio.band_tx_power(band, "dBm") assert band_power == 40.0 band_power = radio.band_tx_power(band, "dBW") assert band_power == 10.0 @@ -335,7 +343,10 @@ def test_05_emit_power_conversion(self): bad_units = consts.unit_converter(power, "Power", "w", "dBm") assert bad_units == power - @pytest.mark.skipif(config["desktopVersion"] <= "2023.1", reason="Skipped on versions earlier than 2023 R2.") + @pytest.mark.skipif( + config["desktopVersion"] <= "2023.1" or config["desktopVersion"] > "2025.1", + reason="Skipped on versions earlier than 2023 R2 and later than 2025 R1.", + ) def test_06_units_getters(self, add_app): self.aedtapp = add_app(application=Emit) @@ -397,8 +408,8 @@ def test_07_antenna_component(self, add_app): assert position == (0.0, 0.0, 0.0) @pytest.mark.skipif( - config["desktopVersion"] <= "2023.1", - reason="Skipped on versions earlier than 2023.2", + (config["desktopVersion"] <= "2023.1") or (config["desktopVersion"] > "2025.1"), + reason="Skipped on versions earlier than 2023.2 or later than 2025.1", ) def test_08_revision_generation(self, add_app): self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) @@ -466,6 +477,43 @@ def test_08_revision_generation(self, add_app): rev6 = self.aedtapp.results.analyze() assert rev6.name == "Revision 16" + @pytest.mark.skipif( + config["desktopVersion"] < "2025.2", + reason="Skipped on versions earlier than 2025.2", + ) + def test_08b_revision_generation(self, add_app): + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) + assert len(self.aedtapp.results.revisions) == 0 + # place components and generate the appropriate number of revisions + rad1 = self.aedtapp.modeler.components.create_component("UE - Handheld") + ant1 = self.aedtapp.modeler.components.create_component("Antenna") + ant1.move_and_connect_to(rad1) + rad2 = self.aedtapp.modeler.components.create_component("Bluetooth") + ant2 = self.aedtapp.modeler.components.create_component("Antenna") + ant2.move_and_connect_to(rad2) + rad3 = self.aedtapp.modeler.components.create_component("Bluetooth") + ant3 = self.aedtapp.modeler.components.create_component("Antenna") + ant3.move_and_connect_to(rad3) + rev = self.aedtapp.results.analyze() + assert len(self.aedtapp.results.revisions) == 1 + assert rev.name == "Current" + self.aedtapp.results.analyze() + assert len(self.aedtapp.results.revisions) == 1 + rad4 = self.aedtapp.modeler.components.create_component("Bluetooth") + ant4 = self.aedtapp.modeler.components.create_component("Antenna") + ant4.move_and_connect_to(rad4) + rev2 = self.aedtapp.results.analyze() + assert len(self.aedtapp.results.revisions) == 1 + rad5 = self.aedtapp.modeler.components.create_component("HAVEQUICK Airborne") + ant5 = self.aedtapp.modeler.components.create_component("Antenna") + ant4.move_and_connect_to(rad5) + assert len(self.aedtapp.results.revisions) == 1 + assert rev2.name == "Current" + + # get the revision + rev3 = self.aedtapp.results.get_revision() + assert rev3.name == "Current" + @pytest.mark.skipif( config["desktopVersion"] <= "2023.1", reason="Skipped on versions earlier than 2023.2", @@ -493,12 +541,11 @@ def test_09_manual_revision_access_test_getters(self, add_app): bandsRX = rev.get_band_names(radiosRX[0], modeRx) assert bandsRX[0] == "Rx - Base Data Rate" assert bandsRX[1] == "Rx - Enhanced Data Rate" - rx_frequencies = rev.get_active_frequencies(radiosRX[0], bandsRX[0], modeRx) + rx_frequencies = rev.get_active_frequencies(radiosRX[0], bandsRX[0], modeRx, "MHz") assert rx_frequencies[0] == 2402.0 assert rx_frequencies[1] == 2403.0 # Change the units globally - self.aedtapp.set_units("Frequency", "GHz") - rx_frequencies = rev.get_active_frequencies(radiosRX[0], bandsRX[0], modeRx) + rx_frequencies = rev.get_active_frequencies(radiosRX[0], bandsRX[0], modeRx, "GHz") assert rx_frequencies[0] == 2.402 assert rx_frequencies[1] == 2.403 # Change the return units only @@ -518,14 +565,14 @@ def test_09_manual_revision_access_test_getters(self, add_app): sampling.set_channel_sampling("Random", max_channels=75) rev3 = self.aedtapp.results.analyze() - rx_frequencies = rev3.get_active_frequencies(radiosRX[1], bandsRX[0], modeRx) + rx_frequencies = rev3.get_active_frequencies(radiosRX[1], bandsRX[0], modeRx, "GHz") assert len(rx_frequencies) == 75 assert rx_frequencies[0] == 2.402 assert rx_frequencies[1] == 2.403 sampling.set_channel_sampling("Random", percentage=25, seed=100) rev4 = self.aedtapp.results.analyze() - rx_frequencies = rev4.get_active_frequencies(radiosRX[1], bandsRX[0], modeRx) + rx_frequencies = rev4.get_active_frequencies(radiosRX[1], bandsRX[0], modeRx, "GHz") assert len(rx_frequencies) == 19 assert rx_frequencies[0] == 2.402 assert rx_frequencies[1] == 2.411 @@ -744,8 +791,8 @@ def test_14_version(self, add_app): assert len(more_info) > len(less_info) @pytest.mark.skipif( - config["desktopVersion"] <= "2023.1", - reason="Skipped on versions earlier than 2023.2", + config["desktopVersion"] <= "2023.1" or config["desktopVersion"] > "2025.1", + reason="Skipped on versions earlier than 2023.2 or later than 2025.1", ) def test_15_basic_run(self, add_app): self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) @@ -882,8 +929,8 @@ def test_16_optimal_n_to_1_feature(self, add_app): assert instance.get_value(ResultType.EMI) == 76.02 @pytest.mark.skipif( - config["desktopVersion"] <= "2023.1", - reason="Skipped on versions earlier than 2023.2", + config["desktopVersion"] <= "2023.1" or config["desktopVersion"] > "2025.1", + reason="Skipped on versions earlier than 2023.2 or later than 2025.1", ) def test_17_availability_1_to_1(self, add_app): self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) @@ -1158,7 +1205,10 @@ def test_22_couplings(self, add_app): assert antenna_nodes[key].name == antenna_names[i] i += 1 - @pytest.mark.skipif(config["desktopVersion"] < "2024.1", reason="Skipped on versions earlier than 2024.1") + @pytest.mark.skipif( + config["desktopVersion"] < "2024.1" or config["desktopVersion"] > "2025.1", + reason="Skipped on versions earlier than 2024.1 or later than 2025.1", + ) def test_23_result_categories(self, add_app): # set up project and run self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) @@ -1205,6 +1255,56 @@ def test_23_result_categories(self, add_app): instance.get_largest_emi_problem_type() assert "An EMI value is not available so the largest EMI problem type is undefined." in str(e) + @pytest.mark.skipif(config["desktopVersion"] < "2025.2" or True, reason="Skipped on versions earlier than 2025.2") + def test_23b_result_categories(self, add_app): + # set up project and run + self.aedtapp = add_app(application=Emit, project_name=generate_unique_project_name()) + rad1 = self.aedtapp.modeler.components.create_component("GPS Receiver") + ant1 = self.aedtapp.modeler.components.create_component("Antenna") + ant1.move_and_connect_to(rad1) + for band in rad1.bands(): + band.enabled = True + rad2 = self.aedtapp.modeler.components.create_component("Bluetooth Low Energy (LE)") + ant2 = self.aedtapp.modeler.components.create_component("Antenna") + ant2.move_and_connect_to(rad2) + rev = self.aedtapp.results.analyze() + domain = self.aedtapp.results.interaction_domain() + interaction = rev.run(domain) + + result_categorization_node = rev.get_result_categorization_node() + category_props = [prop for prop in result_categorization_node.properties if prop.startswith("Cat")] + + # initially all categories are enabled + for category in category_props: + assert result_categorization_node._get_property(category) + + # confirm the emi value when all categories are enabled + instance = interaction.get_worst_instance(ResultType.EMI) + assert instance.get_value(ResultType.EMI) == 16.64 + assert instance.get_largest_emi_problem_type() == "In-Channel: Broadband" + + # disable one category and confirm the emi value changes + result_categorization_node._set_property("CatInChannelNoise", "false") + instance = interaction.get_worst_instance(ResultType.EMI) + assert instance.get_value(ResultType.EMI) == 2.0 + assert instance.get_largest_emi_problem_type() == "Out-of-Channel: Tx Fundamental" + + # disable another category and confirm the emi value changes + result_categorization_node._set_property("CatOutOfChannelFund", "false") + instance = interaction.get_worst_instance(ResultType.EMI) + assert instance.get_value(ResultType.EMI) == -58.0 + assert instance.get_largest_emi_problem_type() == "Out-of-Channel: Tx Harmonic/Spurious" + + # disable last existing category and confirm expected exceptions and error messages + result_categorization_node._set_property("CatOutOfChannelHarmSpur", "false") + instance = interaction.get_worst_instance(ResultType.EMI) + with pytest.raises(RuntimeError) as e: + instance.get_value(ResultType.EMI) + assert "Unable to evaluate value: No power received." in str(e) + with pytest.raises(RuntimeError) as e: + instance.get_largest_emi_problem_type() + assert "An EMI value is not available so the largest EMI problem type is undefined." in str(e) + @pytest.mark.skipif(config["desktopVersion"] < "2024.2", reason="Skipped on versions earlier than 2024 R2.") def test_24_license_session(self, add_app): self.aedtapp = add_app(project_name="interference", application=Emit, subfolder=TEST_SUBFOLDER) @@ -1213,8 +1313,6 @@ def test_24_license_session(self, add_app): results = self.aedtapp.results revision = self.aedtapp.results.analyze() - self.aedtapp.set_units("Frequency", "GHz") - def do_run(): domain = results.interaction_domain() rev = results.current_revision @@ -1293,3 +1391,232 @@ def count_license_actions(license_file_path): expected_checkins = checkins_per_run * (number_of_runs + 1) assert checkouts == expected_checkouts and checkins == expected_checkins + + @pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025 R2.") + def test_25_emit_nodes(self, add_app): + self.aedtapp = add_app(project_name="interference", application=Emit, subfolder=TEST_SUBFOLDER) + + # Generate and run a revision + results = self.aedtapp.results + revision = self.aedtapp.results.analyze() + + domain = results.interaction_domain() + interaction = revision.run(domain) + + nodes = revision.get_all_nodes() + assert len(nodes) > 0 + + # Test various properties of the Scene node + scene_node = revision.get_scene_node() + assert scene_node + + assert scene_node.valid + assert scene_node.name + + assert scene_node.properties + + assert len(scene_node.allowed_child_types) > 0 + + assert not scene_node._is_component + + assert scene_node == scene_node + + @pytest.mark.skipif(config["desktopVersion"] < "2025.2", reason="Skipped on versions earlier than 2025 R2.") + def test_26_all_generated_emit_node_properties(self, add_app): + # Define enum for result types + class Result(Enum): + SKIPPED = 0 + VALUE = 1 + EXCEPTION = 2 + NEEDS_PARAMETERS = 3 + + def get_value_for_parameter(arg_type, docstring): + value = None + + if arg_type in (int, float): + value = 0 + + # If there's a min or max in the docstring, use it. + if docstring: + if "between" in docstring: + min_val = float(docstring.split("between")[1].split("and")[0].strip()) + max_val = float(docstring.split("and")[1].split(".")[0].strip()) + value = min_val + elif "less than" in docstring: + max_val = float(docstring.split("less than")[1].split(".")[0].strip()) + value = max_val + elif "greater than" in docstring: + min_val = float(docstring.split("greater than")[1].split(".")[0].strip()) + value = min_val + elif arg_type == str: + value = "TestString" + elif arg_type == bool: + value = True + elif isinstance(arg_type, type) and issubclass(arg_type, Enum): + # Type is an Enum + first_enum_value = list(arg_type.__members__.values())[0] + value = first_enum_value + elif isinstance(arg_type, types.UnionType): + # Type is a Union + possible_arg_types = arg_type.__args__ + if int in possible_arg_types or float in possible_arg_types: + value = 0 + + return value + + def test_all_members(node, results, results_of_get_props): + # Dynamically get list of properties and methods + members = dir(node) + + for member in members: + key = f"{type(node).__name__}.{member}" + + try: + if member.startswith("_"): + results[key] = (Result.SKIPPED, "Skipping private member") + continue + + if member.startswith("delete"): + results[key] = (Result.SKIPPED, "Skipping delete method") + continue + + if member.startswith("rename"): + results[key] = (Result.SKIPPED, "Skipping rename method") + continue + + class_attr = getattr(node.__class__, member) + if isinstance(class_attr, property): + # Member is a property + + has_fget = class_attr.fget is not None + has_fset = class_attr.fset is not None + + if has_fget and has_fset: + arg_type = class_attr.fset.__annotations__["value"] + docstring = class_attr.fset.__doc__ + + value = get_value_for_parameter(arg_type, docstring) + + # If value is None here, we failed to find a suitable value to call the setter with. + # Just call the getter, and put that in the results. + if value is not None: + class_attr.fset(node, value) + + result = class_attr.fget(node) + + if value: + assert value == result + + results[key] = (Result.VALUE, result) + results_of_get_props[class_attr] = result + elif has_fget: + result = class_attr.fget(node) + results[key] = (Result.VALUE, result) + results_of_get_props[class_attr] = result + else: + attr = getattr(node, member) + + if inspect.ismethod(attr) or inspect.isfunction(attr): + # Member is a function + signature = inspect.signature(attr) + + values = [] + bad_param = None + for parameter in signature.parameters: + arg_type = type(parameter) + docstring = attr.__doc__ + + value = get_value_for_parameter(arg_type, docstring) + if value is not None: + values.append(value) + else: + bad_param = parameter + break + + if len(values) == len(signature.parameters): + result = attr(*values) + results[key] = (Result.VALUE, result) + else: + results[key] = ( + Result.NEEDS_PARAMETERS, + f'Could not find valid value for parameter "{bad_param}".', + ) + else: + results[key] = (Result.VALUE, attr) + except Exception as e: + results[key] = (Result.EXCEPTION, f"{e}") + + def test_nodes_from_top_level(nodes, nodes_tested, results, results_of_get_props): + # Test every method on every node, but add node children to list while iterating + for node in nodes: + node_type = type(node).__name__ + if node_type not in nodes_tested: + nodes_tested.append(node_type) + + # Add any untested child nodes + for child_type in node.allowed_child_types: + # Skip any nodes that end in ..., as they open a dialog + if child_type not in nodes_tested and not child_type.endswith("..."): + node._add_child_node(child_type) + + nodes.extend(node.children) + + test_all_members(node, results, results_of_get_props) + + self.aedtapp = add_app(project_name="interference", application=Emit, subfolder=TEST_SUBFOLDER) + + # Add some components + self.aedtapp.modeler.components.create_component("Antenna", "TestAntenna") + self.aedtapp.modeler.components.create_component("New Emitter", "TestEmitter") + self.aedtapp.modeler.components.create_component("Amplifier", "TestAmplifier") + self.aedtapp.modeler.components.create_component("Cable", "TestCable") + self.aedtapp.modeler.components.create_component("Circulator", "TestCirculator") + self.aedtapp.modeler.components.create_component("Divider", "TestDivider") + self.aedtapp.modeler.components.create_component("Band Pass", "TestBPF") + self.aedtapp.modeler.components.create_component("Band Stop", "TestBSF") + self.aedtapp.modeler.components.create_component("File-based", "TestFilterByFile") + self.aedtapp.modeler.components.create_component("High Pass", "TestHPF") + self.aedtapp.modeler.components.create_component("Low Pass", "TestLPF") + self.aedtapp.modeler.components.create_component("Tunable Band Pass", "TestTBPF") + self.aedtapp.modeler.components.create_component("Tunable Band Stop", "TestTBSF") + self.aedtapp.modeler.components.create_component("Isolator", "TestIsolator") + self.aedtapp.modeler.components.create_component("TR Switch", "TestSwitch") + self.aedtapp.modeler.components.create_component("Terminator", "TestTerminator") + self.aedtapp.modeler.components.create_component("3 Port", "Test3port") + + # Generate and run a revision + results = self.aedtapp.results + revision = self.aedtapp.results.analyze() + + domain = results.interaction_domain() + revision.run(domain) + + results_dict = {} + results_of_get_props = {} + nodes_tested = [] + + test_nodes_from_top_level(revision.get_all_nodes(), nodes_tested, results_dict, results_of_get_props) + + kept_result_name = self.aedtapp.odesign.KeepResult() + # kept_result_directory = self.aedtapp.odesign.GetResultDirectory(kept_result_name) + # kept_revision = Revision(results, results.emit_project, kept_result_directory) + + kept_revision = results.get_revision(kept_result_name) + + readonly_results_dict = {} + readonly_results_of_get_props = {} + test_nodes_from_top_level( + kept_revision.get_all_nodes(), nodes_tested, readonly_results_dict, readonly_results_of_get_props + ) + + # Categorize results from all node member calls + results_by_type = {Result.SKIPPED: {}, Result.VALUE: {}, Result.EXCEPTION: {}, Result.NEEDS_PARAMETERS: {}} + + for key, value in results_dict.items(): + results_by_type[value[0]][key] = value[1] + + # Verify we tested most of the generated nodes + all_nodes = generated.__all__ + nodes_untested = [node for node in all_nodes if (node not in nodes_tested)] + + assert len(nodes_tested) > len(nodes_untested)