def __init__( self, app: Dash, webviz_settings: WebvizSettings, ensembles: list, attributes: list = None, attribute_settings: dict = None, wellfolder: Path = None, wellsuffix: str = ".w", map_height: int = 600, ): super().__init__() self.ens_paths = { ens: webviz_settings.shared_settings["scratch_ensembles"][ens] for ens in ensembles } # Find surfaces self._surface_table = find_surfaces(self.ens_paths) # Extract realizations and sensitivity information self.ens_df = get_realizations( ensemble_paths=self.ens_paths, ensemble_set_name="EnsembleSet" ) # Drop any ensembles that does not have surfaces self.ens_df = self.ens_df.loc[ self.ens_df["ENSEMBLE"].isin(self._surface_table["ENSEMBLE"].unique()) ] if attributes is not None: self._surface_table = self._surface_table[ self._surface_table["attribute"].isin(attributes) ] if self._surface_table.empty: raise ValueError("No surfaces found with the given attributes") self._surface_ensemble_set_model = { ens: SurfaceSetModel(surf_ens_df) for ens, surf_ens_df in self._surface_table.groupby("ENSEMBLE") } self.attribute_settings: dict = attribute_settings if attribute_settings else {} self.map_height = map_height self.surfaceconfig = surfacedf_to_dict(self._surface_table) self.wellfolder = wellfolder self.wellsuffix = wellsuffix self.wellfiles: Union[List[str], None] = ( json.load(find_files(wellfolder, wellsuffix)) if wellfolder is not None else None ) self.well_layer = ( make_well_layers([get_path(wellfile) for wellfile in self.wellfiles]) if self.wellfiles else None ) self.selector = SurfaceSelector(app, self.surfaceconfig, ensembles) self.selector2 = SurfaceSelector(app, self.surfaceconfig, ensembles) self.set_callbacks(app)
def test_surface_set_model(testdata_folder): ensemble_paths = { "iter-0": str( Path(testdata_folder / "01_drogon_ahm" / "realization-*" / "iter-0")) } surface_table = find_surfaces(ensemble_paths) surface_table = surface_table.drop("ENSEMBLE", axis=1) smodel = SurfaceSetModel(surface_table) assert set(smodel.attributes) == set([ "ds_extract_postprocess", "amplitude_mean", "ds_extract_geogrid", "amplitude_rms", "oilthickness", ]) assert set(smodel.names_in_attribute("ds_extract_postprocess")) == set( ["basevolantis", "topvolantis", "toptherys", "topvolon"]) real_surf = smodel.get_realization_surface( attribute="ds_extract_postprocess", name="topvolon", realization=0) assert isinstance(real_surf, xtgeo.RegularSurface) assert real_surf.values.mean() == pytest.approx(1735.42, 0.00001) stat_surf = smodel.calculate_statistical_surface( attribute="ds_extract_postprocess", name="topvolon") assert isinstance(stat_surf, xtgeo.RegularSurface) assert stat_surf.values.mean() == pytest.approx(1741.04, 0.00001) stat_surf = smodel.calculate_statistical_surface( attribute="ds_extract_postprocess", name="topvolon", realizations=[0, 1]) assert stat_surf.values.mean() == pytest.approx(1741.04, 0.00001)
def __init__( self, app, ensembles: list, attributes: list = None, attribute_settings: dict = None, wellfolder: Path = None, wellsuffix: str = ".w", ): super().__init__() self.ens_paths = { ens: app.webviz_settings["shared_settings"]["scratch_ensembles"][ens] for ens in ensembles } # Find surfaces self.surfacedf = find_surfaces(self.ens_paths) if attributes is not None: self.surfacedf = self.surfacedf[ self.surfacedf["attribute"].isin(attributes) ] if self.surfacedf.empty: raise ValueError("No surfaces found with the given attributes") self.attribute_settings = attribute_settings if attribute_settings else {} self.surfaceconfig = surfacedf_to_dict(self.surfacedf) self.wellfolder = wellfolder self.wellsuffix = wellsuffix self.wellfiles = ( json.load(find_files(wellfolder, wellsuffix)) if wellfolder is not None else None ) self.well_layer = ( make_well_layers([get_path(wellfile) for wellfile in self.wellfiles]) if self.wellfiles else None ) # Extract realizations and sensitivity information self.ens_df = get_realizations( ensemble_paths=self.ens_paths, ensemble_set_name="EnsembleSet" ) self.selector = SurfaceSelector(app, self.surfaceconfig, ensembles) self.selector2 = SurfaceSelector(app, self.surfaceconfig, ensembles) self.set_callbacks(app)
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)