コード例 #1
0
def test_simulation_vector_description_existing_vector() -> None:
    # Verify test vector exist in VectorDefinitions
    assert "WOPT" in VectorDefinitions

    # Test WITHOUT vector definitions argument
    assert simulation_vector_description("WOPT:A1") == "Oil Production Total, well A1"
    assert (
        simulation_vector_description("PER_DAY_WOPT:A1")
        == "Average Oil Production Total Per day, well A1"
    )
    assert (
        simulation_vector_description("PER_INTVL_WOPT:A1")
        == "Interval Oil Production Total, well A1"
    )
    assert (
        simulation_vector_description("AVG_WOPT:A1")
        == "Average Oil Production Total, well A1"
    )
    assert (
        simulation_vector_description("INTVL_WOPT:A1")
        == "Interval Oil Production Total, well A1"
    )

    # Test WITH vector definitions argument
    vector_definitions = {
        "WOPT": VectorDefinition(type="well", description="Test Description"),
    }
    assert (
        simulation_vector_description("WOPT:A1", vector_definitions)
        == "Test Description, well A1"
    )
    assert (
        simulation_vector_description("PER_DAY_WOPT:A1", vector_definitions)
        == "Average Test Description Per day, well A1"
    )
    assert (
        simulation_vector_description("PER_INTVL_WOPT:A1", vector_definitions)
        == "Interval Test Description, well A1"
    )
    assert (
        simulation_vector_description("AVG_WOPT:A1", vector_definitions)
        == "Average Test Description, well A1"
    )
    assert (
        simulation_vector_description("INTVL_WOPT:A1", vector_definitions)
        == "Interval Test Description, well A1"
    )
コード例 #2
0
def test_simulation_vector_description_non_existing_vector() -> None:
    # Verify test vector does not exist in VectorDefinitions
    assert "Custom" not in VectorDefinitions

    # Test WITHOUT vector definitions argument
    assert simulation_vector_description("Custom:A1") == "Custom:A1"
    assert (
        simulation_vector_description("PER_DAY_Custom:A1")
        == "Average Custom:A1 Per day"
    )
    assert simulation_vector_description("PER_INTVL_Custom:A1") == "Interval Custom:A1"
    assert simulation_vector_description("AVG_Custom:A1") == "Average Custom:A1"
    assert simulation_vector_description("INTVL_Custom:A1") == "Interval Custom:A1"

    # Test WITH vector definitions argument
    vector_definitions = {
        "Custom": VectorDefinition(type="field", description="Custom Description"),
    }
    assert (
        simulation_vector_description("Custom:A1", vector_definitions)
        == "Custom Description, field A1"
    )
    assert (
        simulation_vector_description("PER_DAY_Custom:A1", vector_definitions)
        == "Average Custom Description Per day, field A1"
    )
    assert (
        simulation_vector_description("PER_INTVL_Custom:A1", vector_definitions)
        == "Interval Custom Description, field A1"
    )
    assert (
        simulation_vector_description("AVG_Custom:A1", vector_definitions)
        == "Average Custom Description, field A1"
    )
    assert (
        simulation_vector_description("INTVL_Custom:A1", vector_definitions)
        == "Interval Custom Description, field A1"
    )
コード例 #3
0
def create_vector_plot_titles_from_provider_set(
    vector_names: List[str],
    expressions: List[ExpressionInfo],
    provider_set: ProviderSet,
) -> Dict[str, str]:
    """Create plot titles for vectors

    Create plot titles for vectors by use of provider set metadata and list of
    calculation expressions

    `Return:`
    * Dictionary with vector names as keys and the corresponding title as value
    """
    vector_title_dict: Dict[str, str] = {}

    all_vector_names = provider_set.all_vector_names()
    for vector_name in vector_names:
        vector = vector_name

        if vector.startswith("AVG_"):
            vector = vector.lstrip("AVG_")
        if vector.startswith("INTVL_"):
            vector = vector.lstrip("INTVL_")

        if vector in all_vector_names:
            metadata = provider_set.vector_metadata(vector)
            title = simulation_vector_description(vector_name)
            if metadata and metadata.unit:
                title = (f"{simulation_vector_description(vector_name)}"
                         f" [{simulation_unit_reformat(metadata.unit)}]")
            vector_title_dict[vector_name] = title
        else:
            expression = get_expression_from_name(vector_name, expressions)
            if expression:
                unit = create_calculated_unit_from_provider_set(
                    expression, provider_set)
                if unit:
                    # TODO: Expression description instead of vector name in title?
                    vector_title_dict[vector_name] = f"{vector_name} [{unit}]"
                else:
                    vector_title_dict[vector_name] = vector_name
            else:
                vector_title_dict[vector_name] = vector_name
    return vector_title_dict
