orchid-python-api 5.25.3__py3-none-any.whl → 5.25.4__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.
- orchid_python_api/examples/search_data_frames.py +1 -1
- {orchid_python_api-5.25.3.dist-info → orchid_python_api-5.25.4.dist-info}/METADATA +4 -3
- orchid_python_api-5.25.4.dist-info/RECORD +38 -0
- {orchid_python_api-5.25.3.dist-info → orchid_python_api-5.25.4.dist-info}/WHEEL +1 -1
- ReleaseNotes.md +0 -730
- copy_orchid_examples.py +0 -88
- copy_orchid_low_level_examples.py +0 -93
- copy_orchid_manual_examples.py +0 -93
- copy_orchid_tutorials.py +0 -88
- orchid/VERSION +0 -1
- orchid/__init__.py +0 -42
- orchid/__version__.py +0 -18
- orchid/base.py +0 -31
- orchid/base_time_series_adapter.py +0 -91
- orchid/configuration.py +0 -162
- orchid/convert.py +0 -44
- orchid/core.py +0 -149
- orchid/dom_project_object.py +0 -28
- orchid/dot_net.py +0 -68
- orchid/dot_net_disposable.py +0 -64
- orchid/dot_net_dom_access.py +0 -241
- orchid/measurement.py +0 -35
- orchid/native_data_frame_adapter.py +0 -247
- orchid/native_fiber_data.py +0 -73
- orchid/native_fiber_data_set_info.py +0 -28
- orchid/native_monitor_adapter.py +0 -67
- orchid/native_project_user_data_adapter.py +0 -137
- orchid/native_stage_adapter.py +0 -631
- orchid/native_stage_part_adapter.py +0 -50
- orchid/native_subsurface_point.py +0 -70
- orchid/native_time_series_adapter.py +0 -54
- orchid/native_trajectory_adapter.py +0 -246
- orchid/native_treatment_calculations.py +0 -158
- orchid/native_treatment_curve_adapter.py +0 -60
- orchid/native_well_adapter.py +0 -134
- orchid/net_date_time.py +0 -328
- orchid/net_enumerable.py +0 -72
- orchid/net_fracture_diagnostics_factory.py +0 -55
- orchid/net_quantity.py +0 -620
- orchid/net_stage_qc.py +0 -62
- orchid/physical_quantity.py +0 -37
- orchid/project.py +0 -182
- orchid/project_store.py +0 -269
- orchid/reference_origins.py +0 -34
- orchid/script_adapter_context.py +0 -81
- orchid/searchable_data_frames.py +0 -44
- orchid/searchable_project_objects.py +0 -190
- orchid/searchable_stage_parts.py +0 -73
- orchid/searchable_stages.py +0 -29
- orchid/unit_system.py +0 -173
- orchid/utils.py +0 -14
- orchid/validation.py +0 -52
- orchid/version.py +0 -37
- orchid_python_api-5.25.3.dist-info/LICENSE +0 -176
- orchid_python_api-5.25.3.dist-info/RECORD +0 -88
- {orchid_python_api-5.25.3.dist-info → orchid_python_api-5.25.4.dist-info}/entry_points.txt +0 -0
- /LICENSE → /orchid_python_api-5.25.4.dist-info/licenses/LICENSE +0 -0
orchid/physical_quantity.py
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# This file is part of Orchid and related technologies.
|
|
3
|
-
#
|
|
4
|
-
# Copyright (c) 2017-2025 KAPPA. All Rights Reserved.
|
|
5
|
-
#
|
|
6
|
-
# LEGAL NOTICE:
|
|
7
|
-
# Orchid contains trade secrets and otherwise confidential information
|
|
8
|
-
# owned by KAPPA. Access to and use of this information is
|
|
9
|
-
# strictly limited and controlled by the Company. This file may not be copied,
|
|
10
|
-
# distributed, or otherwise disclosed outside of the Company's facilities
|
|
11
|
-
# except under appropriate precautions to maintain the confidentiality hereof,
|
|
12
|
-
# and may not be used in any way not expressly authorized by the Company.
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
from enum import Enum
|
|
17
|
-
|
|
18
|
-
# noinspection PyUnresolvedReferences
|
|
19
|
-
import UnitsNet
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class PhysicalQuantity(Enum):
|
|
23
|
-
"""The enumeration of physical quantities available via the Orchid Python API."""
|
|
24
|
-
|
|
25
|
-
ANGLE = 'angle'
|
|
26
|
-
DENSITY = 'density'
|
|
27
|
-
DURATION = 'duration'
|
|
28
|
-
ENERGY = 'energy'
|
|
29
|
-
FORCE = 'force'
|
|
30
|
-
LENGTH = 'length'
|
|
31
|
-
MASS = 'mass'
|
|
32
|
-
POWER = 'power'
|
|
33
|
-
PRESSURE = 'pressure'
|
|
34
|
-
PROPPANT_CONCENTRATION = 'proppant concentration'
|
|
35
|
-
SLURRY_RATE = 'slurry rate'
|
|
36
|
-
TEMPERATURE = 'temperature'
|
|
37
|
-
VOLUME = 'volume'
|
orchid/project.py
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2017-2025 KAPPA
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
#
|
|
15
|
-
# This file is part of Orchid and related technologies.
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
from collections import namedtuple
|
|
19
|
-
from typing import Iterable, List, Tuple
|
|
20
|
-
|
|
21
|
-
import deal
|
|
22
|
-
import option
|
|
23
|
-
import toolz.curried as toolz
|
|
24
|
-
|
|
25
|
-
from orchid import (
|
|
26
|
-
dot_net_dom_access as dna,
|
|
27
|
-
native_data_frame_adapter as dfa,
|
|
28
|
-
native_fiber_data as nfd,
|
|
29
|
-
native_monitor_adapter as nma,
|
|
30
|
-
native_time_series_adapter as tsa,
|
|
31
|
-
native_project_user_data_adapter as uda,
|
|
32
|
-
native_well_adapter as nwa,
|
|
33
|
-
net_quantity as onq,
|
|
34
|
-
searchable_data_frames as sdf,
|
|
35
|
-
searchable_project_objects as spo,
|
|
36
|
-
unit_system as units,
|
|
37
|
-
)
|
|
38
|
-
from orchid.project_store import ProjectStore
|
|
39
|
-
|
|
40
|
-
# noinspection PyUnresolvedReferences,PyPackageRequirements
|
|
41
|
-
from Orchid.FractureDiagnostics import IWell, UnitSystem
|
|
42
|
-
# noinspection PyUnresolvedReferences,PyPackageRequirements
|
|
43
|
-
from Orchid.FractureDiagnostics.Settings import IProjectUserData
|
|
44
|
-
# noinspection PyUnresolvedReferences
|
|
45
|
-
import UnitsNet
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
ProjectBounds = namedtuple('ProjectBounds', [
|
|
49
|
-
'min_x', 'max_x',
|
|
50
|
-
'min_y', 'max_y',
|
|
51
|
-
'min_depth', 'max_depth',
|
|
52
|
-
])
|
|
53
|
-
SurfacePoint = namedtuple('SurfacePoint', ['x', 'y'])
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
class Project(dna.IdentifiedDotNetAdapter):
|
|
57
|
-
"""Adapts a .NET `IProject` to a Pythonic interface."""
|
|
58
|
-
|
|
59
|
-
@deal.pre(lambda self, project_loader: project_loader is not None)
|
|
60
|
-
def __init__(self, project_loader: ProjectStore):
|
|
61
|
-
"""
|
|
62
|
-
Construct an instance adapting the .NET IProject.
|
|
63
|
-
|
|
64
|
-
project_loader: Loads an IProject to be adapted.
|
|
65
|
-
"""
|
|
66
|
-
super().__init__(project_loader.native_project())
|
|
67
|
-
self._project_loader = project_loader
|
|
68
|
-
|
|
69
|
-
azimuth = dna.transformed_dom_property('azimuth', 'The azimuth of the project measured east of north.',
|
|
70
|
-
toolz.compose(onq.as_measurement(units.Common.ANGLE),
|
|
71
|
-
option.maybe))
|
|
72
|
-
name = dna.dom_property('name', 'The name of this project.')
|
|
73
|
-
project_units = dna.transformed_dom_property('project_units', 'The project unit system.', units.as_unit_system)
|
|
74
|
-
|
|
75
|
-
# _data_frames = dna.map_reduce_dom_property('data_frames', 'The project data frames.',
|
|
76
|
-
# dfa.NativeDataFrameAdapterIdentified, dna.dictionary_by_id, {})
|
|
77
|
-
|
|
78
|
-
@property
|
|
79
|
-
def fluid_density(self):
|
|
80
|
-
"""The fluid density of the project in project units."""
|
|
81
|
-
return onq.as_measurement(self.project_units.DENSITY, option.maybe(self.dom_object.FluidDensity))
|
|
82
|
-
|
|
83
|
-
def data_frames(self) -> spo.SearchableProjectObjects:
|
|
84
|
-
"""
|
|
85
|
-
Return a `spo.SearchableProjectObjects` instance of all the data frames for this project.
|
|
86
|
-
|
|
87
|
-
Returns:
|
|
88
|
-
An `spo.SearchableProjectObjects` for all the data frames of this project.
|
|
89
|
-
"""
|
|
90
|
-
return sdf.SearchableDataFrames(dfa.NativeDataFrameAdapterIdentified, self.dom_object.DataFrames.Items)
|
|
91
|
-
|
|
92
|
-
def default_well_colors(self) -> List[Tuple[float, float, float]]:
|
|
93
|
-
"""
|
|
94
|
-
Calculate the default well colors for this project.
|
|
95
|
-
:return: A list of RGB tuples.
|
|
96
|
-
"""
|
|
97
|
-
result = list(map(tuple, self._project_loader.native_project().PlottingSettings.GetDefaultWellColors()))
|
|
98
|
-
return result
|
|
99
|
-
|
|
100
|
-
def monitors(self) -> spo.SearchableProjectObjects:
|
|
101
|
-
"""
|
|
102
|
-
Return a `spo.SearchableProjectObjects` instance of all the monitors for this project.
|
|
103
|
-
|
|
104
|
-
Returns:
|
|
105
|
-
An `spo.SearchableProjectObjects` for all the monitors of this project.
|
|
106
|
-
"""
|
|
107
|
-
return spo.SearchableProjectObjects(nma.NativeMonitorAdapter, self.dom_object.Monitors.Items)
|
|
108
|
-
|
|
109
|
-
def fiber_data(self) -> List[nfd.NativeFiberData]:
|
|
110
|
-
"""
|
|
111
|
-
Return a `spo.SearchableProjectObjects` instance of all the fiber data for this project.
|
|
112
|
-
|
|
113
|
-
Returns:
|
|
114
|
-
An `spo.SearchableProjectObjects` for all the monitors of this project.
|
|
115
|
-
"""
|
|
116
|
-
return list(spo.SearchableProjectObjects(nfd.NativeFiberData, self.dom_object.FiberDataSets.Items))
|
|
117
|
-
|
|
118
|
-
def project_bounds(self) -> ProjectBounds:
|
|
119
|
-
result = toolz.pipe(self.dom_object.GetProjectBounds(),
|
|
120
|
-
toolz.map(option.maybe),
|
|
121
|
-
toolz.map(onq.as_measurement(self.project_units.LENGTH)),
|
|
122
|
-
list,
|
|
123
|
-
lambda ls: ProjectBounds(*ls))
|
|
124
|
-
return result
|
|
125
|
-
|
|
126
|
-
def project_center(self) -> SurfacePoint:
|
|
127
|
-
"""
|
|
128
|
-
Return the location of the project center on the surface measured in project units.
|
|
129
|
-
"""
|
|
130
|
-
net_center = self.dom_object.GetProjectCenter()
|
|
131
|
-
result = toolz.pipe(net_center,
|
|
132
|
-
toolz.map(option.maybe),
|
|
133
|
-
toolz.map(onq.as_measurement(self.project_units.LENGTH)),
|
|
134
|
-
list,
|
|
135
|
-
lambda ls: SurfacePoint(ls[0], ls[1]))
|
|
136
|
-
return result
|
|
137
|
-
|
|
138
|
-
def proppant_concentration_mass_unit(self):
|
|
139
|
-
if self.project_units == units.UsOilfield:
|
|
140
|
-
return units.UsOilfield.MASS
|
|
141
|
-
elif self.project_units == units.Metric:
|
|
142
|
-
return units.Metric.MASS
|
|
143
|
-
else:
|
|
144
|
-
raise ValueError(f'Unknown unit system: {self.project_units}')
|
|
145
|
-
|
|
146
|
-
def slurry_rate_volume_unit(self):
|
|
147
|
-
if self.project_units == units.UsOilfield:
|
|
148
|
-
return units.UsOilfield.VOLUME
|
|
149
|
-
elif self.project_units == units.Metric:
|
|
150
|
-
return units.Metric.VOLUME
|
|
151
|
-
else:
|
|
152
|
-
raise ValueError(f'Unknown unit system: {self.project_units}')
|
|
153
|
-
|
|
154
|
-
def time_series(self) -> spo.SearchableProjectObjects:
|
|
155
|
-
"""
|
|
156
|
-
Return a `spo.SearchableProjectObjects` instance of all the time series for this project.
|
|
157
|
-
|
|
158
|
-
Returns:
|
|
159
|
-
An `spo.SearchableProjectObjects` for all the time series of this project.
|
|
160
|
-
"""
|
|
161
|
-
return spo.SearchableProjectObjects(tsa.NativeTimeSeriesAdapter, self.dom_object.WellTimeSeriesList.Items)
|
|
162
|
-
|
|
163
|
-
@property
|
|
164
|
-
def user_data(self) -> uda.NativeProjectUserDataAdapter:
|
|
165
|
-
return uda.NativeProjectUserDataAdapter(self.dom_object.ProjectUserData)
|
|
166
|
-
|
|
167
|
-
def wells(self) -> spo.SearchableProjectObjects:
|
|
168
|
-
"""
|
|
169
|
-
Return a `spo.SearchableProjectObjects` instance of all the wells for this project.
|
|
170
|
-
|
|
171
|
-
Returns:
|
|
172
|
-
An `spo.SearchableProjectObjects` for all the wells of this project.
|
|
173
|
-
"""
|
|
174
|
-
return spo.SearchableProjectObjects(nwa.NativeWellAdapter, self.dom_object.Wells.Items)
|
|
175
|
-
|
|
176
|
-
def wells_by_name(self, name: str) -> Iterable[IWell]:
|
|
177
|
-
"""
|
|
178
|
-
Return all the wells in this project with the specified name.
|
|
179
|
-
|
|
180
|
-
name: The name of the well(s) of interest.
|
|
181
|
-
"""
|
|
182
|
-
return toolz.filter(lambda w: name == w.name, self.wells)
|
orchid/project_store.py
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
# Copyright (c) 2017-2025 KAPPA
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
#
|
|
15
|
-
# This file is part of Orchid and related technologies.
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
import functools
|
|
19
|
-
import pathlib
|
|
20
|
-
from typing import Union
|
|
21
|
-
|
|
22
|
-
import deal
|
|
23
|
-
import option
|
|
24
|
-
import toolz.curried as toolz
|
|
25
|
-
|
|
26
|
-
from orchid import (
|
|
27
|
-
dot_net,
|
|
28
|
-
dot_net_disposable as dnd,
|
|
29
|
-
script_adapter_context as sac,
|
|
30
|
-
validation,
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
# noinspection PyUnresolvedReferences
|
|
34
|
-
from System import InvalidOperationException, TimeZoneInfo
|
|
35
|
-
# noinspection PyUnresolvedReferences
|
|
36
|
-
from System.IO import (FileStream, FileMode, FileAccess, FileShare)
|
|
37
|
-
# noinspection PyUnresolvedReferences
|
|
38
|
-
from Orchid.FractureDiagnostics.SDKFacade import (
|
|
39
|
-
PythonTimesSeriesArraysDto,
|
|
40
|
-
ScriptAdapter,
|
|
41
|
-
)
|
|
42
|
-
# noinspection PyUnresolvedReferences
|
|
43
|
-
from Orchid.FractureDiagnostics.TimeSeries import IQuantityTimeSeries
|
|
44
|
-
|
|
45
|
-
# To support doctests only
|
|
46
|
-
import json
|
|
47
|
-
import shutil
|
|
48
|
-
import zipfile
|
|
49
|
-
|
|
50
|
-
import orchid
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class OrchidError(Exception):
|
|
54
|
-
pass
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
# Ensure that a pathname is a string. Useful especially for converting `pathlib.Path` instances.
|
|
58
|
-
pathname_to_str = toolz.compose(str, toolz.identity)
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def as_python_time_series_arrays(native_time_series: IQuantityTimeSeries):
|
|
62
|
-
"""
|
|
63
|
-
Calculate the Python time series arrays equivalent to the `native_time_series` samples.
|
|
64
|
-
Args:
|
|
65
|
-
native_time_series: The native time series whose samples are sought.
|
|
66
|
-
|
|
67
|
-
Returns:
|
|
68
|
-
A `PythonTimeSeriesArraysDto` containing two arrays:
|
|
69
|
-
- Sample magnitudes
|
|
70
|
-
- Unix time stamps in seconds
|
|
71
|
-
"""
|
|
72
|
-
with sac.ScriptAdapterContext():
|
|
73
|
-
result = ScriptAdapter.AsPythonTimeSeriesArrays(native_time_series)
|
|
74
|
-
return result
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@functools.lru_cache()
|
|
78
|
-
def native_treatment_calculations():
|
|
79
|
-
"""
|
|
80
|
-
Returns a .NET ITreatmentCalculations instance to be adapted.
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
An `ITreatmentCalculations` implementation.
|
|
84
|
-
"""
|
|
85
|
-
with sac.ScriptAdapterContext():
|
|
86
|
-
result = ScriptAdapter.CreateTreatmentCalculations()
|
|
87
|
-
return result
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class ProjectStore:
|
|
91
|
-
"""Provides an .NET IProject to be adapted."""
|
|
92
|
-
|
|
93
|
-
# TODO: consider changing `project_pathname` to be `pathlib.Path`
|
|
94
|
-
@deal.pre(validation.arg_not_none)
|
|
95
|
-
@deal.pre(validation.arg_neither_empty_nor_all_whitespace)
|
|
96
|
-
def __init__(self, project_pathname: str):
|
|
97
|
-
"""
|
|
98
|
-
Construct an instance that loads project data from project_pathname
|
|
99
|
-
|
|
100
|
-
Args:
|
|
101
|
-
project_pathname: Identifies the data file for the project of interest.
|
|
102
|
-
"""
|
|
103
|
-
self._project_pathname = pathlib.Path(project_pathname)
|
|
104
|
-
self._native_project = None
|
|
105
|
-
self._in_context = False
|
|
106
|
-
|
|
107
|
-
def native_project(self):
|
|
108
|
-
"""
|
|
109
|
-
Return the native (.NET) Orchid project.
|
|
110
|
-
|
|
111
|
-
Returns:
|
|
112
|
-
The loaded `IProject`.
|
|
113
|
-
"""
|
|
114
|
-
if self._native_project is None:
|
|
115
|
-
self.load_project()
|
|
116
|
-
return self._native_project
|
|
117
|
-
|
|
118
|
-
def load_project(self):
|
|
119
|
-
"""
|
|
120
|
-
Load a project from the path, `self._project_pathname`.
|
|
121
|
-
|
|
122
|
-
Examples:
|
|
123
|
-
>>> load_path = orchid.training_data_path().joinpath('frankNstein_Bakken_UTM13_FEET.ifrac')
|
|
124
|
-
>>> store = ProjectStore(pathname_to_str(load_path))
|
|
125
|
-
>>> store.load_project()
|
|
126
|
-
>>> loaded_project = store.native_project()
|
|
127
|
-
>>> loaded_project.Name
|
|
128
|
-
'frankNstein_Bakken_UTM13_FEET'
|
|
129
|
-
"""
|
|
130
|
-
with sac.ScriptAdapterContext():
|
|
131
|
-
reader = ScriptAdapter.CreateProjectFileReader(dot_net.app_settings_path())
|
|
132
|
-
self._native_project = reader.Read(pathname_to_str(self._project_pathname), TimeZoneInfo.Utc)
|
|
133
|
-
|
|
134
|
-
def save_project(self, project):
|
|
135
|
-
"""
|
|
136
|
-
Save the specified project to `self._project_pathname`.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
Args:
|
|
140
|
-
project: The project to be saved.
|
|
141
|
-
|
|
142
|
-
Examples:
|
|
143
|
-
>>> # Test saving changed project
|
|
144
|
-
>>> load_path = orchid.training_data_path().joinpath('frankNstein_Bakken_UTM13_FEET.ifrac')
|
|
145
|
-
>>> # Use `orchid.core.load_project` to avoid circular dependency with `orchid.project`
|
|
146
|
-
>>> changed_project = orchid.load_project(pathname_to_str(load_path))
|
|
147
|
-
>>> # TODO: move this code to the property eventually, I think.
|
|
148
|
-
>>> with (dnd.disposable(changed_project.dom_object.ToMutable())) as mnp:
|
|
149
|
-
... mnp.Name = 'nomen mutatum'
|
|
150
|
-
>>> save_path = load_path.with_name(f'nomen mutatum{load_path.suffix}')
|
|
151
|
-
>>> save_store = ProjectStore(pathname_to_str(save_path))
|
|
152
|
-
>>> save_store.save_project(changed_project)
|
|
153
|
-
>>> save_path.exists()
|
|
154
|
-
True
|
|
155
|
-
>>> with zipfile.ZipFile(save_path) as archive:
|
|
156
|
-
... content = json.loads(archive.read('project.json'))
|
|
157
|
-
... content['Object']['Name']
|
|
158
|
-
'nomen mutatum'
|
|
159
|
-
>>> save_path.unlink()
|
|
160
|
-
>>> # Test side_effect of `save_project`: `native_project` returns project that was saved
|
|
161
|
-
>>> # I do not expect end users to utilize this side-effect.
|
|
162
|
-
>>> # TODO: Because this code tests a side-effect, an actual unit test might be better.
|
|
163
|
-
>>> load_path = orchid.training_data_path().joinpath('frankNstein_Bakken_UTM13_FEET.ifrac')
|
|
164
|
-
>>> # Use `orchid.core.load_project` to avoid circular dependency with `orchid.project`
|
|
165
|
-
>>> changed_project = orchid.load_project(pathname_to_str(load_path))
|
|
166
|
-
>>> # TODO: move this code to the property eventually, I think.
|
|
167
|
-
>>> with (dnd.disposable(changed_project.dom_object.ToMutable())) as mnp:
|
|
168
|
-
... mnp.Name = 'mutatio project'
|
|
169
|
-
>>> save_path = load_path.with_name(f'mutatio project{load_path.suffix}')
|
|
170
|
-
>>> save_store = ProjectStore(pathname_to_str(save_path))
|
|
171
|
-
>>> save_store.save_project(changed_project)
|
|
172
|
-
>>> changed_project.dom_object == save_store.native_project()
|
|
173
|
-
True
|
|
174
|
-
>>> save_path.unlink()
|
|
175
|
-
"""
|
|
176
|
-
with sac.ScriptAdapterContext():
|
|
177
|
-
writer = ScriptAdapter.CreateProjectFileWriter()
|
|
178
|
-
use_binary_format = False
|
|
179
|
-
writer.Write(project.dom_object, pathname_to_str(self._project_pathname), use_binary_format)
|
|
180
|
-
self._native_project = project.dom_object
|
|
181
|
-
|
|
182
|
-
def optimized_but_possibly_unsafe_save(self, project, maybe_to_pathname: option.Option[Union[str, pathlib.Path]]):
|
|
183
|
-
"""
|
|
184
|
-
Saves `project` `to_pathname` is an optimized, but possibly "unsafe" manner.
|
|
185
|
-
|
|
186
|
-
This method is unsafe because it only writes some data from `project`; the remainder of the data is simply
|
|
187
|
-
(bulk) copied from the `project_pathname` supplied to the constructor.
|
|
188
|
-
|
|
189
|
-
This method assumes that `project` was originally loaded from `project_pathname` and was then changed in
|
|
190
|
-
such a way that the "bulk" data **was not** changed. If this assumption is not true, the project saved in
|
|
191
|
-
`to_pathname` will **not** contain all the changes to `project`.
|
|
192
|
-
|
|
193
|
-
Specifically, this method **does not** save changes to data like:
|
|
194
|
-
|
|
195
|
-
- Trajectories
|
|
196
|
-
- Treatment curves
|
|
197
|
-
- Monitor curves
|
|
198
|
-
|
|
199
|
-
We believe that this method will generally finish more quickly than `save_project`; however, we cannot
|
|
200
|
-
guarantee this behavior. We encourage the developer calling this method to perform her own performance tests
|
|
201
|
-
and to understand if his use case meets the assumptions made by this method.
|
|
202
|
-
|
|
203
|
-
Args:
|
|
204
|
-
project: The project to be saved.
|
|
205
|
-
maybe_to_pathname: The "target" pathname for the newly saved data.
|
|
206
|
-
|
|
207
|
-
Examples:
|
|
208
|
-
>>> # Test optimized saving of changed project
|
|
209
|
-
>>> load_path = orchid.training_data_path().joinpath('Project_frankNstein_Permian_UTM13_FEET.ifrac')
|
|
210
|
-
>>> # Use `orchid.core.load_project` to avoid circular dependency with `orchid.project`
|
|
211
|
-
>>> changed_project = orchid.load_project(pathname_to_str(load_path))
|
|
212
|
-
>>> # TODO: eventually move this code to a project property, I think.
|
|
213
|
-
>>> with (dnd.disposable(changed_project.dom_object.ToMutable())) as mnp:
|
|
214
|
-
... mnp.Name = 'permanet melius'
|
|
215
|
-
>>> save_path = load_path.with_name(f'permanet melius{load_path.suffix}')
|
|
216
|
-
>>> # Remember original path used to load `changed_project`
|
|
217
|
-
>>> changed_project_store = ProjectStore(pathname_to_str(load_path))
|
|
218
|
-
>>> changed_project_store.optimized_but_possibly_unsafe_save(changed_project, option.maybe(save_path))
|
|
219
|
-
>>> save_path.exists()
|
|
220
|
-
True
|
|
221
|
-
>>> with zipfile.ZipFile(save_path) as archive:
|
|
222
|
-
... content = json.loads(archive.read('project.json'))
|
|
223
|
-
... content['Object']['Name']
|
|
224
|
-
'permanet melius'
|
|
225
|
-
>>> save_path.unlink()
|
|
226
|
-
>>> # Test side_effect of `save_project`: `native_project` returns project that was saved
|
|
227
|
-
>>> # I do not expect end users to utilize this side-effect.
|
|
228
|
-
>>> # TODO: Because this code tests a side-effect, an actual unit test might be better.
|
|
229
|
-
>>> load_path = orchid.training_data_path().joinpath('Project_frankNstein_Permian_UTM13_FEET.ifrac')
|
|
230
|
-
>>> # Use `orchid.core.load_project` to avoid circular dependency with `orchid.project`
|
|
231
|
-
>>> changed_project = orchid.load_project(pathname_to_str(load_path))
|
|
232
|
-
>>> # TODO: move this code to the property eventually, I think.
|
|
233
|
-
>>> with (dnd.disposable(changed_project.dom_object.ToMutable())) as mnp:
|
|
234
|
-
... mnp.Name = 'mutatio project melius'
|
|
235
|
-
>>> save_path = load_path.with_name(f'mutatio project melius{load_path.suffix}')
|
|
236
|
-
>>> # Remember original path used to load `changed_project`
|
|
237
|
-
>>> changed_project_store = ProjectStore(pathname_to_str(load_path))
|
|
238
|
-
>>> changed_project_store.optimized_but_possibly_unsafe_save(changed_project, option.maybe(save_path))
|
|
239
|
-
>>> changed_project.dom_object == changed_project_store.native_project()
|
|
240
|
-
True
|
|
241
|
-
>>> save_path.unlink()
|
|
242
|
-
>>> # Test supplying **no** `maybe_to_pathname`
|
|
243
|
-
>>> source_path = orchid.training_data_path().joinpath('Project_frankNstein_Permian_UTM13_FEET.ifrac')
|
|
244
|
-
>>> load_path = source_path.with_name(f'idem filum{source_path.suffix}')
|
|
245
|
-
>>> # ignore returned result for doctest
|
|
246
|
-
>>> _to_path = shutil.copyfile(pathname_to_str(source_path), pathname_to_str(load_path))
|
|
247
|
-
>>> # Use `orchid.core.load_project` to avoid circular dependency with `orchid.project`
|
|
248
|
-
>>> changed_project = orchid.load_project(pathname_to_str(load_path))
|
|
249
|
-
>>> # TODO: eventually move this code to a project property, I think.
|
|
250
|
-
>>> with (dnd.disposable(changed_project.dom_object.ToMutable())) as mnp:
|
|
251
|
-
... mnp.Name = 'idem filum'
|
|
252
|
-
>>> changed_project_store = ProjectStore(pathname_to_str(load_path))
|
|
253
|
-
>>> changed_project_store.optimized_but_possibly_unsafe_save(changed_project, option.NONE)
|
|
254
|
-
>>> load_path.exists()
|
|
255
|
-
True
|
|
256
|
-
>>> load_path.unlink()
|
|
257
|
-
"""
|
|
258
|
-
with sac.ScriptAdapterContext():
|
|
259
|
-
writer = ScriptAdapter.CreateProjectFileWriter()
|
|
260
|
-
use_binary_format = False
|
|
261
|
-
writer.Write(project.dom_object, pathname_to_str(self._project_pathname),
|
|
262
|
-
maybe_to_pathname.map_or(pathname_to_str, pathname_to_str(self._project_pathname)),
|
|
263
|
-
use_binary_format)
|
|
264
|
-
self._native_project = project.dom_object
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
if __name__ == '__main__':
|
|
268
|
-
import doctest
|
|
269
|
-
doctest.testmod()
|
orchid/reference_origins.py
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# This file is part of Orchid and related technologies.
|
|
3
|
-
#
|
|
4
|
-
# Copyright (c) 2017-2025 KAPPA. All Rights Reserved.
|
|
5
|
-
#
|
|
6
|
-
# LEGAL NOTICE:
|
|
7
|
-
# Orchid contains trade secrets and otherwise confidential information
|
|
8
|
-
# owned by KAPPA. Access to and use of this information is
|
|
9
|
-
# strictly limited and controlled by the Company. This file may not be copied,
|
|
10
|
-
# distributed, or otherwise disclosed outside of the Company's facilities
|
|
11
|
-
# except under appropriate precautions to maintain the confidentiality hereof,
|
|
12
|
-
# and may not be used in any way not expressly authorized by the Company.
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
import enum
|
|
16
|
-
|
|
17
|
-
# noinspection PyUnresolvedReferences,PyPackageRequirements
|
|
18
|
-
from Orchid.FractureDiagnostics import WellReferenceFrameXy as NetWellReferenceFrameXy
|
|
19
|
-
# noinspection PyUnresolvedReferences,PyPackageRequirements
|
|
20
|
-
from Orchid.FractureDiagnostics import DepthDatum as NetDepthDatum
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# TODO: Consider adding base with methods like `toNetEnum` and `fromNetEnum`
|
|
24
|
-
class WellReferenceFrameXy(enum.Enum):
|
|
25
|
-
ABSOLUTE_STATE_PLANE = NetWellReferenceFrameXy.AbsoluteStatePlane
|
|
26
|
-
PROJECT = NetWellReferenceFrameXy.Project
|
|
27
|
-
WELL_HEAD = NetWellReferenceFrameXy.WellHead
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
# TODO: Consider adding base with methods like `toNetEnum` and `fromNetEnum`
|
|
31
|
-
class DepthDatum(enum.Enum):
|
|
32
|
-
GROUND_LEVEL = NetDepthDatum.GroundLevel
|
|
33
|
-
KELLY_BUSHING = NetDepthDatum.KellyBushing
|
|
34
|
-
SEA_LEVEL = NetDepthDatum.SeaLevel
|
orchid/script_adapter_context.py
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# This file is part of Orchid and related technologies.
|
|
3
|
-
#
|
|
4
|
-
# Copyright (c) 2017-2025 KAPPA. All Rights Reserved.
|
|
5
|
-
#
|
|
6
|
-
# LEGAL NOTICE:
|
|
7
|
-
# Orchid contains trade secrets and otherwise confidential information
|
|
8
|
-
# owned by KAPPA. Access to and use of this information is
|
|
9
|
-
# strictly limited and controlled by the Company. This file may not be copied,
|
|
10
|
-
# distributed, or otherwise disclosed outside of the Company's facilities
|
|
11
|
-
# except under appropriate precautions to maintain the confidentiality hereof,
|
|
12
|
-
# and may not be used in any way not expressly authorized by the Company.
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import sys
|
|
17
|
-
|
|
18
|
-
import orchid.configuration
|
|
19
|
-
|
|
20
|
-
import toolz.curried as toolz
|
|
21
|
-
|
|
22
|
-
from pythonnet import load
|
|
23
|
-
load('coreclr')
|
|
24
|
-
|
|
25
|
-
# noinspection PyPackageRequirements
|
|
26
|
-
import clr
|
|
27
|
-
# noinspection PyUnresolvedReferences
|
|
28
|
-
from System import InvalidOperationException
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def append_orchid_assemblies_directory_path() -> None:
|
|
32
|
-
"""
|
|
33
|
-
Append the directory containing the required Orchid assemblies to `sys.path`.
|
|
34
|
-
"""
|
|
35
|
-
orchid_bin_dir = toolz.get_in(['orchid', 'root'], orchid.configuration.get_configuration())
|
|
36
|
-
if orchid_bin_dir not in sys.path:
|
|
37
|
-
sys.path.append(orchid_bin_dir)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
append_orchid_assemblies_directory_path()
|
|
41
|
-
|
|
42
|
-
clr.AddReference('Orchid.FractureDiagnostics.SDKFacade')
|
|
43
|
-
# noinspection PyUnresolvedReferences
|
|
44
|
-
from Orchid.FractureDiagnostics.SDKFacade import ScriptAdapter
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class ScriptAdapterContext:
|
|
48
|
-
"""
|
|
49
|
-
A "private" class with the responsibility to initialize and shutdown the .NET ScriptAdapter class.
|
|
50
|
-
|
|
51
|
-
I considered making `ProjectStore` a context manager; however, the API then becomes somewhat unclear.
|
|
52
|
-
|
|
53
|
-
- Does the constructor enter the context? Must a caller initialize the instance and then enter the
|
|
54
|
-
context?
|
|
55
|
-
- What results if a caller *does not* enter the context?
|
|
56
|
-
- Enters the context twice?
|
|
57
|
-
|
|
58
|
-
Because I was uncertain I created this private class to model the `ScriptAdapter` context. The property,
|
|
59
|
-
`ProjectStore.native_project`, enters the context if it will actually read the project and exits the
|
|
60
|
-
context when the read operation is finished.
|
|
61
|
-
|
|
62
|
-
For information on Python context managers, see
|
|
63
|
-
[the Python docs](https://docs.python.org/3.8/library/stdtypes.html#context-manager-types)
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
def __enter__(self):
|
|
67
|
-
try:
|
|
68
|
-
ScriptAdapter.Init()
|
|
69
|
-
return self
|
|
70
|
-
# TODO: Correct exception type / DEADFALL issue
|
|
71
|
-
except InvalidOperationException as ioe:
|
|
72
|
-
if 'REVEAL-CORE-0xDEADFA11' in ioe.Message:
|
|
73
|
-
print('Orchid licensing error. Please contact Orchid technical support.')
|
|
74
|
-
sys.exit(-1)
|
|
75
|
-
else:
|
|
76
|
-
raise
|
|
77
|
-
|
|
78
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
79
|
-
ScriptAdapter.Shutdown()
|
|
80
|
-
# Returning no value will propagate the exception to the caller in the normal way
|
|
81
|
-
return
|
orchid/searchable_data_frames.py
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# This file is part of Orchid and related technologies.
|
|
3
|
-
#
|
|
4
|
-
# Copyright (c) 2017-2025 KAPPA. All Rights Reserved.
|
|
5
|
-
#
|
|
6
|
-
# LEGAL NOTICE:
|
|
7
|
-
# Orchid contains trade secrets and otherwise confidential information
|
|
8
|
-
# owned by KAPPA. Access to and use of this information is
|
|
9
|
-
# strictly limited and controlled by the Company. This file may not be copied,
|
|
10
|
-
# distributed, or otherwise disclosed outside of the Company's facilities
|
|
11
|
-
# except under appropriate precautions to maintain the confidentiality hereof,
|
|
12
|
-
# and may not be used in any way not expressly authorized by the Company.
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
import warnings
|
|
16
|
-
from typing import Callable, Iterator
|
|
17
|
-
|
|
18
|
-
import toolz.curried as toolz
|
|
19
|
-
|
|
20
|
-
from orchid import searchable_project_objects as spo
|
|
21
|
-
|
|
22
|
-
# noinspection PyUnresolvedReferences
|
|
23
|
-
from Orchid.FractureDiagnostics import IProjectObject
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class SearchableDataFrames(spo.SearchableProjectObjects):
|
|
27
|
-
def __init__(self, make_adapter: Callable, net_project_objects: Iterator[IProjectObject]):
|
|
28
|
-
super(SearchableDataFrames, self).__init__(make_adapter, net_project_objects)
|
|
29
|
-
|
|
30
|
-
def has_duplicate_object_ids(pos):
|
|
31
|
-
return not toolz.pipe(
|
|
32
|
-
pos,
|
|
33
|
-
toolz.map(lambda npo: npo.ObjectId.ToString()),
|
|
34
|
-
toolz.isdistinct,
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
if has_duplicate_object_ids(net_project_objects):
|
|
38
|
-
warnings.warn("""
|
|
39
|
-
KNOWN ISSUE: Multiple data frames with duplicate object IDs detected.
|
|
40
|
-
|
|
41
|
-
Workarounds:
|
|
42
|
-
- **DO NOT** use `find_by_object_id`; use `find_by_name` or `find_by_display_name` to search.
|
|
43
|
-
- Delete and recreate all data frames in a release of Orchid > 2022.3.
|
|
44
|
-
""")
|