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.
- {completor-1.0.0 → completor-1.1.0}/PKG-INFO +4 -4
- {completor-1.0.0 → completor-1.1.0}/completor/completion.py +3 -9
- {completor-1.0.0 → completor-1.1.0}/completor/create_output.py +4 -7
- completor-1.1.0/completor/exceptions/__init__.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/hook_implementations/jobs.py +21 -12
- {completor-1.0.0 → completor-1.1.0}/completor/input_validation.py +1 -1
- {completor-1.0.0 → completor-1.1.0}/completor/main.py +1 -4
- {completor-1.0.0 → completor-1.1.0}/completor/prepare_outputs.py +1 -1
- {completor-1.0.0 → completor-1.1.0}/completor/read_casefile.py +2 -1
- {completor-1.0.0 → completor-1.1.0}/completor/utils.py +4 -33
- {completor-1.0.0 → completor-1.1.0}/completor/wells.py +0 -2
- {completor-1.0.0 → completor-1.1.0}/pyproject.toml +6 -6
- completor-1.0.0/completor/exceptions/__init__.py +0 -4
- {completor-1.0.0 → completor-1.1.0}/LICENSE +0 -0
- {completor-1.0.0 → completor-1.1.0}/README.md +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/__init__.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/config_jobs/run_completor +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/constants.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/exceptions/clean_exceptions.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/exceptions/exceptions.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/get_version.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/launch_args_parser.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/logger.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/parse.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/read_schedule.py +0 -0
- {completor-1.0.0 → completor-1.1.0}/completor/visualization.py +0 -0
- {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.
|
|
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 (>=
|
|
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 (
|
|
20
|
-
Requires-Dist: pandas (>=2.
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
17
|
-
|
|
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
|
-
|
|
20
|
-
return {config_file.name: config_file}
|
|
30
|
+
return _get_jobs_from_directory("config_jobs")
|
|
21
31
|
|
|
22
32
|
|
|
23
|
-
@
|
|
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
|
|
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
|
|
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.
|
|
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 = "
|
|
25
|
-
pandas = "^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="^
|
|
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 = "
|
|
39
|
-
pytest = "^8.
|
|
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]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|