cosapp.ports.port

Classes

BasePort(name, direction)

Base class for ports, containers gathering variables.

ExtensiblePort(name, direction)

Class describing ports with a varying number of variables.

ModeVarPort(name, direction)

Class used for the local storage of mode variables.

Port(name, direction[, variables])

A Port is a container gathering variables tightly linked.

class cosapp.ports.port.BasePort(name: str, direction: PortType)[source]

Bases: Component

Base class for ports, containers gathering variables.

Common users should not use this class directly.

Parameters:
  • name (str) – Port name

  • direction ({PortType.IN, PortType.OUT}) – Port direction

accept(visitor: Visitor) None[source]

Specifies course of action when visited by visitor

add_variable(name: str, value: Any = 1, unit: str = '', dtype: Any | Tuple[Any, ...] | None = None, valid_range: Tuple[Any, Any] | None = None, invalid_comment: str = '', limits: Tuple[Any, Any] | None = None, out_of_limits_comment: str = '', desc: str = '', distribution: Distribution | None = None, scope: Scope = Scope.PRIVATE) None[source]

Add a variable to the port.

The valid_range defines the range of value for which a model is known to behave correctly. The limits are at least as large as the validity range.

Parameters:
  • name (str) – Name of the variable

  • value (Any, optional) – Value of the variable; default 1

  • unit (str, optional) – Variable unit; default empty string (i.e. dimensionless)

  • dtype (type or iterable of type, optional) – Variable type; default None (i.e. type of initial value)

  • valid_range (Tuple[Any, Any] or Tuple[Tuple], optional) – Validity range of the variable; default None (i.e. all values are valid)

  • invalid_comment (str, optional) – Comment to show in case the value is not valid; default ‘’

  • limits (Tuple[Any, Any] or Tuple[Tuple], optional) – Limits over which the use of the model is wrong; default valid_range

  • out_of_limits_comment (str, optional) – Comment to show in case the value is not valid; default ‘’

  • desc (str, optional) – Variable description; default ‘’

  • distribution (Distribution, optional) – Probability distribution of the variable; default None (no distribution)

  • scope (Scope {PRIVATE, PROTECTED, PUBLIC}, optional) – Variable visibility; default PRIVATE

check(name: str | None = None) Dict[str, Validity] | Validity[source]

Get the variable value validity.

If name is not provided, returns a dictionary with the validity of all variables. Else only, the validity for the given variable will be returned.

Parameters:

name (str, optional) – Variable name; default None = All variables will be tested

Returns:

(Dictionary of) the variable(s) value validity

Return type:

Dict[str, Validity] or Validity

property contextual_name: str

Join port owner name and port name.

If the port has no owner, the port name is returned.

Type:

str

copy(name: str | None = None, direction: PortType | None = None)[source]

Duplicates the port.

Parameters:
  • name (str, optional) – Name of the duplicated port; default original port name

  • direction ({PortType.IN, PortType.OUT}, optional) – Direction of the duplicated port; default original direction

Returns:

The copy of the current port

Return type:

Port

copy_variable_from(port: BasePort, name: str, alias: str | None = None) None[source]

Copy variable name from another port into variable alias.

Parameters:
  • port (BasePort) – Port from which variable is copied

  • name (str) – Variable name from source port.

  • alias (str, optional) – Variable name in current port (same as name if not specified).

property description: str

Port description

Type:

str

property direction: PortType

Port direction

Type:

PortType.IN or PortType.OUT

full_name(trim_root=False) str[source]

Returns full name up to root owner.

Parameters:

trim_root (bool (optional, default False)) – Exclude root owner name if True.

Returns:

The port full name

Return type:

str

get_details(name: str | None = None) Dict[str, BaseVariable] | BaseVariable[source]

Return the variable(s).

Parameters:

name (str, optional) – Name of the variable looked for; default None (all variable are returned).

Returns:

The sought variable, or a read-only view on all port variables.

Return type:

types.MappingProxyType[str, cosapp.ports.variable.Variable] or cosapp.ports.variable.Variable

get_validity_ground(status: Validity, name: str | None = None) Dict[str, str] | str[source]

Get the ground arguments used to established the variable validity range.

The status Validity.OK has no ground arguments.

Parameters:
  • status (Validity.{OK, WARNING, ERROR}) – Validity status for which the reasons are looked for.

  • name (str, optional) – Variable name; default None = All variables will be tested

Returns:

(Dictionary of) the variable(s) validity ground

Return type:

Dict[str, str] or str

property is_clean: bool
property is_input: bool

True if port is an input, False otherwise.

Type:

bool

property is_output: bool

True if port is an output, False otherwise.

Type:

bool

items() Generator[Tuple[str, Any], None, None][source]

Dictionary-like item generator yielding (name, value) tuples for all port variables.

morph(port: BasePort) None[source]

Morph the provided port into this port.

Morphing a port is useful when converting a System in something equivalent. The morphing goal is to preserve connections and adapt the port content if needed.

Parameters:

port (BasePort) – The port to morph to

property name: str

Port name

Type:

str

