completor 1.0.0__tar.gz → 1.1.0__tar.gz

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.
Files changed (27) hide show
  1. {completor-1.0.0 → completor-1.1.0}/PKG-INFO +4 -4
  2. {completor-1.0.0 → completor-1.1.0}/completor/completion.py +3 -9
  3. {completor-1.0.0 → completor-1.1.0}/completor/create_output.py +4 -7
  4. completor-1.1.0/completor/exceptions/__init__.py +0 -0
  5. {completor-1.0.0 → completor-1.1.0}/completor/hook_implementations/jobs.py +21 -12
  6. {completor-1.0.0 → completor-1.1.0}/completor/input_validation.py +1 -1
  7. {completor-1.0.0 → completor-1.1.0}/completor/main.py +1 -4
  8. {completor-1.0.0 → completor-1.1.0}/completor/prepare_outputs.py +1 -1
  9. {completor-1.0.0 → completor-1.1.0}/completor/read_casefile.py +2 -1
  10. {completor-1.0.0 → completor-1.1.0}/completor/utils.py +4 -33
  11. {completor-1.0.0 → completor-1.1.0}/completor/wells.py +0 -2
  12. {completor-1.0.0 → completor-1.1.0}/pyproject.toml +6 -6
  13. completor-1.0.0/completor/exceptions/__init__.py +0 -4
  14. {completor-1.0.0 → completor-1.1.0}/LICENSE +0 -0
  15. {completor-1.0.0 → completor-1.1.0}/README.md +0 -0
  16. {completor-1.0.0 → completor-1.1.0}/completor/__init__.py +0 -0
  17. {completor-1.0.0 → completor-1.1.0}/completor/config_jobs/run_completor +0 -0
  18. {completor-1.0.0 → completor-1.1.0}/completor/constants.py +0 -0
  19. {completor-1.0.0 → completor-1.1.0}/completor/exceptions/clean_exceptions.py +0 -0
  20. {completor-1.0.0 → completor-1.1.0}/completor/exceptions/exceptions.py +0 -0
  21. {completor-1.0.0 → completor-1.1.0}/completor/get_version.py +0 -0
  22. {completor-1.0.0 → completor-1.1.0}/completor/launch_args_parser.py +0 -0
  23. {completor-1.0.0 → completor-1.1.0}/completor/logger.py +0 -0
  24. {completor-1.0.0 → completor-1.1.0}/completor/parse.py +0 -0
  25. {completor-1.0.0 → completor-1.1.0}/completor/read_schedule.py +0 -0
  26. {completor-1.0.0 → completor-1.1.0}/completor/visualization.py +0 -0
  27. {completor-1.0.0 → completor-1.1.0}/completor/visualize_well.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: completor
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: Advanced mulit-segmented well completion tool.
5
5
  Home-page: https://github.com/equinor/completor
6
6
  License: LGPL-3.0-only
@@ -14,10 +14,10 @@ Classifier: Programming Language :: Python :: 3
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Provides-Extra: ert
16
16
  Requires-Dist: docutils (==0.20.1) ; extra == "ert"
17
- Requires-Dist: ert (>=10.1.2,<11.0.0) ; extra == "ert"
17
+ Requires-Dist: ert (>=11.1.0,<12.0.0) ; extra == "ert"
18
18
  Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
19
- Requires-Dist: numpy (>=1.26.4,<2.0.0)
20
- Requires-Dist: pandas (>=2.2.2,<3.0.0)
19
+ Requires-Dist: numpy (<2.0.0)
20
+ Requires-Dist: pandas (>=2.1.4,<3.0.0)
21
21
  Requires-Dist: pyqt5-qt5 (==5.15.2) ; extra == "ert"
22
22
  Requires-Dist: pytest-env (>=1.1.4,<2.0.0)
23
23
  Requires-Dist: rstcheck-core (>=1.2.1,<2.0.0) ; extra == "ert"
@@ -9,9 +9,9 @@ import numpy.typing as npt
9
9
  import pandas as pd
10
10
 
11
11
  from completor.constants import Content, Headers, Method
12
- from completor.exceptions import CompletorError
12
+ from completor.exceptions.clean_exceptions import CompletorError
13
13
  from completor.logger import logger
14
- from completor.utils import log_and_raise_exception, shift_array
14
+ from completor.utils import shift_array
15
15
 
16
16
 
