cosapp.ports.port¶
Classes
|
Base class for ports, containers gathering variables. |
|
Class describing ports with a varying number of variables. |
|
Class used for the local storage of mode 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
- 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.
- 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:
- 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
- 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 scope_clearance: Scope¶
Current clearance level of the port. Determines the set of read-only port variables.
- Type:
- serialize_data() Dict[str, Any] [source]¶
Serialize the variable values in a dictionary.
- Returns:
The dictionary (variable name, value)
- Return type:
Dict[str, Any]
- 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
- 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.
- 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:
- 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)