out_of_scope(name: str) bool[source]

Asserts if current scope scope_clearance is high enough to allow the modification of port variable name.

Parameters:

name (str) – Variable name to test

Returns:

  • bool – Is modification forbidden?

  • The behavior of this function is set by method scope_clearance().

  • By default, clearance level is set to Scope.PUBLIC.

Examples

>>> port = Port("myPort", PortType.IN)
>>> port.add_variable("x", 1.5, scope=Scope.PUBLIC)
>>> port.add_variable("y", 0.2, scope=Scope.PROTECTED)
>>> port.add_variable("z", 0.3, scope=Scope.PRIVATE)
>>>
>>> port.scope_clearance(Scope.PROTECTED)  # only `port.x` and `port.y` can be modified
>>> assert not port.out_of_scope("x")
>>> assert not port.out_of_scope("y")
>>> assert port.out_of_scope("z")
>>>
>>> port.scope_clearance(Scope.PUBLIC)     # only `port.x` can be modified
>>> assert not port.out_of_scope("x")
>>> assert port.out_of_scope("y")
>>> assert port.out_of_scope("z")
property owner: cosapp.systems.System | None

System owning the port.

Type:

System

property scope_clearance: Scope

Current clearance level of the port. Determines the set of read-only port variables.

Type:

Scope

serialize_data() Dict[str, Any][source]

Serialize the variable values in a dictionary.

Returns:

The dictionary (variable name, value)

Return type:

Dict[str, Any]

set_clean() None[source]

Set port as ‘clean’.

static set_type_checking(activate: bool) None[source]

(Un)set type checking when affecting port variables.

By default type checking is activated.

Parameters:

activate (bool) – True to activate type checking, False to deactivate

set_values(**modifications) None[source]

Generic setter for port variable values, offering a convenient way of modifying multiple variables at once.

Parameters:

**modifications:

Variable names and values given as keyword arguments.

Examples:

>>> from cosapp.base import Port, System
>>>
>>> class DummyPort(Port):
>>>     def setup(self):
>>>         self.add_variable('a')
>>>         self.add_variable('b')
>>>
>>> class DummySystem(System):
>>>     def setup(self):
>>>         self.add_input(DummyPort, 'p_in')
>>>         self.add_output(DummyPort, 'p_out')
>>>
>>>     def compute(self):
>>>         p_in = self.p_in
>>>         self.p_out.set_values(
>>>             a = p_in.b,
>>>             b = p_in.a - p_in.b,
>>>         )
to_dict(with_def: bool = False) Dict[str, str | Tuple[Dict[str, str], str]][source]

Convert this port in a dictionary.

Parameters:

with_def (bool) – Flag to export also output ports and its class name (default: False).

Returns:

The dictionary representing this port.

Return type:

dict

touch() None[source]

Set port as ‘dirty’.

validate(key: str, value: Any) None[source]

Check if a variable is in the scope of the user and the type is valid.

Parameters:
  • key (str) – Name of the variable to test

  • value (Any) – Value to validate

Raises:
  • ScopeError – If the variable is not visible for the user

  • TypeError – If the value has an unauthorized type

variables() Iterator[BaseVariable][source]

Iterator over port BaseVariable instances.

class cosapp.ports.port.ExtensiblePort(name: str, direction: PortType)[source]

Bases: BasePort

Class describing ports with a varying number of variables.

remove_variable(name: str) None[source]

Removes a variable from the port.

Parameters:

name (str) – Name of the variable to be removed

Raises:

AttributeError – If the variable does not exists

class cosapp.ports.port.ModeVarPort(name: str, direction: PortType)[source]

Bases: BasePort

Class used for the local storage of mode variables.

add_mode_variable(name: str, value: Any | None = None, unit: str = '', dtype: Any | Tuple[Any, ...] | None = None, desc: str = '', init: Any | None = None, scope: Scope = Scope.PRIVATE) None[source]

Add a mode variable to the port.

Parameters:
  • name (str) – Name of the variable

  • value (Any, optional) – Value of the variable; default 1

  • unit (str, optional) – Variable unit; default empty string (i.e. dimensionless)

  • dtype (type or iterable of type, optional) – Variable type; default None (i.e. type of initial value)

  • desc (str, optional) – Variable description; default ‘’

  • scope (Scope {PRIVATE, PROTECTED, PUBLIC}, optional) – Variable visibility; default PRIVATE

class cosapp.ports.port.Port(name: str, direction: PortType, variables: Dict[str, Any] | None = None)[source]

Bases: BasePort

A Port is a container gathering variables tightly linked.

An optional dictionary may be specified to overwrite variable value and some of their metadata. Values of the dictionary may be of two kinds: - Only the new value - A dictionary with new value and/or new details

If the value or a metadata is set to None, the default value will be kept.

Parameters:
  • name (str) – Port name

  • direction ({PortType.IN, PortType.OUT}) – Port direction

  • variables (Dict[str, Any], optional) – Dictionary of variables with their value and details; default: None = default value

_locked

if True, add_variable is deactivated. This is the default behavior outside the setup function.

