예제 #1
0
def make_surfaces(
    surface_table: pd.DataFrame,
    prop: str,
    zone: str,
    ensemble: str,
    delta_ensemble: str,
    get_uuid: Callable,
    statistic: str = "mean",
) -> html.Div:

    try:
        ens_surface = surface_from_zone_prop(
            surface_table,
            zone=zone,
            prop=prop,
            ensemble=ensemble,
            stype=statistic,
        )
        delta_ens_surface = surface_from_zone_prop(
            surface_table,
            zone=zone,
            prop=prop,
            ensemble=delta_ensemble,
            stype=statistic,
        )
    except ValueError:
        return html.Div("No surfaces found")

    # Truncating surface values to highest low and lowest high for each map
    min_val = max([ens_surface.values.min(), delta_ens_surface.values.min()])
    max_val = min([ens_surface.values.max(), delta_ens_surface.values.max()])

    ens_surface.values[ens_surface.values < min_val] = min_val
    ens_surface.values[ens_surface.values > max_val] = max_val
    delta_ens_surface.values[delta_ens_surface.values < min_val] = min_val
    delta_ens_surface.values[delta_ens_surface.values > max_val] = max_val
    diff_surface = ens_surface.copy()
    diff_surface.values = ens_surface.values - delta_ens_surface.values
    return surface_views(
        ens_layer=SurfaceLeafletModel(ens_surface, name="ens_surface").layer,
        delta_ens_layer=SurfaceLeafletModel(
            delta_ens_surface, name="delta_ens_surface"
        ).layer,
        diff_layer=SurfaceLeafletModel(diff_surface, name="diff_surface").layer,
        ensemble=ensemble,
        delta_ensemble=delta_ensemble,
        get_uuid=get_uuid,
        prop=prop,
        zone=zone,
    )
예제 #2
0
        def _render_surface(
            fencespec: List[List[float]],
            surfacename: str,
            surfacetype: str,
            ensemble: str,
        ) -> List[dict]:
            """Update map"""
            intersect_layer = {
                "name":
                "Well",
                "id":
                "Well",
                "action":
                "replace",
                "checked":
                True,
                "base_layer":
                False,
                "data": [{
                    "type": "polyline",
                    "color": "red",
                    "positions": fencespec,
                }],
            }

            surface = get_surface_statistics(
                self.realizations.to_dict(orient="records"),
                ensemble,
                self.surfacefiles[self.surfacenames.index(surfacename)],
                self.surfacefolder,
            )[surfacetype]

            surface_layer = SurfaceLeafletModel(surface,
                                                name=surfacename).layer
            return [surface_layer, intersect_layer]
        def _render_surface(
            surfacepath,
            surface_type,
            gridparameter,
            color_values,
            colorscale,
            hillshade,
        ):

            surface = xtgeo.RegularSurface(get_path(surfacepath))
            min_val = None
            max_val = None
            color = None

            if surface_type == "attribute":
                min_val = color_values[0] if color_values else None
                max_val = color_values[1] if color_values else None
                color = colorscale if colorscale else color
                grid = load_grid(get_path(self.gridfile))
                gridparameter = load_grid_parameter(grid,
                                                    get_path(gridparameter))
                surface.slice_grid3d(grid, gridparameter)

            return [
                SurfaceLeafletModel(
                    surface,
                    name="surface",
                    clip_min=min_val,
                    clip_max=max_val,
                    apply_shading=hillshade.get("value", False),
                ).layer
            ]
예제 #4
0
def create_or_return_base_layer(
    update_controls: Dict,
    surface: xtgeo.RegularSurface,
    current_map: List[Dict],
    shade_map: Dict[str, bool],
    color_range_settings: Dict,
    map_id: str,
) -> List[Dict]:

    surface_layers = []
    if update_controls[map_id]["use_base_layer"]:
        for layer in current_map:
            if layer["baseLayer"]:
                layer["data"][0]["shader"]["applyHillshading"] = shade_map.get(
                    "value")
                surface_layers = [layer]
    else:
        surface_layers = [
            SurfaceLeafletModel(
                surface,
                clip_min=color_range_settings[map_id]["color_range"][0],
                clip_max=color_range_settings[map_id]["color_range"][1],
                name=map_id,
                apply_shading=shade_map.get("value", False),
            ).layer
        ]
    return surface_layers
