res2df 1.3.9__py3-none-any.whl → 1.3.11__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 CHANGED
@@ -1,5 +1,22 @@
1
- import importlib
2
-
1
+ from . import compdat as compdat
2
+ from . import csv2res as csv2res
3
+ from . import equil as equil
4
+ from . import faults as faults
5
+ from . import fipreports as fipreports
6
+ from . import grid as grid
7
+ from . import gruptree as gruptree
8
+ from . import nnc as nnc
9
+ from . import pillars as pillars
10
+ from . import pvt as pvt
11
+ from . import res2csv as res2csv
12
+ from . import rft as rft
13
+ from . import satfunc as satfunc
14
+ from . import summary as summary
15
+ from . import trans as trans
16
+ from . import vfp as vfp
17
+ from . import wcon as wcon
18
+ from . import wellcompletiondata as wellcompletiondata
19
+ from . import wellconnstatus as wellconnstatus
3
20
  from .__version__ import __version__ as __version__
4
21
  from .res2csvlogger import getLogger_res2csv as getLogger_res2csv
5
22
  from .resdatafiles import ResdataFiles as ResdataFiles
@@ -25,5 +42,27 @@ SUBMODULES: list[str] = [
25
42
  ]
26
43
 
27
44
 
28
- for submodule in [*SUBMODULES, "res2csv", "csv2res"]:
29
- importlib.import_module("res2df." + submodule)
45
+ __all__ = [
46
+ "ResdataFiles",
47
+ "__version__",
48
+ "compdat",
49
+ "csv2res",
50
+ "equil",
51
+ "faults",
52
+ "fipreports",
53
+ "getLogger_res2csv",
54
+ "grid",
55
+ "gruptree",
56
+ "nnc",
57
+ "pillars",
58
+ "pvt",
59
+ "res2csv",
60
+ "rft",
61
+ "satfunc",
62
+ "summary",
63
+ "trans",
64
+ "vfp",
65
+ "wcon",
66
+ "wellcompletiondata",
67
+ "wellconnstatus",
68
+ ]
res2df/__version__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  try:
2
- from .version import version # type: ignore
2
+ from .version import version
3
3
 
4
4
  __version__ = version
5
5
  except ImportError:
res2df/common.py CHANGED
@@ -11,28 +11,24 @@ import shlex
11
11
  import signal
12
12
  import sys
13
13
  from collections import defaultdict
14
+ from collections.abc import Mapping
14
15
  from importlib import resources
15
16
  from pathlib import Path
16
17
  from typing import Any, cast
17
18
 
18
19
  import dateutil.parser
19
20
  import numpy as np
21
+ import opm.io.deck
20
22
  import pandas as pd
21
23
  import pyarrow as pa
24
+
25
+ # This import is seemingly not used, but necessary for some attributes
26
+ # to be included in DeckItem objects.
27
+ from opm.io.deck import DeckKeyword # noqa: F401
22
28
  from pyarrow import (
23
29
  feather, # necessary as this module is not loaded unless explicitly imported
24
30
  )
25
31
 
26
- try:
27
- import opm.io.deck
28
-
29
- # This import is seemingly not used, but necessary for some attributes
30
- # to be included in DeckItem objects.
31
- from opm.io.deck import DeckKeyword # noqa: F401
32
- except ImportError:
33
- # Allow parts of res2df to work without OPM:
34
- pass
35
-
36
32
  from .__version__ import __version__
37
33
  from .constants import MAGIC_STDOUT
38
34
 
@@ -189,9 +185,9 @@ def datetime_to_ecldate(timestamp: str | datetime.datetime | datetime.date) -> s
189
185
 
190
186
 
191
187
  def keyworddata_to_df(
192
- deck,
188
+ deck: "opm.opmcommon_python.Deck",
193
189
  keyword: str,
194
- renamer: dict[str, str | list[str]] | None = None,
190
+ renamer: Mapping[str, str | list[str]] | None = None,
195
191
  recordcountername: str | None = None,
196
192
  emptyrecordcountername: str | None = None,
197
193
  ) -> pd.DataFrame:
