def __init__( self, app: Dash, webviz_settings: WebvizSettings, realizations: pd.DataFrame, reference: str = "rms_seed", allow_click: bool = False, ): self.realizations = realizations self.sensnames = list(self.realizations["SENSNAME"].unique()) if self.sensnames == [None]: raise KeyError( "No sensitivity information found in ensemble. " "Containers utilizing tornadoplot can only be used for ensembles with " "one by one design matrix setup " "(SENSNAME and SENSCASE must be present in parameter file)." ) self.initial_reference = ( reference if reference in self.sensnames else self.sensnames[0] ) self.allow_click = allow_click self.uid = uuid4() self.plotly_theme = webviz_settings.theme.plotly_theme WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "js" / "clientside_functions.js" ) self.set_callbacks(app)
def __init__( self, app: dash.Dash, webviz_settings: WebvizSettings, ensembles: Optional[list] = None, statistics_file: str = "share/results/tables/gridpropstatistics.csv", csvfile_statistics: pathlib.Path = None, csvfile_smry: pathlib.Path = None, surface_renaming: Optional[dict] = None, time_index: str = "monthly", column_keys: Optional[list] = None, ): super().__init__() WEBVIZ_ASSETS.add( pathlib.Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "container.css") self.theme: WebvizConfigTheme = webviz_settings.theme self.time_index = time_index self.column_keys = column_keys self.statistics_file = statistics_file self.ensembles = ensembles self.csvfile_statistics = csvfile_statistics self.csvfile_smry = csvfile_smry self.surface_folders: Union[dict, None] if ensembles is not None: self.emodel: EnsembleSetModel = ( caching_ensemble_set_model_factory.get_or_create_model( ensemble_paths={ ens: webviz_settings.shared_settings["scratch_ensembles"] [ens] for ens in ensembles }, time_index=self.time_index, column_keys=self.column_keys, )) self.pmodel = PropertyStatisticsModel( dataframe=self.emodel.load_csv( csv_file=pathlib.Path(self.statistics_file)), theme=self.theme, ) self.vmodel = SimulationTimeSeriesModel( dataframe=self.emodel.get_or_load_smry_cached(), theme=self.theme, ) self.surface_folders = { ens: folder / "share" / "results" / "maps" / ens for ens, folder in self.emodel.ens_folders.items() } else: self.pmodel = PropertyStatisticsModel( dataframe=read_csv(csvfile_statistics), theme=self.theme) self.vmodel = SimulationTimeSeriesModel( dataframe=read_csv(csvfile_smry), theme=self.theme) self.surface_folders = None self.surface_renaming = surface_renaming if surface_renaming else {} self.set_callbacks(app)
def __init__( self, app: dash.Dash, webviz_settings: WebvizSettings, csvfile_vol: Path = None, csvfile_parameters: Path = None, ensembles: list = None, volfiles: dict = None, volfolder: str = "share/results/volumes", non_net_facies: Optional[List[str]] = None, ): super().__init__() WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "container.css") WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "inplace_volumes.css") self.csvfile_vol = csvfile_vol self.csvfile_parameters = csvfile_parameters self.volfiles = volfiles self.volfolder = volfolder if csvfile_vol and ensembles: raise ValueError( 'Incorrent arguments. Either provide a "csvfile" or "ensembles" and "volfiles"' ) if csvfile_vol: volumes_table = read_csv(csvfile_vol) parameters: Optional[pd.DataFrame] = ( read_csv(csvfile_parameters) if csvfile_parameters else None) elif ensembles and volfiles: ensemble_paths = { ens: webviz_settings.shared_settings["scratch_ensembles"][ens] for ens in ensembles } self.emodel: EnsembleSetModel = ( caching_ensemble_set_model_factory.get_or_create_model( ensemble_paths=ensemble_paths, )) parameters = self.emodel.load_parameters() volumes_table = extract_volumes(self.emodel, volfolder, volfiles) else: raise ValueError( 'Incorrent arguments. Either provide a "csvfile" or "ensembles" and "volfiles"' ) self.volmodel = InplaceVolumesModel( volumes_table=volumes_table, parameter_table=parameters, non_net_facies=non_net_facies, ) self.theme = webviz_settings.theme self.set_callbacks(app)
def __init__( self, app, webviz_settings: WebvizSettings, ensembles: Optional[list] = None, csvfile_parameters: pathlib.Path = None, csvfile_smry: pathlib.Path = None, time_index: str = "monthly", column_keys: Optional[list] = None, drop_constants: bool = True, ): super().__init__() WEBVIZ_ASSETS.add( pathlib.Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "container.css") self.theme = webviz_settings.theme self.time_index = time_index self.column_keys = column_keys self.ensembles = ensembles self.csvfile_parameters = csvfile_parameters self.csvfile_smry = csvfile_smry if ensembles is not None: self.emodel: EnsembleSetModel = ( caching_ensemble_set_model_factory.get_or_create_model( ensemble_paths={ ens: webviz_settings.shared_settings["scratch_ensembles"] [ens] for ens in ensembles }, time_index=self.time_index, column_keys=self.column_keys, )) self.pmodel = ParametersModel( dataframe=self.emodel.load_parameters(), theme=self.theme, drop_constants=drop_constants, ) self.vmodel = SimulationTimeSeriesModel( dataframe=self.emodel.get_or_load_smry_cached()) elif self.csvfile_parameters is None: raise ValueError( "Either ensembles or csvfile_parameters must be specified") else: self.pmodel = ParametersModel( dataframe=read_csv(csvfile_parameters), theme=self.theme, drop_constants=drop_constants, ) if self.csvfile_smry is not None: self.vmodel = SimulationTimeSeriesModel( dataframe=read_csv(csvfile_smry)) else: self.vmodel = None self.set_callbacks(app)
def __init__(self, app, csv_file): super().__init__() self.graph_id = f"graph-{uuid4()}" self.controls_dropdown_id = f"dropdown-{uuid4()}" self.csv_file = csv_file self.set_callbacks(app) ASSETS_DIR = Path(pkg_resources.resource_filename("everviz", "assets")) WEBVIZ_ASSETS.add(ASSETS_DIR / "axis_customization.css")
def __init__( self, app, ensembles: Optional[list] = None, statistics_file: str = "share/results/tables/gridpropstatistics.csv", csvfile_statistics: pathlib.Path = None, csvfile_smry: pathlib.Path = None, surface_renaming: Optional[dict] = None, time_index: str = "monthly", column_keys: Optional[list] = None, ): super().__init__() WEBVIZ_ASSETS.add( pathlib.Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "container.css") self.theme = app.webviz_settings["theme"] self.time_index = time_index self.column_keys = column_keys self.statistics_file = statistics_file self.ensembles = ensembles self.csvfile_statistics = csvfile_statistics self.csvfile_smry = csvfile_smry if ensembles is not None: self.emodel = EnsembleSetModel( ensemble_paths={ ens: app.webviz_settings["shared_settings"] ["scratch_ensembles"][ens] for ens in ensembles } if ensembles is not None else None) self.pmodel = PropertyStatisticsModel( dataframe=self.emodel.load_csv(csv_file=self.statistics_file), theme=self.theme, ) self.vmodel = SimulationTimeSeriesModel( dataframe=self.emodel.load_smry(time_index=self.time_index, ), theme=self.theme, ) self.surface_folders = { ens: folder / "share" / "results" / "maps" / ens for ens, folder in self.emodel.ens_folders.items() } else: self.pmodel = PropertyStatisticsModel( dataframe=read_csv(csvfile_statistics), theme=self.theme) self.vmodel = SimulationTimeSeriesModel( dataframe=read_csv(csvfile_smry), theme=self.theme.plotly_theme) self.surface_folders = None self.surface_renaming = surface_renaming if surface_renaming else {} self.set_callbacks(app)
def __init__(self, app, values_file, statistics_file): super().__init__() self.graph_id = f"graph-{uuid4()}" self.radio_id = f"dropdown-{uuid4()}" self.function_dropdown_id = f"dropdown-{uuid4()}" self.values_file = values_file self.statistics_file = statistics_file self.set_callbacks(app) ASSETS_DIR = Path(pkg_resources.resource_filename("everviz", "assets")) WEBVIZ_ASSETS.add(ASSETS_DIR / "axis_customization.css")
def __init__(self, app, csv_file): super().__init__() self.graph_id = f"graph-{uuid4()}" self.radio_id = f"dropdown-{uuid4()}" self.radio_id_mode = f"dropdown-{uuid4()}" self.function_dropdown_id = f"dropdown-{uuid4()}" self.realization_filter_check_id = f"check-{uuid4()}" self.realization_filter_input_id = f"input-{uuid4()}" self.csv_file = csv_file self.set_callbacks(app) ASSETS_DIR = Path(pkg_resources.resource_filename("everviz", "assets")) WEBVIZ_ASSETS.add(ASSETS_DIR / "axis_customization.css")
def __init__( self, app: Dash, webviz_settings: WebvizSettings, ensembles: Optional[List[str]] = None, rel_file_pattern: str = "share/results/unsmry/*.arrow", gruptree_file: str = "share/results/tables/gruptree.csv", well_attributes_file: str = "rms/output/wells/well_attributes.json", time_index: str = Frequency.YEARLY.value, filter_out_startswith: Optional[str] = None, ) -> None: super().__init__() # This is used to format the buttons in the well overview tab WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "inplace_volumes.css") self._ensembles = ensembles self._theme = webviz_settings.theme if ensembles is None: raise ValueError('Incorrect argument, must provide "ensembles"') self._ensemble_paths: Dict[str, Path] = { ensemble_name: webviz_settings.shared_settings["scratch_ensembles"][ensemble_name] for ensemble_name in ensembles } provider_factory = EnsembleSummaryProviderFactory.instance() self._data_models: Dict[str, EnsembleWellAnalysisData] = {} sampling = Frequency(time_index) for ens_name, ens_path in self._ensemble_paths.items(): provider: EnsembleSummaryProvider = ( provider_factory.create_from_arrow_unsmry_presampled( str(ens_path), rel_file_pattern, sampling)) self._data_models[ens_name] = EnsembleWellAnalysisData( ens_name, provider, GruptreeModel(ens_name, ens_path, gruptree_file), WellAttributesModel(ens_name, ens_path, well_attributes_file), filter_out_startswith=filter_out_startswith, ) self.set_callbacks(app)
def __init__(self, app, values_file, statistics_file, xaxis="date"): super().__init__() self.graph_id = f"graph-{uuid4()}" self.key_dropdown_id = f"dropdown-{uuid4()}" self.xaxis_dropdown_id = f"dropdown-{uuid4()}" self.radio_id = f"radio-{uuid4()}" self.values_file = values_file self.statistics_file = statistics_file self.xaxis = xaxis self.set_callbacks(app) ASSETS_DIR = pkg_resources.resource_filename("everviz", "assets") WEBVIZ_ASSETS.add(Path(ASSETS_DIR) / "axis_customization.css")
def __init__(self, app, csv_file, xaxis="date"): super().__init__() self.graph_id = f"graph-{uuid4()}" self.key_dropdown_id = f"dropdown-{uuid4()}" self.xaxis_dropdown_id = f"dropdown-{uuid4()}" self.radio_id = f"radio-{uuid4()}" self.realization_filter_check_id = f"check-{uuid4()}" self.realization_filter_input_id = f"input-{uuid4()}" self.csv_file = csv_file self.xaxis = xaxis self.set_callbacks(app) ASSETS_DIR = pkg_resources.resource_filename("everviz", "assets") WEBVIZ_ASSETS.add(Path(ASSETS_DIR) / "axis_customization.css")
def __init__(self, app, data_path, title="Indexed Crossplot"): super().__init__() self.title = title self.graph_id = f"graph-{uuid4()}" self.dropdown_x_id = f"dropdown-{uuid4()}" self.dropdown_y_id = f"dropdown-{uuid4()}" self.axis_type_x_id = f"radio-{uuid4()}" self.axis_type_y_id = f"radio-{uuid4()}" self.axis_options_x_id = f"radio-{uuid4()}" self.axis_options_y_id = f"radio-{uuid4()}" self.dropdown_realization_id = f"dropdown-{uuid4()}" self.interpolation_id = f"interpolation-{uuid4()}" self.data_path = data_path self.set_callbacks(app) ASSETS_DIR = pkg_resources.resource_filename("everviz", os.path.join("assets")) WEBVIZ_ASSETS.add(Path(ASSETS_DIR) / "axis_customization.css")
def __init__( self, app: Dash, webviz_settings: WebvizSettings, basedir: Path, planned_wells_dir: Path = None, ): super().__init__() self.plotly_theme = webviz_settings.theme.plotly_theme self.uid = uuid4() WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "modal.css") self.set_callbacks(app) self.basedir = basedir self.planned_wells_dir = planned_wells_dir self.modelfile_path = basedir / "model_file.xml" self.modelfile = get_path(self.modelfile_path) self.surfaces = load_surfaces(basedir, self.modelfile_path) self.planned_wellfiles = (json.load( find_files(planned_wells_dir, "*.txt")) if planned_wells_dir else None) self.wellfiles = json.load( find_files(basedir / "input" / "welldata", "*.txt")) self.wellfiles = [str(get_path(Path(w))) for w in self.wellfiles] self.allfiles = json.load(find_files(basedir)) self.allfiles.append(self.modelfile_path) self.allfiles += self.planned_wellfiles self.planned_wellfiles = [ str(get_path(Path(w))) for w in self.planned_wellfiles ] self.surface_attributes = {} for i, surface in enumerate(self.surfaces): self.surface_attributes[surface["name"]] = { "color": get_color(i), "order": i, "name": surface["name"], "topofzone": surface["topofzone"], "surface": surface["d_"], "surface_de": surface["de_"], "surface_dt": surface["dt_"], "surface_dr": surface["dr_"], "surface_dte": surface["dte_"], } self.surfacenames = [surface["name"] for surface in self.surfaces] # Log files zonation_status_file = get_zonation_status(basedir) well_points_file = get_well_points(basedir) zonelog_name = get_zonelog_name(self.modelfile) self.xsec = HuvXsection( self.surface_attributes, zonation_status_file, well_points_file, zonelog_name, ) target_points_file = get_target_points(basedir) self.df_well_target_points = FilterTable(target_points_file, well_points_file) # Wellfiles and planned wells self.planned_wells = {} if planned_wells_dir is not None: self.planned_wells = { wf: xtgeo.well_from_file(wfile=wf) for wf in self.planned_wellfiles } self.wells = { wf: xtgeo.well_from_file(wfile=wf) for wf in self.wellfiles } # Store current layers self.state = {"switch": False} self.layers_state = []
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)
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)
def __init__( self, app, webviz_settings: WebvizSettings, ensembles: list, relpermfile: str = None, scalfile: Path = None, sheet_name: Optional[Union[str, int, list]] = None, ): super().__init__() WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "block_options.css") self.ens_paths = { ens: webviz_settings.shared_settings["scratch_ensembles"][ens] for ens in ensembles } self.plotly_theme = webviz_settings.theme.plotly_theme self.relpermfile = relpermfile if self.relpermfile is not None: self.satfunc = load_csv(ensemble_paths=self.ens_paths, csv_file=relpermfile) self.satfunc = self.satfunc.rename( str.upper, axis="columns").rename(columns={"TYPE": "KEYWORD"}) if "KEYWORD" not in self.satfunc.columns: raise ValueError( "There has to be a KEYWORD or TYPE column with corresponding Eclipse keyword: " "e.g SWOF, SGOF and etc.") # pylint: disable=literal-comparison valid_columns = (["ENSEMBLE", "REAL", "KEYWORD", "SATNUM"] + RelativePermeability.SATURATIONS + [ key for key in RelativePermeability.SCAL_COLORMAP if key != "Missing" ]) self.satfunc = self.satfunc[[ col for col in self.satfunc.columns if col in valid_columns ]] else: self.satfunc = load_satfunc(self.ens_paths) if any(keyword in RelativePermeability.RELPERM_FAMILIES[1] for keyword in self.satfunc["KEYWORD"].unique()): self.family = 1 if any(keyword in RelativePermeability.RELPERM_FAMILIES[2] for keyword in self.satfunc["KEYWORD"].unique()): warnings.warn(( "Mix of keyword family 1 and 2, currently only support one family at the " "time. Dropping all data of family 2 ('SWFN', 'SGFN', 'SGWFN', 'SOF2', " "'SOF3', 'SOF32D') and continues with family 1 ('SWOF', 'SGOF', 'SLGOF')." ), ) self.satfunc = self.satfunc[self.satfunc["KEYWORD"].isin( RelativePermeability.RELPERM_FAMILIES["fam1"])] if "SGOF" in self.satfunc["KEYWORD"].unique(): if "SLGOF" in self.satfunc["KEYWORD"].unique(): warnings.warn(( "Mix of 'SGOF' and 'SLGOF' in ensembles, resulting in non-unique " "horizontal axis ('SG' and 'SL') for 'KRG', 'KROG' and 'PCOG'. " "Dropping all data with 'SLGOF'."), ) self.satfunc = self.satfunc[ self.satfunc["KEYWORD"] != "SLGOF"] self.sat_axes_maps = { "SW": ["KRW", "KROW", "PCOW"], "SG": ["KRG", "KROG", "PCOG"], } else: self.sat_axes_maps = { "SW": ["KRW", "KROW", "PCOW"], "SL": ["KRG", "KROG", "PCOG"], } elif not all(keyword in RelativePermeability.RELPERM_FAMILIES[2] for keyword in self.satfunc["KEYWORD"].unique()): raise ValueError( "Unrecognized saturation table keyword in data. This should not occur unless " "there has been changes to ecl2df. Update of this plugin might be required." ) else: self.family = 2 self.sat_axes_maps = { "SW": ["KRW", "PCOW"], "SG": ["KRG", "PCOG"], "SO": ["KROW", "KROG"], } self.scalfile = scalfile self.sheet_name = sheet_name self.scal = (load_scal_recommendation(self.scalfile, self.sheet_name) if self.scalfile is not None else None) self.set_callbacks(app)
def __init__( self, app: Dash, webviz_settings: WebvizSettings, csvfile: str = None, ensembles: list = None, aggregated_csvfile: Path = None, aggregated_parameterfile: Path = None, observation_file: Path = None, observation_group: str = "general", remap_observation_keys: Dict[str, str] = None, remap_observation_values: Dict[str, str] = None, colors: Dict = None, initial_data: Dict = None, initial_layout: Dict = None, ): super().__init__() provider = EnsembleTableProviderFactory.instance() self._initial_data = initial_data if initial_data else {} self._initial_layout = initial_layout if initial_layout else {} if ensembles is not None and csvfile is not None: ensembles_dict: Dict[str, str] = { ens_name: webviz_settings.shared_settings["scratch_ensembles"][ens_name] for ens_name in ensembles } self._parameterproviderset = ( provider. create_provider_set_from_per_realization_parameter_file( ensembles_dict)) self._tableproviderset = ( provider.create_provider_set_from_per_realization_csv_file( ensembles_dict, csvfile)) self._ensemble_names = ensembles elif aggregated_csvfile and aggregated_parameterfile is not None: self._tableproviderset = ( provider.create_provider_set_from_aggregated_csv_file( aggregated_csvfile)) self._parameterproviderset = ( provider.create_provider_set_from_aggregated_csv_file( aggregated_parameterfile)) self._ensemble_names = self._tableproviderset.ensemble_names() else: raise ValueError( "Specify either ensembles and csvfile or aggregated_csvfile " "and aggregated_parameterfile") all_parameters: list = [ self._parameterproviderset.ensemble_provider(ens).column_names() for ens in self._ensemble_names ] self._parameter_names: list = list(set().union(*all_parameters)) all_data_columns: list = [ self._tableproviderset.ensemble_provider(ens).column_names() for ens in self._ensemble_names ] self._data_column_names: list = list(set().union(*all_data_columns)) dfs = [] for ens in self._ensemble_names: df = self._parameterproviderset.ensemble_provider( ens).get_column_data(column_names=self._parameterproviderset. ensemble_provider(ens).column_names()) df["ENSEMBLE"] = ens dfs.append(df) parameterdf = pd.concat(dfs) self._realizations = sorted(list(parameterdf["REAL"].unique())) self._parameter_filter = ParameterFilter(self.uuid("parameter-filter"), parameterdf) self._observationfile = observation_file self._observationmodel = (ObservationModel( get_path(self._observationfile), observation_group, remap_observation_keys, remap_observation_values, ) if self._observationfile else None) WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "js" / "clientside_functions.js") self._colors: Dict = unique_colors(self._ensemble_names, webviz_settings.theme) if colors is not None: self._colors.update(colors) self.set_callbacks(app)
def __init__(self): super().__init__() self._screenshot_filename = f"{self.plugin_name()}.png" ASSETS_DIR = Path(pkg_resources.resource_filename("everviz", "assets")) WEBVIZ_ASSETS.add(ASSETS_DIR / "axis_customization.css")
import pkg_resources import json from pathlib import Path from webviz_config.webviz_assets import WEBVIZ_ASSETS ASSETS_DIR = Path(pkg_resources.resource_filename("webviz_ert", "assets")) WEBVIZ_ASSETS.add(ASSETS_DIR / "bootstrap-grid.css") WEBVIZ_ASSETS.add(ASSETS_DIR / "ert-style.css") with open(ASSETS_DIR / "ert-style.json") as f: ERTSTYLE = json.load(f) WEBVIZ_CONFIG = ( Path(pkg_resources.resource_filename("webviz_ert", "assets")) / "webviz-config.yml")
import pkg_resources import json from pathlib import Path from webviz_config.webviz_assets import WEBVIZ_ASSETS ASSETS_DIR = Path(pkg_resources.resource_filename("ertviz", "assets")) WEBVIZ_ASSETS.add(ASSETS_DIR / "ert-style.css") with open(ASSETS_DIR / "ert-style.json") as f: ERTSTYLE = json.load(f) WEBVIZ_CONFIG = (Path(pkg_resources.resource_filename("ertviz", "assets")) / "webviz-config.yml")
def __init__( self, app: Dash, webviz_settings: WebvizSettings, ensembles: list, surface_attributes: list, surface_name_filter: List[str] = None, wellfolder: Path = None, wellsuffix: str = ".w", zonelog: str = None, mdlog: str = None, well_tvdmin: Union[int, float] = None, well_tvdmax: Union[int, float] = None, well_downsample_interval: int = None, calculate_percentiles: bool = False, initial_settings: Dict = None, ): super().__init__() self._initial_settings = initial_settings if initial_settings else {} WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "css" / "structural_uncertainty.css") WEBVIZ_ASSETS.add( Path(webviz_subsurface.__file__).parent / "_assets" / "js" / "clientside_functions.js") self._calculate_percentiles = calculate_percentiles self._wellfolder = wellfolder self._wellsuffix = wellsuffix self._wellfiles: List = [] if wellfolder is not None: self._wellfiles = json.load(find_files(wellfolder, wellsuffix)) self._well_set_model = WellSetModel( self._wellfiles, zonelog=zonelog, mdlog=mdlog, tvdmin=well_tvdmin, tvdmax=well_tvdmax, downsample_interval=well_downsample_interval, ) self._use_wells = bool(self._wellfiles) if (self._initial_settings.get("intersection_data", {}).get("well") and not self._use_wells): raise KeyError( "Well is specified in initial settings but no well data is found!" ) self._surf_attrs = surface_attributes self._ensemble_paths = { ens: webviz_settings.shared_settings["scratch_ensembles"][ens] for ens in ensembles } # Create a table of surface files surface_table = find_surfaces(self._ensemble_paths) # Filter on provided surface attributes surface_table = surface_table[surface_table["attribute"].isin( self._surf_attrs)] # Filter on provided surface names self._surfacenames = (list(surface_table["name"].unique()) if surface_name_filter is None else surface_name_filter) surface_table = surface_table[surface_table["name"].isin( surface_name_filter)] if surface_table.empty: raise ValueError("No surfaces found with the given attributes") self.ensembles = list(surface_table["ENSEMBLE"].unique()) for _, attr_df in surface_table.groupby("attribute"): if set(attr_df["name"].unique()) != set(self._surfacenames): raise ValueError( "Surface attributes has different surfaces. This is not supported!" ) self._surface_ensemble_set_model = { ens: SurfaceSetModel(surf_ens_df) for ens, surf_ens_df in surface_table.groupby("ENSEMBLE") } self._realizations = sorted(list(surface_table["REAL"].unique())) self._zonelog = zonelog colors = [ "#1f77b4", # muted blue "#ff7f0e", # safety orange "#2ca02c", # cooked asparagus green "#d62728", # brick red "#9467bd", # muted purple "#8c564b", # chestnut brown "#e377c2", # raspberry yogurt pink "#7f7f7f", # middle gray "#bcbd22", # curry yellow-green "#17becf", # blue-teal ] self._surfacecolors = [{ "surfacename": surfacename, "ensemble": ens, "COLOR": self._initial_settings.get("colors", {}).get(surfacename, {}).get( ens, colors[idx % len(colors)]), } for idx, surfacename in enumerate(self._surfacenames) for ens in self.ensembles] self._color_picker = ColorPicker( app=app, uuid=self.uuid("colorpicker"), dframe=pd.DataFrame(self._surfacecolors), ) self.first_surface_geometry = self._surface_ensemble_set_model[ self.ensembles[0]].first_surface_geometry self.set_callbacks(app)