コード例 #4
0
ファイル: _plugin.py プロジェクト: equinor/webviz-subsurface
    def __init__(
        self,
        app: dash.Dash,
        webviz_settings: WebvizSettings,
        ensembles: Optional[list] = None,
        rel_file_pattern: str = "share/results/unsmry/*.arrow",
        perform_presampling: bool = False,
        obsfile: Path = None,
        options: dict = None,
        sampling: str = Frequency.MONTHLY.value,
        predefined_expressions: str = None,
        user_defined_vector_definitions: str = None,
        line_shape_fallback: str = "linear",
    ) -> None:
        super().__init__()

        # NOTE: Temporary css, pending on new wcc modal component.
        # See: https://github.com/equinor/webviz-core-components/issues/163
        WEBVIZ_ASSETS.add(
            Path(webviz_subsurface.__file__).parent / "_assets" / "css" /
            "modal.css")

        self._webviz_settings = webviz_settings
        self._obsfile = obsfile

        # Retrieve user defined vector descriptions from configuration and validate
        self._user_defined_vector_descriptions_path = (
            None if user_defined_vector_definitions is None else
            webviz_settings.shared_settings["user_defined_vector_definitions"]
            [user_defined_vector_definitions])
        self._user_defined_vector_definitions: Dict[
            str, wsc.
            VectorDefinition] = create_user_defined_vector_descriptions_from_config(
                get_path(self._user_defined_vector_descriptions_path) if self.
                _user_defined_vector_descriptions_path else None)
        self._custom_vector_definitions = copy.deepcopy(
            self._user_defined_vector_definitions)

        self._line_shape_fallback = set_simulation_line_shape_fallback(
            line_shape_fallback)

        # Must define valid freqency!
        if Frequency.from_string_value(sampling) is None:
            raise ValueError(
                'Sampling frequency conversion is "None", i.e. Raw sampling, and '
                "is not supported by plugin yet!")
        self._sampling = Frequency(sampling)
        self._presampled_frequency = None

        # TODO: Update functionality when allowing raw data and csv file input
        # NOTE: If csv is implemented-> handle/disable statistics, PER_INTVL_, PER_DAY_, delta
        # ensemble, etc.
        if ensembles is not None:
            ensemble_paths: Dict[str, Path] = {
                ensemble_name:
                webviz_settings.shared_settings["scratch_ensembles"]
                [ensemble_name]
                for ensemble_name in ensembles
            }
            if perform_presampling:
                self._presampled_frequency = self._sampling
                self._input_provider_set = create_presampled_provider_set_from_paths(
                    ensemble_paths, rel_file_pattern,
                    self._presampled_frequency)
            else:
                self._input_provider_set = create_lazy_provider_set_from_paths(
                    ensemble_paths, rel_file_pattern)
        else:
            raise ValueError('Incorrect argument, must provide "ensembles"')

        if not self._input_provider_set:
            raise ValueError(
                "Initial provider set is undefined, and ensemble summary providers"
                " are not instanciated for plugin")

        self._theme = webviz_settings.theme

        self._observations = {}
        if self._obsfile:
            self._observations = check_and_format_observations(
                get_path(self._obsfile))

        # NOTE: Initially keep set of all vector names - can make dynamic if wanted?
        vector_names = self._input_provider_set.all_vector_names()
        non_historical_vector_names = [
            vector for vector in vector_names
            if historical_vector(vector, None, False) not in vector_names
        ]

        # NOTE: Initially: With set of vector names, the vector selector data is static
        # Can be made dynamic based on selected ensembles - i.e. vectors present among
        # selected providers?
        self._vector_selector_base_data: list = []
        self._vector_calculator_data: list = []
        for vector in non_historical_vector_names:
            add_vector_to_vector_selector_data(
                self._vector_selector_base_data,
                vector,
            )

            # Only vectors from providers are provided to vector calculator
            add_vector_to_vector_selector_data(
                self._vector_calculator_data,
                vector,
            )

            metadata = (self._input_provider_set.vector_metadata(vector)
                        if self._input_provider_set else None)
            if metadata and metadata.is_total:
                # Get the likely name for equivalent rate vector and make dropdown options.
                # Requires that the time_index was either defined or possible to infer.
                per_day_vec = create_per_day_vector_name(vector)
                per_intvl_vec = create_per_interval_vector_name(vector)

                add_vector_to_vector_selector_data(
                    self._vector_selector_base_data,
                    per_day_vec,
                )
                add_vector_to_vector_selector_data(
                    self._vector_selector_base_data,
                    per_intvl_vec,
                )

                # Add vector base to custom vector definition if not existing
                vector_base = vector.split(":")[0]
                _definition = wsc.VectorDefinitions.get(vector_base, None)
                _type = _definition["type"] if _definition else "others"

                per_day_vec_base = per_day_vec.split(":")[0]
                per_intvl_vec_base = per_intvl_vec.split(":")[0]
                if per_day_vec_base not in self._custom_vector_definitions:
                    self._custom_vector_definitions[
                        per_day_vec_base] = wsc.VectorDefinition(
                            type=_type,
                            description=simulation_vector_description(
                                per_day_vec_base,
                                self._user_defined_vector_definitions),
                        )
                if per_intvl_vec_base not in self._custom_vector_definitions:
                    self._custom_vector_definitions[
                        per_intvl_vec_base] = wsc.VectorDefinition(
                            type=_type,
                            description=simulation_vector_description(
                                per_intvl_vec_base,
                                self._user_defined_vector_definitions),
                        )

        # Retreive predefined expressions from configuration and validate
        self._predefined_expressions_path = (
            None if predefined_expressions is None else webviz_settings.
            shared_settings["predefined_expressions"][predefined_expressions])
        self._predefined_expressions = expressions_from_config(
            get_path(self._predefined_expressions_path) if self.
            _predefined_expressions_path else None)
        for expression in self._predefined_expressions:
            valid, message = validate_predefined_expression(
                expression, self._vector_selector_base_data)
            if not valid:
                warnings.warn(message)
            expression["isValid"] = valid

        # Add expressions to custom vector definitions
        self._custom_vector_definitions_base = copy.deepcopy(
            self._custom_vector_definitions)
        _custom_vector_definitions_from_expressions = (
            get_vector_definitions_from_expressions(
                self._predefined_expressions))
        for key, value in _custom_vector_definitions_from_expressions.items():
            if key not in self._custom_vector_definitions:
                self._custom_vector_definitions[key] = value

        # Create initial vector selector data with predefined expressions
        self._initial_vector_selector_data = copy.deepcopy(
            self._vector_selector_base_data)
        add_expressions_to_vector_selector_data(
            self._initial_vector_selector_data, self._predefined_expressions)

        plot_options = options if options else {}
        self._initial_visualization_selection = VisualizationOptions(
            plot_options.get("visualization", "statistics"))

        # Initial selected vectors - NB: {vector1, vector2, vector3} is deprecated!
        initial_vectors: List[str] = plot_options.get("vectors", [])

        # TODO: Remove when depretaced code is not utilized anymore
        if "vectors" in plot_options and any(
                elm in plot_options
                for elm in ["vector1", "vector2", "vector3"]):
            warnings.warn(
                'Providing new user input option "vectors" and deprecated user input options '
                '"vector1", "vector2" and "vector3" simultaneously. Initially selected vectors '
                'for plugin are set equal to new user input option "vectors".')
        if not initial_vectors:
            initial_vectors = [
                plot_options[elm] for elm in ["vector1", "vector2", "vector3"]
                if elm in plot_options
            ][:3]

        # Check if initially selected vectors exist in data, raise ValueError if not
        missing_vectors = [
            elm for elm in initial_vectors
            if not is_vector_name_in_vector_selector_data(
                elm, self._initial_vector_selector_data)
        ]
        if missing_vectors:
            raise ValueError(
                f"Cannot find: {', '.join(missing_vectors)} to plot initially in "
                "SimulationTimeSeries. Check that the vector(s) exist in your data."
            )

        if len(initial_vectors) > 3:
            warnings.warn(
                'User input option "vectors" contains more than 3 vectors. Only the first 3 listed '
                "vectors are kept for initially selected vectors - the remaining are neglected."
            )
        self._initial_vectors = initial_vectors[:3]

        # Set callbacks
        self.set_callbacks(app)