Type:

bool

Examples

Use this class by subclassing it:

>>> class FlowPort(Port):
>>>     def setup(self):
>>>         self.add_variable('Pt', 101325., unit='Pa')
>>>         self.add_variable('Tt', 273.15, unit='K')
>>>         self.add_variable('W', 1.0, unit='kg/s')
>>>
>>> p = FlowPort('myPort', PortType.IN)
>>> # Overwrite value and some details
>>> f = FlowPort(
>>>     'myPort2',
>>>     PortType.OUT,
>>>     {
>>>         'Pt': 10e6,
>>>         'W': {
>>>             'value': 10.,  # New value
>>>             'unit': 'lbm/s',  # New unit - should be compatible of the original one
>>>             'valid_range': (0., None),  # Updated validated range
>>>             'invalid_comment': 'Flow should be positive',  # Comment if out of validated range
>>>             'limits': None,  # Limits
>>>             'out_of_limits_comment': '',  # Comment if out of limits
>>>         }
>>>     }
>>> )
add_variable(name: str, value: Any = 1, unit: str = '', dtype: Any | Tuple[Any, ...] | None = None, valid_range: Tuple[Any, Any] | None = None, invalid_comment: str = '', limits: Tuple[Any, Any] | None = None, out_of_limits_comment: str = '', desc: str = '', distribution: Distribution | None = None, scope=Scope.PUBLIC) None[source]

Add a variable to the port.

The valid_range defines the range of value for which a model is known to behave correctly. The limits are at least as large as the validity range.

Notes

The default visibility of a Port variable is Scope.PUBLIC. This is a difference compared to BasePort.

Parameters:
  • name (str) – Name of the variable

  • value (Any, optional) – Value of the variable; default 1

  • unit (str, optional) – Variable unit; default empty string (i.e. dimensionless)

  • dtype (type or iterable of type, optional) – Variable type; default None (i.e. type of initial value)

  • valid_range (Tuple[Any, Any] or Tuple[Tuple], optional) – Validity range of the variable; default None (i.e. all values are valid)

  • invalid_comment (str, optional) – Comment to show in case the value is not valid; default ‘’

  • limits (Tuple[Any, Any] or Tuple[Tuple], optional) – Limits over which the use of the model is wrong; default valid_range

  • out_of_limits_comment (str, optional) – Comment to show in case the value is not valid; default ‘’

  • desc (str, optional) – Variable description; default ‘’

  • distribution (Distribution, optional) – Probability distribution of the variable; default None (no distribution)

  • scope (Scope {PRIVATE, PROTECTED, PUBLIC}, optional) – Variable visibility; default PUBLIC

copy(name: str | None = None, direction: PortType | None = None)[source]

Duplicates the port.

Parameters:
  • name (str, optional) – Name of the duplicated port; default original port name

  • direction ({PortType.IN, PortType.OUT}, optional) – Direction of the duplicated port; default original direction

Returns:

The copy of the current port

Return type:

Port

set_from(source: ~cosapp.ports.port.BasePort, transfer: ~typing.Callable[[~cosapp.ports.port.T], ~cosapp.ports.port.T] = <function Port.<lambda>>, check_names: bool = True) None[source]

Set values from another port.

Parameters:

  • source [BasePort]:

    Source port.

  • transfer [Callable[[T], T], optional]:

    Transfer function to pass values. By default, transfer is the identity function, which corresponds to plain assignment target.var = source.var. Copies can be performed by setting transfer = copy.copy, e.g.

  • check_names [bool, optional]:

    If True (default), figure out common variables before transfering values. If current and source ports are of the same type, no check is performed.

Examples:

>>> from cosapp.base import Port, System
>>> import copy
>>>
>>> class DummyPort(Port):
>>>     def setup(self):
>>>         self.add_variable('a')
>>>         self.add_variable('b')
>>>
>>> class DummySystem(System):
>>>     def setup(self):
>>>         self.add_inward('a')
>>>         self.add_inward('x')
>>>         self.add_input(DummyPort, 'p_in')
>>>         self.add_output(DummyPort, 'p_out')
>>>
>>>     def compute(self):
>>>         self.p_out.set_from(self.p_in)     # peer-to-peer: no check
>>>         self.p_out.set_from(self.inwards)  # will transfer `self.a`
>>>         # Peer-to-peer, with deepcopy:
>>>         self.p_out.set_from(self.p_in, copy.deepcopy)
>>>         # Transfer `inwards` into `p_out`, with no name check:
>>>         # raises AttributeError, as `DummyPort` has no variable `x`
>>>         self.p_out.set_from(
>>>             self.inwards,
>>>             check_names=False,
>>>         )
setup() None[source]

Port variables are defined in this function by calling add_variable.

This function allows to populate a customized Port class. The add_variable function is only callable in the frame of this function.

Examples

Here is an example of Port subclassing:

>>> class FlowPort(Port):
>>>     def setup(self):
>>>         self.add_variable('Pt', 101325.)
>>>         self.add_variable('Tt', 273.15)
>>>         self.add_variable('W', 1.0)