res2df 1.3.6__py3-none-any.whl → 1.3.8__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.
- res2df/__init__.py +2 -3
- res2df/common.py +79 -75
- res2df/compdat.py +27 -32
- res2df/csv2res.py +5 -9
- res2df/equil.py +24 -29
- res2df/faults.py +2 -7
- res2df/fipreports.py +10 -14
- res2df/grid.py +61 -68
- res2df/gruptree.py +33 -35
- res2df/inferdims.py +6 -9
- res2df/nnc.py +9 -13
- res2df/opmkeywords/__init__.py +0 -0
- res2df/parameters.py +12 -12
- res2df/pillars.py +24 -31
- res2df/pvt.py +29 -34
- res2df/res2csv.py +10 -15
- res2df/res2csvlogger.py +1 -3
- res2df/resdatafiles.py +8 -8
- res2df/rft.py +36 -42
- res2df/satfunc.py +22 -28
- res2df/summary.py +57 -60
- res2df/trans.py +16 -38
- res2df/version.py +16 -3
- res2df/vfp/__init__.py +1 -1
- res2df/vfp/_vfp.py +28 -33
- res2df/vfp/_vfpcommon.py +18 -19
- res2df/vfp/_vfpdefs.py +2 -3
- res2df/vfp/_vfpinj.py +23 -58
- res2df/vfp/_vfpprod.py +28 -64
- res2df/wcon.py +4 -11
- res2df/wellcompletiondata.py +26 -26
- res2df/wellconnstatus.py +4 -5
- {res2df-1.3.6.dist-info → res2df-1.3.8.dist-info}/METADATA +4 -2
- {res2df-1.3.6.dist-info → res2df-1.3.8.dist-info}/RECORD +38 -37
- {res2df-1.3.6.dist-info → res2df-1.3.8.dist-info}/WHEEL +0 -0
- {res2df-1.3.6.dist-info → res2df-1.3.8.dist-info}/entry_points.txt +0 -0
- {res2df-1.3.6.dist-info → res2df-1.3.8.dist-info}/licenses/LICENSE +0 -0
- {res2df-1.3.6.dist-info → res2df-1.3.8.dist-info}/top_level.txt +0 -0
res2df/vfp/_vfpprod.py
CHANGED
|
@@ -11,7 +11,7 @@ pyarrow.Table to file as Eclipse .Ecl format.
|
|
|
11
11
|
|
|
12
12
|
import logging
|
|
13
13
|
import numbers
|
|
14
|
-
from typing import Any
|
|
14
|
+
from typing import Any
|
|
15
15
|
|
|
16
16
|
import numpy as np
|
|
17
17
|
import pandas as pd
|
|
@@ -19,13 +19,11 @@ import pyarrow as pa
|
|
|
19
19
|
|
|
20
20
|
try:
|
|
21
21
|
# Needed for mypy
|
|
22
|
-
|
|
23
|
-
# pylint: disable=unused-import
|
|
24
22
|
import opm.io
|
|
25
23
|
|
|
26
24
|
# This import is seemingly not used, but necessary for some attributes
|
|
27
25
|
# to be included in DeckItem objects.
|
|
28
|
-
from opm.io.deck import DeckKeyword # noqa
|
|
26
|
+
from opm.io.deck import DeckKeyword # noqa: F401
|
|
29
27
|
except ImportError:
|
|
30
28
|
pass
|
|
31
29
|
|
|
@@ -77,9 +75,9 @@ logger = logging.getLogger(__name__)
|
|
|
77
75
|
|
|
78
76
|
|
|
79
77
|
def basic_data(
|
|
80
|
-
keyword: "opm.
|
|
81
|
-
vfpnumbers_str:
|
|
82
|
-
) ->
|
|
78
|
+
keyword: "opm.opmcommon_python.DeckKeyword",
|
|
79
|
+
vfpnumbers_str: str | None = None,
|
|
80
|
+
) -> dict[str, Any] | None:
|
|
83
81
|
"""Read and return all data for Eclipse VFPPROD keyword as basic data types
|
|
84
82
|
|
|
85
83
|
Empty string returned if vfp table number does not match any number in list
|
|
@@ -146,14 +144,14 @@ def basic_data(
|
|
|
146
144
|
)
|
|
147
145
|
|
|
148
146
|
# Extract interpolation values and tabulated values (BHP values)
|
|
149
|
-
bhp_table:
|
|
150
|
-
thp_indices:
|
|
151
|
-
wfr_indices:
|
|
152
|
-
gfr_indices:
|
|
153
|
-
alq_indices:
|
|
147
|
+
bhp_table: list[list[float]] = []
|
|
148
|
+
thp_indices: list[float] = []
|
|
149
|
+
wfr_indices: list[float] = []
|
|
150
|
+
gfr_indices: list[float] = []
|
|
151
|
+
alq_indices: list[float] = []
|
|
154
152
|
for n in range(6, num_rec):
|
|
155
153
|
bhp_record = parse_opmio_deckrecord(keyword[n], "VFPPROD", "records", 6)
|
|
156
|
-
bhp_values:
|
|
154
|
+
bhp_values: Any | list[float]
|
|
157
155
|
if isinstance(bhp_record.get("VALUES"), list):
|
|
158
156
|
bhp_values = bhp_record.get("VALUES")
|
|
159
157
|
elif isinstance(bhp_record.get("VALUES"), numbers.Number):
|
|
@@ -389,7 +387,7 @@ def basic_data2pyarrow(
|
|
|
389
387
|
wfr_idx = wfr_indices[i]
|
|
390
388
|
gfr_idx = gfr_indices[i]
|
|
391
389
|
alq_idx = alq_indices[i]
|
|
392
|
-
col_name =
|
|
390
|
+
col_name = f"{thp_idx!s}_{wfr_idx!s}_{gfr_idx!s}_{alq_idx!s}"
|
|
393
391
|
col_dtype = pa.float64()
|
|
394
392
|
col_metadata = {
|
|
395
393
|
bytes("thp_idx", encoding="ascii"): bytes(str(thp_idx), encoding="ascii"),
|
|
@@ -414,7 +412,7 @@ def basic_data2pyarrow(
|
|
|
414
412
|
return pa_table
|
|
415
413
|
|
|
416
414
|
|
|
417
|
-
def df2basic_data(dframe: pd.DataFrame) ->
|
|
415
|
+
def df2basic_data(dframe: pd.DataFrame) -> dict[str, Any]:
|
|
418
416
|
"""Return basic data type for VFPPROD from a pandas dataframe.
|
|
419
417
|
|
|
420
418
|
Return format is a dictionary all data in VFPPROD in basic data types
|
|
@@ -494,32 +492,32 @@ def df2basic_data(dframe: pd.DataFrame) -> Dict[str, Any]:
|
|
|
494
492
|
if no_tab_values % no_flow_values != 0:
|
|
495
493
|
raise ValueError(
|
|
496
494
|
f"Number of unique rate values {no_flow_values} not consistent "
|
|
497
|
-
"with number of tabulated values {no_tab_values}"
|
|
495
|
+
f"with number of tabulated values {no_tab_values}"
|
|
498
496
|
)
|
|
499
497
|
if no_tab_values % no_wfr_values != 0:
|
|
500
498
|
raise ValueError(
|
|
501
499
|
f"Number of unique wfr values {no_wfr_values} not "
|
|
502
|
-
"consistent with number of tabulated values {no_tab_values}"
|
|
500
|
+
f"consistent with number of tabulated values {no_tab_values}"
|
|
503
501
|
)
|
|
504
502
|
if no_tab_values % no_gfr_values != 0:
|
|
505
503
|
raise ValueError(
|
|
506
504
|
f"Number of unique gfr values {no_gfr_values} not consistent "
|
|
507
|
-
"with number of tabulated values {no_tab_values}"
|
|
505
|
+
f"with number of tabulated values {no_tab_values}"
|
|
508
506
|
)
|
|
509
507
|
if no_tab_values % no_alq_values != 0:
|
|
510
508
|
raise ValueError(
|
|
511
509
|
f"Number of unique alq values {no_alq_values} not consistent "
|
|
512
|
-
"with number of tabulated values {no_tab_values}"
|
|
510
|
+
f"with number of tabulated values {no_tab_values}"
|
|
513
511
|
)
|
|
514
512
|
if no_tab_values % no_thp_values != 0:
|
|
515
513
|
raise ValueError(
|
|
516
514
|
f"Number of unique thp values {no_thp_values} not consistent "
|
|
517
|
-
"with number of tabulated values {no_tab_values}"
|
|
515
|
+
f"with number of tabulated values {no_tab_values}"
|
|
518
516
|
)
|
|
519
517
|
if no_tab_values % no_interp_values != 0:
|
|
520
518
|
raise ValueError(
|
|
521
519
|
f"Number of unique interpolation values {no_interp_values} not consistent "
|
|
522
|
-
"with number of tabulated values {no_tab_values}"
|
|
520
|
+
f"with number of tabulated values {no_tab_values}"
|
|
523
521
|
)
|
|
524
522
|
|
|
525
523
|
# Replace interpolation values with index in dataframe
|
|
@@ -584,7 +582,7 @@ def df2basic_data(dframe: pd.DataFrame) -> Dict[str, Any]:
|
|
|
584
582
|
return vfpprod_data
|
|
585
583
|
|
|
586
584
|
|
|
587
|
-
def pyarrow2basic_data(pa_table: pa.Table) ->
|
|
585
|
+
def pyarrow2basic_data(pa_table: pa.Table) -> dict[str, Any]:
|
|
588
586
|
"""Return basic data type for VFPPROD from a pyarrow.Table.
|
|
589
587
|
|
|
590
588
|
Return format is a dictionary all data in VFPPROD in basic data types
|
|
@@ -652,7 +650,7 @@ def pyarrow2basic_data(pa_table: pa.Table) -> Dict[str, Any]:
|
|
|
652
650
|
return vfpprod_data
|
|
653
651
|
|
|
654
652
|
|
|
655
|
-
def _check_basic_data(vfp_data:
|
|
653
|
+
def _check_basic_data(vfp_data: dict[str, Any]) -> bool:
|
|
656
654
|
"""Perform a check of the VFPPROD data contained in the dictionary.
|
|
657
655
|
Checks if all data is present and if the dimensions of the arrays
|
|
658
656
|
are consistent.
|
|
@@ -716,9 +714,9 @@ def _check_basic_data(vfp_data: Dict[str, Any]) -> bool:
|
|
|
716
714
|
|
|
717
715
|
|
|
718
716
|
def df(
|
|
719
|
-
keyword: "opm.
|
|
720
|
-
vfpnumbers_str:
|
|
721
|
-
) ->
|
|
717
|
+
keyword: "opm.opmcommon_python.DeckKeyword",
|
|
718
|
+
vfpnumbers_str: str | None = None,
|
|
719
|
+
) -> pd.DataFrame | None:
|
|
722
720
|
"""Return a dataframe or pyarrow Table of a single VFPPROD table
|
|
723
721
|
from a :term:`.DATA file`.
|
|
724
722
|
|
|
@@ -761,9 +759,9 @@ def df(
|
|
|
761
759
|
|
|
762
760
|
|
|
763
761
|
def pyarrow(
|
|
764
|
-
keyword: "opm.
|
|
765
|
-
vfpnumbers_str:
|
|
766
|
-
) ->
|
|
762
|
+
keyword: "opm.opmcommon_python.DeckKeyword",
|
|
763
|
+
vfpnumbers_str: str | None = None,
|
|
764
|
+
) -> pa.Table | None:
|
|
767
765
|
"""Return a pyarrow Table of a single VFPPROD table from a :term:`.DATA file`.
|
|
768
766
|
If no VFPPROD curve found, return None
|
|
769
767
|
|
|
@@ -851,40 +849,6 @@ def _write_basic_record(
|
|
|
851
849
|
return deck_str
|
|
852
850
|
|
|
853
851
|
|
|
854
|
-
def _write_table(
|
|
855
|
-
table: pd.DataFrame,
|
|
856
|
-
format: str = "%10.3",
|
|
857
|
-
values_per_line: int = 5,
|
|
858
|
-
) -> str:
|
|
859
|
-
"""Creates a :term:`include file` content string representing
|
|
860
|
-
a resdata record for a VFPPROD table (BHP part)
|
|
861
|
-
|
|
862
|
-
Args:
|
|
863
|
-
table: DataFrame with multiindex for table ranges and colums
|
|
864
|
-
for tabulated values (BHP)
|
|
865
|
-
format: Format string for values
|
|
866
|
-
values_per_line: Number of values per line in output
|
|
867
|
-
"""
|
|
868
|
-
|
|
869
|
-
deck_str = ""
|
|
870
|
-
for idx, _row in table.iterrows():
|
|
871
|
-
deck_str += f"{idx[0]:2d} {idx[1]:2d} {idx[2]:2d} {idx[3]:2d}"
|
|
872
|
-
no_flo = len(table.loc[idx].to_list())
|
|
873
|
-
for n, value in enumerate(table.loc[idx].to_list()):
|
|
874
|
-
deck_str += format % value
|
|
875
|
-
if (n + 1) % values_per_line == 0:
|
|
876
|
-
if n < no_flo - 1:
|
|
877
|
-
deck_str += "\n"
|
|
878
|
-
deck_str += " " * 11
|
|
879
|
-
else:
|
|
880
|
-
deck_str += "\n"
|
|
881
|
-
elif n == no_flo - 1:
|
|
882
|
-
deck_str += "\n"
|
|
883
|
-
deck_str += "/\n"
|
|
884
|
-
|
|
885
|
-
return deck_str
|
|
886
|
-
|
|
887
|
-
|
|
888
852
|
def _write_table_records(
|
|
889
853
|
thp_indices: np.ndarray,
|
|
890
854
|
wfr_indices: np.ndarray,
|
|
@@ -940,7 +904,7 @@ def _write_table_records(
|
|
|
940
904
|
return deck_str
|
|
941
905
|
|
|
942
906
|
|
|
943
|
-
def df2res(dframe: pd.DataFrame, comment:
|
|
907
|
+
def df2res(dframe: pd.DataFrame, comment: str | None = None) -> str:
|
|
944
908
|
"""Creates a :term:`include file` content string
|
|
945
909
|
representing single VFPPROD Eclipse input from a dataframe
|
|
946
910
|
|
res2df/wcon.py
CHANGED
|
@@ -4,14 +4,11 @@ import argparse
|
|
|
4
4
|
import contextlib
|
|
5
5
|
import datetime
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Union
|
|
8
7
|
|
|
9
8
|
import pandas as pd
|
|
10
9
|
|
|
11
10
|
with contextlib.suppress(ImportError):
|
|
12
11
|
# Needed for mypy
|
|
13
|
-
|
|
14
|
-
# pylint: disable=unused-import
|
|
15
12
|
import opm.io
|
|
16
13
|
|
|
17
14
|
from .common import (
|
|
@@ -28,7 +25,7 @@ logger = logging.getLogger(__name__)
|
|
|
28
25
|
WCONKEYS = ["WCONHIST", "WCONINJE", "WCONINJH", "WCONPROD"]
|
|
29
26
|
|
|
30
27
|
|
|
31
|
-
def df(deck:
|
|
28
|
+
def df(deck: "ResdataFiles | opm.opmcommon_python.Deck") -> pd.DataFrame:
|
|
32
29
|
"""Loop through the :term:`deck` and pick up information found
|
|
33
30
|
|
|
34
31
|
The loop over the :term:`deck` is a state machine, as it has to pick up dates
|
|
@@ -42,7 +39,7 @@ def df(deck: Union[ResdataFiles, "opm.libopmcommon_python.Deck"]) -> pd.DataFram
|
|
|
42
39
|
for kword in deck:
|
|
43
40
|
if kword.name in ["DATES", "START"]:
|
|
44
41
|
for rec in kword:
|
|
45
|
-
logger.info("Parsing at date %s",
|
|
42
|
+
logger.info("Parsing at date %s", date)
|
|
46
43
|
date = parse_opmio_date_rec(rec)
|
|
47
44
|
elif kword.name == "TSTEP":
|
|
48
45
|
if not date:
|
|
@@ -53,9 +50,7 @@ def df(deck: Union[ResdataFiles, "opm.libopmcommon_python.Deck"]) -> pd.DataFram
|
|
|
53
50
|
# Assuming not LAB units, then the unit is days.
|
|
54
51
|
days = sum(steplist)
|
|
55
52
|
date += datetime.timedelta(days=days)
|
|
56
|
-
logger.info(
|
|
57
|
-
"Advancing %s days to %s through TSTEP", str(days), str(date)
|
|
58
|
-
)
|
|
53
|
+
logger.info("Advancing %s days to %s through TSTEP", days, date)
|
|
59
54
|
elif kword.name in WCONKEYS:
|
|
60
55
|
for rec in kword: # Loop over the lines inside WCON* record
|
|
61
56
|
rec_data = parse_opmio_deckrecord(rec, kword.name)
|
|
@@ -92,9 +87,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
|
92
87
|
|
|
93
88
|
def wcon_main(args) -> None:
|
|
94
89
|
"""Read from disk and write CSV back to disk"""
|
|
95
|
-
logger = getLogger_res2csv(
|
|
96
|
-
__name__, vars(args)
|
|
97
|
-
)
|
|
90
|
+
logger = getLogger_res2csv(__name__, vars(args))
|
|
98
91
|
resdatafiles = ResdataFiles(args.DATAFILE)
|
|
99
92
|
if resdatafiles:
|
|
100
93
|
deck = resdatafiles.get_deck()
|
res2df/wellcompletiondata.py
CHANGED
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
4
|
import logging
|
|
5
|
-
from enum import
|
|
5
|
+
from enum import StrEnum
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
import pandas as pd
|
|
10
|
-
import pyarrow
|
|
11
|
-
import pyarrow.feather
|
|
10
|
+
import pyarrow as pa
|
|
12
11
|
|
|
13
12
|
from .common import convert_lyrlist_to_zonemap, parse_lyrfile, write_dframe_stdout_file
|
|
14
13
|
from .compdat import df as create_compdat_df
|
|
@@ -19,14 +18,14 @@ from .wellconnstatus import df as create_wellconnstatus_df
|
|
|
19
18
|
logger = logging.getLogger(__name__)
|
|
20
19
|
|
|
21
20
|
|
|
22
|
-
class UnitSystem(
|
|
21
|
+
class UnitSystem(StrEnum):
|
|
23
22
|
METRIC = "METRIC"
|
|
24
23
|
FIELD = "FIELD"
|
|
25
24
|
LAB = "LAB"
|
|
26
25
|
PVTM = "PVT-M"
|
|
27
26
|
|
|
28
27
|
|
|
29
|
-
class KHUnit(
|
|
28
|
+
class KHUnit(StrEnum):
|
|
30
29
|
METRIC = "mDm"
|
|
31
30
|
FIELD = "mDft"
|
|
32
31
|
LAB = "mDcm"
|
|
@@ -35,9 +34,9 @@ class KHUnit(Enum):
|
|
|
35
34
|
|
|
36
35
|
def df(
|
|
37
36
|
resdatafiles: ResdataFiles,
|
|
38
|
-
zonemap:
|
|
37
|
+
zonemap: dict[int, str],
|
|
39
38
|
use_wellconnstatus: bool = False,
|
|
40
|
-
excl_well_startswith:
|
|
39
|
+
excl_well_startswith: str | None = None,
|
|
41
40
|
) -> pd.DataFrame:
|
|
42
41
|
"""Aggregates compdat to zone level. If use_wellconnstatus is True,
|
|
43
42
|
the actual OP/SH status of a connection will be extracted from summary
|
|
@@ -85,7 +84,9 @@ def df(
|
|
|
85
84
|
meta = _get_metadata(resdatafiles)
|
|
86
85
|
# Slice meta to dataframe columns:
|
|
87
86
|
compdat_df.attrs["meta"] = {
|
|
88
|
-
column_key: meta[column_key]
|
|
87
|
+
column_key: meta[str(column_key)]
|
|
88
|
+
for column_key in compdat_df
|
|
89
|
+
if column_key in meta
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
return compdat_df
|
|
@@ -105,9 +106,9 @@ def _get_unit_system(resdatafiles: ResdataFiles) -> UnitSystem:
|
|
|
105
106
|
return UnitSystem.METRIC
|
|
106
107
|
|
|
107
108
|
|
|
108
|
-
def _get_metadata(resdatafiles: ResdataFiles) ->
|
|
109
|
+
def _get_metadata(resdatafiles: ResdataFiles) -> dict[str, dict[str, Any]]:
|
|
109
110
|
"""Provide metadata for the well completion data export"""
|
|
110
|
-
meta:
|
|
111
|
+
meta: dict[str, dict[str, str]] = {}
|
|
111
112
|
unitsystem = _get_unit_system(resdatafiles)
|
|
112
113
|
kh_units = {
|
|
113
114
|
UnitSystem.METRIC: KHUnit.METRIC,
|
|
@@ -188,18 +189,17 @@ def _merge_compdat_and_connstatus(
|
|
|
188
189
|
pd.DataFrame with one row per unique combination of well, zone and date.
|
|
189
190
|
"""
|
|
190
191
|
match_on = ["WELL", "I", "J", "K1"]
|
|
191
|
-
wellconnstatus_df.rename({"K": "K1"}, axis=1
|
|
192
|
+
wellconnstatus_df = wellconnstatus_df.rename({"K": "K1"}, axis=1)
|
|
192
193
|
|
|
193
|
-
dframe =
|
|
194
|
-
|
|
195
|
-
compdat_df[match_on + ["KH", "ZONE"]],
|
|
194
|
+
dframe = wellconnstatus_df.merge(
|
|
195
|
+
compdat_df[[*match_on, "KH", "ZONE"]],
|
|
196
196
|
on=match_on,
|
|
197
197
|
how="left",
|
|
198
198
|
)
|
|
199
199
|
|
|
200
200
|
# There will often be several rows (with different OP/SH) matching in compdat.
|
|
201
201
|
# Only the first is kept
|
|
202
|
-
dframe.drop_duplicates(subset=["DATE"
|
|
202
|
+
dframe = dframe.drop_duplicates(subset=["DATE", *match_on], keep="first")
|
|
203
203
|
|
|
204
204
|
# Concat from compdat the wells that are not in well connection status
|
|
205
205
|
dframe = pd.concat(
|
|
@@ -210,7 +210,7 @@ def _merge_compdat_and_connstatus(
|
|
|
210
210
|
return dframe
|
|
211
211
|
|
|
212
212
|
|
|
213
|
-
def _df2pyarrow(dframe: pd.DataFrame) ->
|
|
213
|
+
def _df2pyarrow(dframe: pd.DataFrame) -> pa.Table:
|
|
214
214
|
"""Construct a pyarrow table from dataframe with well
|
|
215
215
|
completion data.
|
|
216
216
|
|
|
@@ -218,7 +218,7 @@ def _df2pyarrow(dframe: pd.DataFrame) -> pyarrow.Table:
|
|
|
218
218
|
|
|
219
219
|
32-bit types will be used for integers and floats
|
|
220
220
|
"""
|
|
221
|
-
field_list:
|
|
221
|
+
field_list: list[pa.Field] = []
|
|
222
222
|
for colname in dframe.columns:
|
|
223
223
|
if "meta" in dframe.attrs and colname in dframe.attrs["meta"]:
|
|
224
224
|
# Boolean objects in the metadata dictionary must be converted to bytes:
|
|
@@ -229,17 +229,17 @@ def _df2pyarrow(dframe: pd.DataFrame) -> pyarrow.Table:
|
|
|
229
229
|
else:
|
|
230
230
|
field_metadata = {}
|
|
231
231
|
if colname == "DATE":
|
|
232
|
-
dtype =
|
|
232
|
+
dtype = pa.timestamp("ms")
|
|
233
233
|
elif pd.api.types.is_integer_dtype(dframe.dtypes[colname]):
|
|
234
|
-
dtype =
|
|
234
|
+
dtype = pa.int32()
|
|
235
235
|
elif pd.api.types.is_string_dtype(dframe.dtypes[colname]):
|
|
236
|
-
dtype =
|
|
236
|
+
dtype = pa.string()
|
|
237
237
|
else:
|
|
238
|
-
dtype =
|
|
239
|
-
field_list.append(
|
|
238
|
+
dtype = pa.float32()
|
|
239
|
+
field_list.append(pa.field(colname, dtype, metadata=field_metadata))
|
|
240
240
|
|
|
241
|
-
schema =
|
|
242
|
-
return
|
|
241
|
+
schema = pa.schema(field_list)
|
|
242
|
+
return pa.Table.from_pandas(dframe, schema=schema, preserve_index=False)
|
|
243
243
|
|
|
244
244
|
|
|
245
245
|
def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
|
|
@@ -293,7 +293,7 @@ def wellcompletiondata_main(args):
|
|
|
293
293
|
resdatafiles = ResdataFiles(args.DATAFILE)
|
|
294
294
|
if not Path(args.zonemap).is_file():
|
|
295
295
|
wellcompletiondata_df = pd.DataFrame()
|
|
296
|
-
logger.info(
|
|
296
|
+
logger.info("Zonemap not found: %s", args.zonemap)
|
|
297
297
|
else:
|
|
298
298
|
zonemap = convert_lyrlist_to_zonemap(parse_lyrfile(args.zonemap))
|
|
299
299
|
wellcompletiondata_df = df(
|
res2df/wellconnstatus.py
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
import argparse
|
|
4
4
|
import logging
|
|
5
5
|
import re
|
|
6
|
-
from typing import Any
|
|
6
|
+
from typing import Any
|
|
7
7
|
|
|
8
|
-
import numpy as np
|
|
9
8
|
import pandas as pd
|
|
10
9
|
|
|
11
10
|
from .common import write_dframe_stdout_file
|
|
@@ -39,7 +38,7 @@ def _extract_status_changes(smry: pd.DataFrame) -> pd.DataFrame:
|
|
|
39
38
|
cpi_columns = [
|
|
40
39
|
col
|
|
41
40
|
for col in smry.columns
|
|
42
|
-
if re.match("^CPI:[A-Z0-9_-]{1,8}:[0-9]+,[0-9]+,[0-9]+$", col)
|
|
41
|
+
if re.match(r"^CPI:[A-Z0-9_-]{1,8}:[0-9]+,[0-9]+,[0-9]+$", col)
|
|
43
42
|
]
|
|
44
43
|
dframe = pd.DataFrame(columns=["DATE", "WELL", "I", "J", "K", "OP/SH"])
|
|
45
44
|
|
|
@@ -66,8 +65,8 @@ def _extract_status_changes(smry: pd.DataFrame) -> pd.DataFrame:
|
|
|
66
65
|
|
|
67
66
|
|
|
68
67
|
def _extract_single_connection_status_changes(
|
|
69
|
-
dates:
|
|
70
|
-
) ->
|
|
68
|
+
dates: pd.Index, conn_values: pd.Series
|
|
69
|
+
) -> list[tuple[Any, str]]:
|
|
71
70
|
"""Extracts the status history of a single connection as a list of tuples
|
|
72
71
|
on the form (date, status)
|
|
73
72
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: res2df
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.8
|
|
4
4
|
Summary: Convert reservoir simulator input and output to DataFrames
|
|
5
5
|
Author-email: Håvard Berland <havb@equinor.com>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -696,6 +696,7 @@ Description-Content-Type: text/markdown
|
|
|
696
696
|
License-File: LICENSE
|
|
697
697
|
Requires-Dist: resdata>=5.0.0-b0
|
|
698
698
|
Requires-Dist: resfo
|
|
699
|
+
Requires-Dist: networkx
|
|
699
700
|
Requires-Dist: numpy
|
|
700
701
|
Requires-Dist: opm>=2020.10.2
|
|
701
702
|
Requires-Dist: pandas
|
|
@@ -703,7 +704,6 @@ Requires-Dist: pyarrow
|
|
|
703
704
|
Requires-Dist: pyyaml>=5.1
|
|
704
705
|
Requires-Dist: treelib
|
|
705
706
|
Provides-Extra: tests
|
|
706
|
-
Requires-Dist: networkx; extra == "tests"
|
|
707
707
|
Requires-Dist: pytest; extra == "tests"
|
|
708
708
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
709
709
|
Requires-Dist: pytest-mock; extra == "tests"
|
|
@@ -715,6 +715,8 @@ Requires-Dist: mypy; extra == "types"
|
|
|
715
715
|
Requires-Dist: types-PyYAML; extra == "types"
|
|
716
716
|
Requires-Dist: types-python-dateutil; extra == "types"
|
|
717
717
|
Requires-Dist: types-setuptools; extra == "types"
|
|
718
|
+
Requires-Dist: types-networkx; extra == "types"
|
|
719
|
+
Requires-Dist: pandas-stubs; extra == "types"
|
|
718
720
|
Provides-Extra: docs
|
|
719
721
|
Requires-Dist: autoapi; extra == "docs"
|
|
720
722
|
Requires-Dist: ipython; extra == "docs"
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
res2df/__init__.py,sha256=
|
|
1
|
+
res2df/__init__.py,sha256=op6PPtJBOLn7JRGZW09BIjJbHCFva4VY2iXmbKaGhnE,577
|
|
2
2
|
res2df/__version__.py,sha256=UtExCuqQ29NY2we1bzLXvNkP21JU7hx1wXM4G1uPvts,128
|
|
3
|
-
res2df/common.py,sha256=
|
|
4
|
-
res2df/compdat.py,sha256=
|
|
3
|
+
res2df/common.py,sha256=wpmxgl-QMEdSLmh71J6mfWCjO5sjoejPPPnwKaqqsYA,35004
|
|
4
|
+
res2df/compdat.py,sha256=4-T3bUWZLqUQw99YJUQblFXa2kwmpMWSeZi-RWuBL1w,36630
|
|
5
5
|
res2df/constants.py,sha256=0W-ZYlm3Bbe9MONrRhA0c4yLXfJlqGX5apFN64i8RU0,258
|
|
6
|
-
res2df/csv2res.py,sha256=
|
|
7
|
-
res2df/equil.py,sha256=
|
|
8
|
-
res2df/faults.py,sha256=
|
|
9
|
-
res2df/fipreports.py,sha256=
|
|
10
|
-
res2df/grid.py,sha256=
|
|
11
|
-
res2df/gruptree.py,sha256
|
|
12
|
-
res2df/inferdims.py,sha256=
|
|
13
|
-
res2df/nnc.py,sha256=
|
|
14
|
-
res2df/parameters.py,sha256=
|
|
15
|
-
res2df/pillars.py,sha256=
|
|
16
|
-
res2df/pvt.py,sha256=
|
|
17
|
-
res2df/res2csv.py,sha256=
|
|
18
|
-
res2df/res2csvlogger.py,sha256=
|
|
19
|
-
res2df/resdatafiles.py,sha256=
|
|
20
|
-
res2df/rft.py,sha256=
|
|
21
|
-
res2df/satfunc.py,sha256=
|
|
22
|
-
res2df/summary.py,sha256=
|
|
6
|
+
res2df/csv2res.py,sha256=i1SqzDYoKDmwik0ZHRb-F775Lhmt2GQPoFrquE_viOI,3093
|
|
7
|
+
res2df/equil.py,sha256=Fk5aGYhje4pgrHLHEn2MdQwhl59pel4cOg5dLdWMWaU,16911
|
|
8
|
+
res2df/faults.py,sha256=JMOib30354Me9qLonqRlo9hhhhfB4oUg5vit1-GGb-U,3038
|
|
9
|
+
res2df/fipreports.py,sha256=1d7rp1me51dN2Rr6wYMq_wVWbh1bbSM-srnNlehtYFY,7549
|
|
10
|
+
res2df/grid.py,sha256=XarFKldUfyAVf1nwLHKfgJDM_PLV-eoYL4SwFKmGVeU,27302
|
|
11
|
+
res2df/gruptree.py,sha256=ET7IuqHkamxDpZN2mK6FDwZwC1lqgg4aNodexghW-0A,16926
|
|
12
|
+
res2df/inferdims.py,sha256=xRNkHJ9EQMx2ai9hDBntlXYqDIuB-0tO3EXsHcIZI_Q,7241
|
|
13
|
+
res2df/nnc.py,sha256=UvgBVqs8b3hXfumiAZT6xv4yF3Rjaxwc71iLNcJ-UfI,9193
|
|
14
|
+
res2df/parameters.py,sha256=zdGvmFg3qyzopXRTgb9CvyI1izCBYS9aZYPNBRzeDOg,6215
|
|
15
|
+
res2df/pillars.py,sha256=4zB_SCrE8sU444y0DpWO00a2SQa67JZLv3gGk4RwsjY,15957
|
|
16
|
+
res2df/pvt.py,sha256=WnVVh8wGz2DVQwmuwllz_TnJdl1AdpI-8LWztRGCOgw,22385
|
|
17
|
+
res2df/res2csv.py,sha256=Xu0qHubHlmxzxblwdhRY6H6CLTMTGQvsLQq8HpMBF40,10851
|
|
18
|
+
res2df/res2csvlogger.py,sha256=n9gMmlgzPNbtZAN9dhrBDpahEK1bG2jPWQZ7CHjSN6c,2243
|
|
19
|
+
res2df/resdatafiles.py,sha256=v68iKobzSNC_5_1uDBTdK5t2TcYQcPn0buURtxZ9QLk,10029
|
|
20
|
+
res2df/rft.py,sha256=zIVJf2nwzUMYWaA_h9uT-Tc8QWhdcornLA_btBDKeP8,27950
|
|
21
|
+
res2df/satfunc.py,sha256=V_8e_x5OByKyfmke8uZUPRJ_kUnGkp4uwdArpZV1ZaM,13570
|
|
22
|
+
res2df/summary.py,sha256=42zn8Lj7QmywYbmf3YQjUyAYK9jerZEt-r38-3TTtzI,31483
|
|
23
23
|
res2df/svg_color_keyword_names.txt,sha256=yiI2Ohv3NxxEAJC5OjVERZi7MLi2-bk7okyI5-xFDr8,1456
|
|
24
|
-
res2df/trans.py,sha256=
|
|
25
|
-
res2df/version.py,sha256=
|
|
26
|
-
res2df/wcon.py,sha256=
|
|
27
|
-
res2df/wellcompletiondata.py,sha256=
|
|
28
|
-
res2df/wellconnstatus.py,sha256=
|
|
24
|
+
res2df/trans.py,sha256=AHBJ-UUqU-BToLzygezMzM8YVGPBixGNRzxemOHOy84,10455
|
|
25
|
+
res2df/version.py,sha256=_hPMnsWQOeGw9lqV0fueN3y4Gw7vLcBaoT0Bio9pJWo,704
|
|
26
|
+
res2df/wcon.py,sha256=4Fq8JG2GeLJs7GKCC3F3RkkyJMmwn3iESJeXQuY01iA,3198
|
|
27
|
+
res2df/wellcompletiondata.py,sha256=u_qD1XiCxAJM_corqHWZH9t2mvO1TIGVyc0l6MUd1II,10918
|
|
28
|
+
res2df/wellconnstatus.py,sha256=5MWqtyagl_t9FbbEosTG50FsFdLOatqGR1yRxzl6TDM,4035
|
|
29
29
|
res2df/hook_implementations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
30
|
res2df/hook_implementations/forward_model_steps.py,sha256=I8T9HGmTW95mHHjBuZkhTxaYwIPg7CJwbusfJotXfSA,4800
|
|
31
31
|
res2df/opmkeywords/BRANPROP,sha256=MZA6L6J9olaprrUhRah_wgJoOiYXP-DknVAYOdsIC14,475
|
|
@@ -71,17 +71,18 @@ res2df/opmkeywords/WLIST,sha256=r2qcSSzNvBjeZlRo-apCTeWRAxrzNL2oNDq_QIHEm-c,317
|
|
|
71
71
|
res2df/opmkeywords/WSEGAICD,sha256=kDUukuTv_C4zMG5kho8Jiy4YIqHmr2YILgXIVR727CA,2192
|
|
72
72
|
res2df/opmkeywords/WSEGSICD,sha256=b34kWwhzl5ansUKp_3-64stIbeKadi_esh9D4SnRx1A,1447
|
|
73
73
|
res2df/opmkeywords/WSEGVALV,sha256=iCknAC9AEhGx_28iv1FSYhukQFT8_ekDdqxfhVrHFJo,963
|
|
74
|
+
res2df/opmkeywords/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
75
|
res2df/opmkeywords/readme,sha256=xJM2Or6oiSP02xTe-aY4efPeh5UQiTieScoPHGV4rH0,285
|
|
75
76
|
res2df/opmkeywords/runmetoupdate.sh,sha256=GKvjvd3H3Sf0bmeIduQ43pYcDmcBlOL_Epfm_xjDFUA,996
|
|
76
|
-
res2df/vfp/__init__.py,sha256=
|
|
77
|
-
res2df/vfp/_vfp.py,sha256=
|
|
78
|
-
res2df/vfp/_vfpcommon.py,sha256=
|
|
79
|
-
res2df/vfp/_vfpdefs.py,sha256=
|
|
80
|
-
res2df/vfp/_vfpinj.py,sha256=
|
|
81
|
-
res2df/vfp/_vfpprod.py,sha256=
|
|
82
|
-
res2df-1.3.
|
|
83
|
-
res2df-1.3.
|
|
84
|
-
res2df-1.3.
|
|
85
|
-
res2df-1.3.
|
|
86
|
-
res2df-1.3.
|
|
87
|
-
res2df-1.3.
|
|
77
|
+
res2df/vfp/__init__.py,sha256=cbUr7EjH9WUJvuVeleDQyxp0g_TbXMCCYEpQ_NiYD4w,362
|
|
78
|
+
res2df/vfp/_vfp.py,sha256=hezXkWz58RDy9EHC8mcOE3-VmpLy6BGmxOn_f-SBzcc,19392
|
|
79
|
+
res2df/vfp/_vfpcommon.py,sha256=iq3kim4Zrs-y47NtEpoSTEyeS2hPXTaKBsfcxdzj2gw,6964
|
|
80
|
+
res2df/vfp/_vfpdefs.py,sha256=TT0bHHbbdGMS3Xm7dzpZPR7zBLPvlCuQIKvH7sr5TBA,6985
|
|
81
|
+
res2df/vfp/_vfpinj.py,sha256=xojHI2hcdUFBUslMKu5K2p2etN-8sinlx-HlkINZOs4,22523
|
|
82
|
+
res2df/vfp/_vfpprod.py,sha256=vohQOu63pQsinGT8wgreeUwxzfwH6S1Om90XB8gfUzs,35669
|
|
83
|
+
res2df-1.3.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
84
|
+
res2df-1.3.8.dist-info/METADATA,sha256=JeOigbs6ZzDTCRf654WED4NYYLDfyIWSmqEA_ZDqw1E,44498
|
|
85
|
+
res2df-1.3.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
86
|
+
res2df-1.3.8.dist-info/entry_points.txt,sha256=ctl-_CwayyUVqFMUrwTT3Z3gZdnW6WCaiaLUJ4f_HnY,180
|
|
87
|
+
res2df-1.3.8.dist-info/top_level.txt,sha256=U8AZBqrFHm9PMXg0toCfHJ817VfFtdKQpc8JuS5qToM,7
|
|
88
|
+
res2df-1.3.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|