plaid.containers.sample ======================= .. py:module:: plaid.containers.sample .. autoapi-nested-parse:: Implementation of the `Sample` container. Attributes ---------- .. autoapisummary:: plaid.containers.sample.Self Classes ------- .. autoapisummary:: plaid.containers.sample.Sample Module Contents --------------- .. py:data:: Self .. py:class:: Sample(/, **data: Any) Bases: :py:obj:`pydantic.BaseModel` Represents a single sample. It contains data and information related to a single observation or measurement within a dataset. By default, the sample is empty but: - You can provide a path to a folder containing the sample data, and it will be loaded during initialization. - You can provide `SampleMeshes` and `SampleScalars` instances to initialize the sample with existing data. - You can also provide a dictionary of time series data. The default `SampleMeshes` instance is initialized with: - `meshes=None`, `links=None`, and `paths=None` (i.e., no mesh data). - `mesh_base_name="Base"` and `mesh_zone_name="Zone"`. The default `SampleScalars` instance is initialized with: - `scalars=None` (i.e., no scalar data). Create a new model by parsing and validating input data from keyword arguments. Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model. `self` is explicitly positional-only to allow `self` as a field name. .. py:attribute:: model_config Configuration for the model, should be a dictionary conforming to [`ConfigDict`][pydantic.config.ConfigDict]. .. py:attribute:: path :type: Optional[Union[str, pathlib.Path]] :value: None .. py:attribute:: meshes :type: Optional[plaid.containers.features.SampleMeshes] :value: None .. py:attribute:: scalars :type: Optional[plaid.containers.features.SampleScalars] :value: None .. py:attribute:: time_series :type: Optional[dict[str, plaid.types.TimeSeries]] :value: None .. py:attribute:: _extra_data :type: Optional[dict] :value: None .. py:method:: model_post_init(_context: Any) -> None Post-initialization processing for the Sample model. .. py:method:: copy() -> Self Create a deep copy of the current `Sample` instance. Usage of `model_copy(deep=True)` from Pydantic to ensure all internal data is deeply copied. :returns: A new `Sample` instance with all internal data (scalars, time series, fields, meshes, etc.) deeply copied to ensure full isolation from the original. .. note:: This operation may be memory-intensive for large samples. .. py:method:: get_scalar(name: str) -> Optional[plaid.types.Scalar] Retrieve a scalar value associated with the given name. :param name: The name of the scalar value to retrieve. :type name: str :returns: The scalar value associated with the given name, or None if the name is not found. :rtype: Scalar or None .. py:method:: add_scalar(name: str, value: plaid.types.Scalar) -> None Add a scalar value to a dictionary. :param name: The name of the scalar value. :type name: str :param value: The scalar value to add or update in the dictionary. :type value: Scalar .. py:method:: del_scalar(name: str) -> plaid.types.Scalar Delete a scalar value from the dictionary. :param name: The name of the scalar value to be deleted. :type name: str :raises KeyError: Raised when there is no scalar / there is no scalar with the provided name. :returns: The value of the deleted scalar. :rtype: Scalar .. py:method:: get_scalar_names() -> list[str] Get a set of scalar names available in the object. :returns: A set containing the names of the available scalars. :rtype: list[str] .. py:method:: get_mesh(time: Optional[float] = None, apply_links: bool = False, in_memory=False) -> Optional[plaid.types.CGNSTree] Retrieve the CGNS tree structure for a specified time step, if available. :param time: The time step for which to retrieve the CGNS tree structure. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :param apply_links: Activates the following of the CGNS links to reconstruct the complete CGNS tree - in this case, a deepcopy of the tree is made to prevent from modifying the existing tree. :type apply_links: bool, optional :param in_memory: Active if apply_links == True, ONLY WORKING if linked mesh is in the current sample. This option follows the link in memory from current sample. :type in_memory: bool, optional :returns: The CGNS tree structure for the specified time step if available; otherwise, returns None. :rtype: CGNSTree .. py:method:: set_default_base(base_name: str, time: Optional[float] = None) -> None Set the default base for the specified time (that will also be set as default if provided). The default base is a reference point for various operations in the system. :param base_name: The name of the base to be set as the default. :type base_name: str :param time: The time at which the base should be set as default. If not provided, the default base and active zone will be set with the default time. :type time: float, optional :raises ValueError: If the specified base does not exist at the given time. .. note:: - Setting the default base and is important for synchronizing operations with a specific base in the system's data. - The available mesh base can be obtained using the `get_base_names` method. .. rubric:: Example .. code-block:: python from plaid import Sample sample = Sample("path_to_plaid_sample") print(sample) >>> Sample(2 scalars, 1 timestamp, 5 fields) print(sample.get_physical_dim("BaseA", 0.5)) >>> 3 # Set "BaseA" as the default base for the default time sample.set_default_base("BaseA") # You can now use class functions with "BaseA" as default base print(sample.get_physical_dim(0.5)) >>> 3 # Set "BaseB" as the default base for a specific time sample.set_default_base("BaseB", 0.5) # You can now use class functions with "BaseB" as default base and 0.5 as default time print(sample.get_physical_dim()) # Physical dim of the base "BaseB" >>> 3 .. py:method:: set_default_zone_base(zone_name: str, base_name: str, time: Optional[float] = None) -> None Set the default base and active zone for the specified time (that will also be set as default if provided). The default base and active zone serve as reference points for various operations in the system. :param zone_name: The name of the zone to be set as the active zone. :type zone_name: str :param base_name: The name of the base to be set as the default. :type base_name: str :param time: The time at which the base and zone should be set as default. If not provided, the default base and active zone will be set with the default time. :type time: float, optional :raises ValueError: If the specified base or zone does not exist at the given time .. note:: - Setting the default base and zone are important for synchronizing operations with a specific base/zone in the system's data. - The available mesh bases and zones can be obtained using the `get_base_names` and `get_base_zones` methods, respectively. .. rubric:: Example .. code-block:: python from plaid import Sample sample = Sample("path_to_plaid_sample") print(sample) >>> Sample(2 scalars, 1 timestamp, 5 fields) print(sample.get_zone_type("ZoneX", "BaseA", 0.5)) >>> Structured # Set "BaseA" as the default base and "ZoneX" as the active zone for the default time sample.set_default_zone_base("ZoneX", "BaseA") # You can now use class functions with "BaseA" as default base with "ZoneX" as default zone print(sample.get_zone_type(0.5)) # type of the zone "ZoneX" of base "BaseA" >>> Structured # Set "BaseB" as the default base and "ZoneY" as the active zone for a specific time sample.set_default_zone_base("ZoneY", "BaseB", 0.5) # You can now use class functions with "BaseB" as default base with "ZoneY" as default zone and 0.5 as default time print(sample.get_zone_type()) # type of the zone "ZoneY" of base "BaseB" at 0.5 >>> Unstructured .. py:method:: init_base(topological_dim: int, physical_dim: int, base_name: Optional[str] = None, time: Optional[float] = None) -> plaid.types.CGNSNode Create a Base node named `base_name` if it doesn't already exists. :param topological_dim: Cell dimension, see [CGNS standard](https://pycgns.github.io/PAT/lib.html#CGNS.PAT.cgnslib.newCGNSBase). :type topological_dim: int :param physical_dim: Ambient space dimension, see [CGNS standard](https://pycgns.github.io/PAT/lib.html#CGNS.PAT.cgnslib.newCGNSBase). :type physical_dim: int :param base_name: If not specified, uses `mesh_base_name` specified in Sample initialization. Defaults to None. :type base_name: str :param time: The time at which to initialize the base. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :returns: The created Base node. :rtype: CGNSNode .. py:method:: init_zone(zone_shape: numpy.ndarray, zone_type: str = CGK.Unstructured_s, zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None) -> plaid.types.CGNSNode Initialize a new zone within a CGNS base. :param zone_shape: An array specifying the shape or dimensions of the zone. :type zone_shape: np.ndarray :param zone_type: The type of the zone. Defaults to CGK.Unstructured_s. :type zone_type: str, optional :param zone_name: The name of the zone to initialize. If not provided, uses `mesh_zone_name` specified in Sample initialization. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base to which the zone will be added. If not provided, the zone will be added to the currently active base. Defaults to None. :type base_name: str, optional :param time: The time at which to initialize the zone. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :raises KeyError: If the specified base does not exist. You can create a base using `Sample.init_base(base_name)`. :returns: The newly initialized zone node within the CGNS tree. :rtype: CGLNode .. py:method:: set_default_time(time: float) -> None Set the default time for the system. This function sets the default time to be used for various operations in the system. :param time: The time value to be set as the default. :type time: float :raises ValueError: If the specified time does not exist in the available mesh times. .. note:: - Setting the default time is important for synchronizing operations with a specific time point in the system's data. - The available mesh times can be obtained using the `get_all_mesh_times` method. .. rubric:: Example .. code-block:: python from plaid import Sample sample = Sample("path_to_plaid_sample") print(sample) >>> Sample(2 scalars, 1 timestamp, 5 fields) print(sample.show_tree(0.5)) >>> ... # Set the default time to 0.5 seconds sample.set_default_time(0.5) # You can now use class functions with 0.5 as default time print(sample.show_tree()) # show the cgns tree at the time 0.5 >>> ... .. py:method:: get_field_names(location: str = None, zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None) -> list[str] Get a set of field names associated with a specified zone, base, location, and time. :param location: The desired grid location where the field is defined. Defaults to None. Possible values : :py:const:`plaid.constants.CGNS_FIELD_LOCATIONS` :type location: str, optional :param zone_name: The name of the zone to search for. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base to search for. Defaults to None. :type base_name: str, optional :param time: The specific time at which to retrieve field names. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :returns: A set containing the names of the fields that match the specified criteria. :rtype: set[str] .. py:method:: link_tree(path_linked_sample: Union[str, pathlib.Path], linked_sample: Sample, linked_time: float, time: float) -> plaid.types.CGNSTree Link the geometrical features of the CGNS tree of the current sample at a given time, to the ones of another sample. :param path_linked_sample: The absolute path of the folder containing the linked CGNS :type path_linked_sample: Union[str,Path] :param linked_sample: The linked sample :type linked_sample: Sample :param linked_time: The time step of the linked CGNS in the linked sample :type linked_time: float :param time: The time step the current sample to which the CGNS tree is linked. :type time: float :returns: The deleted CGNS tree. :rtype: CGNSTree .. py:method:: show_tree(time: Optional[float] = None) -> None Display the structure of the CGNS tree for a specified time. :param time: The time step for which you want to display the CGNS tree structure. Defaults to None. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional .. rubric:: Examples .. code-block:: python # To display the CGNS tree structure for the default time step: sample.show_tree() # To display the CGNS tree structure for a specific time step: sample.show_tree(0.5) .. py:method:: add_field(name: str, field: plaid.types.Field, location: str = 'Vertex', zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None, warning_overwrite=True) -> None Add a field to a specified zone in the grid. :param name: The name of the field to be added. :type name: str :param field: The field data to be added. :type field: Field :param zone_name: The name of the zone where the field will be added. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base where the zone is located. Defaults to None. :type base_name: str, optional :param location: The grid location where the field will be stored. Defaults to 'Vertex'. Possible values : :py:const:`plaid.constants.CGNS_FIELD_LOCATIONS` :type location: str, optional :param time: The time associated with the field. Defaults to 0. :type time: float, optional :param warning_overwrite: Show warning if an preexisting field is being overwritten :type warning_overwrite: bool, optional :raises KeyError: Raised if the specified zone does not exist in the given base. .. py:method:: get_field(name: str, location: str = 'Vertex', zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None) -> plaid.types.Field Retrieve a field with a specified name from a given zone, base, location, and time. :param name: The name of the field to retrieve. :type name: str :param location: The location at which to retrieve the field. Defaults to 'Vertex'. Possible values : :py:const:`plaid.constants.CGNS_FIELD_LOCATIONS` :type location: str, optional :param zone_name: The name of the zone to search for. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base to search for. Defaults to None. :type base_name: str, optional :param time: The time value to consider when searching for the field. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :returns: A set containing the names of the fields that match the specified criteria. :rtype: Field .. py:method:: del_field(name: str, location: str = 'Vertex', zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None) -> plaid.types.CGNSTree Delete a field from a specified zone in the grid. :param name: The name of the field to be deleted. :type name: str :param location: The grid location where the field is stored. Defaults to 'Vertex'. Possible values : :py:const:`plaid.constants.CGNS_FIELD_LOCATIONS` :type location: str, optional :param zone_name: The name of the zone from which the field will be deleted. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base where the zone is located. Defaults to None. :type base_name: str, optional :param time: The time associated with the field. Defaults to 0. :type time: float, optional :raises KeyError: Raised if the specified zone or field does not exist in the given base. :returns: The tree at the provided time (without the deleted node) :rtype: CGNSTree .. py:method:: get_nodes(zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None) -> Optional[numpy.ndarray] Get grid node coordinates from a specified base, zone, and time. :param zone_name: The name of the zone to search for. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base to search for. Defaults to None. :type base_name: str, optional :param time: The time value to consider when searching for the zone. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :raises TypeError: Raised if multiple nodes are found. Only one is expected. :returns: A NumPy array containing the grid node coordinates. If no matching zone or grid coordinates are found, None is returned. :rtype: Optional[np.ndarray] Seealso: This function can also be called using `get_points()` or `get_vertices()`. .. py:method:: set_nodes(nodes: numpy.ndarray, zone_name: Optional[str] = None, base_name: Optional[str] = None, time: Optional[float] = None) -> None Set the coordinates of nodes for a specified base and zone at a given time. :param nodes: A numpy array containing the new node coordinates. :type nodes: np.ndarray :param zone_name: The name of the zone where the nodes should be updated. Defaults to None. :type zone_name: str, optional :param base_name: The name of the base where the nodes should be updated. Defaults to None. :type base_name: str, optional :param time: The time at which the node coordinates should be updated. If a specific time is not provided, the method will display the tree structure for the default time step. :type time: float, optional :raises KeyError: Raised if the specified base or zone do not exist. You should first :raises create the base and zone using the `Sample.init_zone(zone_name,base_name)` method.: Seealso: This function can also be called using `set_points()` or `set_vertices()` .. py:method:: get_time_series_names() -> set[str] Get the names of time series associated with the object. :returns: A set of strings containing the names of the time series. :rtype: set[str] .. py:method:: get_time_series(name: str) -> Optional[plaid.types.TimeSeries] Retrieve a time series by name. :param name: The name of the time series to retrieve. :type name: str :returns: If a time series with the given name exists, it returns the corresponding time series, or None otherwise. :rtype: TimeSeries or None .. py:method:: add_time_series(name: str, time_sequence: plaid.types.TimeSequence, values: plaid.types.Field) -> None Add a time series to the sample. :param name: A descriptive name for the time series. :type name: str :param time_sequence: The time sequence, array of time points. :type time_sequence: TimeSequence :param values: The values corresponding to the time sequence. :type values: Field .. rubric:: Example .. code-block:: python from plaid import Sample sample.add_time_series('stuff', np.arange(2), np.random.randn(2)) print(sample.get_time_series('stuff')) >>> (array([0, 1]), array([-0.59630135, -1.15572306])) :raises TypeError: Raised if the length of `time_sequence` is not equal to the length of `values`. .. py:method:: del_time_series(name: str) -> tuple[plaid.types.TimeSequence, plaid.types.Field] Delete a time series from the sample. :param name: The name of the time series to be deleted. :type name: str :raises KeyError: Raised when there is no time series / there is no time series with the provided name. :returns: A tuple containing the time sequence and values of the deleted time series. :rtype: tuple[TimeSequence, Field] .. py:method:: del_all_fields() -> Self Delete alls field from sample, while keeping geometrical info. :returns: The sample with deleted fields :rtype: Sample .. py:method:: get_all_features_identifiers() -> list[plaid.types.FeatureIdentifier] Get all features identifiers from the sample. :returns: A list of dictionaries containing the identifiers of all features in the sample. :rtype: list[FeatureIdentifier] .. py:method:: get_all_features_identifiers_by_type(feature_type: str) -> list[plaid.types.FeatureIdentifier] Get all features identifiers of a given type from the sample. :param feature_type: Type of features to return :type feature_type: str :returns: A list of dictionaries containing the identifiers of a given type of all features in the sample. :rtype: list[FeatureIdentifier] .. py:method:: get_feature_from_string_identifier(feature_string_identifier: str) -> plaid.types.Feature Retrieve a specific feature from its encoded string identifier. The `feature_string_identifier` must follow the format: ":://.../" Supported feature types: - "scalar": expects 1 detail → `scalars.get(name)` - "time_series": expects 1 detail → `get_time_series(name)` - "field": up to 5 details → `get_field(name, base_name, zone_name, location, time)` - "nodes": up to 3 details → `get_nodes(base_name, zone_name, time)` :param feature_string_identifier: Structured identifier of the feature. :type feature_string_identifier: str :returns: The retrieved feature object. :rtype: Feature :raises AssertionError: If `feature_type` is unknown. .. warning:: - If "time" is present in a field/nodes identifier, it is cast to float. - `name` is required for scalar, time_series and field features. - The order of the details must be respected. One cannot specify a detail in the feature_string_identifier string without specified the previous ones. .. py:method:: get_feature_from_identifier(feature_identifier: plaid.types.FeatureIdentifier) -> plaid.types.Feature Retrieve a feature object based on a structured identifier dictionary. The `feature_identifier` must include a `"type"` key specifying the feature kind: - `"scalar"` → calls `scalars.get(name)` - `"time_series"` → calls `get_time_series(name)` - `"field"` → calls `get_field(name, base_name, zone_name, location, time)` - `"nodes"` → calls `get_nodes(base_name, zone_name, time)` Required keys: - `"type"`: one of `"scalar"`, `"time_series"`, `"field"`, or `"nodes"` - `"name"`: required for all types except `"nodes"` Optional keys depending on type: - `"base_name"`, `"zone_name"`, `"location"`, `"time"`: used in `"field"` and `"nodes"` Any omitted optional keys will rely on the default values mechanics of the class. :param feature_identifier ( dict[str: Union[str, float]]): A dictionary encoding the feature type and its relevant parameters. :returns: The corresponding feature instance retrieved via the appropriate accessor. :rtype: Feature .. py:method:: get_features_from_identifiers(feature_identifiers: list[plaid.types.FeatureIdentifier]) -> list[plaid.types.Feature] Retrieve features based on a list of structured identifier dictionaries. Elements of `feature_identifiers` must include a `"type"` key specifying the feature kind: - `"scalar"` → calls `scalars.get(name)` - `"time_series"` → calls `get_time_series(name)` - `"field"` → calls `get_field(name, base_name, zone_name, location, time)` - `"nodes"` → calls `get_nodes(base_name, zone_name, time)` Required keys: - `"type"`: one of `"scalar"`, `"time_series"`, `"field"`, or `"nodes"` - `"name"`: required for all types except `"nodes"` Optional keys depending on type: - `"base_name"`, `"zone_name"`, `"location"`, `"time"`: used in `"field"` and `"nodes"` Any omitted optional keys will rely on the default values mechanics of the class. :param feature_identifiers: A dictionary encoding the feature type and its relevant parameters. :type feature_identifiers: list[FeatureIdentifier] :returns: List of corresponding feature instance retrieved via the appropriate accessor. :rtype: list[Feature] .. py:method:: _add_feature(feature_identifier: plaid.types.FeatureIdentifier, feature: plaid.types.Feature) -> Self Add a feature to current sample. This method applies updates to scalars, time series, fields, or nodes using feature identifiers, and corresponding feature data. :param feature_identifier: A feature identifier. :type feature_identifier: dict :param feature: A feature corresponding to the identifiers. :type feature: Feature :returns: The updated sample :rtype: Self :raises AssertionError: If types are inconsistent or identifiers contain unexpected keys. .. py:method:: update_features_from_identifier(feature_identifiers: Union[plaid.types.FeatureIdentifier, list[plaid.types.FeatureIdentifier]], features: Union[plaid.types.Feature, list[plaid.types.Feature]], in_place: bool = False) -> Self Update one or several features of the sample by their identifier(s). This method applies updates to scalars, time series, fields, or nodes using feature identifiers, and corresponding feature data. When `in_place=False`, a deep copy of the sample is created before applying updates, ensuring full isolation from the original. :param feature_identifiers: One or more feature identifiers. :type feature_identifiers: dict or list of dict :param features: One or more features corresponding to the identifiers. :type features: Feature or list of Feature :param in_place: If True, modifies the current sample in place. If False, returns a deep copy with updated features. :type in_place: bool, optional :returns: The updated sample (either the current instance or a new copy). :rtype: Self :raises AssertionError: If types are inconsistent or identifiers contain unexpected keys. .. py:method:: extract_sample_from_identifier(feature_identifiers: Union[plaid.types.FeatureIdentifier, list[plaid.types.FeatureIdentifier]]) -> Self Extract features of the sample by their identifier(s) and return a new sample containing these features. This method applies updates to scalars, time series, fields, or nodes using feature identifiers :param feature_identifiers: One or more feature identifiers. :type feature_identifiers: dict or list of dict :returns: New sample containing the provided feature identifiers :rtype: Self :raises AssertionError: If types are inconsistent or identifiers contain unexpected keys. .. py:method:: from_features_identifier(feature_identifiers: Union[plaid.types.FeatureIdentifier, list[plaid.types.FeatureIdentifier]]) -> Self DEPRECATED: Use extract_sample_from_identifier() instead. .. py:method:: merge_features(sample: Self, in_place: bool = False) -> Self Merge features from another sample into the current sample. This method applies updates to scalars, time series, fields, or nodes using features from another sample. When `in_place=False`, a deep copy of the sample is created before applying updates, ensuring full isolation from the original. :param sample: The sample from which features will be merged. :type sample: Sample :param in_place: If True, modifies the current sample in place. If False, returns a deep copy with updated features. :type in_place: bool, optional :returns: The updated sample (either the current instance or a new copy). :rtype: Self .. py:method:: save(path: Union[str, pathlib.Path], overwrite: bool = False) -> None Save the Sample in directory `path`. :param path: relative or absolute directory path. :type path: Union[str,Path] :param overwrite: target directory overwritten if True. :type overwrite: bool .. py:method:: load_from_dir(path: Union[str, pathlib.Path]) -> Self :classmethod: Load the Sample from directory `path`. This is a class method, you don't need to instantiate a `Sample` first. :param path: Relative or absolute directory path. :type path: Union[str,Path] :returns: Sample .. rubric:: Example .. code-block:: python from plaid import Sample sample = Sample.load_from_dir(dir_path) print(sample) >>> Sample(2 scalars, 1 timestamp, 5 fields) .. note:: It calls 'load' function during execution. .. py:method:: load(path: Union[str, pathlib.Path]) -> None Load the Sample from directory `path`. :param path: Relative or absolute directory path. :type path: Union[str,Path] :raises FileNotFoundError: Triggered if the provided directory does not exist. :raises FileExistsError: Triggered if the provided path is a file instead of a directory. .. rubric:: Example .. code-block:: python from plaid import Sample sample = Sample() sample.load(path) print(sample) >>> Sample(3 scalars, 1 timestamp, 3 fields) .. py:method:: summarize() -> str Provide detailed summary of the Sample content, showing feature names and mesh information. This provides more detailed information than the __repr__ method, including the name of each feature. :returns: A detailed string representation of the sample content. :rtype: str .. rubric:: Example .. code-block:: bash Sample Summary: ================================================== Scalars (8): - Pr: 0.9729006564945664 - Q: 0.2671142611487964 - Tr: 0.9983394202616822 - angle_in: 45.5066666666667 - angle_out: 61.89519547386746 - eth_is: 0.21238326882538008 - mach_out: 0.81003 - power: 0.0019118127462776008 Meshes (1 timestamps): Time: 0.0 Base: Base_2_2 Nodes (36421) Tags (6): Intrado (122), Extrado (122), Inflow (121), Outflow (121), Periodic_1 (120), Periodic_2 (238) Fields (7): ro, sdf, rou, nut, mach, roe, rov Elements (36000) QUAD_4 (36000) Base: Base_1_2 Nodes (244) Fields (1): M_iso Elements (242) BAR_2 (242) .. py:method:: check_completeness() -> str Check the completeness of features in this sample. :returns: A report on feature completeness. :rtype: str .. rubric:: Example .. code-block:: bash Sample Completeness Check: ============================== Has scalars: True Has time series: False Has meshes: True Total unique fields: 8 Field names: M_iso, mach, nut, ro, roe, rou, rov, sdf