@@ -275,7 +271,7 @@ def parse_opmio_deckrecord(
275
271
  keyword: str,
276
272
  itemlistname: str = "items",
277
273
  recordindex: int | None = None,
278
- renamer: dict[str, str] | dict[str, str | list[str]] | None = None,
274
+ renamer: Mapping[str, str | list[str]] | None = None,
279
275
  ) -> dict[str, Any]:
280
276
  """
281
277
  Parse an opm.io.DeckRecord belonging to a certain keyword
@@ -344,8 +340,9 @@ def parse_opmio_deckrecord(
344
340
  if renamer:
345
341
  renamed_dict: dict[str, Any] = {}
346
342
  for key, value in rec_dict.items():
347
- if key in renamer and not isinstance(renamer[key], list):
348
- renamed_dict[renamer[key]] = value # type: ignore
343
+ renamed_key = renamer.get(key)
344
+ if isinstance(renamed_key, str):
345
+ renamed_dict[renamed_key] = value
349
346
  else:
350
347
  renamed_dict[key] = value
351
348
  return renamed_dict
@@ -470,7 +467,7 @@ def handle_wanted_keywords(
470
467
 
471
468
  def fill_reverse_parser(
472
469
  parser: argparse.ArgumentParser, modulename: str, defaultoutputfile: str
473
- ):
470
+ ) -> argparse.ArgumentParser:
474
471
  """A standardized submodule parser for the command line utility
475
472
  to produce :term:`include files <include file>` from a CSV file.
476
473
 