예제 #5
0
 def _render_surface(wellfile: str) -> List[Dict[str, Any]]:
     """Update map"""
     wellname = Path(wellfile).stem
     wellfile = get_path(wellfile)
     surface = load_surface(get_path(self.surfacefiles[0]))
     well = load_well(wellfile)
     s_layer = SurfaceLeafletModel(surface, name=self.surfacenames[0]).layer
     well_layer = make_well_layer(well, wellname)
     return [s_layer, well_layer]
def make_surfaces(
    parent: "PropertyStatistics",
    prop: str,
    zone: str,
    ensemble: str,
    delta_ensemble: str,
    statistic: str = "mean",
) -> html.Div:

    sprop = parent.surface_renaming.get(prop, prop)
    szone = parent.surface_renaming.get(zone, zone)
    ens_surface = surface_from_zone_prop(parent,
                                         zone=szone,
                                         prop=sprop,
                                         ensemble=ensemble,
                                         stype=statistic)
    delta_ens_surface = surface_from_zone_prop(parent,
                                               zone=szone,
                                               prop=sprop,
                                               ensemble=delta_ensemble,
                                               stype=statistic)

    # Truncating surface values to highest low and lowest high for each map
    min_val = max([ens_surface.values.min(), delta_ens_surface.values.min()])
    max_val = min([ens_surface.values.max(), delta_ens_surface.values.max()])

    ens_surface.values[ens_surface.values < min_val] = min_val
    ens_surface.values[ens_surface.values > max_val] = max_val
    delta_ens_surface.values[delta_ens_surface.values < min_val] = min_val
    delta_ens_surface.values[delta_ens_surface.values > max_val] = max_val
    diff_surface = ens_surface.copy()
    diff_surface.values = ens_surface.values - delta_ens_surface.values
    return surface_views(
        ens_layer=SurfaceLeafletModel(ens_surface, name="ens_surface").layer,
        delta_ens_layer=SurfaceLeafletModel(delta_ens_surface,
                                            name="delta_ens_surface").layer,
        diff_layer=SurfaceLeafletModel(diff_surface,
                                       name="diff_surface").layer,
        ensemble=ensemble,
        delta_ensemble=delta_ensemble,
        parent=parent,
        prop=prop,
        zone=zone,
    )
예제 #7
0
 def _update_surface(clickdata: Union[None, dict], ensemble: str,
                     stype: str) -> Tuple[list, str]:
     if clickdata is not None:
         label = clickdata["points"][0]["y"]
         prop = label.split(" | ")[0]
         zone = label.split(" | ")[1]
         sprop = parent.surface_renaming.get(prop, prop)
         szone = parent.surface_renaming.get(zone, zone)
         surface = surface_from_zone_prop(parent,
                                          zone=szone,
                                          prop=sprop,
                                          ensemble=ensemble,
                                          stype=stype)
         surface_layer = SurfaceLeafletModel(surface, name="surface").layer
         return [surface_layer], f"{stype.capitalize()} for {prop}, {zone}"
     raise PreventUpdate
        def _render_surface(surfacepath, surface_type, cubepath, color_values,
                            hillshade):

            surface = xtgeo.surface_from_file(get_path(surfacepath))
            min_val = None
            max_val = None
            if surface_type == "attribute":
                min_val = color_values[0] if color_values else None
                max_val = color_values[1] if color_values else None
                cube = load_cube_data(get_path(cubepath))
                surface.slice_cube(cube)
            return [
                SurfaceLeafletModel(
                    surface,
                    name="surface",
                    clip_min=min_val,
                    clip_max=max_val,
                    apply_shading=hillshade.get("value", False),
                ).layer
            ]