コード例 #5
0
def create_vector_plot_titles_from_provider_set(
    vector_names: List[str],
    expressions: List[ExpressionInfo],
    provider_set: ProviderSet,
    user_defined_vector_definitions: Dict[str, VectorDefinition],
    resampling_frequency: Optional[Frequency] = None,
) -> Dict[str, str]:
    """Create plot titles for vectors

    Create plot titles for vectors by use of provider set metadata and list of
    calculation expressions

    `Return:`
    * Dictionary with vector names as keys and the corresponding title as value
    """
    vector_title_dict: Dict[str, str] = {}

    all_vector_names = provider_set.all_vector_names()
    for vector_name in vector_names:

        # Provider vector
        if vector_name in all_vector_names:
            metadata = provider_set.vector_metadata(vector_name)
            title = simulation_vector_description(
                vector_name, user_defined_vector_definitions)
            if metadata and metadata.unit:
                title += f" [{simulation_unit_reformat(metadata.unit)}]"
            vector_title_dict[vector_name] = title

        # Per Interval or Per Day vector
        elif is_per_interval_or_per_day_vector(vector_name):
            title = simulation_vector_description(
                vector_name, user_defined_vector_definitions)

            cumulative_vector = get_cumulative_vector_name(vector_name)
            metadata = provider_set.vector_metadata(cumulative_vector)
            if resampling_frequency:
                title = f"{str(resampling_frequency.value).capitalize()} " + title
            if vector_name.startswith("PER_DAY_"):
                if metadata and metadata.unit:
                    _unit = metadata.unit + "/DAY"
                    title += f" [{simulation_unit_reformat(_unit)}]"
            if vector_name.startswith("PER_INTVL_"):
                if metadata and metadata.unit:
                    title += f" [{simulation_unit_reformat(metadata.unit)}]"
            vector_title_dict[vector_name] = title

        # Calculated vector
        else:
            expression = get_expression_from_name(vector_name, expressions)
            if expression:
                unit = create_calculated_unit_from_provider_set(
                    expression, provider_set)
                if unit:
                    # TODO: Expression description instead of vector name in title?
                    vector_title_dict[vector_name] = f"{vector_name} [{unit}]"
                else:
                    vector_title_dict[vector_name] = vector_name
            else:
                vector_title_dict[vector_name] = vector_name
    return vector_title_dict
