fmu-sumo 2.4.10__py3-none-any.whl → 2.6.0__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.
- fmu/sumo/explorer/_version.py +16 -3
- fmu/sumo/explorer/objects/_child.py +5 -2
- fmu/sumo/explorer/objects/_document.py +3 -4
- fmu/sumo/explorer/objects/_metrics.py +53 -0
- fmu/sumo/explorer/objects/_search_context.py +294 -206
- fmu/sumo/explorer/objects/ensemble.py +24 -1
- fmu/sumo/explorer/objects/ensembles.py +1 -37
- fmu/sumo/explorer/objects/iteration.py +24 -1
- fmu/sumo/explorer/objects/iterations.py +1 -37
- fmu/sumo/explorer/objects/realization.py +9 -1
- fmu/sumo/explorer/objects/realizations.py +20 -37
- {fmu_sumo-2.4.10.dist-info → fmu_sumo-2.6.0.dist-info}/METADATA +1 -1
- {fmu_sumo-2.4.10.dist-info → fmu_sumo-2.6.0.dist-info}/RECORD +16 -16
- {fmu_sumo-2.4.10.dist-info → fmu_sumo-2.6.0.dist-info}/WHEEL +0 -0
- {fmu_sumo-2.4.10.dist-info → fmu_sumo-2.6.0.dist-info}/licenses/LICENSE +0 -0
- {fmu_sumo-2.4.10.dist-info → fmu_sumo-2.6.0.dist-info}/top_level.txt +0 -0
fmu/sumo/explorer/_version.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
3
|
|
|
4
|
-
__all__ = [
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
5
12
|
|
|
6
13
|
TYPE_CHECKING = False
|
|
7
14
|
if TYPE_CHECKING:
|
|
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
|
|
|
9
16
|
from typing import Union
|
|
10
17
|
|
|
11
18
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
12
20
|
else:
|
|
13
21
|
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
14
23
|
|
|
15
24
|
version: str
|
|
16
25
|
__version__: str
|
|
17
26
|
__version_tuple__: VERSION_TUPLE
|
|
18
27
|
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
19
30
|
|
|
20
|
-
__version__ = version = '2.
|
|
21
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = '2.6.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 6, 0)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -21,7 +21,7 @@ class Child(Document):
|
|
|
21
21
|
self._sumo = sumo
|
|
22
22
|
self._blob = blob
|
|
23
23
|
|
|
24
|
-
def
|
|
24
|
+
def __str__(self):
|
|
25
25
|
if self.stage == "case" and self.__class__.__name__ != "Case":
|
|
26
26
|
return (
|
|
27
27
|
f"<{self.__class__.__name__}: {self.name} {self.uuid}(uuid) "
|
|
@@ -46,7 +46,10 @@ class Child(Document):
|
|
|
46
46
|
f"in asset {self.asset}>"
|
|
47
47
|
)
|
|
48
48
|
else:
|
|
49
|
-
return super().
|
|
49
|
+
return super().__str__()
|
|
50
|
+
|
|
51
|
+
def __repr__(self):
|
|
52
|
+
return self.__str__()
|
|
50
53
|
|
|
51
54
|
@property
|
|
52
55
|
def blob(self) -> BytesIO:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"""Contains class for one document"""
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
3
|
import re
|
|
5
4
|
from typing import Any, Dict, List, Union
|
|
6
5
|
|
|
@@ -20,14 +19,14 @@ class Document:
|
|
|
20
19
|
self._metadata = metadata["_source"]
|
|
21
20
|
|
|
22
21
|
def __str__(self):
|
|
23
|
-
return f"{json.dumps(self.metadata, indent=4)}"
|
|
24
|
-
|
|
25
|
-
def __repr__(self):
|
|
26
22
|
return (
|
|
27
23
|
f"<{self.__class__.__name__}: {self.name} {self.uuid}(uuid) "
|
|
28
24
|
f"in asset {self.asset}>"
|
|
29
25
|
)
|
|
30
26
|
|
|
27
|
+
def __repr__(self):
|
|
28
|
+
return self.__str__()
|
|
29
|
+
|
|
31
30
|
@property
|
|
32
31
|
def uuid(self):
|
|
33
32
|
"""Return uuid
|
|
@@ -272,3 +272,56 @@ class Metrics:
|
|
|
272
272
|
"percentiles", field=field, percents=percents
|
|
273
273
|
)
|
|
274
274
|
)["values"]
|
|
275
|
+
|
|
276
|
+
def _fnv1a_script(self, field):
|
|
277
|
+
return {
|
|
278
|
+
"init_script": """
|
|
279
|
+
state.h = state.count = state.total = 0L;
|
|
280
|
+
""",
|
|
281
|
+
"map_script": f"""
|
|
282
|
+
state.total++;
|
|
283
|
+
if (doc['{field}'].size() == 0) return;
|
|
284
|
+
def s = doc.get('{field}').value;
|
|
285
|
+
long h = -3750763034362895579L;
|
|
286
|
+
for (int i = 0; i < s.length(); i++) {{
|
|
287
|
+
h ^= (long) s.charAt(i);
|
|
288
|
+
h *= 1099511628211L;
|
|
289
|
+
}}
|
|
290
|
+
state.h ^= h;
|
|
291
|
+
state.count++;
|
|
292
|
+
""",
|
|
293
|
+
"combine_script": """
|
|
294
|
+
return state;
|
|
295
|
+
""",
|
|
296
|
+
"reduce_script": """
|
|
297
|
+
long h = 0, c = 0, t = 0;
|
|
298
|
+
for (st in states) {
|
|
299
|
+
h ^= st.h; c += st.count; t += st.total
|
|
300
|
+
}
|
|
301
|
+
return ['checksum': Long.toHexString(h), 'docs_in_checksum': c, 'docs_total': t];
|
|
302
|
+
""",
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
def fnv1a(self, field):
|
|
306
|
+
"""Compute the 64-bit FNV-1a checksum for field over the current set of objects.
|
|
307
|
+
|
|
308
|
+
Arguments:
|
|
309
|
+
- field (str): the name of a property in the metadata.
|
|
310
|
+
|
|
311
|
+
Returns:
|
|
312
|
+
- a dict with the keys "docs_all", "docs_seen" and "xor_fnv64_hex".
|
|
313
|
+
"""
|
|
314
|
+
return self._aggregate("scripted_metric", **self._fnv1a_script(field))
|
|
315
|
+
|
|
316
|
+
async def fnv1a_async(self, field):
|
|
317
|
+
"""Compute the 64-bit FNV-1a checksum for field over the current set of objects.
|
|
318
|
+
|
|
319
|
+
Arguments:
|
|
320
|
+
- field (str): the name of a property in the metadata.
|
|
321
|
+
|
|
322
|
+
Returns:
|
|
323
|
+
- a dict with the keys "docs_all", "docs_seen" and "xor_fnv64_hex".
|
|
324
|
+
"""
|
|
325
|
+
return await self._aggregate_async(
|
|
326
|
+
"scripted_metric", **self._fnv1a_script(field)
|
|
327
|
+
)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
3
|
import warnings
|
|
5
4
|
from datetime import datetime
|
|
6
5
|
from typing import TYPE_CHECKING, Any, Dict, List, Tuple, Union
|
|
@@ -299,14 +298,6 @@ class SearchContext:
|
|
|
299
298
|
return
|
|
300
299
|
|
|
301
300
|
def __str__(self):
|
|
302
|
-
length = len(self)
|
|
303
|
-
if length == 0:
|
|
304
|
-
return "None"
|
|
305
|
-
else:
|
|
306
|
-
preview = [self[i].metadata for i in range(min(5, length))]
|
|
307
|
-
return f"Data Preview:\n{json.dumps(preview, indent=4)}"
|
|
308
|
-
|
|
309
|
-
def __repr__(self):
|
|
310
301
|
cls = self.__class__.__name__
|
|
311
302
|
length = len(self)
|
|
312
303
|
if length == 0:
|
|
@@ -317,6 +308,9 @@ class SearchContext:
|
|
|
317
308
|
else:
|
|
318
309
|
return f"<{cls}: {length} objects of types {self.classes}>"
|
|
319
310
|
|
|
311
|
+
def __repr__(self):
|
|
312
|
+
return self.__str__()
|
|
313
|
+
|
|
320
314
|
@property
|
|
321
315
|
def _query(self):
|
|
322
316
|
must = self._must[:]
|
|
@@ -581,6 +575,66 @@ class SearchContext:
|
|
|
581
575
|
self._cache.clear()
|
|
582
576
|
return self
|
|
583
577
|
|
|
578
|
+
def _ensemble_or_realization_query(self, uuid: str) -> dict:
|
|
579
|
+
return {
|
|
580
|
+
"query": {
|
|
581
|
+
"bool": {
|
|
582
|
+
"minimum_should_match": 1,
|
|
583
|
+
"should": [
|
|
584
|
+
{"term": {"fmu.ensemble.uuid.keyword": uuid}},
|
|
585
|
+
{"term": {"fmu.iteration.uuid.keyword": uuid}},
|
|
586
|
+
{"term": {"fmu.realization.uuid.keyword": uuid}},
|
|
587
|
+
],
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
"size": 1,
|
|
591
|
+
"_source": {
|
|
592
|
+
"includes": [
|
|
593
|
+
"$schema",
|
|
594
|
+
"class",
|
|
595
|
+
"source",
|
|
596
|
+
"version",
|
|
597
|
+
"access",
|
|
598
|
+
"masterdata",
|
|
599
|
+
"fmu.case",
|
|
600
|
+
"fmu.iteration",
|
|
601
|
+
"fmu.ensemble",
|
|
602
|
+
"fmu.realization",
|
|
603
|
+
],
|
|
604
|
+
},
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
def _patch_ensemble_or_realization(self, uuid, hits):
|
|
608
|
+
if len(hits) == 1:
|
|
609
|
+
obj = hits[0]["_source"]
|
|
610
|
+
if obj["fmu"]["ensemble"]["uuid"] == uuid:
|
|
611
|
+
obj["class"] = "ensemble"
|
|
612
|
+
elif obj["fmu"]["iteration"]["uuid"] == uuid:
|
|
613
|
+
obj["class"] = "iteration"
|
|
614
|
+
elif obj["fmu"]["realization"]["uuid"] == uuid:
|
|
615
|
+
obj["class"] = "realization"
|
|
616
|
+
if (
|
|
617
|
+
obj["class"] in ["iteration", "ensemble"]
|
|
618
|
+
and "realization" in obj["fmu"]
|
|
619
|
+
):
|
|
620
|
+
del obj["fmu"]["realization"]
|
|
621
|
+
|
|
622
|
+
def _get_ensemble_or_realization(self, uuid: str) -> List[Dict]:
|
|
623
|
+
query = self._ensemble_or_realization_query(uuid)
|
|
624
|
+
res = self._sumo.post("/search", json=query)
|
|
625
|
+
hits = res.json()["hits"]["hits"]
|
|
626
|
+
self._patch_ensemble_or_realization(uuid, hits)
|
|
627
|
+
return hits
|
|
628
|
+
|
|
629
|
+
async def _get_ensemble_or_realization_async(
|
|
630
|
+
self, uuid: str
|
|
631
|
+
) -> List[Dict]:
|
|
632
|
+
query = self._ensemble_or_realization_query(uuid)
|
|
633
|
+
res = await self._sumo.post_async("/search", json=query)
|
|
634
|
+
hits = res.json()["hits"]["hits"]
|
|
635
|
+
self._patch_ensemble_or_realization(uuid, hits)
|
|
636
|
+
return hits
|
|
637
|
+
|
|
584
638
|
def get_object(self, uuid: str) -> objects.Document:
|
|
585
639
|
"""Get metadata object by uuid
|
|
586
640
|
|
|
@@ -603,7 +657,10 @@ class SearchContext:
|
|
|
603
657
|
hits = res.json()["hits"]["hits"]
|
|
604
658
|
|
|
605
659
|
if len(hits) == 0:
|
|
606
|
-
|
|
660
|
+
hits = self._get_ensemble_or_realization(uuid)
|
|
661
|
+
if len(hits) == 0:
|
|
662
|
+
raise Exception(f"Document not found: {uuid}")
|
|
663
|
+
pass
|
|
607
664
|
obj = hits[0]
|
|
608
665
|
self._cache.put(uuid, obj)
|
|
609
666
|
|
|
@@ -632,7 +689,10 @@ class SearchContext:
|
|
|
632
689
|
hits = res.json()["hits"]["hits"]
|
|
633
690
|
|
|
634
691
|
if len(hits) == 0:
|
|
635
|
-
|
|
692
|
+
hits = await self._get_ensemble_or_realization_async(uuid)
|
|
693
|
+
if len(hits) == 0:
|
|
694
|
+
raise Exception(f"Document not found: {uuid}")
|
|
695
|
+
pass
|
|
636
696
|
obj = hits[0]
|
|
637
697
|
self._cache.put(uuid, obj)
|
|
638
698
|
|
|
@@ -869,6 +929,26 @@ class SearchContext:
|
|
|
869
929
|
"""
|
|
870
930
|
return self.get_field_values(field)
|
|
871
931
|
|
|
932
|
+
def match_field_values(self, field: str, patterns: list[str]) -> list[str]:
|
|
933
|
+
query = {
|
|
934
|
+
"query": self._query,
|
|
935
|
+
"size": 0,
|
|
936
|
+
"aggs": {
|
|
937
|
+
"values": {
|
|
938
|
+
"terms": {
|
|
939
|
+
"field": field,
|
|
940
|
+
"include": "|".join(patterns),
|
|
941
|
+
"size": 1000,
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
}
|
|
946
|
+
res = self._sumo.post("/search", json=query).json()
|
|
947
|
+
return [
|
|
948
|
+
bucket["key"]
|
|
949
|
+
for bucket in res["aggregations"]["values"]["buckets"]
|
|
950
|
+
]
|
|
951
|
+
|
|
872
952
|
async def get_field_values_and_counts_async(
|
|
873
953
|
self, field: str
|
|
874
954
|
) -> Dict[str, int]:
|
|
@@ -918,6 +998,28 @@ class SearchContext:
|
|
|
918
998
|
"""
|
|
919
999
|
return await self.get_field_values_async(field)
|
|
920
1000
|
|
|
1001
|
+
async def match_field_values_async(
|
|
1002
|
+
self, field: str, patterns: list[str]
|
|
1003
|
+
) -> list[str]:
|
|
1004
|
+
query = {
|
|
1005
|
+
"query": self._query,
|
|
1006
|
+
"size": 0,
|
|
1007
|
+
"aggs": {
|
|
1008
|
+
"values": {
|
|
1009
|
+
"terms": {
|
|
1010
|
+
"field": field,
|
|
1011
|
+
"include": "|".join(patterns),
|
|
1012
|
+
"size": 1000,
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
},
|
|
1016
|
+
}
|
|
1017
|
+
res = (await self._sumo.post_async("/search", json=query)).json()
|
|
1018
|
+
return [
|
|
1019
|
+
bucket["key"]
|
|
1020
|
+
for bucket in res["aggregations"]["values"]["buckets"]
|
|
1021
|
+
]
|
|
1022
|
+
|
|
921
1023
|
_timestamp_query = {
|
|
922
1024
|
"bool": {
|
|
923
1025
|
"must": [{"exists": {"field": "data.time.t0"}}],
|
|
@@ -1012,6 +1114,22 @@ class SearchContext:
|
|
|
1012
1114
|
)
|
|
1013
1115
|
return objects.Realizations(self, uuids)
|
|
1014
1116
|
|
|
1117
|
+
@property
|
|
1118
|
+
def reference_realizations(self):
|
|
1119
|
+
"""Reference realizations from current selection."""
|
|
1120
|
+
return self.filter(
|
|
1121
|
+
cls="realization",
|
|
1122
|
+
complex={"term": {"fmu.realization.is_reference": True}},
|
|
1123
|
+
)
|
|
1124
|
+
|
|
1125
|
+
@property
|
|
1126
|
+
async def reference_realizations_async(self):
|
|
1127
|
+
"""Reference realizations from current selection."""
|
|
1128
|
+
return self.filter(
|
|
1129
|
+
cls="realization",
|
|
1130
|
+
complex={"term": {"fmu.realization.is_reference": True}},
|
|
1131
|
+
)
|
|
1132
|
+
|
|
1015
1133
|
@property
|
|
1016
1134
|
def template_paths(self) -> List[str]:
|
|
1017
1135
|
return {obj.template_path for obj in self}
|
|
@@ -1236,24 +1354,6 @@ class SearchContext:
|
|
|
1236
1354
|
"""
|
|
1237
1355
|
return await self._get_object_by_class_and_uuid_async("case", uuid)
|
|
1238
1356
|
|
|
1239
|
-
def _iteration_query(self, uuid):
|
|
1240
|
-
return {
|
|
1241
|
-
"query": {"term": {"fmu.iteration.uuid.keyword": {"value": uuid}}},
|
|
1242
|
-
"size": 1,
|
|
1243
|
-
"_source": {
|
|
1244
|
-
"includes": [
|
|
1245
|
-
"$schema",
|
|
1246
|
-
"class",
|
|
1247
|
-
"source",
|
|
1248
|
-
"version",
|
|
1249
|
-
"access",
|
|
1250
|
-
"masterdata",
|
|
1251
|
-
"fmu.case",
|
|
1252
|
-
"fmu.iteration",
|
|
1253
|
-
],
|
|
1254
|
-
},
|
|
1255
|
-
}
|
|
1256
|
-
|
|
1257
1357
|
def get_iteration_by_uuid(self, uuid: str) -> objects.Iteration:
|
|
1258
1358
|
"""Get iteration object by uuid
|
|
1259
1359
|
|
|
@@ -1262,23 +1362,9 @@ class SearchContext:
|
|
|
1262
1362
|
|
|
1263
1363
|
Returns: iteration object
|
|
1264
1364
|
"""
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
return obj
|
|
1269
|
-
except Exception:
|
|
1270
|
-
res = self._sumo.post(
|
|
1271
|
-
"/search", json=self._iteration_query(uuid)
|
|
1272
|
-
).json()
|
|
1273
|
-
hits = res["hits"]["hits"]
|
|
1274
|
-
if len(hits) == 0:
|
|
1275
|
-
raise Exception(f"Document not found: {uuid}")
|
|
1276
|
-
obj = hits[0]
|
|
1277
|
-
obj["_id"] = uuid
|
|
1278
|
-
obj["_source"]["class"] = "iteration"
|
|
1279
|
-
ret = self._to_sumo(obj)
|
|
1280
|
-
self._cache.put(uuid, ret)
|
|
1281
|
-
return ret
|
|
1365
|
+
obj = self.get_object(uuid)
|
|
1366
|
+
assert isinstance(obj, objects.Iteration)
|
|
1367
|
+
return obj
|
|
1282
1368
|
|
|
1283
1369
|
async def get_iteration_by_uuid_async(
|
|
1284
1370
|
self, uuid: str
|
|
@@ -1290,43 +1376,9 @@ class SearchContext:
|
|
|
1290
1376
|
|
|
1291
1377
|
Returns: iteration object
|
|
1292
1378
|
"""
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
return obj
|
|
1297
|
-
except Exception:
|
|
1298
|
-
res = (
|
|
1299
|
-
await self._sumo.post_async(
|
|
1300
|
-
"/search", json=self._iteration_query(uuid)
|
|
1301
|
-
)
|
|
1302
|
-
).json()
|
|
1303
|
-
hits = res["hits"]["hits"]
|
|
1304
|
-
if len(hits) == 0:
|
|
1305
|
-
raise Exception(f"Document not found: {uuid}")
|
|
1306
|
-
obj = hits[0]
|
|
1307
|
-
obj["_id"] = uuid
|
|
1308
|
-
obj["_source"]["class"] = "iteration"
|
|
1309
|
-
ret = self._to_sumo(obj)
|
|
1310
|
-
self._cache.put(uuid, ret)
|
|
1311
|
-
return ret
|
|
1312
|
-
|
|
1313
|
-
def _ensemble_query(self, uuid):
|
|
1314
|
-
return {
|
|
1315
|
-
"query": {"term": {"fmu.ensemble.uuid.keyword": {"value": uuid}}},
|
|
1316
|
-
"size": 1,
|
|
1317
|
-
"_source": {
|
|
1318
|
-
"includes": [
|
|
1319
|
-
"$schema",
|
|
1320
|
-
"class",
|
|
1321
|
-
"source",
|
|
1322
|
-
"version",
|
|
1323
|
-
"access",
|
|
1324
|
-
"masterdata",
|
|
1325
|
-
"fmu.case",
|
|
1326
|
-
"fmu.ensemble",
|
|
1327
|
-
],
|
|
1328
|
-
},
|
|
1329
|
-
}
|
|
1379
|
+
obj = await self.get_object_async(uuid)
|
|
1380
|
+
assert isinstance(obj, objects.Iteration)
|
|
1381
|
+
return obj
|
|
1330
1382
|
|
|
1331
1383
|
def get_ensemble_by_uuid(self, uuid: str) -> objects.Ensemble:
|
|
1332
1384
|
"""Get ensemble object by uuid
|
|
@@ -1336,23 +1388,9 @@ class SearchContext:
|
|
|
1336
1388
|
|
|
1337
1389
|
Returns: ensemble object
|
|
1338
1390
|
"""
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
return obj
|
|
1343
|
-
except Exception:
|
|
1344
|
-
res = self._sumo.post(
|
|
1345
|
-
"/search", json=self._ensemble_query(uuid)
|
|
1346
|
-
).json()
|
|
1347
|
-
hits = res["hits"]["hits"]
|
|
1348
|
-
if len(hits) == 0:
|
|
1349
|
-
raise Exception(f"Document not found: {uuid}")
|
|
1350
|
-
obj = hits[0]
|
|
1351
|
-
obj["_id"] = uuid
|
|
1352
|
-
obj["_source"]["class"] = "ensemble"
|
|
1353
|
-
ret = self._to_sumo(obj)
|
|
1354
|
-
self._cache.put(uuid, ret)
|
|
1355
|
-
return ret
|
|
1391
|
+
obj = self.get_object(uuid)
|
|
1392
|
+
assert isinstance(obj, objects.Ensemble)
|
|
1393
|
+
return obj
|
|
1356
1394
|
|
|
1357
1395
|
async def get_ensemble_by_uuid_async(self, uuid: str) -> objects.Ensemble:
|
|
1358
1396
|
"""Get ensemble object by uuid
|
|
@@ -1362,47 +1400,9 @@ class SearchContext:
|
|
|
1362
1400
|
|
|
1363
1401
|
Returns: ensemble object
|
|
1364
1402
|
"""
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
return obj
|
|
1369
|
-
except Exception:
|
|
1370
|
-
res = (
|
|
1371
|
-
await self._sumo.post_async(
|
|
1372
|
-
"/search", json=self._ensemble_query(uuid)
|
|
1373
|
-
)
|
|
1374
|
-
).json()
|
|
1375
|
-
hits = res["hits"]["hits"]
|
|
1376
|
-
if len(hits) == 0:
|
|
1377
|
-
raise Exception(f"Document not found: {uuid}")
|
|
1378
|
-
obj = hits[0]
|
|
1379
|
-
obj["_id"] = uuid
|
|
1380
|
-
obj["_source"]["class"] = "ensemble"
|
|
1381
|
-
ret = self._to_sumo(obj)
|
|
1382
|
-
self._cache.put(uuid, ret)
|
|
1383
|
-
return ret
|
|
1384
|
-
|
|
1385
|
-
def _realization_query(self, uuid) -> Dict:
|
|
1386
|
-
return {
|
|
1387
|
-
"query": {
|
|
1388
|
-
"term": {"fmu.realization.uuid.keyword": {"value": uuid}}
|
|
1389
|
-
},
|
|
1390
|
-
"size": 1,
|
|
1391
|
-
"_source": {
|
|
1392
|
-
"includes": [
|
|
1393
|
-
"$schema",
|
|
1394
|
-
"class",
|
|
1395
|
-
"source",
|
|
1396
|
-
"version",
|
|
1397
|
-
"access",
|
|
1398
|
-
"masterdata",
|
|
1399
|
-
"fmu.case",
|
|
1400
|
-
"fmu.iteration",
|
|
1401
|
-
"fmu.ensemble",
|
|
1402
|
-
"fmu.realization",
|
|
1403
|
-
],
|
|
1404
|
-
},
|
|
1405
|
-
}
|
|
1403
|
+
obj = await self.get_object_async(uuid)
|
|
1404
|
+
assert isinstance(obj, objects.Ensemble)
|
|
1405
|
+
return obj
|
|
1406
1406
|
|
|
1407
1407
|
def get_realization_by_uuid(self, uuid: str) -> objects.Realization:
|
|
1408
1408
|
"""Get realization object by uuid
|
|
@@ -1412,21 +1412,9 @@ class SearchContext:
|
|
|
1412
1412
|
|
|
1413
1413
|
Returns: realization object
|
|
1414
1414
|
"""
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
return obj
|
|
1419
|
-
except Exception:
|
|
1420
|
-
res = self._sumo.post(
|
|
1421
|
-
"/search", json=self._realization_query(uuid)
|
|
1422
|
-
).json()
|
|
1423
|
-
hits = res["hits"]["hits"]
|
|
1424
|
-
if len(hits) == 0:
|
|
1425
|
-
raise Exception(f"Document not found: {uuid}")
|
|
1426
|
-
obj = hits[0]
|
|
1427
|
-
obj["_id"] = uuid
|
|
1428
|
-
obj["_source"]["class"] = "realization"
|
|
1429
|
-
return self._to_sumo(obj)
|
|
1415
|
+
obj = self.get_object(uuid)
|
|
1416
|
+
assert isinstance(obj, objects.Realization)
|
|
1417
|
+
return obj
|
|
1430
1418
|
|
|
1431
1419
|
async def get_realization_by_uuid_async(
|
|
1432
1420
|
self, uuid: str
|
|
@@ -1438,23 +1426,9 @@ class SearchContext:
|
|
|
1438
1426
|
|
|
1439
1427
|
Returns: realization object
|
|
1440
1428
|
"""
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
return obj
|
|
1445
|
-
except Exception:
|
|
1446
|
-
res = (
|
|
1447
|
-
await self._sumo.post_async(
|
|
1448
|
-
"/search", json=self._realization_query(uuid)
|
|
1449
|
-
)
|
|
1450
|
-
).json()
|
|
1451
|
-
hits = res["hits"]["hits"]
|
|
1452
|
-
if len(hits) == 0:
|
|
1453
|
-
raise Exception(f"Document not found: {uuid}")
|
|
1454
|
-
obj = hits[0]
|
|
1455
|
-
obj["_id"] = uuid
|
|
1456
|
-
obj["_source"]["class"] = "realization"
|
|
1457
|
-
return self._to_sumo(obj)
|
|
1429
|
+
obj = await self.get_object_async(uuid)
|
|
1430
|
+
assert isinstance(obj, objects.Realization)
|
|
1431
|
+
return obj
|
|
1458
1432
|
|
|
1459
1433
|
def get_surface_by_uuid(self, uuid: str) -> objects.Surface:
|
|
1460
1434
|
"""Get surface object by uuid
|
|
@@ -1543,7 +1517,7 @@ class SearchContext:
|
|
|
1543
1517
|
|
|
1544
1518
|
def __verify_aggregation_operation(
|
|
1545
1519
|
self, sres
|
|
1546
|
-
) -> Tuple[str, str, str, str]:
|
|
1520
|
+
) -> Tuple[str, str, str, str, str]:
|
|
1547
1521
|
tot_hits = sres["hits"]["total"]["value"]
|
|
1548
1522
|
if tot_hits == 0:
|
|
1549
1523
|
raise Exception("No matching realizations found.")
|
|
@@ -1570,18 +1544,38 @@ class SearchContext:
|
|
|
1570
1544
|
"key"
|
|
1571
1545
|
]
|
|
1572
1546
|
classname = sres["aggregations"]["class"]["buckets"][0]["key"]
|
|
1573
|
-
|
|
1547
|
+
|
|
1548
|
+
return caseuuid, classname, entityuuid, ensemblename, tot_hits
|
|
1574
1549
|
|
|
1575
1550
|
def _verify_aggregation_operation(
|
|
1576
|
-
self, columns
|
|
1551
|
+
self, columns
|
|
1577
1552
|
) -> Tuple[str, str, str, str]:
|
|
1578
|
-
assert columns is None or len(columns) == 1, (
|
|
1579
|
-
"Exactly one column required for collection aggregation."
|
|
1580
|
-
)
|
|
1581
1553
|
sc = self if columns is None else self.filter(column=columns)
|
|
1582
1554
|
query = sc.__prepare_verify_aggregation_query()
|
|
1583
1555
|
sres = sc._sumo.post("/search", json=query).json()
|
|
1584
|
-
|
|
1556
|
+
caseuuid, classname, entityuuid, ensemblename, tot_hits = (
|
|
1557
|
+
sc.__verify_aggregation_operation(sres)
|
|
1558
|
+
)
|
|
1559
|
+
|
|
1560
|
+
if (
|
|
1561
|
+
classname != "surface"
|
|
1562
|
+
and isinstance(columns, list)
|
|
1563
|
+
and len(columns) == 1
|
|
1564
|
+
):
|
|
1565
|
+
sc = SearchContext(
|
|
1566
|
+
sumo=self._sumo,
|
|
1567
|
+
).filter(
|
|
1568
|
+
cls=classname,
|
|
1569
|
+
realization=True,
|
|
1570
|
+
entity=entityuuid,
|
|
1571
|
+
ensemble=ensemblename,
|
|
1572
|
+
)
|
|
1573
|
+
|
|
1574
|
+
if len(sc) != tot_hits:
|
|
1575
|
+
raise Exception(
|
|
1576
|
+
"Filtering on realization is not allowed for table and parameter aggregation."
|
|
1577
|
+
)
|
|
1578
|
+
return caseuuid, classname, entityuuid, ensemblename
|
|
1585
1579
|
|
|
1586
1580
|
def __prepare_aggregation_spec(
|
|
1587
1581
|
self, caseuuid, classname, entityuuid, ensemblename, operation, columns
|
|
@@ -1598,9 +1592,11 @@ class SearchContext:
|
|
|
1598
1592
|
spec["columns"] = columns
|
|
1599
1593
|
return spec
|
|
1600
1594
|
|
|
1601
|
-
def _aggregate(
|
|
1595
|
+
def _aggregate(
|
|
1596
|
+
self, columns=None, operation=None, no_wait=False
|
|
1597
|
+
) -> objects.Child | httpx.Response:
|
|
1602
1598
|
caseuuid, classname, entityuuid, ensemblename = (
|
|
1603
|
-
self._verify_aggregation_operation(columns
|
|
1599
|
+
self._verify_aggregation_operation(columns)
|
|
1604
1600
|
)
|
|
1605
1601
|
spec = self.__prepare_aggregation_spec(
|
|
1606
1602
|
caseuuid, classname, entityuuid, ensemblename, operation, columns
|
|
@@ -1612,36 +1608,91 @@ class SearchContext:
|
|
|
1612
1608
|
print(ex.response.reason_phrase)
|
|
1613
1609
|
print(ex.response.text)
|
|
1614
1610
|
raise ex
|
|
1611
|
+
if no_wait:
|
|
1612
|
+
return res
|
|
1613
|
+
# ELSE
|
|
1615
1614
|
res = self._sumo.poll(res).json()
|
|
1616
1615
|
return self._to_sumo(res)
|
|
1617
1616
|
|
|
1618
|
-
def aggregate(
|
|
1617
|
+
def aggregate(
|
|
1618
|
+
self, columns=None, operation=None, no_wait=False
|
|
1619
|
+
) -> objects.Child | httpx.Response:
|
|
1620
|
+
assert columns is None or len(columns) == 1, (
|
|
1621
|
+
"Exactly one column required for collection aggregation."
|
|
1622
|
+
)
|
|
1619
1623
|
sc = self.filter(realization=True, column=columns)
|
|
1620
1624
|
if len(sc.hidden) > 0:
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1625
|
+
sc = sc.hidden
|
|
1626
|
+
return sc._aggregate(
|
|
1627
|
+
columns=columns, operation=operation, no_wait=no_wait
|
|
1628
|
+
)
|
|
1629
|
+
|
|
1630
|
+
def batch_aggregate(self, columns=None, operation=None, no_wait=False):
|
|
1631
|
+
"""Aggregate one or more columns for the current context.
|
|
1632
|
+
|
|
1633
|
+
Args:
|
|
1634
|
+
columns: list of column names or regular expressions for column names.
|
|
1635
|
+
operation: must be "collection"
|
|
1636
|
+
no_wait: set to True if the client handles polling itself.
|
|
1637
|
+
|
|
1638
|
+
Returns:
|
|
1639
|
+
list of column names that occur in the current context and match the names/patterns.
|
|
1640
|
+
"""
|
|
1641
|
+
assert operation == "collection"
|
|
1642
|
+
assert type(columns) is list and len(columns) > 0
|
|
1643
|
+
assert len(columns) < 1000, (
|
|
1644
|
+
"Maximum 1000 columns allowed for a single call to batch_aggregate."
|
|
1645
|
+
)
|
|
1646
|
+
sc = self.filter(realization=True, column=columns)
|
|
1647
|
+
if len(sc.hidden) > 0:
|
|
1648
|
+
sc = sc.hidden
|
|
1649
|
+
res = sc._aggregate(columns=columns, operation=operation, no_wait=True)
|
|
1650
|
+
assert type(res) is httpx.Response
|
|
1651
|
+
if no_wait:
|
|
1652
|
+
return res
|
|
1653
|
+
# ELSE
|
|
1654
|
+
return self._sumo.poll(res)
|
|
1624
1655
|
|
|
1625
1656
|
async def _verify_aggregation_operation_async(
|
|
1626
|
-
self, columns
|
|
1657
|
+
self, columns
|
|
1627
1658
|
) -> Tuple[str, str, str, str]:
|
|
1628
|
-
assert columns is None or len(columns) == 1, (
|
|
1629
|
-
"Exactly one column required for collection aggregation."
|
|
1630
|
-
)
|
|
1631
1659
|
sc = self if columns is None else self.filter(column=columns)
|
|
1632
1660
|
query = sc.__prepare_verify_aggregation_query()
|
|
1633
1661
|
sres = (await self._sumo.post_async("/search", json=query)).json()
|
|
1634
|
-
|
|
1662
|
+
caseuuid, classname, entityuuid, ensemblename, tot_hits = (
|
|
1663
|
+
sc.__verify_aggregation_operation(sres)
|
|
1664
|
+
)
|
|
1665
|
+
|
|
1666
|
+
if (
|
|
1667
|
+
classname != "surface"
|
|
1668
|
+
and isinstance(columns, list)
|
|
1669
|
+
and len(columns) == 1
|
|
1670
|
+
):
|
|
1671
|
+
sc = SearchContext(
|
|
1672
|
+
sumo=self._sumo,
|
|
1673
|
+
).filter(
|
|
1674
|
+
cls=classname,
|
|
1675
|
+
realization=True,
|
|
1676
|
+
entity=entityuuid,
|
|
1677
|
+
ensemble=ensemblename,
|
|
1678
|
+
)
|
|
1679
|
+
|
|
1680
|
+
tot_reals = await sc.length_async()
|
|
1681
|
+
if tot_reals != tot_hits:
|
|
1682
|
+
raise Exception(
|
|
1683
|
+
"Filtering on realization is not allowed for table and parameter aggregation."
|
|
1684
|
+
)
|
|
1685
|
+
return caseuuid, classname, entityuuid, ensemblename
|
|
1635
1686
|
|
|
1636
1687
|
async def _aggregate_async(
|
|
1637
|
-
self, columns=None, operation=None
|
|
1638
|
-
) -> objects.Child:
|
|
1688
|
+
self, columns=None, operation=None, no_wait=False
|
|
1689
|
+
) -> objects.Child | httpx.Response:
|
|
1639
1690
|
(
|
|
1640
1691
|
caseuuid,
|
|
1641
1692
|
classname,
|
|
1642
1693
|
entityuuid,
|
|
1643
1694
|
ensemblename,
|
|
1644
|
-
) = await self._verify_aggregation_operation_async(columns
|
|
1695
|
+
) = await self._verify_aggregation_operation_async(columns)
|
|
1645
1696
|
spec = self.__prepare_aggregation_spec(
|
|
1646
1697
|
caseuuid, classname, entityuuid, ensemblename, operation, columns
|
|
1647
1698
|
)
|
|
@@ -1652,24 +1703,59 @@ class SearchContext:
|
|
|
1652
1703
|
print(ex.response.reason_phrase)
|
|
1653
1704
|
print(ex.response.text)
|
|
1654
1705
|
raise ex
|
|
1706
|
+
if no_wait:
|
|
1707
|
+
return res
|
|
1708
|
+
# ELSE
|
|
1655
1709
|
res = (await self._sumo.poll_async(res)).json()
|
|
1656
1710
|
return self._to_sumo(res)
|
|
1657
1711
|
|
|
1658
1712
|
async def aggregate_async(
|
|
1659
|
-
self, columns=None, operation=None
|
|
1660
|
-
) -> objects.Child:
|
|
1713
|
+
self, columns=None, operation=None, no_wait=False
|
|
1714
|
+
) -> objects.Child | httpx.Response:
|
|
1715
|
+
assert columns is None or len(columns) == 1, (
|
|
1716
|
+
"Exactly one column required for collection aggregation."
|
|
1717
|
+
)
|
|
1661
1718
|
sc = self.filter(realization=True, column=columns)
|
|
1662
1719
|
length_hidden = await sc.hidden.length_async()
|
|
1663
1720
|
if length_hidden > 0:
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1721
|
+
sc = sc.hidden
|
|
1722
|
+
return await sc._aggregate_async(
|
|
1723
|
+
columns=columns, operation=operation, no_wait=no_wait
|
|
1724
|
+
)
|
|
1725
|
+
|
|
1726
|
+
async def batch_aggregate_async(
|
|
1727
|
+
self, columns=None, operation=None, no_wait=False
|
|
1728
|
+
):
|
|
1729
|
+
"""Aggregate one or more columns for the current context.
|
|
1730
|
+
|
|
1731
|
+
Args:
|
|
1732
|
+
columns: list of column names or regular expressions for column names.
|
|
1733
|
+
operation: must be "collection"
|
|
1734
|
+
no_wait: set to True if the client handles polling itself.
|
|
1735
|
+
|
|
1736
|
+
Returns:
|
|
1737
|
+
list of column names that occur in the current context and match the names/patterns.
|
|
1738
|
+
"""
|
|
1739
|
+
assert operation == "collection"
|
|
1740
|
+
assert type(columns) is list and len(columns) > 0
|
|
1741
|
+
assert len(columns) < 1000, (
|
|
1742
|
+
"Maximum 1000 columns allowed for a single call to batch_aggregate_async."
|
|
1743
|
+
)
|
|
1744
|
+
sc = self.filter(realization=True, column=columns)
|
|
1745
|
+
if len(sc.hidden) > 0:
|
|
1746
|
+
sc = sc.hidden
|
|
1747
|
+
res = await sc._aggregate_async(
|
|
1748
|
+
columns=columns, operation=operation, no_wait=True
|
|
1749
|
+
)
|
|
1750
|
+
assert type(res) is httpx.Response
|
|
1751
|
+
if no_wait:
|
|
1752
|
+
return res
|
|
1753
|
+
# ELSE
|
|
1754
|
+
return await self._sumo.poll_async(res)
|
|
1671
1755
|
|
|
1672
|
-
def aggregation(
|
|
1756
|
+
def aggregation(
|
|
1757
|
+
self, column=None, operation=None, no_wait=False
|
|
1758
|
+
) -> objects.Child | httpx.Response:
|
|
1673
1759
|
assert operation is not None
|
|
1674
1760
|
assert column is None or isinstance(column, str)
|
|
1675
1761
|
sc = self.filter(aggregation=operation, column=column)
|
|
@@ -1691,11 +1777,12 @@ class SearchContext:
|
|
|
1691
1777
|
return self.filter(realization=True).aggregate(
|
|
1692
1778
|
columns=[column] if column is not None else None,
|
|
1693
1779
|
operation=operation,
|
|
1780
|
+
no_wait=no_wait,
|
|
1694
1781
|
)
|
|
1695
1782
|
|
|
1696
1783
|
async def aggregation_async(
|
|
1697
|
-
self, column=None, operation=None
|
|
1698
|
-
) -> objects.Child:
|
|
1784
|
+
self, column=None, operation=None, no_wait=False
|
|
1785
|
+
) -> objects.Child | httpx.Response:
|
|
1699
1786
|
assert operation is not None
|
|
1700
1787
|
assert column is None or isinstance(column, str)
|
|
1701
1788
|
sc = self.filter(aggregation=operation, column=column)
|
|
@@ -1720,6 +1807,7 @@ class SearchContext:
|
|
|
1720
1807
|
return await self.filter(realization=True).aggregate_async(
|
|
1721
1808
|
columns=[column] if column is not None else None,
|
|
1722
1809
|
operation=operation,
|
|
1810
|
+
no_wait=no_wait,
|
|
1723
1811
|
)
|
|
1724
1812
|
|
|
1725
1813
|
@deprecation.deprecated(
|
|
@@ -23,13 +23,16 @@ class Ensemble(Document, SearchContext):
|
|
|
23
23
|
)
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def __str__(self):
|
|
27
27
|
return (
|
|
28
28
|
f"<{self.__class__.__name__}: {self.name} {self.uuid}(uuid) "
|
|
29
29
|
f"in case {self.casename} "
|
|
30
30
|
f"in asset {self.asset}>"
|
|
31
31
|
)
|
|
32
32
|
|
|
33
|
+
def __repr__(self):
|
|
34
|
+
return self.__str__()
|
|
35
|
+
|
|
33
36
|
@property
|
|
34
37
|
def field(self) -> str:
|
|
35
38
|
"""Case field"""
|
|
@@ -74,3 +77,23 @@ class Ensemble(Document, SearchContext):
|
|
|
74
77
|
def uuid(self) -> str:
|
|
75
78
|
"""FMU ensemble uuid"""
|
|
76
79
|
return self.get_property("fmu.ensemble.uuid")
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def reference_realizations(self):
|
|
83
|
+
"""Reference realizations in ensemble. If none, return
|
|
84
|
+
realizations 0 and 1, if they exist."""
|
|
85
|
+
sc = super().reference_realizations
|
|
86
|
+
if len(sc) > 0:
|
|
87
|
+
return sc
|
|
88
|
+
else:
|
|
89
|
+
return self.filter(realization=[0, 1]).realizations
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
async def reference_realizations_async(self):
|
|
93
|
+
"""Reference realizations in ensemble. If none, return
|
|
94
|
+
realizations 0 and 1, if they exist."""
|
|
95
|
+
sc = await super().reference_realizations_async
|
|
96
|
+
if await sc.length_async() > 0:
|
|
97
|
+
return sc
|
|
98
|
+
else:
|
|
99
|
+
return self.filter(realization=[0, 1]).realizations
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Module for searchcontext for collection of ensembles."""
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import List
|
|
4
4
|
|
|
5
5
|
from ._search_context import SearchContext
|
|
6
6
|
|
|
@@ -25,42 +25,6 @@ class Ensembles(SearchContext):
|
|
|
25
25
|
async def _maybe_prefetch_async(self, index):
|
|
26
26
|
return
|
|
27
27
|
|
|
28
|
-
def get_object(self, uuid: str) -> Dict:
|
|
29
|
-
"""Get metadata object by uuid
|
|
30
|
-
|
|
31
|
-
Args:
|
|
32
|
-
uuid (str): uuid of metadata object
|
|
33
|
-
select (List[str]): list of metadata fields to return
|
|
34
|
-
|
|
35
|
-
Returns:
|
|
36
|
-
Dict: a metadata object
|
|
37
|
-
"""
|
|
38
|
-
obj = self._cache.get(uuid)
|
|
39
|
-
if obj is None:
|
|
40
|
-
obj = self.get_ensemble_by_uuid(uuid)
|
|
41
|
-
self._cache.put(uuid, obj)
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
return obj
|
|
45
|
-
|
|
46
|
-
async def get_object_async(self, uuid: str) -> Dict:
|
|
47
|
-
"""Get metadata object by uuid
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
uuid (str): uuid of metadata object
|
|
51
|
-
select (List[str]): list of metadata fields to return
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
Dict: a metadata object
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
obj = self._cache.get(uuid)
|
|
58
|
-
if obj is None:
|
|
59
|
-
obj = await self.get_ensemble_by_uuid_async(uuid)
|
|
60
|
-
self._cache.put(uuid, obj)
|
|
61
|
-
|
|
62
|
-
return obj
|
|
63
|
-
|
|
64
28
|
def filter(self, **kwargs):
|
|
65
29
|
sc = super().filter(**kwargs)
|
|
66
30
|
uuids = sc.get_field_values("fmu.ensemble.uuid.keyword")
|
|
@@ -23,13 +23,16 @@ class Iteration(Document, SearchContext):
|
|
|
23
23
|
)
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def __str__(self):
|
|
27
27
|
return (
|
|
28
28
|
f"<{self.__class__.__name__}: {self.name} {self.uuid}(uuid) "
|
|
29
29
|
f"in case {self.casename} "
|
|
30
30
|
f"in asset {self.asset}>"
|
|
31
31
|
)
|
|
32
32
|
|
|
33
|
+
def __repr__(self):
|
|
34
|
+
return self.__str__()
|
|
35
|
+
|
|
33
36
|
@property
|
|
34
37
|
def field(self) -> str:
|
|
35
38
|
"""Case field"""
|
|
@@ -74,3 +77,23 @@ class Iteration(Document, SearchContext):
|
|
|
74
77
|
def uuid(self) -> str:
|
|
75
78
|
"""FMU iteration uuid"""
|
|
76
79
|
return self.get_property("fmu.iteration.uuid")
|
|
80
|
+
|
|
81
|
+
@property
|
|
82
|
+
def reference_realizations(self):
|
|
83
|
+
"""Reference realizations in iteration. If none, return
|
|
84
|
+
realizations 0 and 1, if they exist."""
|
|
85
|
+
sc = super().reference_realizations
|
|
86
|
+
if len(sc) > 0:
|
|
87
|
+
return sc
|
|
88
|
+
else:
|
|
89
|
+
return self.filter(realization=[0, 1]).realizations
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
async def reference_realizations_async(self):
|
|
93
|
+
"""Reference realizations in iteration. If none, return
|
|
94
|
+
realizations 0 and 1, if they exist."""
|
|
95
|
+
sc = await super().reference_realizations_async
|
|
96
|
+
if await sc.length_async() > 0:
|
|
97
|
+
return sc
|
|
98
|
+
else:
|
|
99
|
+
return self.filter(realization=[0, 1]).realizations
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Module for searchcontext for collection of iterations."""
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import List
|
|
4
4
|
|
|
5
5
|
from ._search_context import SearchContext
|
|
6
6
|
|
|
@@ -25,42 +25,6 @@ class Iterations(SearchContext):
|
|
|
25
25
|
async def _maybe_prefetch_async(self, index):
|
|
26
26
|
return
|
|
27
27
|
|
|
28
|
-
def get_object(self, uuid: str) -> Dict:
|
|
29
|
-
"""Get metadata object by uuid
|
|
30
|
-
|
|
31
|
-
Args:
|
|
32
|
-
uuid (str): uuid of metadata object
|
|
33
|
-
select (List[str]): list of metadata fields to return
|
|
34
|
-
|
|
35
|
-
Returns:
|
|
36
|
-
Dict: a metadata object
|
|
37
|
-
"""
|
|
38
|
-
obj = self._cache.get(uuid)
|
|
39
|
-
if obj is None:
|
|
40
|
-
obj = self.get_iteration_by_uuid(uuid)
|
|
41
|
-
self._cache.put(uuid, obj)
|
|
42
|
-
pass
|
|
43
|
-
|
|
44
|
-
return obj
|
|
45
|
-
|
|
46
|
-
async def get_object_async(self, uuid: str) -> Dict:
|
|
47
|
-
"""Get metadata object by uuid
|
|
48
|
-
|
|
49
|
-
Args:
|
|
50
|
-
uuid (str): uuid of metadata object
|
|
51
|
-
select (List[str]): list of metadata fields to return
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
Dict: a metadata object
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
obj = self._cache.get(uuid)
|
|
58
|
-
if obj is None:
|
|
59
|
-
obj = await self.get_iteration_by_uuid_async(uuid)
|
|
60
|
-
self._cache.put(uuid, obj)
|
|
61
|
-
|
|
62
|
-
return obj
|
|
63
|
-
|
|
64
28
|
def filter(self, **kwargs):
|
|
65
29
|
sc = super().filter(**kwargs)
|
|
66
30
|
uuids = sc.get_field_values("fmu.iteration.uuid.keyword")
|
|
@@ -23,7 +23,7 @@ class Realization(Document, SearchContext):
|
|
|
23
23
|
)
|
|
24
24
|
pass
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def __str__(self):
|
|
27
27
|
return (
|
|
28
28
|
f"<{self.__class__.__name__}: {self.realizationid} {self.uuid}(uuid) "
|
|
29
29
|
f"in iteration {self.iterationname} "
|
|
@@ -31,6 +31,9 @@ class Realization(Document, SearchContext):
|
|
|
31
31
|
f"in asset {self.asset}>"
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
+
def __repr__(self):
|
|
35
|
+
return self.__str__()
|
|
36
|
+
|
|
34
37
|
@property
|
|
35
38
|
def field(self) -> str:
|
|
36
39
|
"""Case field"""
|
|
@@ -80,3 +83,8 @@ class Realization(Document, SearchContext):
|
|
|
80
83
|
def realizationid(self) -> int:
|
|
81
84
|
"""FMU realization id"""
|
|
82
85
|
return self.get_property("fmu.realization.id")
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def is_reference(self) -> bool:
|
|
89
|
+
"""Check if reference realization."""
|
|
90
|
+
return self.get_property("fmu.realization.is_reference") is True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Module for searchcontext for collection of realizations."""
|
|
2
2
|
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import List
|
|
4
4
|
|
|
5
5
|
from ._search_context import SearchContext
|
|
6
6
|
|
|
@@ -17,43 +17,26 @@ class Realizations(SearchContext):
|
|
|
17
17
|
async def _maybe_prefetch_async(self, index):
|
|
18
18
|
return
|
|
19
19
|
|
|
20
|
-
def get_object(self, uuid: str) -> Dict:
|
|
21
|
-
"""Get metadata object by uuid
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
uuid (str): uuid of metadata object
|
|
25
|
-
select (List[str]): list of metadata fields to return
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
Dict: a metadata object
|
|
29
|
-
"""
|
|
30
|
-
obj = self._cache.get(uuid)
|
|
31
|
-
if obj is None:
|
|
32
|
-
obj = self.get_realization_by_uuid(uuid)
|
|
33
|
-
self._cache.put(uuid, obj)
|
|
34
|
-
pass
|
|
35
|
-
|
|
36
|
-
return obj
|
|
37
|
-
|
|
38
|
-
async def get_object_async(self, uuid: str) -> Dict:
|
|
39
|
-
"""Get metadata object by uuid
|
|
40
|
-
|
|
41
|
-
Args:
|
|
42
|
-
uuid (str): uuid of metadata object
|
|
43
|
-
select (List[str]): list of metadata fields to return
|
|
44
|
-
|
|
45
|
-
Returns:
|
|
46
|
-
Dict: a metadata object
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
obj = self._cache.get(uuid)
|
|
50
|
-
if obj is None:
|
|
51
|
-
obj = await self.get_realization_by_uuid_async(uuid)
|
|
52
|
-
self._cache.put(uuid, obj)
|
|
53
|
-
|
|
54
|
-
return obj
|
|
55
|
-
|
|
56
20
|
def filter(self, **kwargs):
|
|
57
21
|
sc = super().filter(**kwargs)
|
|
58
22
|
uuids = sc.get_field_values("fmu.realization.uuid.keyword")
|
|
59
23
|
return Realizations(self, uuids)
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def classes(self) -> List[str]:
|
|
27
|
+
return ["realization"]
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
async def classes_async(self) -> List[str]:
|
|
31
|
+
return ["realization"]
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def realizationids(self) -> List[int]:
|
|
35
|
+
return [self.get_object(uuid).realizationid for uuid in self._hits]
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
async def realizationids_async(self) -> List[int]:
|
|
39
|
+
return [
|
|
40
|
+
(await self.get_object_async(uuid)).realizationid
|
|
41
|
+
for uuid in self._hits
|
|
42
|
+
]
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
fmu/__init__.py,sha256=ftS-xRPSH-vU7fIHlnZQaCTWbNvs4owJivNW65kzsIM,85
|
|
2
2
|
fmu/sumo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
fmu/sumo/explorer/__init__.py,sha256=Bc1wd1lQO3HP3tsVyPbqaesf2boZwGdtookWp8lmG-k,317
|
|
4
|
-
fmu/sumo/explorer/_version.py,sha256=
|
|
4
|
+
fmu/sumo/explorer/_version.py,sha256=2GXF52IIutfiInnoWGItHWB6xM45HGVQYJ3J77-iUV0,704
|
|
5
5
|
fmu/sumo/explorer/cache.py,sha256=uvz8TciwBnDEwJIHa9wneC0WVWuzhUqyF3dzk4kvGNk,1037
|
|
6
6
|
fmu/sumo/explorer/explorer.py,sha256=_3nUTO1E_nf6jqpivjgjKcX6rX1fx_mIG76YOM8xb-8,2931
|
|
7
7
|
fmu/sumo/explorer/filters.py,sha256=_t2PmHeTY9XiBvQeEGM-BpudWUaxIfyUSdNyG70xfRU,875
|
|
8
8
|
fmu/sumo/explorer/timefilter.py,sha256=AQHa18vkCz2BzH7X9GR1ypmNxfvI4gExh_jxAVYrDjc,6260
|
|
9
9
|
fmu/sumo/explorer/objects/__init__.py,sha256=72G0yfWWMTXA-oZw5GMRkrWvQqAYfadjerEwsyndCzc,637
|
|
10
|
-
fmu/sumo/explorer/objects/_child.py,sha256=
|
|
11
|
-
fmu/sumo/explorer/objects/_document.py,sha256=
|
|
12
|
-
fmu/sumo/explorer/objects/_metrics.py,sha256=
|
|
13
|
-
fmu/sumo/explorer/objects/_search_context.py,sha256=
|
|
10
|
+
fmu/sumo/explorer/objects/_child.py,sha256=I-TVxC5JhmcuCAkj1A_dK-cUzvbQarbonX1zq59d0ZU,6088
|
|
11
|
+
fmu/sumo/explorer/objects/_document.py,sha256=UR607n9N33vYaTSsYQoMmJUgnmS3To_uVyRSf7Vxulo,1797
|
|
12
|
+
fmu/sumo/explorer/objects/_metrics.py,sha256=Z7iJ8qmvH3iY5dsSf6At_AFIzITyM0rDfum_oGmUFG8,9989
|
|
13
|
+
fmu/sumo/explorer/objects/_search_context.py,sha256=C_HaiqqnERr_WV9sRX4P9MQdGl2rEco1FpxtM32j24M,66500
|
|
14
14
|
fmu/sumo/explorer/objects/case.py,sha256=fKp7X43ETLE1RaH3rMYxZiIuduRmf0JSnJ5gRoUgNPE,3813
|
|
15
15
|
fmu/sumo/explorer/objects/cases.py,sha256=i2bnvk7NWIkzbdWMs3BXU7TCqD5tH2r7pg1m1QXUj3o,561
|
|
16
16
|
fmu/sumo/explorer/objects/cpgrid.py,sha256=nuRgZ6FVEOPZT1ibd-rJhlbYYZ6BuUxXZPzovcH0kVc,2548
|
|
17
17
|
fmu/sumo/explorer/objects/cpgrid_property.py,sha256=PqqR05oKKKiTTG0iDO9V6TADdHY7VUsLHjai6SqahVo,2694
|
|
18
18
|
fmu/sumo/explorer/objects/cube.py,sha256=6pJLDajex-mblkt9YRZxtcK1XHcRZ8mlPPqJ-yDGEbA,1948
|
|
19
19
|
fmu/sumo/explorer/objects/dictionary.py,sha256=9Nt8Br7H4TgXO6qc46HtV1vB40LsEQb6WjWYDT-Ve0g,1191
|
|
20
|
-
fmu/sumo/explorer/objects/ensemble.py,sha256=
|
|
21
|
-
fmu/sumo/explorer/objects/ensembles.py,sha256=
|
|
22
|
-
fmu/sumo/explorer/objects/iteration.py,sha256=
|
|
23
|
-
fmu/sumo/explorer/objects/iterations.py,sha256=
|
|
20
|
+
fmu/sumo/explorer/objects/ensemble.py,sha256=MoGiXrtyVL8_cQt5vjh0rIA5bMMGRahPb284teQEqfs,2767
|
|
21
|
+
fmu/sumo/explorer/objects/ensembles.py,sha256=uFtnWDgk316NRM_JvD1C7PK20gDOPQVQjCygPFhe3ZE,772
|
|
22
|
+
fmu/sumo/explorer/objects/iteration.py,sha256=vXaH6G93pNPvufgliqRSs4fpqgNvgxa7QI0G0ucgr_U,2784
|
|
23
|
+
fmu/sumo/explorer/objects/iterations.py,sha256=ZRQOxPl6MpX7JV7lfvtXp8mGLHl37pl3-F9YAXYfRgc,778
|
|
24
24
|
fmu/sumo/explorer/objects/polygons.py,sha256=k5BKuXHsLxzhMR5KId6Fly4FNygTOcShFCCMXvhjWg4,1187
|
|
25
|
-
fmu/sumo/explorer/objects/realization.py,sha256=
|
|
26
|
-
fmu/sumo/explorer/objects/realizations.py,sha256=
|
|
25
|
+
fmu/sumo/explorer/objects/realization.py,sha256=HK47WyX6kwe6ZoHaGHeTWEno86Wkh9THLOtEzOt1FGE,2483
|
|
26
|
+
fmu/sumo/explorer/objects/realizations.py,sha256=ojyQDZNEGubRE97z7c5WHK1ZnO267jsIureNeIzouAw,1120
|
|
27
27
|
fmu/sumo/explorer/objects/surface.py,sha256=zHBtjLCIfkRHBv39OeJjA9lq3puLTfTII6TndZTtxVI,1627
|
|
28
28
|
fmu/sumo/explorer/objects/table.py,sha256=vLor3YTddHkDWZSMyWPQsddFNQ2_VXE_O-stmPIWIaQ,4900
|
|
29
|
-
fmu_sumo-2.
|
|
30
|
-
fmu_sumo-2.
|
|
31
|
-
fmu_sumo-2.
|
|
32
|
-
fmu_sumo-2.
|
|
33
|
-
fmu_sumo-2.
|
|
29
|
+
fmu_sumo-2.6.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
30
|
+
fmu_sumo-2.6.0.dist-info/METADATA,sha256=56_A-Dt1Bk1Q9ZfnIGVTQrTetphpp3kgI-bkquj2IFw,14781
|
|
31
|
+
fmu_sumo-2.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
32
|
+
fmu_sumo-2.6.0.dist-info/top_level.txt,sha256=Z-FIY3pxn0UK2Wxi9IJ7fKoLSraaxuNGi1eokiE0ShM,4
|
|
33
|
+
fmu_sumo-2.6.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|