@@ -543,6 +540,7 @@ def df2res(
543
540
  """
544
541
  from_module = inspect.stack()[1]
545
542
  calling_module = inspect.getmodule(from_module[0])
543
+ assert calling_module is not None
546
544
  if dataframe.empty:
547
545
  raise ValueError("Empty dataframe")
548
546
  if (
@@ -580,7 +578,7 @@ def df2res(
580
578
  if not_supported:
581
579
  logger.warning(
582
580
  "Requested keyword(s) not supported by %s: %s",
583
- calling_module.__name__, # type: ignore
581
+ calling_module.__name__,
584
582
  not_supported,
585
583
  )
586
584
  # Warn if some requested keywords are not in frame:
@@ -601,7 +599,7 @@ def df2res(
601
599
  string = ""
602
600
  res2df_header = (
603
601
  "Output file printed by "
604
- + calling_module.__name__ # type: ignore
602
+ + calling_module.__name__
605
603
  + " "
606
604
  + __version__
607
605
  + "\n"
@@ -631,7 +629,7 @@ def generic_deck_table(
631
629
  dframe: pd.DataFrame,
632
630
  keyword: str,
633
631
  comment: str | None = None,
634
- renamer: dict[str, str] | None = None,
632
+ renamer: Mapping[str, str] | None = None,
635
633
  drop_trailing_columns: bool = True,
636
634
  ) -> str:
637
635
  """Construct string contents of a :term:`.DATA file` table.
@@ -855,7 +853,7 @@ def is_color(input_string: str) -> bool:
855
853
  return bool(re.match(regex, input_string))
856
854
 
857
855
 
858
- def parse_lyrfile(filename: str) -> list[dict[str, Any]] | None:
856
+ def parse_lyrfile(filename: str | Path) -> list[dict[str, Any]] | None:
859
857
  """Return a list of dicts representation of the lyr file.
860
858
 
861
859
  The lyr file contains data of the following format,
@@ -927,7 +925,9 @@ def parse_lyrfile(filename: str) -> list[dict[str, Any]] | None:
927
925
  return lyrlist
928
926
 
929
927
 
930
- def convert_lyrlist_to_zonemap(lyrlist: list[dict[str, Any]]) -> dict[int, str]:
928
+ def convert_lyrlist_to_zonemap(
929
+ lyrlist: list[dict[str, Any]] | None,
930
+ ) -> dict[int, str] | None:
931
931
  """Returns a layer to zone map as a dictionary
932
932
 
933
933
  Args:
@@ -949,7 +949,7 @@ def convert_lyrlist_to_zonemap(lyrlist: list[dict[str, Any]]) -> dict[int, str]:
949
949
  return zonemap
950
950
 
951
951
 
952
- def get_wells_matching_template(template: str, wells: list):
952
+ def get_wells_matching_template(template: str, wells: list[str]) -> list[str]:
953
953
  """Returns the wells in the list that is matching the template
954
954
  containing wilcard characters. The wildcard charachters supported
955
955
  are * to match zero or more charachters and ? to match a single
@@ -972,9 +972,6 @@ def get_wells_matching_template(template: str, wells: list):
972
972
  "Well template not allowed to start with a wildcard character: "
973
973
  f"Must be preceded with a \\: {template}"
974
974
  )
975
- if template.startswith("\\"):
976
- # Note that the two \\ are actually read as one and
977
- # this will return True for f.ex '\*P1'
978
- template = template[1:]
975
+ template = template.removeprefix("\\")
979
976
  regex = template.replace("*", ".*").replace("?", ".")
980
977
  return [well for well in wells if bool(re.match(regex, well))]
res2df/compdat.py CHANGED
@@ -11,16 +11,14 @@
11
11
  """
12
12
 
13
13
  import argparse
14
- import contextlib
15
14
  import datetime
16
15
  import logging
16
+ from typing import Any
17
17
 
18
18
  import numpy as np
19
+ import opm.io.deck
19
20
  import pandas as pd
20
21
 
21
- with contextlib.suppress(ImportError):
22
- import opm.io.deck
23
-
24
22
  from .common import (
25
23
  get_wells_matching_template,
26
24
  merge_zones,
@@ -97,6 +95,7 @@ def deck2dfs(
97
95
  complumprecords = []
98
96
  welspecs = {}
99
97
  date = start_date # DATE column will always be there, but can contain NaN/None
98
+ rec_data: dict[str, Any]
100
99
  for idx, kword in enumerate(deck):
101
100
  if kword.name in ["DATES", "START"]:
102
101
  for rec in kword:
@@ -752,7 +751,7 @@ def expand_complump_in_welopen_df(
752
751
  exp_welopens.append(cell_row)
753
752
 
754
753
  dframe = pd.DataFrame(exp_welopens)
755
- return dframe.astype(object).where(pd.notna(dframe), None)
754
+ return dframe.astype(object).where(pd.notna(dframe), None) # type: ignore[call-overload]
756
755
 
757
756
 
758
757
  def expand_wlist_in_welopen_df(
@@ -786,7 +785,7 @@ def expand_wlist_in_welopen_df(
786
785
  # Explicit wellname was used, no expansion to happen:
787
786
  exp_welopens.append(row)
788
787
  dframe = pd.DataFrame(exp_welopens)
789
- return dframe.astype(object).where(pd.notna(dframe), None)
788
+ return dframe.astype(object).where(pd.notna(dframe), None) # type: ignore[call-overload]
790
789
 
791
790
 
792
791
  def applywelopen(
@@ -845,7 +844,7 @@ def applywelopen(
845
844
  "The WLIST dataframe must be expanded through expand_wlist()"
846
845
  )
847
846
 
848
- welopen_df = welopen_df.astype(object).where(pd.notna(welopen_df), None)
847
+ welopen_df = welopen_df.astype(object).where(pd.notna(welopen_df), None) # type: ignore[call-overload]
849
848
  if wlist_df is not None:
850
849
  welopen_df = expand_wlist_in_welopen_df(welopen_df, wlist_df)
851
850
  if complump_df is not None:
@@ -951,7 +950,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
951
950
  return parser
952
951
 
953
952
 
954
- def compdat_main(args):
953
+ def compdat_main(args: argparse.Namespace) -> None:
955
954
  """Entry-point for module, for command line utility"""
956
955
  logger = getLogger_res2csv(__name__, vars(args))
957
956
  resdatafiles = ResdataFiles(args.DATAFILE)
res2df/csv2res.py CHANGED
@@ -34,7 +34,7 @@ def get_parser() -> argparse.ArgumentParser:
34
34
  version=f"%(prog)s {__version__}",
35
35
  )
36
36
 
37
- subparsers = parser.add_subparsers( # type: ignore
37
+ subparsers = parser.add_subparsers(
38
38
  required=True,
39
39
  dest="subcommand",
40
40
  parser_class=argparse.ArgumentParser,
res2df/equil.py CHANGED
@@ -3,11 +3,12 @@ Extract EQUIL from a :term:`.DATA file` as Pandas DataFrame
3
3
  """
4
4
 
5
5
  import argparse
6
- import contextlib
7
6
  import logging
8
7
  from collections.abc import Container
9
8
  from pathlib import Path
9
+ from typing import Final
10
10
 
11
+ import opm.io
11
12
  import pandas as pd
12
13
 
13
14
  from .common import (
@@ -24,57 +25,56 @@ from .inferdims import DIMS_POS, inject_xxxdims_ntxxx
24
25
  from .res2csvlogger import getLogger_res2csv
25
26
  from .resdatafiles import ResdataFiles
26
27
 
27
- with contextlib.suppress(ImportError):
28
- import opm.io
29
-
30
-
31
28
  logger = logging.getLogger(__name__)
32
29
 
33
- SUPPORTED_KEYWORDS: list[str] = ["EQUIL", "PBVD", "PDVD", "RSVD", "RVVD"]
34
- RENAMERS: dict[str, dict[str, str | list[str]]] = {}
35
- RENAMERS["PBVD"] = {"DATA": ["Z", "PB"]}
36
- RENAMERS["PDVD"] = {"DATA": ["Z", "PD"]}
37
- RENAMERS["RSVD"] = {"DATA": ["Z", "RS"]}
38
- RENAMERS["RVVD"] = {"DATA": ["Z", "RV"]}
39
- RENAMERS["oil-water-gas"] = {
40
- "DATUM_DEPTH": "Z",
41
- "DATUM_PRESSURE": "PRESSURE",
42
- "OWC": "OWC",
43
- "PC_OWC": "PCOWC",
44
- "GOC": "GOC",
45
- "PC_GOC": "PCGOC",
46
- "BLACK_OIL_INIT": "INITRS",
47
- "BLACK_OIL_INIT_WG": "INITRV",
48
- }
49
- RENAMERS["gas-water"] = {
50
- "DATUM_DEPTH": "Z",
51
- "DATUM_PRESSURE": "PRESSURE",
52
- "OWC": "GWC",
53
- "PC_OWC": "PCGWC",
54
- "GOC": "IGNORE1",
55
- "PC_GOC": "IGNORE2",
56
- "BLACK_OIL_INIT": "IGNORE3",
57
- "BLACK_OIL_INIT_WG": "IGNORE4",
58
- }
59
- RENAMERS["oil-water"] = {
60
- "DATUM_DEPTH": "Z",
61
- "DATUM_PRESSURE": "PRESSURE",
62
- "OWC": "OWC",
63
- "PC_OWC": "PCOWC",
64
- "GOC": "IGNORE1",
65
- "PC_GOC": "IGNORE2",
66
- "BLACK_OIL_INIT": "IGNORE3",
67
- "BLACK_OIL_INIT_WG": "IGNORE4",
30
+ SUPPORTED_KEYWORDS: Final[list[str]] = ["EQUIL", "PBVD", "PDVD", "RSVD", "RVVD"]
31
+ TABLE_RENAMERS: Final[dict[str, dict[str, list[str]]]] = {
32
+ "PBVD": {"DATA": ["Z", "PB"]},
33
+ "PDVD": {"DATA": ["Z", "PD"]},
34
+ "RSVD": {"DATA": ["Z", "RS"]},
35
+ "RVVD": {"DATA": ["Z", "RV"]},
68
36
  }
69
- RENAMERS["oil-gas"] = {
70
- "DATUM_DEPTH": "Z",
71
- "DATUM_PRESSURE": "PRESSURE",
72
- "OWC": "IGNORE1",
73
- "PC_OWC": "IGNORE2",
74
- "GOC": "GOC",
75
- "PC_GOC": "PCGOC",
76
- "BLACK_OIL_INIT": "IGNORE3",
77
- "BLACK_OIL_INIT_WG": "IGNORE4",
37
+ PHASE_RENAMERS: Final[dict[str, dict[str, str]]] = {
38
+ "oil-water-gas": {
39
+ "DATUM_DEPTH": "Z",
40
+ "DATUM_PRESSURE": "PRESSURE",
41
+ "OWC": "OWC",
42
+ "PC_OWC": "PCOWC",
43
+ "GOC": "GOC",
44
+ "PC_GOC": "PCGOC",
45
+ "BLACK_OIL_INIT": "INITRS",
46
+ "BLACK_OIL_INIT_WG": "INITRV",
47
+ },
48
+ "gas-water": {
49
+ "DATUM_DEPTH": "Z",
50
+ "DATUM_PRESSURE": "PRESSURE",
51
+ "OWC": "GWC",
52
+ "PC_OWC": "PCGWC",
53
+ "GOC": "IGNORE1",
54
+ "PC_GOC": "IGNORE2",
55
+ "BLACK_OIL_INIT": "IGNORE3",
56
+ "BLACK_OIL_INIT_WG": "IGNORE4",
57
+ },
58
+ "oil-water": {
59
+ "DATUM_DEPTH": "Z",
60
+ "DATUM_PRESSURE": "PRESSURE",
61
+ "OWC": "OWC",
62
+ "PC_OWC": "PCOWC",
63
+ "GOC": "IGNORE1",
64
+ "PC_GOC": "IGNORE2",
65
+ "BLACK_OIL_INIT": "IGNORE3",
66
+ "BLACK_OIL_INIT_WG": "IGNORE4",
67
+ },
68
+ "oil-gas": {
69
+ "DATUM_DEPTH": "Z",
70
+ "DATUM_PRESSURE": "PRESSURE",
71
+ "OWC": "IGNORE1",
72
+ "PC_OWC": "IGNORE2",
73
+ "GOC": "GOC",
74
+ "PC_GOC": "PCGOC",
75
+ "BLACK_OIL_INIT": "IGNORE3",
76
+ "BLACK_OIL_INIT_WG": "IGNORE4",
77
+ },
78
78
  }
79
79
 
80
80
 
@@ -149,7 +149,7 @@ def rsvd_fromdeck(
149
149
  if "EQLDIMS" not in deck:
150
150
  deck = inject_xxxdims_ntxxx("EQLDIMS", "NTEQUL", deck, ntequl)
151
151
  return keyworddata_to_df(
152
- deck, "RSVD", renamer=RENAMERS["RSVD"], recordcountername="EQLNUM"
152
+ deck, "RSVD", renamer=TABLE_RENAMERS["RSVD"], recordcountername="EQLNUM"
153
153
  )
154
154
 
155
155
 
@@ -166,7 +166,7 @@ def rvvd_fromdeck(
166
166
  if "EQLDIMS" not in deck:
167
167
  deck = inject_xxxdims_ntxxx("EQLDIMS", "NTEQUL", deck, ntequl)
168
168
  return keyworddata_to_df(
169
- deck, "RVVD", renamer=RENAMERS["RVVD"], recordcountername="EQLNUM"
169
+ deck, "RVVD", renamer=TABLE_RENAMERS["RVVD"], recordcountername="EQLNUM"
170
170
  )
171
171
 
172
172
 
@@ -183,7 +183,7 @@ def pbvd_fromdeck(
183
183
  if "EQLDIMS" not in deck:
184
184
  deck = inject_xxxdims_ntxxx("EQLDIMS", "NTEQUL", deck, ntequl)
185
185
  return keyworddata_to_df(
186
- deck, "PBVD", renamer=RENAMERS["PBVD"], recordcountername="EQLNUM"
186
+ deck, "PBVD", renamer=TABLE_RENAMERS["PBVD"], recordcountername="EQLNUM"
187
187
  )
188
188
 
189
189
 
@@ -200,7 +200,7 @@ def pdvd_fromdeck(
200
200
  if "EQLDIMS" not in deck:
201
201
  deck = inject_xxxdims_ntxxx("EQLDIMS", "NTEQUL", deck, ntequl)
202
202
  return keyworddata_to_df(
203
- deck, "PDVD", renamer=RENAMERS["PDVD"], recordcountername="EQLNUM"
203
+ deck, "PDVD", renamer=TABLE_RENAMERS["PDVD"], recordcountername="EQLNUM"
204
204
  )
205
205
 
206
206
 
@@ -267,9 +267,9 @@ def equil_fromdeck(
267
267
  deck = inject_xxxdims_ntxxx("EQLDIMS", "NTEQUL", deck, ntequl)
268
268
 
269
269
  phases = phases_from_deck(deck)
270
- if not phases or phases not in RENAMERS:
270
+ if not phases or phases not in PHASE_RENAMERS:
271
271
  raise ValueError(f"Could not determine phase configuration, got '{phases}'")
272
- columnrenamer = RENAMERS[phases_from_deck(deck)]
272
+ columnrenamer = PHASE_RENAMERS[phases]
273
273
 
274
274
  dataframe = keyworddata_to_df(
275
275
  deck, "EQUIL", renamer=columnrenamer, recordcountername="EQLNUM"
@@ -318,7 +318,7 @@ def fill_reverse_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentPar
318
318
  return common_fill_reverse_parser(parser, "EQUIL, RSVD++", "solution.inc")
319
319
 
320
320
 
321
- def equil_main(args) -> None:
321
+ def equil_main(args: argparse.Namespace) -> None:
322
322
  """Read from disk and write CSV back to disk"""
323
323
  logger = getLogger_res2csv(__name__, vars(args))
324
324
  resdatafiles = ResdataFiles(args.DATAFILE)
@@ -348,7 +348,7 @@ def equil_main(args) -> None:
348
348
  )
349
349
 
350
350
 
351
- def equil_reverse_main(args) -> None:
351
+ def equil_reverse_main(args: argparse.Namespace) -> None:
352
352
  """Entry-point for module, for command line utility
353
353
  for CSV to reservoir simulator :term:`include files <include file>`
354
354
  """
@@ -424,7 +424,7 @@ def df2res_equil(dframe: pd.DataFrame, comment: str | None = None) -> str:
424
424
  return generic_deck_table(
425
425
  subset,
426
426
  "EQUIL",
427
- renamer=RENAMERS[phases], # type: ignore
427
+ renamer=PHASE_RENAMERS[phases],
428
428
  comment=comment,
429
429
  drop_trailing_columns=False,
430
430
  )
@@ -471,7 +471,7 @@ def df2res_pbvd(dframe: pd.DataFrame, comment: str | None = None) -> str:
471
471
  return _df2res_equilfuncs("PBVD", dframe, comment)
472
472
 
473
473
 
474
- def df2res_pdvd(dframe: pd.DataFrame, comment: str | None = None):
474
+ def df2res_pdvd(dframe: pd.DataFrame, comment: str | None = None) -> str:
475
475
  """Create string with :term:`include file` contents for PDVD keyword.
476
476
 
477
477
  Dew-point versus depth.
@@ -494,7 +494,7 @@ def _df2res_equilfuncs(
494
494
  return "-- No data!"
495
495
  string = f"{keyword}\n"
496
496
  string += comment_formatter(comment)
497
- col_headers = RENAMERS[keyword]["DATA"]
497
+ col_headers = TABLE_RENAMERS[keyword]["DATA"]
498
498
 
499
499
  string += f"-- {'DEPTH':^21} {col_headers[1]:^21} \n"
500
500
  # Use everything if KEYWORD not in dframe..
res2df/faults.py CHANGED
@@ -6,20 +6,17 @@ a DataFrame
6
6
  """
7
7
 
8
8
  import argparse
9
- import contextlib
10
9
  import logging
10
+ from itertools import product
11
11
 
12
+ # Needed for mypy
13
+ import opm.io
12
14
  import pandas as pd
13
15
 
14
16
  from .common import parse_opmio_deckrecord, write_dframe_stdout_file
15
17
  from .res2csvlogger import getLogger_res2csv
16
18
  from .resdatafiles import ResdataFiles
17
19
 
18
- with contextlib.suppress(ImportError):
19
- # Needed for mypy
20
- import opm.io
21
-
22
-
23
20
  logger = logging.getLogger(__name__)
24
21
 
25
22
  RECORD_COLUMNS = ["NAME", "IX1", "IX2", "IY1", "IY2", "IZ1", "IZ2", "FACE"]
@@ -40,7 +37,7 @@ def df(deck: "ResdataFiles | opm.opmcommon_python.Deck") -> pd.DataFrame:
40
37
 
41
38
  # In[91]: list(deck['FAULTS'][0])
42
39
  # Out[91]: [[u'F1'], [36], [36], [41], [42], [1], [14], [u'I']]
43
- data = []
40
+ data: list[list[str | int]] = []
44
41
  # It is allowed in Eclipse to use the keyword FAULTS
45
42
  # as many times as needed. Thus we need to loop in some way:
46
43
  for keyword in deck:
@@ -51,10 +48,13 @@ def df(deck: "ResdataFiles | opm.opmcommon_python.Deck") -> pd.DataFrame:
51
48
  frec_dict = parse_opmio_deckrecord(rec, "FAULTS")
52
49
  faultname = frec_dict["NAME"]
53
50
  faultface = frec_dict["FACE"]
54
- for i_idx in range(frec_dict["IX1"], frec_dict["IX2"] + 1):
55
- for j_idx in range(frec_dict["IY1"], frec_dict["IY2"] + 1):
56
- for k_idx in range(frec_dict["IZ1"], frec_dict["IZ2"] + 1):
57
- data.append([faultname, i_idx, j_idx, k_idx, faultface])
51
+
52
+ indices = product(
53
+ range(frec_dict["IX1"], frec_dict["IX2"] + 1),
54
+ range(frec_dict["IY1"], frec_dict["IY2"] + 1),
55
+ range(frec_dict["IZ1"], frec_dict["IZ2"] + 1),
56
+ )
57
+ data.extend([faultname, i, j, k, faultface] for i, j, k in indices)
58
58
  dframe = pd.DataFrame(columns=COLUMNS, data=data)
59
59
  logger.info("Extracted %i faults", len(dframe["NAME"].unique()))
60
60
  return dframe
@@ -80,7 +80,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
80
80
  return parser
81
81
 
82
82
 
83
- def faults_main(args) -> None:
83
+ def faults_main(args: argparse.Namespace) -> None:
84
84
  """Read from disk and write CSV back to disk"""
85
85
  logger = getLogger_res2csv(__name__, vars(args))
86
86
  resdatafiles = ResdataFiles(args.DATAFILE)
res2df/fipreports.py CHANGED
@@ -4,6 +4,7 @@ import argparse
4
4
  import datetime
5
5
  import logging
6
6
  import re
7
+ from pathlib import Path
7
8
 
8
9
  import numpy as np
9
10
  import pandas as pd
@@ -133,7 +134,7 @@ def df(prtfile: str | ResdataFiles, fipname: str = "FIPNUM") -> pd.DataFrame:
133
134
  ".+" + fipname + r"\s+REPORT\s+REGION\s+(\d+)", re.IGNORECASE
134
135
  )
135
136
 
136
- with open(prtfile, encoding="utf-8") as prt_fh:
137
+ with Path(prtfile).open(encoding="utf-8") as prt_fh:
137
138
  logger.info(
138
139
  "Parsing file %s for blocks starting with %s REPORT REGION",
139
140
  prtfile,
@@ -207,7 +208,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
207
208
  return parser
208
209
 
209
210
 
210
- def fipreports_main(args) -> None:
211
+ def fipreports_main(args: argparse.Namespace) -> None:
211
212
  """Command line API"""
212
213
  logger = getLogger_res2csv(__name__, vars(args))
213
214
  if args.PRTFILE.endswith(".PRT"):
res2df/grid.py CHANGED
@@ -481,7 +481,7 @@ def df(
481
481
  dateinheaders: bool = False,
482
482
  stackdates: bool = False,
483
483
  zonemap: dict[int, str] | None = None,
484
- ):
484
+ ) -> pd.DataFrame:
485
485
  """Produce a dataframe with grid information
486
486
 
487
487
  Grid information (center coordinates x, y, z), cell
@@ -544,7 +544,7 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
544
544
  parser.add_argument(
545
545
  "DATAFILE",
546
546
  help="Name of the .DATA input file for the reservoir simulator."
547
- + " There must exist .INIT and .EGRID files with the same path and basename.",
547
+ " There must exist .INIT and .EGRID files with the same path and basename.",
548
548
  )
549
549
  parser.add_argument(
550
550
  "--vectors",
@@ -556,8 +556,8 @@ def fill_parser(parser: argparse.ArgumentParser) -> argparse.ArgumentParser:
556
556
  "--rstdates",
557
557
  type=str,
558
558
  help="Point in time to grab restart data from, "
559
- + "either 'first' or 'last', 'all', or a date in "
560
- + "YYYY-MM-DD format",
559
+ "either 'first' or 'last', 'all', or a date in "
560
+ "YYYY-MM-DD format",
561
561
  default="",
562
562
  )
563
563
  parser.add_argument(
@@ -610,10 +610,11 @@ def drop_constant_columns(
610
610
  if dframe.empty:
611
611
  return dframe
612
612
 
613
- columnstodelete = []
614
- for col in set(dframe.columns) - set(alwayskeep):
615
- if len(dframe[col].unique()) == 1:
616
- columnstodelete.append(col)
613
+ columnstodelete = [
614
+ col
615
+ for col in (set(dframe.columns) - set(alwayskeep))
616
+ if len(dframe[col].unique()) == 1
617
+ ]
617
618
  if columnstodelete:
618
619
  logging.info("Deleting constant columns %s", columnstodelete)
619
620
  return dframe.drop(columnstodelete, axis=1)
@@ -698,11 +699,7 @@ def df2res(
698
699
 
699
700
  res2df_header = (
700
701
  "Output file printed by "
701
- + "res2df.grid "
702
- + __version__
703
- + "\n"
704
- + " at "
705
- + str(datetime.datetime.now())
702
+ "res2df.grid " + __version__ + "\n" + " at " + str(datetime.datetime.now())
706
703
  )
707
704
 
708
705
  string = ""
@@ -759,7 +756,7 @@ def df2res(
759
756
  return string
760
757
 
761
758
 
762
- def grid_main(args) -> None:
759
+ def grid_main(args: argparse.Namespace) -> None:
763
760
  """This is the command line API"""
764
761
  logger = getLogger_res2csv(__name__, vars(args))
765
762
  resdatafiles = ResdataFiles(args.DATAFILE)