コード例 #6
0
def eclipse_vector_description(keyword):
    return UDF_VECTOR.get(keyword, simulation_vector_description(keyword))
コード例 #7
0
    def __init__(
        self,
        app,
        x_axis=None,
        y_axis=None,
        ensembles=None,
        reference_cases=None,
        column_keys=None,
        krpc_ensembles=None,
        ensembles_idx=None,
        krpc_references=None,
    ):
        super().__init__()

        # Get setting from shared_settings
        shared_settings = app.webviz_settings["shared_settings"]

        self.plot_profile = ensembles or reference_cases
        self.plot_krpc = krpc_ensembles or krpc_references
        self.plot_ensembles = ensembles or krpc_ensembles
        self.plot_references = reference_cases or krpc_references
        self.x_axis = x_axis
        self.y_axis = [] if y_axis is None else y_axis

        self.column_keys = column_keys
        self.krpc_csv_tables = None
        self.references_tuple = ()
        self.case_tuple = ()
        self.ensemble_paths = ()
        self.colors = PALETTE["tableau"]
        if not (self.plot_profile or self.plot_krpc):
            raise ValueError(
                "Nothing to visualize.\n Please specify at least one Eclipse case or krpc table"
            )

        keywords = []
        if self.plot_profile:
            if ensembles is None:
                self.ensemble_paths = ()
                self.df_ens = None
            else:
                self.ensemble_paths = tuple(
                    (ensemble, shared_settings["scratch_ensembles"][ensemble])
                    for ensemble in ensembles)
                self.df_ens = get_ensemble_df(self.ensemble_paths,
                                              self.column_keys)
                keywords.extend(self.df_ens.columns)
            if reference_cases is None:
                warning(
                    "[UpCaRs Container] User didn't specify any reference cases"
                )
                self.df_ref = None
            else:
                self.references_tuple = tuple(
                    (reference, shared_settings["realizations"][reference])
                    for reference in reference_cases)
                self.df_ref = get_summary_df(self.references_tuple,
                                             self.column_keys)
                keywords.extend(self.df_ref.columns)
            # Get all columns
            keywords.remove("REAL")
            keywords.remove("ENSEMBLE")
            keywords = sorted(list(set(keywords)))
            self.keywords_options = [{
                "label":
                "{} ({})".format(
                    UDF_VECTOR.get(val, simulation_vector_description(val)),
                    val),
                "value":
                val,
            } for val in keywords]
            if x_axis in keywords:
                self.x_axis = x_axis
            else:
                self.x_axis = keywords[0]
            self.y_axis = [key for key in y_axis if key in keywords]
        else:
            self.keywords_options = []
            self.x_axis = None
            self.y_axis = []

        if self.plot_krpc:
            if krpc_references:
                self.case_tuple = tuple(
                    (case, shared_settings["krpc_csv_tables"][case])
                    for case in krpc_references)
                self.df_ref_krpc = get_multiple_table_df(self.case_tuple)