17
17
  def well_trajectory(df_well_segments_header: pd.DataFrame, df_well_segments_content: pd.DataFrame) -> pd.DataFrame:
@@ -405,7 +405,7 @@ def get_completion(
405
405
 
406
406
  if idx0 == -1 or idx1 == -1:
407
407
  well_name = df_completion[Headers.WELL].iloc[0]
408
- log_and_raise_exception(f"No completion is defined on well {well_name} from {start} to {end}.")
408
+ raise CompletorError(f"No completion is defined for well {well_name} from {start} to {end}.")
409
409
 
410
410
  indices = np.arange(idx0, idx1 + 1)
411
411
  lengths = np.minimum(end_completion[indices], end) - np.maximum(start_completion[indices], start)
@@ -468,12 +468,6 @@ def complete_the_well(
468
468
 
469
469
  # loop through the cells
470
470
  for i in range(df_tubing_segments.shape[0]):
471
- indices = [np.array(completion_index(df_completion, s, e)) for s, e in zip(start, end)]
472
-
473
- if any(idx0 == -1 or idx1 == -1 for idx0, idx1 in indices):
474
- well_name = df_completion[Headers.WELL].iloc[0]
475
- log_and_raise_exception(f"No completion is defined on well {well_name} from {start} to {end}.")
476
-
477
471
  completion_data = get_completion(start[i], end[i], df_completion, joint_length)
478
472
  number_of_devices.append(completion_data[0])
479
473
  device_type.append(completion_data[1])
@@ -12,7 +12,7 @@ from matplotlib.backends.backend_pdf import PdfPages # type: ignore
12
12
 
13
13
  from completor import prepare_outputs
14
14
  from completor.constants import Headers, Keywords
15
- from completor.exceptions import CompletorError
15
+ from completor.exceptions.clean_exceptions import CompletorError
16
16
  from completor.get_version import get_version
17
17
  from completor.logger import logger
18
18
  from completor.read_casefile import ReadCasefile
@@ -76,7 +76,8 @@ def format_output(well: Well, case: ReadCasefile, figure_name: str | None = None
76
76
  if df_annulus.empty:
77
77
  logger.info("No annular flow in Well : %s Lateral : %d", well.well_name, lateral.lateral_number)
78
78
 
79
- start_segment, start_branch = _update_segmentbranch(lateral.df_device, df_annulus)
79
+ if not lateral.df_device.empty:
80
+ start_segment, start_branch = _update_segmentbranch(lateral.df_device, df_annulus)
80
81
 
81
82
  lateral.df_tubing = _connect_lateral(well.well_name, lateral, top, well, case)
82
83
 
@@ -234,15 +235,11 @@ def _update_segmentbranch(df_device: pd.DataFrame, df_annulus: pd.DataFrame) ->
234
235
  Returns:
235
236
  The numbers for starting segment and branch.
236
237
 
237
- Raises:
238
- ValueError: If there is neither device nor annulus data.
239
238
  """
240
- if df_annulus.empty and df_device.empty:
241
- raise ValueError("Cannot determine starting segment and branch without device and annulus data.")
242
239
  if df_annulus.empty and not df_device.empty:
243
240
  start_segment = max(df_device[Headers.START_SEGMENT_NUMBER].to_numpy()) + 1
244
241
  start_branch = max(df_device[Headers.BRANCH].to_numpy()) + 1
245
- else:
242
+ elif not df_annulus.empty:
246
243
  start_segment = max(df_annulus[Headers.START_SEGMENT_NUMBER].to_numpy()) + 1
247
244
  start_branch = max(df_annulus[Headers.BRANCH].to_numpy()) + 1
248
245
  return start_segment, start_branch
File without changes
@@ -1,27 +1,36 @@
1
- from importlib.resources import files
1
+ import sys
2
2
  from pathlib import Path
3
3
 
4
4
  from completor.logger import logger
5
5
 
6
- SKIP_TESTS = False
7
6
  try:
8
- from ert.shared.plugins.plugin_manager import hook_implementation # type: ignore
9
- from ert.shared.plugins.plugin_response import plugin_response # type: ignore
10
-
7
+ from ert import plugin as ert_plugin # type: ignore
11
8
  except ModuleNotFoundError:
9
+
10
+ def ert_plugin(name: str = ""):
11
+ """Dummy decorator"""
12
+
13
+ def decorator(func):
14
+ return func
15
+
16
+ return decorator
17
+
12
18
  logger.warning("Cannot import ERT, did you install Completor with ert option enabled?")
13
- pass
14
19
 
15
20
 
16
- @hook_implementation
17
- @plugin_response(plugin_name="completor") # type: ignore
21
+ def _get_jobs_from_directory(directory):
22
+ resources = Path(sys.modules["completor"].__file__).parent / directory
23
+
24
+ all_files = [resources / filename for filename in resources.glob("*") if (resources / filename).exists()]
25
+ return {path.name: str(path) for path in all_files}
26
+
27
+
28
+ @ert_plugin(name="completor")
18
29
  def installable_jobs():
19
- config_file = Path(files("completor") / "config_jobs/run_completor")
20
- return {config_file.name: config_file}
30
+ return _get_jobs_from_directory("config_jobs")
21
31
 
22
32
 
23
- @hook_implementation
24
- @plugin_response(plugin_name="completor") # type: ignore # pylint: disable=no-value-for-parameter
33
+ @ert_plugin(name="completor")
25
34
  def job_documentation(job_name):
26
35
  if job_name != "run_completor":
27
36
  return None
@@ -6,7 +6,7 @@ import numpy as np
6
6
  import pandas as pd
7
7
 
8
8
  from completor.constants import Content, Headers
9
- from completor.exceptions import CompletorError
9
+ from completor.exceptions.clean_exceptions import CompletorError
10
10
 
11
11
 
12
12
  def set_default_packer_section(df_comp: pd.DataFrame) -> pd.DataFrame:
@@ -7,12 +7,11 @@ import os
7
7
  import re
8
8
  import time
9
9
 
10
- import pandas as pd
11
10
  from tqdm import tqdm
12
11
 
13
12
  from completor import create_output, parse, read_schedule, utils
14
13
  from completor.constants import Keywords, ScheduleData
15
- from completor.exceptions import CompletorError
14
+ from completor.exceptions.clean_exceptions import CompletorError
16
15
  from completor.get_version import get_version
17
16
  from completor.launch_args_parser import get_parser
18
17
  from completor.logger import handle_error_messages, logger
@@ -27,8 +26,6 @@ from completor.utils import (
27
26
  )
28
27
  from completor.wells import Well
29
28
 
30
- pd.set_option("future.no_silent_downcasting", True)
31
-
32
29
 
33
30
  def get_content_and_path(case_content: str, file_path: str | None, keyword: str) -> tuple[str | None, str | None]:
34
31
  """Get the contents of a file from a path defined by user or case file.
@@ -9,7 +9,7 @@ import numpy.typing as npt
9
9
  import pandas as pd
10
10
 
11
11
  from completor.constants import Content, Headers, Keywords
12
- from completor.exceptions import CompletorError
12
+ from completor.exceptions.clean_exceptions import CompletorError
13
13
  from completor.logger import logger
14
14
  from completor.utils import check_width_lines
15
15
  from completor.wells import Lateral, Well
@@ -11,7 +11,8 @@ import pandas as pd
11
11
 
12
12
  from completor import input_validation, parse
13
13
  from completor.constants import Content, Headers, Keywords, Method, WellData
14
- from completor.exceptions import CaseReaderFormatError, CompletorError
14
+ from completor.exceptions.clean_exceptions import CompletorError
15
+ from completor.exceptions.exceptions import CaseReaderFormatError
15
16
  from completor.logger import logger
16
17
  from completor.utils import clean_file_lines
17
18
 
@@ -5,14 +5,14 @@ from __future__ import annotations
5
5
  import re
6
6
  import sys
7
7
  from collections.abc import Mapping
8
- from typing import Any, Literal, NoReturn, overload
8
+ from typing import Any
9
9
 
10
10
  import numpy as np
11
11
  import numpy.typing as npt
12
12
  import pandas as pd
13
13
 
14
14
  from completor.constants import Content, Headers, Keywords
15
- from completor.exceptions import CompletorError
15
+ from completor.exceptions.clean_exceptions import CompletorError
16
16
  from completor.logger import logger
17
17
 
18
18
 
@@ -57,35 +57,6 @@ def sort_by_midpoint(
57
57
  return df.drop([_temp_column], axis=1)
58
58
 
59
59
 
60
- @overload
61
- def log_and_raise_exception(message: str, kind: type = ..., throw: Literal[True] = ...) -> NoReturn: ...
62
-
63
-
64
- @overload
65
- def log_and_raise_exception(message: str, kind: type = ..., throw: Literal[False] = ...) -> BaseException: ...
66
-
67
-
68
- def log_and_raise_exception(message: str, kind: type = ValueError, throw: bool = False) -> BaseException | None:
69
- """Log and throw an exception.
70
-
71
- Arguments:
72
- message: The message to be logged, and given to the exception.
73
- kind: The type of exception to be thrown.
74
- throw: Flag to toggle whether this function actually raises the exception or not.
75
-
76
- Raises:
77
- Exception: In general it can be any exception.
78
- ValueError: This is the default exception.
79
- """
80
- logger.error(message)
81
- if not isinstance(kind, (Exception, BaseException)):
82
- raise ValueError(f"The provided exception type ({kind}) does not inherit from Exception")
83
- if throw:
84
- raise kind(message)
85
- else:
86
- return kind(message)
87
-
88
-
89
60
  def find_quote(string: str) -> re.Match | None:
90
61
  """Find single or double quotes in a string.
91
62
 
@@ -354,7 +325,7 @@ def find_well_keyword_data(well: str, keyword: str, text: str) -> str:
354
325
  """
355
326
  matches = find_keyword_data(keyword, text)
356
327
 
357
- lines = []
328
+ lines: list[str] = []
358
329
  for match in matches:
359
330
  if re.search(well, match) is None:
360
331
  continue
@@ -375,7 +346,7 @@ def find_well_keyword_data(well: str, keyword: str, text: str) -> str:
375
346
  once = True
376
347
  # Remove contiguous comments above the first line by looking backwards,
377
348
  # adding it to the replaceable text match.
378
- comments = []
349
+ comments: list[str] = []
379
350
  for prev_line in matchlines[i - 1 :: -1]:
380
351
  if not prev_line.strip().startswith("--") or not prev_line:
381
352
  break
@@ -121,8 +121,6 @@ class Lateral:
121
121
  self.df_device = pd.DataFrame()
122
122
 
123
123
  self.df_reservoir = self._select_well(well_name, well_data, lateral_number)
124
- if self.df_reservoir.empty:
125
- print("")
126
124
  self.df_measured_true_vertical_depth = completion.well_trajectory(
127
125
  self.df_welsegs_header, self.df_welsegs_content
128
126
  )
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "completor"
3
- version = "1.0.0"
3
+ version = "1.1.0"
4
4
  description = "Advanced mulit-segmented well completion tool."
5
5
  authors = ["Equinor ASA <opensource@equinor.com>"]
6
6
  repository = "https://github.com/equinor/completor"
@@ -21,22 +21,22 @@ classifiers = [
21
21
  [tool.poetry.dependencies]
22
22
  python = ">=3.11, <3.12"
23
23
  matplotlib = "^3.9.2"
24
- numpy = "^1.26.4"
25
- pandas = "^2.2.2"
24
+ numpy = "<2.0.0"
25
+ pandas = "^2.1.4"
26
26
  scipy = "^1.14.1"
27
27
  tqdm = "^4.66.5"
28
28
  pytest-env = "^1.1.4"
29
29
 
30
30
  docutils = {version="0.20.1", optional=true} # Pinned due to problems with OS spesific builds
31
31
  rstcheck-core = {version="^1.2.1", optional=true}
32
- ert = {version="^10.1.2", optional=true}
32
+ ert = {version="^11.1.0", optional=true}
33
33
  pyqt5-qt5 = {version="5.15.2", optional=true} # Pinned due to problems with OS spesific builds
34
34
 
35
35
  [tool.poetry.group.dev.dependencies]
36
36
  black = "^24.4.2"
37
37
  flake8 = "^7.0.0"
38
- pre-commit = ">3"
39
- pytest = "^8.2.0"
38
+ pre-commit = "^4.0.1"
39
+ pytest = "^8.3.3"
40
40
  pytest-xdist = "^3.6.1"
41
41
 
42
42
  [tool.poetry.extras]
@@ -1,4 +0,0 @@
1
- from completor.exceptions.clean_exceptions import CompletorError
2
- from completor.exceptions.exceptions import CaseReaderFormatError
3
-
4
- __all__ = ["CompletorError", "CaseReaderFormatError"]
File without changes
File without changes
File without changes
File without changes