예제 #9
0
        def _render_map(surface_name, switch, wellfile):
            """Renders map view for one surface with de, dt, dte, dr, dre and depth
            Wells marked with circles, trajectory and hillshading toggle
            """

            surfaces = [
                self.surface_attributes[surface_name]["surface"],
                self.surface_attributes[surface_name]["surface_de"],
                self.surface_attributes[surface_name]["surface_dr"],
                self.surface_attributes[surface_name]["surface_dt"],
                self.surface_attributes[surface_name]["surface_dte"],
            ]
            well_layers = get_well_layers(
                self.wells,
                self.planned_wells,
                surface_name,
                surfaces[0],
                wellfile,
            )
            layers = []
            for i, surface in enumerate(surfaces):
                layers.append(
                    SurfaceLeafletModel(
                        surface,
                        name=self.surface_types[i],
                        apply_shading=switch["value"],
                        updatemode="add",
                    ).layer
                )
            layers.extend(well_layers)
            # Deletes old layers when switching surface in dropdown
            old_layers = self.layers_state
            self.layers_state = layers.copy()
            if old_layers is not None and len(old_layers) > 0:
                for layer in old_layers:
                    layer["action"] = "delete"
                old_layers.extend(layers)
                layers = old_layers
            return layers
예제 #10
0
    def _update_surface(clickdata: Union[None, dict], ensemble: str,
                        stype: str) -> Tuple[list, str]:
        if clickdata is not None:
            label = clickdata["points"][0]["y"]
            prop = label.split(" | ")[0]
            zone = label.split(" | ")[1]

            try:
                surface = surface_from_zone_prop(
                    surface_table,
                    zone=zone,
                    prop=prop,
                    ensemble=ensemble,
                    stype=stype,
                )
            except ValueError:  # Surface does not exist
                return (
                    no_update,
                    f"No surface found for {stype.capitalize()} for {prop}, {zone}",
                )
            surface_layer = SurfaceLeafletModel(surface, name="surface").layer
            return [surface_layer], f"{stype.capitalize()} for {prop}, {zone}"
        raise PreventUpdate
예제 #11
0
        def _set_base_layer(
            stored_selector_data: str,
            ensemble: str,
            real: str,
            stored_selector2_data: str,
            ensemble2: str,
            real2: str,
            calculation: str,
            stored_attribute_settings: str,
            diff_min: Union[int, float, None],
            diff_max: Union[int, float, None],
            hillshade: dict,
            hillshade2: dict,
            hillshade3: dict,
        ) -> Tuple[List[dict], List[dict], List[dict], str]:
            ctx = callback_context.triggered
            if not ctx or not stored_selector_data or not stored_selector2_data:
                raise PreventUpdate

            # TODO(Sigurd)
            # These two are presumably of type dict, but the type depends on the actual python
            # objects that get serialized inside SurfaceSelector.
            # Should deserialization and validation be delegated to SurfaceSelector?
            # Note that according to the doc, it seems that dcc.Store actualy does the
            # serialization/deserialization for us!
            # Should be refactored
            data: dict = json.loads(stored_selector_data)
            data2: dict = json.loads(stored_selector2_data)
            if not isinstance(data, dict) or not isinstance(data2, dict):
                raise TypeError("Selector data payload must be of type dict")
            attribute_settings: dict = json.loads(stored_attribute_settings)
            if not isinstance(attribute_settings, dict):
                raise TypeError("Expected stored attribute_settings to be of type dict")

            if real in ["Mean", "StdDev", "Min", "Max"]:
                surface = self._surface_ensemble_set_model[
                    ensemble
                ].calculate_statistical_surface(**data, calculation=real)

            else:
                surface = self._surface_ensemble_set_model[
                    ensemble
                ].get_realization_surface(**data, realization=int(real))

            if real2 in ["Mean", "StdDev", "Min", "Max"]:
                surface2 = self._surface_ensemble_set_model[
                    ensemble2
                ].calculate_statistical_surface(**data2, calculation=real2)

            else:
                surface2 = self._surface_ensemble_set_model[
                    ensemble2
                ].get_realization_surface(**data2, realization=int(real2))

            surface_layers: List[dict] = [
                SurfaceLeafletModel(
                    surface,
                    name="surface",
                    colors=attribute_settings.get(data["attribute"], {}).get("color"),
                    apply_shading=hillshade.get("value", False),
                    clip_min=attribute_settings.get(data["attribute"], {}).get(
                        "min", None
                    ),
                    clip_max=attribute_settings.get(data["attribute"], {}).get(
                        "max", None
                    ),
                    unit=attribute_settings.get(data["attribute"], {}).get("unit", " "),
                ).layer
            ]
            surface_layers2: List[dict] = [
                SurfaceLeafletModel(
                    surface2,
                    name="surface2",
                    colors=attribute_settings.get(data2["attribute"], {}).get("color"),
                    apply_shading=hillshade2.get("value", False),
                    clip_min=attribute_settings.get(data2["attribute"], {}).get(
                        "min", None
                    ),
                    clip_max=attribute_settings.get(data2["attribute"], {}).get(
                        "max", None
                    ),
                    unit=attribute_settings.get(data2["attribute"], {}).get(
                        "unit", " "
                    ),
                ).layer
            ]

            try:
                surface3 = calculate_surface_difference(surface, surface2, calculation)
                if diff_min is not None:
                    surface3.values[surface3.values <= diff_min] = diff_min
                if diff_max is not None:
                    surface3.values[surface3.values >= diff_max] = diff_max
                diff_layers: List[dict] = []
                diff_layers.append(
                    SurfaceLeafletModel(
                        surface3,
                        name="surface3",
                        colors=attribute_settings.get(data["attribute"], {}).get(
                            "color"
                        ),
                        apply_shading=hillshade3.get("value", False),
                    ).layer
                )
                error_label = ""
            except ValueError:
                diff_layers = []
                error_label = (
                    "Cannot calculate because the surfaces have different geometries"
                )

            if self.well_layer:
                surface_layers.append(self.well_layer)
                surface_layers2.append(self.well_layer)
                diff_layers.append(self.well_layer)
            return (surface_layers, surface_layers2, diff_layers, error_label)