コード例 #8
0
    def __init__(
        self,
        app: dash.Dash,
        webviz_settings: WebvizSettings,
        ensembles: Optional[list] = None,
        rel_file_pattern: str = "share/results/unsmry/*.arrow",
        perform_presampling: bool = False,
        obsfile: Path = None,
        options: dict = None,
        sampling: str = Frequency.MONTHLY.value,
        predefined_expressions: str = None,
        line_shape_fallback: str = "linear",
    ) -> None:
        super().__init__()

        # NOTE: Temporary css, pending on new wcc modal component.
        # See: https://github.com/equinor/webviz-core-components/issues/163
        WEBVIZ_ASSETS.add(
            Path(webviz_subsurface.__file__).parent / "_assets" / "css" /
            "modal.css")

        self._webviz_settings = webviz_settings
        self._obsfile = obsfile

        self._line_shape_fallback = set_simulation_line_shape_fallback(
            line_shape_fallback)

        # Must define valid freqency!
        if Frequency.from_string_value(sampling) is None:
            raise ValueError(
                'Sampling frequency conversion is "None", i.e. Raw sampling, and '
                "is not supported by plugin yet!")
        self._sampling = Frequency(sampling)
        self._presampled_frequency = None

        # TODO: Update functionality when allowing raw data and csv file input
        # NOTE: If csv is implemented-> handle/disable statistics, INTVL_, AVG_, delta
        # ensemble, etc.
        if ensembles is not None:
            ensemble_paths: Dict[str, Path] = {
                ensemble_name:
                webviz_settings.shared_settings["scratch_ensembles"]
                [ensemble_name]
                for ensemble_name in ensembles
            }
            if perform_presampling:
                self._presampled_frequency = self._sampling
                self._input_provider_set = create_presampled_provider_set_from_paths(
                    ensemble_paths, rel_file_pattern,
                    self._presampled_frequency)
            else:
                self._input_provider_set = create_lazy_provider_set_from_paths(
                    ensemble_paths, rel_file_pattern)
        else:
            raise ValueError('Incorrect argument, must provide "ensembles"')

        if not self._input_provider_set:
            raise ValueError(
                "Initial provider set is undefined, and ensemble summary providers"
                " are not instanciated for plugin")

        self._theme = webviz_settings.theme

        self._observations = {}
        if self._obsfile:
            self._observations = check_and_format_observations(
                get_path(self._obsfile))

        # NOTE: Initially keep set of all vector names - can make dynamic if wanted?
        vector_names = self._input_provider_set.all_vector_names()
        non_historical_vector_names = [
            vector for vector in vector_names
            if historical_vector(vector, None, False) not in vector_names
        ]

        # NOTE: Initially: With set of vector names, the vector selector data is static
        # Can be made dynamic based on selected ensembles - i.e. vectors present among
        # selected providers?
        self._vector_selector_base_data: list = []
        self._vector_calculator_data: list = []
        for vector in non_historical_vector_names:
            split = vector.split(":")
            add_vector_to_vector_selector_data(
                self._vector_selector_base_data,
                vector,
                simulation_vector_description(split[0]),
            )
            add_vector_to_vector_selector_data(
                self._vector_calculator_data,
                vector,
                simulation_vector_description(split[0]),
            )

            metadata = (self._input_provider_set.vector_metadata(vector)
                        if self._input_provider_set else None)
            if metadata and metadata.is_total:
                # Get the likely name for equivalent rate vector and make dropdown options.
                # Requires that the time_index was either defined or possible to infer.
                avgrate_vec = rename_vector_from_cumulative(vector=vector,
                                                            as_rate=True)
                interval_vec = rename_vector_from_cumulative(vector=vector,
                                                             as_rate=False)

                avgrate_split = avgrate_vec.split(":")
                interval_split = interval_vec.split(":")

                add_vector_to_vector_selector_data(
                    self._vector_selector_base_data,
                    avgrate_vec,
                    f"{simulation_vector_description(avgrate_split[0])} ({avgrate_vec})",
                )
                add_vector_to_vector_selector_data(
                    self._vector_selector_base_data,
                    interval_vec,
                    f"{simulation_vector_description(interval_split[0])} ({interval_vec})",
                )

        # Retreive predefined expressions from configuration and validate
        self._predefined_expressions_path = (
            None if predefined_expressions is None else webviz_settings.
            shared_settings["predefined_expressions"][predefined_expressions])
        self._predefined_expressions = expressions_from_config(
            get_path(self._predefined_expressions_path) if self.
            _predefined_expressions_path else None)
        for expression in self._predefined_expressions:
            valid, message = validate_predefined_expression(
                expression, self._vector_selector_base_data)
            if not valid:
                warnings.warn(message)
            expression["isValid"] = valid

        # Create initial vector selector data with predefined expressions
        self._initial_vector_selector_data = copy.deepcopy(
            self._vector_selector_base_data)
        add_expressions_to_vector_selector_data(
            self._initial_vector_selector_data, self._predefined_expressions)

        plot_options = options if options else {}
        self._initial_visualization_selection = VisualizationOptions(
            plot_options.get("visualization", "statistics"))
        self._initial_vectors: List[str] = []
        if "vectors" not in plot_options:
            self._initial_vectors = []
        for vector in [
                vector for vector in ["vector1", "vector2", "vector3"]
                if vector in plot_options
        ]:
            self._initial_vectors.append(plot_options[vector])
        self._initial_vectors = self._initial_vectors[:3]

        # Set callbacks
        self.set_callbacks(app)