webviz-subsurface 0.2.43__py3-none-any.whl → 0.2.46__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- webviz_subsurface/_datainput/well_completions.py +1 -1
- webviz_subsurface/_models/gruptree_model.py +31 -7
- webviz_subsurface/_providers/ensemble_polygon_provider/_provider_impl_file.py +2 -1
- webviz_subsurface/_version.py +2 -2
- webviz_subsurface/plugins/_co2_migration/_plugin.py +31 -8
- webviz_subsurface/plugins/_co2_migration/_utilities/callbacks.py +183 -19
- webviz_subsurface/plugins/_co2_migration/_utilities/co2volume.py +83 -62
- webviz_subsurface/plugins/_co2_migration/_utilities/containment_data_provider.py +6 -0
- webviz_subsurface/plugins/_co2_migration/_utilities/generic.py +40 -3
- webviz_subsurface/plugins/_co2_migration/_utilities/initialization.py +2 -1
- webviz_subsurface/plugins/_co2_migration/_utilities/polygon_handler.py +4 -0
- webviz_subsurface/plugins/_co2_migration/views/mainview/settings.py +38 -3
- webviz_subsurface/plugins/_simulation_time_series/_views/_subplot_view/_property_serialization/ensemble_subplot_builder.py +3 -1
- webviz_subsurface/plugins/_vfp_analysis/_utils/_vfp_data_model.py +1 -1
- {webviz_subsurface-0.2.43.dist-info → webviz_subsurface-0.2.46.dist-info}/METADATA +1 -2
- {webviz_subsurface-0.2.43.dist-info → webviz_subsurface-0.2.46.dist-info}/RECORD +20 -21
- {webviz_subsurface-0.2.43.dist-info → webviz_subsurface-0.2.46.dist-info}/WHEEL +1 -1
- webviz_subsurface-0.2.43.dist-info/licenses/LICENSE.chromedriver +0 -6291
- {webviz_subsurface-0.2.43.dist-info → webviz_subsurface-0.2.46.dist-info}/entry_points.txt +0 -0
- {webviz_subsurface-0.2.43.dist-info → webviz_subsurface-0.2.46.dist-info}/licenses/LICENSE +0 -0
- {webviz_subsurface-0.2.43.dist-info → webviz_subsurface-0.2.46.dist-info}/top_level.txt +0 -0
|
@@ -69,7 +69,7 @@ def read_zone_layer_mapping(
|
|
|
69
69
|
)
|
|
70
70
|
df_real["K1"] = df_real.index
|
|
71
71
|
df_real["REAL"] = real
|
|
72
|
-
zonelist = remove_invalid_colors(zonelist)
|
|
72
|
+
zonelist = remove_invalid_colors(zonelist) if zonelist else []
|
|
73
73
|
zone_color_mapping = {
|
|
74
74
|
zonedict["name"]: zonedict["color"]
|
|
75
75
|
for zonedict in zonelist
|
|
@@ -191,16 +191,13 @@ GruptreeDataModel({self._ens_name!r}, {self._ens_path!r}, {self._gruptree_file!r
|
|
|
191
191
|
raise ValueError(
|
|
192
192
|
f"Keyword {self._tree_type.value} not found in {row['FULLPATH']}"
|
|
193
193
|
)
|
|
194
|
+
|
|
195
|
+
# Only filter if both tree types are present
|
|
194
196
|
if (
|
|
195
|
-
|
|
197
|
+
TreeType.GRUPTREE.value in unique_keywords
|
|
196
198
|
and TreeType.BRANPROP.value in unique_keywords
|
|
197
199
|
):
|
|
198
|
-
|
|
199
|
-
df_real = df_real[df_real["KEYWORD"] != TreeType.BRANPROP.value]
|
|
200
|
-
|
|
201
|
-
if self._tree_type == TreeType.BRANPROP:
|
|
202
|
-
# Filter out GRUPTREE entries
|
|
203
|
-
df_real = df_real[df_real["KEYWORD"] != TreeType.GRUPTREE.value]
|
|
200
|
+
df_real = self._filter_by_tree_type(df_real, self._tree_type)
|
|
204
201
|
|
|
205
202
|
if (
|
|
206
203
|
i > 0
|
|
@@ -222,3 +219,30 @@ GruptreeDataModel({self._ens_name!r}, {self._ens_path!r}, {self._gruptree_file!r
|
|
|
222
219
|
df["DATE"] = pd.to_datetime(df["DATE"])
|
|
223
220
|
|
|
224
221
|
return df.where(pd.notnull(df), None)
|
|
222
|
+
|
|
223
|
+
@staticmethod
|
|
224
|
+
def _filter_by_tree_type(df: pd.DataFrame, tree_type: TreeType) -> pd.DataFrame:
|
|
225
|
+
"""
|
|
226
|
+
Filter dataframe to include only dates where the selected tree type is defined,
|
|
227
|
+
and only include WELSPECS nodes that belong to the selected tree type.
|
|
228
|
+
|
|
229
|
+
A WELSPECS node belongs to a tree if its parent node exists in that tree's definition.
|
|
230
|
+
"""
|
|
231
|
+
# Find dates where the selected tree type is defined
|
|
232
|
+
dates_with_tree_type = df[df["KEYWORD"] == tree_type.value]["DATE"].unique()
|
|
233
|
+
|
|
234
|
+
# Filter to only include rows from those dates
|
|
235
|
+
df = df[df["DATE"].isin(dates_with_tree_type)].copy()
|
|
236
|
+
|
|
237
|
+
# Get all nodes that are defined in the selected tree type (across all dates)
|
|
238
|
+
tree_nodes = set(df[df["KEYWORD"] == tree_type.value]["CHILD"].unique())
|
|
239
|
+
|
|
240
|
+
# Keep rows that are:
|
|
241
|
+
# 1. The selected tree type itself (GRUPTREE or BRANPROP)
|
|
242
|
+
# 2. WELSPECS whose parent exists in the selected tree type
|
|
243
|
+
is_selected_tree = df["KEYWORD"] == tree_type.value
|
|
244
|
+
is_welspecs_with_valid_parent = (df["KEYWORD"] == "WELSPECS") & df[
|
|
245
|
+
"PARENT"
|
|
246
|
+
].isin(tree_nodes)
|
|
247
|
+
|
|
248
|
+
return df[is_selected_tree | is_welspecs_with_valid_parent].copy()
|
|
@@ -33,7 +33,8 @@ class Col:
|
|
|
33
33
|
|
|
34
34
|
class PolygonType(StrEnum):
|
|
35
35
|
SIMULATED = "simulated"
|
|
36
|
-
|
|
36
|
+
HAZARDOUS_BOUNDARY = "hazardous_boundary" # Keep for backward compatibility
|
|
37
|
+
NOGO_BOUNDARY = "nogo_boundary"
|
|
37
38
|
CONTAINMENT_BOUNDARY = "containment_boundary"
|
|
38
39
|
|
|
39
40
|
|
webviz_subsurface/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.2.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
31
|
+
__version__ = version = '0.2.46'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 2, 46)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -40,6 +40,8 @@ from webviz_subsurface.plugins._co2_migration._utilities.generic import (
|
|
|
40
40
|
MapAttribute,
|
|
41
41
|
MapThresholds,
|
|
42
42
|
MapType,
|
|
43
|
+
check_hazardous_polygon,
|
|
44
|
+
deactivate_polygon_warnings,
|
|
43
45
|
)
|
|
44
46
|
from webviz_subsurface.plugins._co2_migration._utilities.initialization import (
|
|
45
47
|
init_containment_data_providers,
|
|
@@ -95,7 +97,7 @@ class CO2Migration(WebvizPluginABC):
|
|
|
95
97
|
* **`map_surface_names_to_fault_polygons`:** Mapping between surface map names and
|
|
96
98
|
surface names used by the fault polygons
|
|
97
99
|
* **`boundary_settings`:** Settings for polygons representing the containment and
|
|
98
|
-
|
|
100
|
+
nogo areas
|
|
99
101
|
---
|
|
100
102
|
|
|
101
103
|
This plugin is tightly linked to the FMU CCS post-process available in the ccs-scripts
|
|
@@ -141,17 +143,17 @@ class CO2Migration(WebvizPluginABC):
|
|
|
141
143
|
Similar for `map_surface_names_to_fault_polygons`.
|
|
142
144
|
|
|
143
145
|
`boundary_settings` is the final override option, and it can be used to specify
|
|
144
|
-
polygons representing the containment and
|
|
146
|
+
polygons representing the containment and nogo areas. By default, the polygons are
|
|
145
147
|
expected to be named:
|
|
146
148
|
- `share/results/polygons/containment--boundary.csv`
|
|
147
|
-
- `share/results/polygons/
|
|
149
|
+
- `share/results/polygons/nogo--boundary.csv`
|
|
148
150
|
|
|
149
151
|
This corresponds to the following input:
|
|
150
152
|
```
|
|
151
153
|
boundary_settings:
|
|
152
154
|
polygon_file_pattern: share/results/polygons/*.csv
|
|
153
155
|
attribute: boundary
|
|
154
|
-
|
|
156
|
+
nogo_name: nogo
|
|
155
157
|
containment_name: containment
|
|
156
158
|
```
|
|
157
159
|
All four settings are optional, and if not specified, the default values are used.
|
|
@@ -182,6 +184,8 @@ class CO2Migration(WebvizPluginABC):
|
|
|
182
184
|
super().__init__()
|
|
183
185
|
self._error_message = ""
|
|
184
186
|
try:
|
|
187
|
+
deactivate_polygon_warnings()
|
|
188
|
+
check_hazardous_polygon(boundary_settings)
|
|
185
189
|
ensemble_paths = {
|
|
186
190
|
ensemble_name: webviz_settings.shared_settings["scratch_ensembles"][
|
|
187
191
|
ensemble_name
|
|
@@ -435,6 +439,13 @@ class CO2Migration(WebvizPluginABC):
|
|
|
435
439
|
"cm_max_val": Input(
|
|
436
440
|
self._settings_component(ViewSettings.Ids.CM_MAX), "value"
|
|
437
441
|
),
|
|
442
|
+
"contour_switch": Input(
|
|
443
|
+
self._settings_component(ViewSettings.Ids.CONTOURS_SWITCH), "value"
|
|
444
|
+
),
|
|
445
|
+
"contour_quantity": Input(
|
|
446
|
+
self._settings_component(ViewSettings.Ids.CONTOURS_QUANTITY),
|
|
447
|
+
"value",
|
|
448
|
+
),
|
|
438
449
|
"plume_threshold": Input(
|
|
439
450
|
self._settings_component(ViewSettings.Ids.PLUME_THRESHOLD),
|
|
440
451
|
"value",
|
|
@@ -480,12 +491,14 @@ class CO2Migration(WebvizPluginABC):
|
|
|
480
491
|
cm_min_val: Optional[float],
|
|
481
492
|
cm_max_auto: List[str],
|
|
482
493
|
cm_max_val: Optional[float],
|
|
494
|
+
contour_switch: List[str],
|
|
495
|
+
contour_quantity: Optional[float],
|
|
483
496
|
plume_threshold: Optional[float],
|
|
484
497
|
plume_smoothing: Optional[float],
|
|
485
498
|
visualization_update: int,
|
|
486
499
|
mass_unit: str,
|
|
487
500
|
mass_unit_update: int,
|
|
488
|
-
options_dialog_options: List[
|
|
501
|
+
options_dialog_options: List[str],
|
|
489
502
|
selected_wells: List[str],
|
|
490
503
|
ensemble: str,
|
|
491
504
|
current_views: List[Any],
|
|
@@ -545,13 +558,12 @@ class CO2Migration(WebvizPluginABC):
|
|
|
545
558
|
map_attribute_names=self._map_attribute_names,
|
|
546
559
|
)
|
|
547
560
|
assert isinstance(self._visualization_info["unit"], str)
|
|
548
|
-
|
|
561
|
+
current_summed_mass, self._summed_co2 = process_summed_mass(
|
|
549
562
|
formation,
|
|
550
563
|
realization,
|
|
551
564
|
datestr,
|
|
552
565
|
attribute,
|
|
553
566
|
summed_mass,
|
|
554
|
-
surf_data,
|
|
555
567
|
self._summed_co2,
|
|
556
568
|
self._visualization_info["unit"],
|
|
557
569
|
)
|
|
@@ -568,6 +580,9 @@ class CO2Migration(WebvizPluginABC):
|
|
|
568
580
|
fault_polygon_url = self._fault_polygon_handlers[
|
|
569
581
|
ensemble
|
|
570
582
|
].extract_fault_polygon_url(formation, realization)
|
|
583
|
+
nogo_polygon_url = self._polygon_handlers[ensemble].extract_nogo_poly_url(
|
|
584
|
+
realization
|
|
585
|
+
)
|
|
571
586
|
hazardous_polygon_url = self._polygon_handlers[
|
|
572
587
|
ensemble
|
|
573
588
|
].extract_hazardous_poly_url(realization)
|
|
@@ -580,11 +595,14 @@ class CO2Migration(WebvizPluginABC):
|
|
|
580
595
|
surface_data=surf_data,
|
|
581
596
|
fault_polygon_url=fault_polygon_url,
|
|
582
597
|
containment_bounds_url=containment_polygon_url,
|
|
583
|
-
|
|
598
|
+
nogo_bounds_url=nogo_polygon_url,
|
|
599
|
+
hazardous_bounds_url=hazardous_polygon_url,
|
|
584
600
|
well_pick_provider=self._well_pick_provider.get(ensemble, None),
|
|
585
601
|
plume_extent_data=plume_polygon,
|
|
586
602
|
options_dialog_options=options_dialog_options,
|
|
587
603
|
selected_wells=selected_wells,
|
|
604
|
+
show_contours=len(contour_switch) > 0,
|
|
605
|
+
num_contours=contour_quantity,
|
|
588
606
|
)
|
|
589
607
|
annotations = create_map_annotations(
|
|
590
608
|
formation=formation,
|
|
@@ -592,6 +610,11 @@ class CO2Migration(WebvizPluginABC):
|
|
|
592
610
|
colortables=self._color_tables,
|
|
593
611
|
attribute=attribute,
|
|
594
612
|
unit=self._visualization_info["unit"],
|
|
613
|
+
current_total=current_summed_mass,
|
|
614
|
+
options=options_dialog_options,
|
|
615
|
+
con_url=containment_polygon_url,
|
|
616
|
+
haz_url=hazardous_polygon_url,
|
|
617
|
+
nogo_url=nogo_polygon_url,
|
|
595
618
|
)
|
|
596
619
|
viewports = no_update if current_views else create_map_viewports()
|
|
597
620
|
return layers, annotations, viewports
|
|
@@ -7,7 +7,7 @@ import geojson
|
|
|
7
7
|
import numpy as np
|
|
8
8
|
import plotly.graph_objects as go
|
|
9
9
|
import webviz_subsurface_components as wsc
|
|
10
|
-
from dash import dcc, no_update
|
|
10
|
+
from dash import dcc, html, no_update
|
|
11
11
|
from flask_caching import Cache
|
|
12
12
|
|
|
13
13
|
from webviz_subsurface._providers import (
|
|
@@ -234,12 +234,127 @@ def _find_legend_title(attribute: MapAttribute, unit: str) -> str:
|
|
|
234
234
|
return ""
|
|
235
235
|
|
|
236
236
|
|
|
237
|
+
def _create_summed_mass_annotation(
|
|
238
|
+
attribute: MapAttribute,
|
|
239
|
+
summed_mass: Optional[float],
|
|
240
|
+
unit: str,
|
|
241
|
+
) -> Union[str, tuple]:
|
|
242
|
+
annotation = (
|
|
243
|
+
html.P(
|
|
244
|
+
[
|
|
245
|
+
f"Total {MapAttribute[attribute.name].value.lower()}:",
|
|
246
|
+
html.Br(),
|
|
247
|
+
f"{summed_mass:.2f} {unit}",
|
|
248
|
+
]
|
|
249
|
+
)
|
|
250
|
+
if MapType[attribute.name].value == "MASS" and summed_mass is not None
|
|
251
|
+
else ""
|
|
252
|
+
)
|
|
253
|
+
return html.Div(
|
|
254
|
+
annotation,
|
|
255
|
+
style={
|
|
256
|
+
"position": "absolute",
|
|
257
|
+
"top": "210px",
|
|
258
|
+
"right": "4px",
|
|
259
|
+
"backgroundColor": "rgba(255,255,255,0.8)",
|
|
260
|
+
"padding": "1px 1px",
|
|
261
|
+
"fontWeight": "bold",
|
|
262
|
+
"fontSize": "15px",
|
|
263
|
+
"display": "block",
|
|
264
|
+
},
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _create_polygon_legend(
|
|
269
|
+
options: List[str],
|
|
270
|
+
con_url: Optional[str],
|
|
271
|
+
haz_url: Optional[str], # Keep for backward compatibility
|
|
272
|
+
nogo_url: Optional[str],
|
|
273
|
+
) -> List:
|
|
274
|
+
legend: List = []
|
|
275
|
+
hide_con = con_url is None or LayoutLabels.SHOW_CONTAINMENT_POLYGON not in options
|
|
276
|
+
hide_nogo = (
|
|
277
|
+
nogo_url is None and haz_url is None
|
|
278
|
+
) or LayoutLabels.SHOW_NOGO_POLYGON not in options
|
|
279
|
+
outline = LayoutLabels.SHOW_POLYGONS_AS_OUTLINES in options
|
|
280
|
+
if hide_con and hide_nogo:
|
|
281
|
+
return legend
|
|
282
|
+
legend_items = []
|
|
283
|
+
square = {"width": "12px", "height": "12px", "marginRight": "6px"}
|
|
284
|
+
text = {"color": "black", "fontSize": "14px"}
|
|
285
|
+
if not hide_con:
|
|
286
|
+
legend_items.append(
|
|
287
|
+
html.Div(
|
|
288
|
+
style={"display": "flex", "alignItems": "center"},
|
|
289
|
+
children=[
|
|
290
|
+
html.Div(
|
|
291
|
+
style={
|
|
292
|
+
**square,
|
|
293
|
+
"backgroundColor": "transparent"
|
|
294
|
+
if outline
|
|
295
|
+
else "rgba(0, 172, 0, 0.47)",
|
|
296
|
+
"border": "3px solid rgba(0, 172, 0, 0.70)"
|
|
297
|
+
if outline
|
|
298
|
+
else "transparent",
|
|
299
|
+
}
|
|
300
|
+
),
|
|
301
|
+
html.Div("Containment Polygon", style=text),
|
|
302
|
+
],
|
|
303
|
+
)
|
|
304
|
+
)
|
|
305
|
+
if not hide_nogo:
|
|
306
|
+
legend_items.append(
|
|
307
|
+
html.Div(
|
|
308
|
+
style={"display": "flex", "alignItems": "center"},
|
|
309
|
+
children=[
|
|
310
|
+
html.Div(
|
|
311
|
+
style={
|
|
312
|
+
**square,
|
|
313
|
+
"backgroundColor": "transparent"
|
|
314
|
+
if outline
|
|
315
|
+
else "rgba(200, 0, 0, 0.47)",
|
|
316
|
+
"border": "3px solid rgba(200, 0, 0, 0.70)"
|
|
317
|
+
if outline
|
|
318
|
+
else "transparent",
|
|
319
|
+
}
|
|
320
|
+
),
|
|
321
|
+
html.Div("No-go Polygon", style=text),
|
|
322
|
+
],
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
legend.append(
|
|
326
|
+
wsc.ViewAnnotation(
|
|
327
|
+
id="polygon_legends",
|
|
328
|
+
children=html.Div(
|
|
329
|
+
children=legend_items,
|
|
330
|
+
style={
|
|
331
|
+
"position": "absolute",
|
|
332
|
+
"top": "50px",
|
|
333
|
+
"left": "4px",
|
|
334
|
+
"backgroundColor": "rgba(255,255,255,0.9)",
|
|
335
|
+
"padding": "6px 8px",
|
|
336
|
+
"borderRadius": "4px",
|
|
337
|
+
"boxShadow": "0 0 4px rgba(0,0,0,0.2)",
|
|
338
|
+
"zIndex": 10,
|
|
339
|
+
},
|
|
340
|
+
),
|
|
341
|
+
)
|
|
342
|
+
)
|
|
343
|
+
return legend
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
# pylint: disable=too-many-arguments, too-many-locals
|
|
237
347
|
def create_map_annotations(
|
|
238
348
|
formation: str,
|
|
239
349
|
surface_data: Optional[SurfaceData],
|
|
240
350
|
colortables: List[Dict[str, Any]],
|
|
241
351
|
attribute: MapAttribute,
|
|
242
352
|
unit: str,
|
|
353
|
+
current_total: Optional[float],
|
|
354
|
+
options: List[str],
|
|
355
|
+
con_url: Optional[str],
|
|
356
|
+
haz_url: Optional[str],
|
|
357
|
+
nogo_url: Optional[str],
|
|
243
358
|
) -> List[wsc.ViewAnnotation]:
|
|
244
359
|
annotations = []
|
|
245
360
|
if (
|
|
@@ -268,7 +383,9 @@ def create_map_annotations(
|
|
|
268
383
|
colorTables=colortables,
|
|
269
384
|
),
|
|
270
385
|
wsc.ViewFooter(children=formation),
|
|
271
|
-
|
|
386
|
+
_create_summed_mass_annotation(attribute, current_total, unit),
|
|
387
|
+
]
|
|
388
|
+
+ _create_polygon_legend(options, con_url, haz_url, nogo_url),
|
|
272
389
|
)
|
|
273
390
|
)
|
|
274
391
|
return annotations
|
|
@@ -286,7 +403,8 @@ def create_map_viewports() -> Dict:
|
|
|
286
403
|
"colormap-layer",
|
|
287
404
|
"fault-polygons-layer",
|
|
288
405
|
"license-boundary-layer",
|
|
289
|
-
"
|
|
406
|
+
"nogo-boundary-layer",
|
|
407
|
+
"hazardous-boundary-layer", # Keep for backward compatibility
|
|
290
408
|
"well-picks-layer",
|
|
291
409
|
"plume-polygon-layer",
|
|
292
410
|
],
|
|
@@ -302,16 +420,35 @@ def create_map_layers(
|
|
|
302
420
|
surface_data: Optional[SurfaceData],
|
|
303
421
|
fault_polygon_url: Optional[str],
|
|
304
422
|
containment_bounds_url: Optional[str],
|
|
305
|
-
|
|
423
|
+
nogo_bounds_url: Optional[str],
|
|
424
|
+
hazardous_bounds_url: Optional[str], # Keep for backward compatibility
|
|
306
425
|
well_pick_provider: Optional[EnsembleWellPicks],
|
|
307
426
|
plume_extent_data: Optional[geojson.FeatureCollection],
|
|
308
|
-
options_dialog_options: List[
|
|
427
|
+
options_dialog_options: List[str],
|
|
309
428
|
selected_wells: List[str],
|
|
429
|
+
show_contours: bool,
|
|
430
|
+
num_contours: Optional[float],
|
|
310
431
|
) -> List[Dict]:
|
|
311
432
|
layers = []
|
|
433
|
+
outline = LayoutLabels.SHOW_POLYGONS_AS_OUTLINES in options_dialog_options
|
|
312
434
|
if surface_data is not None:
|
|
313
435
|
# Update ColormapLayer
|
|
314
436
|
meta = surface_data.meta_data
|
|
437
|
+
|
|
438
|
+
# Generate contour lines
|
|
439
|
+
contours = []
|
|
440
|
+
if (
|
|
441
|
+
show_contours
|
|
442
|
+
and surface_data.color_map_range[0] is not None
|
|
443
|
+
and surface_data.color_map_range[1] is not None
|
|
444
|
+
and num_contours is not None
|
|
445
|
+
):
|
|
446
|
+
min_val, max_val = surface_data.color_map_range
|
|
447
|
+
assert min_val is not None and max_val is not None
|
|
448
|
+
buffer = 0.01 * (max_val - min_val) # Strange effects at min_val/max_val
|
|
449
|
+
step = (max_val - min_val + 2 * buffer) / (np.round(num_contours) + 1)
|
|
450
|
+
contours = [min_val + step - buffer, step]
|
|
451
|
+
|
|
315
452
|
layers.append(
|
|
316
453
|
{
|
|
317
454
|
"@@type": "MapLayer",
|
|
@@ -327,6 +464,7 @@ def create_map_layers(
|
|
|
327
464
|
"colorMapName": surface_data.color_map_name,
|
|
328
465
|
"colorMapRange": surface_data.color_map_range,
|
|
329
466
|
"material": False,
|
|
467
|
+
"contours": contours,
|
|
330
468
|
}
|
|
331
469
|
)
|
|
332
470
|
|
|
@@ -353,24 +491,52 @@ def create_map_layers(
|
|
|
353
491
|
"name": "Containment Polygon",
|
|
354
492
|
"id": "license-boundary-layer",
|
|
355
493
|
"data": containment_bounds_url,
|
|
356
|
-
"stroked":
|
|
494
|
+
"stroked": outline,
|
|
495
|
+
"filled": not outline,
|
|
357
496
|
"getFillColor": [0, 172, 0, 120],
|
|
497
|
+
"getLineColor": [0, 172, 0, 120],
|
|
498
|
+
"getLineWidth": 3,
|
|
499
|
+
"lineWidthUnits": "pixels",
|
|
500
|
+
"visible": True,
|
|
501
|
+
}
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
if (
|
|
505
|
+
nogo_bounds_url is not None
|
|
506
|
+
and LayoutLabels.SHOW_NOGO_POLYGON in options_dialog_options
|
|
507
|
+
):
|
|
508
|
+
layers.append(
|
|
509
|
+
{
|
|
510
|
+
"@@type": "GeoJsonLayer",
|
|
511
|
+
"name": "No-go Polygon",
|
|
512
|
+
"id": "nogo-boundary-layer",
|
|
513
|
+
"data": nogo_bounds_url,
|
|
514
|
+
"stroked": outline,
|
|
515
|
+
"filled": not outline,
|
|
516
|
+
"getFillColor": [200, 0, 0, 120],
|
|
517
|
+
"getLineColor": [200, 0, 0, 180],
|
|
518
|
+
"getLineWidth": 3,
|
|
519
|
+
"lineWidthUnits": "pixels",
|
|
358
520
|
"visible": True,
|
|
359
521
|
}
|
|
360
522
|
)
|
|
361
523
|
|
|
362
524
|
if (
|
|
363
|
-
|
|
364
|
-
and LayoutLabels.
|
|
525
|
+
hazardous_bounds_url is not None
|
|
526
|
+
and LayoutLabels.SHOW_NOGO_POLYGON in options_dialog_options
|
|
365
527
|
):
|
|
366
528
|
layers.append(
|
|
367
529
|
{
|
|
368
530
|
"@@type": "GeoJsonLayer",
|
|
369
|
-
"name": "
|
|
531
|
+
"name": "No-go Polygon",
|
|
370
532
|
"id": "hazardous-boundary-layer",
|
|
371
|
-
"data":
|
|
372
|
-
"stroked":
|
|
533
|
+
"data": hazardous_bounds_url,
|
|
534
|
+
"stroked": outline,
|
|
535
|
+
"filled": not outline,
|
|
373
536
|
"getFillColor": [200, 0, 0, 120],
|
|
537
|
+
"getLineColor": [200, 0, 0, 180],
|
|
538
|
+
"getLineWidth": 3,
|
|
539
|
+
"lineWidthUnits": "pixels",
|
|
374
540
|
"visible": True,
|
|
375
541
|
}
|
|
376
542
|
)
|
|
@@ -551,7 +717,7 @@ def process_containment_info(
|
|
|
551
717
|
mark_choice=mark_choice,
|
|
552
718
|
sorting=sorting,
|
|
553
719
|
phases=[phase for phase in menu_options["phases"] if phase != "total"],
|
|
554
|
-
containments=["
|
|
720
|
+
containments=["nogo", "outside", "contained"],
|
|
555
721
|
plume_groups=plume_groups,
|
|
556
722
|
use_stats=lines_to_show == "stat",
|
|
557
723
|
date_option=date_option,
|
|
@@ -631,20 +797,18 @@ def process_summed_mass(
|
|
|
631
797
|
datestr: Optional[str],
|
|
632
798
|
attribute: MapAttribute,
|
|
633
799
|
summed_mass: Optional[float],
|
|
634
|
-
surf_data: Optional[SurfaceData],
|
|
635
800
|
summed_co2: Dict[str, float],
|
|
636
801
|
unit: str,
|
|
637
|
-
) -> Tuple[Optional[
|
|
802
|
+
) -> Tuple[Optional[float], Dict[str, float]]:
|
|
638
803
|
summed_co2_key = f"{formation}-{realization[0]}-{datestr}-{attribute}-{unit}"
|
|
804
|
+
current_total = None
|
|
639
805
|
if len(realization) == 1:
|
|
640
806
|
if MapType[MapAttribute(attribute).name].value == "MASS":
|
|
641
807
|
if summed_mass is not None and summed_co2_key not in summed_co2:
|
|
642
808
|
summed_co2[summed_co2_key] = summed_mass
|
|
643
|
-
if summed_co2_key in summed_co2
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
)
|
|
647
|
-
return surf_data, summed_co2
|
|
809
|
+
if summed_co2_key in summed_co2:
|
|
810
|
+
current_total = summed_co2[summed_co2_key]
|
|
811
|
+
return current_total, summed_co2
|
|
648
812
|
|
|
649
813
|
|
|
650
814
|
def export_figure_data_to_csv(
|