예제 #12
0
    def _update_maps(
        surfattr_map: str,
        surfattr_map2: str,
        surfname_map: str,
        surfname_map2: str,
        ensemble_map: str,
        ensemble_map2: str,
        calc_map: str,
        calc_map2: str,
        shade_map: Dict[str, bool],
        shade_map2: Dict[str, bool],
        shade_map3: Dict[str, bool],
        options: List[str],
        options2: List[str],
        color_range_settings: Dict,
        compute_diff: List[str],
        real_list: List[str],
        wellname: Optional[str],
        polyline: Optional[List],
        xline: Optional[List],
        yline: Optional[List],
        source: str,
        current_map: List,
        current_map2: List,
        current_map3: List,
    ) -> Tuple[str, List, str, List, str, List]:
        """Generate Leaflet layers for the three map views"""
        realizations = [int(real) for real in real_list]
        ctx = dash.callback_context.triggered[0]
        if "compute_diff" in ctx["prop_id"]:
            if not compute_diff:
                return (
                    dash.no_update,
                    dash.no_update,
                    dash.no_update,
                    dash.no_update,
                    dash.no_update,
                    [],
                )

        # Check if map is already generated and should just be updated with polylines
        update_poly_only = bool(current_map
                                and ("stored_polyline" in ctx["prop_id"]
                                     or "stored_yline" in ctx["prop_id"]
                                     or "stored_xline" in ctx["prop_id"]))
        if polyline is not None:
            poly_layer = create_leaflet_polyline_layer(polyline,
                                                       name="Polyline",
                                                       poly_id="random_line")
            for map_layers in [current_map, current_map2, current_map3]:
                map_layers = replace_or_add_map_layer(map_layers, "Polyline",
                                                      poly_layer)
        if xline is not None and source == "xline":
            xline_layer = create_leaflet_polyline_layer(xline,
                                                        name="Xline",
                                                        poly_id="x_line")
            for map_layers in [current_map, current_map2, current_map3]:
                map_layers = replace_or_add_map_layer(map_layers, "Xline",
                                                      xline_layer)
        if yline is not None and source == "yline":
            yline_layer = create_leaflet_polyline_layer(yline,
                                                        name="Yline",
                                                        poly_id="y_line")
            for map_layers in [current_map, current_map2, current_map3]:
                map_layers = replace_or_add_map_layer(map_layers, "Yline",
                                                      yline_layer)
        # If callback is triggered by polyline drawing, only update polyline
        if update_poly_only:
            return (
                f"Surface A: {surfattr_map} - {surfname_map} - {ensemble_map} - {calc_map}",
                current_map,
                f"Surface B: {surfattr_map2} - {surfname_map2} - {ensemble_map2} - {calc_map2}",
                dash.no_update,
                "Surface A-B",
                dash.no_update,
            )

        if wellname is not None:
            well = well_set_model.get_well(wellname)
            well_layer = make_well_layer(well, name=well.name)

            # If callback is triggered by well change, only update well layer
            if "well" in ctx["prop_id"] or ("source" in ctx["prop_id"]
                                            and source == "well"):
                for map_layers in [current_map, current_map2, current_map3]:
                    map_layers = replace_or_add_map_layer(
                        map_layers, "Well", well_layer)
                return (
                    f"Surface A: {surfattr_map} - {surfname_map} - "
                    f"{ensemble_map} - {calc_map}",
                    current_map,
                    f"Surface B: {surfattr_map2} - {surfname_map2} - "
                    f"{ensemble_map2} - {calc_map2}",
                    current_map2,
                    "Surface A-B",
                    dash.no_update,
                )

        # Calculate maps
        if calc_map in ["Mean", "StdDev", "Max", "Min", "P90", "P10"]:
            surface = surface_set_models[
                ensemble_map].calculate_statistical_surface(
                    name=surfname_map,
                    attribute=surfattr_map,
                    calculation=calc_map,
                    realizations=realizations,
                )
        else:
            surface = surface_set_models[ensemble_map].get_realization_surface(
                name=surfname_map,
                attribute=surfattr_map,
                realization=int(calc_map))
        if calc_map2 in ["Mean", "StdDev", "Max", "Min", "P90", "P10"]:
            surface2 = surface_set_models[
                ensemble_map2].calculate_statistical_surface(
                    name=surfname_map2,
                    attribute=surfattr_map2,
                    calculation=calc_map2,
                    realizations=realizations,
                )
        else:
            surface2 = surface_set_models[
                ensemble_map2].get_realization_surface(
                    name=surfname_map2,
                    attribute=surfattr_map2,
                    realization=int(calc_map2))

        # Generate Leaflet layers
        update_controls = check_if_update_needed(
            ctx=ctx,
            current_maps=[current_map, current_map2],
            compute_diff=compute_diff,
            color_range_settings=color_range_settings,
        )

        surface_layers = create_or_return_base_layer(
            update_controls,
            surface,
            current_map,
            shade_map,
            color_range_settings,
            map_id="map1",
        )
        surface_layers2 = create_or_return_base_layer(
            update_controls,
            surface2,
            current_map2,
            shade_map2,
            color_range_settings,
            map_id="map2",
        )

        try:
            surface3 = surface.copy()
            surface3.values = surface3.values - surface2.values

            diff_layers = ([
                SurfaceLeafletModel(
                    surface3,
                    name="surface3",
                    apply_shading=shade_map3.get("value", False),
                ).layer
            ] if update_controls["diff_map"]["update"] else [])
        except ValueError:
            diff_layers = []

        if wellname is not None:
            surface_layers.append(well_layer)
            surface_layers2.append(well_layer)
        if polyline is not None:
            surface_layers.append(poly_layer)
        if xline is not None and source == "xline":
            surface_layers.append(xline_layer)
        if yline is not None and source == "yline":
            surface_layers.append(yline_layer)
        if well_set_model is not None:
            if options is not None or options2 is not None:
                if "intersect_well" in options or "intersect_well" in options2:
                    ### This is potentially a heavy task as it loads all wells into memory
                    wells: List[xtgeo.Well] = list(
                        well_set_model.wells.values())
                if "intersect_well" in options and update_controls["map1"][
                        "update"]:
                    surface_layers.append(
                        create_leaflet_well_marker_layer(wells, surface))
                if "intersect_well" in options2 and update_controls["map2"][
                        "update"]:
                    surface_layers2.append(
                        create_leaflet_well_marker_layer(wells, surface2))

        return (
            f"Surface A: {surfattr_map} - {surfname_map} - {ensemble_map} - {calc_map}",
            surface_layers
            if update_controls["map1"]["update"] else dash.no_update,
            f"Surface B: {surfattr_map2} - {surfname_map2} - {ensemble_map2} - {calc_map2}",
            surface_layers2
            if update_controls["map2"]["update"] else dash.no_update,
            "Surface A-B",
            diff_layers
            if update_controls["diff_map"]["update"] else dash.no_update,
        )