fmu-pem 0.0.2__py3-none-any.whl → 0.0.3__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.
Files changed (35) hide show
  1. fmu/pem/__main__.py +32 -16
  2. fmu/pem/forward_models/pem_model.py +19 -27
  3. fmu/pem/pem_functions/__init__.py +2 -2
  4. fmu/pem/pem_functions/density.py +32 -38
  5. fmu/pem/pem_functions/effective_pressure.py +153 -49
  6. fmu/pem/pem_functions/estimate_saturated_rock.py +244 -52
  7. fmu/pem/pem_functions/fluid_properties.py +447 -245
  8. fmu/pem/pem_functions/mineral_properties.py +77 -74
  9. fmu/pem/pem_functions/pressure_sensitivity.py +430 -0
  10. fmu/pem/pem_functions/regression_models.py +129 -97
  11. fmu/pem/pem_functions/run_friable_model.py +106 -37
  12. fmu/pem/pem_functions/run_patchy_cement_model.py +107 -45
  13. fmu/pem/pem_functions/{run_t_matrix_and_pressure.py → run_t_matrix_model.py} +48 -27
  14. fmu/pem/pem_utilities/__init__.py +31 -9
  15. fmu/pem/pem_utilities/cumsum_properties.py +29 -37
  16. fmu/pem/pem_utilities/delta_cumsum_time.py +8 -13
  17. fmu/pem/pem_utilities/enum_defs.py +65 -8
  18. fmu/pem/pem_utilities/export_routines.py +84 -72
  19. fmu/pem/pem_utilities/fipnum_pvtnum_utilities.py +217 -0
  20. fmu/pem/pem_utilities/import_config.py +64 -46
  21. fmu/pem/pem_utilities/import_routines.py +57 -69
  22. fmu/pem/pem_utilities/pem_class_definitions.py +81 -23
  23. fmu/pem/pem_utilities/pem_config_validation.py +331 -139
  24. fmu/pem/pem_utilities/rpm_models.py +473 -100
  25. fmu/pem/pem_utilities/update_grid.py +3 -2
  26. fmu/pem/pem_utilities/utils.py +90 -38
  27. fmu/pem/run_pem.py +70 -39
  28. fmu/pem/version.py +16 -3
  29. {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.3.dist-info}/METADATA +18 -11
  30. fmu_pem-0.0.3.dist-info/RECORD +39 -0
  31. fmu_pem-0.0.2.dist-info/RECORD +0 -37
  32. {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.3.dist-info}/WHEEL +0 -0
  33. {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.3.dist-info}/entry_points.txt +0 -0
  34. {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.3.dist-info}/licenses/LICENSE +0 -0
  35. {fmu_pem-0.0.2.dist-info → fmu_pem-0.0.3.dist-info}/top_level.txt +0 -0
@@ -1,29 +1,33 @@
1
- from typing import List, Union
2
-
3
1
  import numpy as np
4
- from rock_physics_open.sandstone_models import (
5
- patchy_cement_model_cem_frac as patchy_cement,
2
+ from rock_physics_open.equinor_utilities.std_functions import (
3
+ gassmann,
4
+ velocity,
6
5
  )
6
+ from rock_physics_open.sandstone_models import patchy_cement_model_dry
7
7
 
8
8
  from fmu.pem.pem_utilities import (
9
+ DryRockProperties,
9
10
  EffectiveFluidProperties,
10
- MatrixProperties,
11
- PemConfig,
11
+ EffectiveMineralProperties,
12
12
  PressureProperties,
13
+ RockMatrixProperties,
13
14
  SaturatedRockProperties,
14
15
  filter_and_one_dim,
15
16
  reverse_filter_and_restore,
16
17
  )
18
+ from fmu.pem.pem_utilities.enum_defs import ParameterTypes
19
+
20
+ from .pressure_sensitivity import apply_dry_rock_pressure_sensitivity_model
17
21
 
18
22
 
19
23
  def run_patchy_cement(
20
- mineral: MatrixProperties,
21
- fluid: Union[list[EffectiveFluidProperties], EffectiveFluidProperties],
22
- cement: MatrixProperties,
24
+ mineral: EffectiveMineralProperties,
25
+ fluid: list[EffectiveFluidProperties] | EffectiveFluidProperties,
26
+ cement: EffectiveMineralProperties,
23
27
  porosity: np.ma.MaskedArray,
24
- pressure: Union[list[PressureProperties], PressureProperties],
25
- config: PemConfig,
26
- ) -> List[SaturatedRockProperties]:
28
+ pressure: list[PressureProperties] | PressureProperties,
29
+ rock_matrix_props: RockMatrixProperties,
30
+ ) -> tuple[list[SaturatedRockProperties], list[DryRockProperties]]:
27
31
  """Prepare inputs and parameters for running the Patchy Cement model
28
32
 
29
33
  Args:
@@ -32,19 +36,34 @@ def run_patchy_cement(
32
36
  properties in a list
33
37
  cement: cement properties containing k [Pa], mu [Pa] and rho [kg/m3]
34
38
  porosity: porosity fraction
35
- pressure: steps in effective pressure in [bar] due to Eclipse standard
36
- config: parameters for the PEM
39
+ pressure: steps in effective pressure, unit Pa
40
+ rock_matrix_props: parameters for the PEM
37
41
 
38
42
  Returns:
39
43
  saturated rock properties with vp [m/s], vs [m/s], density [kg/m^3], ai
40
44
  (vp * density), si (vs * density), vpvs (vp / vs)
45
+ dry rock properties with bulk modulus [Pa], shear modulus [Pa] and density
46
+ [kg/m^3]
41
47
  """
42
48
  # Mineral and porosity are assumed to be single objects, fluid and
43
49
  # effective_pressure can be lists
44
50
  fluid, pressure = _verify_inputs(fluid, pressure)
51
+
52
+ # Calculate depletion from the initial effective pressure
53
+ initial_effective_pressure = pressure[0].effective_pressure
54
+ # Container for saturated properties
45
55
  saturated_props = []
46
- pat_cem_params = config.rock_matrix.model.parameters
47
- for fl_prop, pres in zip(fluid, pressure):
56
+ dry_props = []
57
+
58
+ # to please the IDE:
59
+ k_dry = None
60
+ mu = None
61
+ rho_dry = None
62
+ k_init = None
63
+ mu_init = None
64
+
65
+ pat_cem_params = rock_matrix_props.model.parameters
66
+ for time_step, (fl_prop, pres) in enumerate(zip(fluid, pressure)):
48
67
  (
49
68
  mask,
50
69
  tmp_min_k,
@@ -57,45 +76,88 @@ def run_patchy_cement(
57
76
  tmp_fl_prop_rho,
58
77
  tmp_por,
59
78
  tmp_pres,
79
+ init_pres,
60
80
  ) = filter_and_one_dim(
61
81
  mineral.bulk_modulus,
62
82
  mineral.shear_modulus,
63
- mineral.dens,
83
+ mineral.density,
64
84
  cement.bulk_modulus,
65
85
  cement.shear_modulus,
66
- cement.dens,
86
+ cement.density,
67
87
  fl_prop.bulk_modulus,
68
- fl_prop.dens,
88
+ fl_prop.density,
69
89
  porosity,
70
- pres.effective_pressure * 1.0e5,
90
+ pres.effective_pressure,
91
+ initial_effective_pressure,
71
92
  return_numpy_array=True,
72
93
  )
73
- """Estimation of effective mineral properties must be able to handle cases where
74
- there is a more complex combination of minerals than the standard sand/shale
75
- case. For carbonates the input can be based on minerals (e.g. calcite,
76
- dolomite, quartz, smectite, ...) or PRTs (petrophysical rock types) that each
77
- have been assigned elastic properties to."""
78
- vp, vs, rho, _, _ = patchy_cement(
79
- tmp_min_k,
80
- tmp_min_mu,
81
- tmp_min_rho,
82
- tmp_cem_k,
83
- tmp_cem_mu,
84
- tmp_cem_rho,
85
- tmp_fl_prop_k,
86
- tmp_fl_prop_rho,
87
- tmp_por,
88
- tmp_pres,
89
- pat_cem_params.cement_fraction,
90
- pat_cem_params.critical_porosity,
91
- pat_cem_params.coordination_number_function.fcn,
92
- pat_cem_params.coordination_number,
93
- pat_cem_params.shear_reduction,
94
+ # At initial pressure, there is no need to estimate pressure effect on dry rock.
95
+ # If there is no pressure sensitivity, we use the initial pressure for the dry
96
+ # rock also after start of production, and the only differences will be due to
97
+ # changes in fluid properties or saturation
98
+ if time_step == 0:
99
+ k_dry, mu, rho_dry = patchy_cement_model_dry(
100
+ tmp_min_k,
101
+ tmp_min_mu,
102
+ tmp_min_rho,
103
+ tmp_cem_k,
104
+ tmp_cem_mu,
105
+ tmp_cem_rho,
106
+ tmp_por,
107
+ tmp_pres,
108
+ pat_cem_params.cement_fraction,
109
+ pat_cem_params.critical_porosity,
110
+ pat_cem_params.coordination_number_function,
111
+ pat_cem_params.coord_num,
112
+ pat_cem_params.shear_reduction,
113
+ )
114
+ # For use at depleted pressure
115
+ k_init = k_dry
116
+ mu_init = mu
117
+ if time_step > 0 and rock_matrix_props.pressure_sensitivity:
118
+ # estimate the properties for the initial pressure by friable model,
119
+ # then apply correction for depletion
120
+
121
+ # Prepare in situ properties
122
+ in_situ_dict = {
123
+ ParameterTypes.K.value: k_init,
124
+ ParameterTypes.MU.value: mu_init,
125
+ ParameterTypes.RHO.value: tmp_min_rho,
126
+ ParameterTypes.POROSITY.value: tmp_por,
127
+ }
128
+ tmp_matrix = EffectiveMineralProperties(
129
+ bulk_modulus=tmp_min_k,
130
+ shear_modulus=tmp_min_mu,
131
+ density=tmp_min_rho,
132
+ )
133
+ depl_props = apply_dry_rock_pressure_sensitivity_model(
134
+ model=rock_matrix_props.pressure_sensitivity_model,
135
+ initial_eff_pressure=init_pres,
136
+ depleted_eff_pressure=tmp_pres,
137
+ in_situ_dict=in_situ_dict,
138
+ mineral_properties=tmp_matrix,
139
+ cement_properties=rock_matrix_props.minerals[rock_matrix_props.cement],
140
+ )
141
+ k_dry = depl_props[ParameterTypes.K.value]
142
+ mu = depl_props[ParameterTypes.MU.value]
143
+
144
+ # Saturate rock
145
+ k_sat = gassmann(k_dry, tmp_por, tmp_fl_prop_k, tmp_min_k)
146
+ rho_sat = rho_dry + tmp_por * tmp_fl_prop_rho
147
+ vp, vs = velocity(k_sat, mu, rho_sat)[0:2]
148
+
149
+ vp, vs, rho_sat, k_dry, mu, rho_dry = reverse_filter_and_restore(
150
+ mask, vp, vs, rho_sat, k_dry, mu, rho_dry
151
+ )
152
+ saturated_props.append(SaturatedRockProperties(vp=vp, vs=vs, density=rho_sat))
153
+ dry_props.append(
154
+ DryRockProperties(
155
+ bulk_modulus=k_dry,
156
+ shear_modulus=mu,
157
+ density=rho_dry,
158
+ )
94
159
  )
95
- vp, vs, rho = reverse_filter_and_restore(mask, vp, vs, rho)
96
- props = SaturatedRockProperties(vp=vp, vs=vs, dens=rho)
97
- saturated_props.append(props)
98
- return saturated_props
160
+ return saturated_props, dry_props
99
161
 
100
162
 
101
163
  def _verify_inputs(fl_prop, pres_prop):
@@ -1,5 +1,4 @@
1
1
  from pathlib import Path
2
- from typing import List, Union
3
2
 
4
3
  import numpy as np
5
4
  from rock_physics_open.t_matrix_models import (
@@ -9,10 +8,11 @@ from rock_physics_open.t_matrix_models import (
9
8
  )
10
9
 
11
10
  from fmu.pem.pem_utilities import (
11
+ DryRockProperties,
12
12
  EffectiveFluidProperties,
13
- MatrixProperties,
14
- PemConfig,
13
+ EffectiveMineralProperties,
15
14
  PressureProperties,
15
+ RockMatrixProperties,
16
16
  SaturatedRockProperties,
17
17
  filter_and_one_dim,
18
18
  reverse_filter_and_restore,
@@ -21,18 +21,19 @@ from fmu.pem.pem_utilities import (
21
21
  from .run_patchy_cement_model import _verify_inputs
22
22
 
23
23
 
24
- def run_t_matrix_and_pressure_models(
25
- mineral_properties: MatrixProperties,
26
- fluid_properties: Union[list[EffectiveFluidProperties], EffectiveFluidProperties],
24
+ def run_t_matrix_model(
25
+ mineral_properties: EffectiveMineralProperties,
26
+ fluid_properties: list[EffectiveFluidProperties] | EffectiveFluidProperties,
27
27
  porosity: np.ma.MaskedArray,
28
- vsh: Union[None, np.ma.MaskedArray],
29
- pressure: Union[list[PressureProperties], PressureProperties],
30
- config: PemConfig,
28
+ vsh: None | np.ma.MaskedArray,
29
+ pressure: list[PressureProperties] | PressureProperties,
30
+ rock_matrix: RockMatrixProperties,
31
+ model_directory: Path,
31
32
  petec_parameter_file: Path = Path("t_mat_params_petec.pkl"),
32
33
  exp_parameter_file: Path = Path("t_mat_params_exp.pkl"),
33
34
  pres_model_vp: Path = Path("carbonate_pressure_model_vp_exp.pkl"),
34
35
  pres_model_vs: Path = Path("carbonate_pressure_model_vs_exp.pkl"),
35
- ) -> List[SaturatedRockProperties]:
36
+ ) -> tuple[list[SaturatedRockProperties], list[DryRockProperties]]:
36
37
  """Model for carbonate rock with possibility to estimate changes due to
37
38
  production, i.e., saturation changes, changes in the fluids due to pore pressure
38
39
  change and also changes in the properties of the matrix by increase in effective
@@ -40,11 +41,21 @@ def run_t_matrix_and_pressure_models(
40
41
 
41
42
  The first timestep is regarded as in situ conditions for the pressure
42
43
  substitution, any later timestep also takes into account the changes in effective
43
- pressure from the initial one.
44
+ pressure from the initial one. Pressure sensitivity can be deselected in the
45
+ configuration of the PEM.
44
46
 
45
47
  Calibration of parameters for the T-Matrix model must be made before running the
46
48
  forward model, this is only possible in RokDoc with 1D match to logs.
47
49
 
50
+ Notice that t-matrix differs from the other saturated rock physics models in that
51
+ there is no intermediate step for dry rock properties. For this reason, the pressure
52
+ sensitive model is fixed, as this is a model that is adapted to saturated carbonate
53
+ rocks. This model can be overridden by saving an alternative model with the same
54
+ format as the default ones.
55
+
56
+ To comply with other functions for saturated rock properties, we also return
57
+ dry rock properties, but for the time being, the values are set to NaN.
58
+
48
59
  Args:
49
60
  mineral_properties: bulk modulus (k) [Pa], shear modulus (mu) [Pa],
50
61
  density [kg/m^3]
@@ -53,7 +64,8 @@ def run_t_matrix_and_pressure_models(
53
64
  porosity: porosity [fraction]
54
65
  vsh: shale volume [fraction]
55
66
  pressure: overburden, effective and formation (pore) pressure per restart date
56
- config: configuration parameters
67
+ rock_matrix: rock matrix properties
68
+ model_directory: folder for model files
57
69
  petec_parameter_file: additional parameters for the T-Matrix model, determined
58
70
  through optimisation to well logs
59
71
  exp_parameter_file: additional parameters for the T-Matrix model, determined
@@ -64,16 +76,18 @@ def run_t_matrix_and_pressure_models(
64
76
  Returns:
65
77
  saturated rock properties with vp [m/s], vs [m/s], density [kg/m^3],
66
78
  ai (vp * density), si (vs * density), vpvs (vp / vs)
79
+ dry rock properties with values set to NaN
67
80
  """
68
81
  fluid_properties, pressure = _verify_inputs(fluid_properties, pressure)
69
82
 
70
83
  # All model files are gathered with the config file for the PEM model,
71
84
  # i.e. in ../sim2seis/model
72
- petec_parameter_file = config.paths.rel_path_pem / petec_parameter_file
73
- exp_parameter_file = config.paths.rel_path_pem / exp_parameter_file
85
+ petec_parameter_file = model_directory / petec_parameter_file
86
+ exp_parameter_file = model_directory / exp_parameter_file
74
87
 
75
88
  saturated_props = []
76
- t_mat_params = config.rock_matrix.model.parameters
89
+ dry_props = []
90
+ t_mat_params = rock_matrix.model.parameters
77
91
 
78
92
  if vsh is None and t_mat_params.t_mat_model_version == "EXP":
79
93
  raise ValueError("Shale volume must be provided for EXP model")
@@ -83,13 +97,13 @@ def run_t_matrix_and_pressure_models(
83
97
  vsh = np.ma.array(
84
98
  np.zeros_like(porosity), mask=np.zeros_like(porosity).astype(bool)
85
99
  )
86
- # Change unit from bar to Pa
87
- pres_ovb = pressure[0].overburden_pressure * 1.0e5
88
- pres_form = pressure[0].formation_pressure * 1.0e5
100
+ # Pressures for initial conditions
101
+ pres_ovb = pressure[0].overburden_pressure
102
+ pres_form = pressure[0].formation_pressure
89
103
 
90
104
  for time_step, fl_prop in enumerate(fluid_properties):
91
105
  if time_step > 0:
92
- pres_depl = pressure[time_step].formation_pressure * 1.0e5
106
+ pres_depl = pressure[time_step].formation_pressure
93
107
  (
94
108
  mask,
95
109
  tmp_min_k,
@@ -105,9 +119,9 @@ def run_t_matrix_and_pressure_models(
105
119
  ) = filter_and_one_dim(
106
120
  mineral_properties.bulk_modulus,
107
121
  mineral_properties.shear_modulus,
108
- mineral_properties.dens,
122
+ mineral_properties.density,
109
123
  fl_prop.bulk_modulus,
110
- fl_prop.dens,
124
+ fl_prop.density,
111
125
  porosity,
112
126
  vsh,
113
127
  pres_ovb,
@@ -128,9 +142,9 @@ def run_t_matrix_and_pressure_models(
128
142
  ) = filter_and_one_dim(
129
143
  mineral_properties.bulk_modulus,
130
144
  mineral_properties.shear_modulus,
131
- mineral_properties.dens,
145
+ mineral_properties.density,
132
146
  fl_prop.bulk_modulus,
133
- fl_prop.dens,
147
+ fl_prop.density,
134
148
  porosity,
135
149
  vsh,
136
150
  )
@@ -162,7 +176,7 @@ def run_t_matrix_and_pressure_models(
162
176
  t_mat_params.freq,
163
177
  str(exp_parameter_file),
164
178
  )
165
- if time_step > 0:
179
+ if time_step > 0 and rock_matrix.pressure_sensitivity:
166
180
  vp, vs, rho, _, _ = carbonate_pressure_model(
167
181
  tmp_fl_rho,
168
182
  vp,
@@ -177,10 +191,17 @@ def run_t_matrix_and_pressure_models(
177
191
  tmp_pres_depl,
178
192
  pres_model_vp,
179
193
  pres_model_vs,
180
- config.paths.rel_path_pem.absolute(),
194
+ model_directory.absolute(),
181
195
  False,
182
196
  )
183
197
  vp, vs, rho = reverse_filter_and_restore(mask, vp, vs, rho)
184
- props = SaturatedRockProperties(vp=vp, vs=vs, dens=rho)
198
+ props = SaturatedRockProperties(vp=vp, vs=vs, density=rho)
185
199
  saturated_props.append(props)
186
- return saturated_props
200
+ dry_props.append(
201
+ DryRockProperties(
202
+ bulk_modulus=np.full_like(vp, np.nan),
203
+ shear_modulus=np.full_like(vp, np.nan),
204
+ density=np.full_like(vp, np.nan),
205
+ )
206
+ )
207
+ return saturated_props, dry_props
@@ -4,39 +4,58 @@ from .delta_cumsum_time import (
4
4
  estimate_sum_delta_time,
5
5
  )
6
6
  from .export_routines import save_results
7
+ from .fipnum_pvtnum_utilities import (
8
+ detect_overlaps,
9
+ input_num_string_to_list,
10
+ missing_num_areas,
11
+ num_boolean_array,
12
+ validate_zone_coverage,
13
+ )
7
14
  from .import_config import get_global_params_and_dates, read_pem_config
8
15
  from .import_routines import (
9
16
  import_fractions,
10
- read_geogrid,
11
- read_ntg_grid,
12
17
  read_sim_grid_props,
13
18
  )
14
19
  from .pem_class_definitions import (
15
20
  DryRockProperties,
16
21
  EffectiveFluidProperties,
17
- MatrixProperties,
22
+ EffectiveMineralProperties,
18
23
  PressureProperties,
19
24
  SaturatedRockProperties,
20
25
  SimInitProperties,
21
26
  SimRstProperties,
22
27
  )
23
- from .pem_config_validation import Fluids, PemConfig, possible_date_string
28
+ from .pem_config_validation import (
29
+ Fluids,
30
+ MineralProperties,
31
+ PemConfig,
32
+ RockMatrixProperties,
33
+ possible_date_string,
34
+ )
24
35
  from .update_grid import update_inactive_grid_cells
25
36
  from .utils import (
37
+ bar_to_pa,
26
38
  estimate_cement,
27
39
  filter_and_one_dim,
40
+ get_masked_array_mask,
28
41
  get_shale_fraction,
29
- ntg_to_shale_fraction,
42
+ pa_to_bar,
30
43
  restore_dir,
31
44
  reverse_filter_and_restore,
45
+ set_mask,
32
46
  to_masked_array,
33
47
  update_dict_list,
34
48
  )
35
49
 
36
50
  __all__ = [
37
51
  "PemConfig",
52
+ "RockMatrixProperties",
53
+ "MineralProperties",
38
54
  "Fluids",
55
+ "bar_to_pa",
56
+ "pa_to_bar",
39
57
  "calculate_diff_properties",
58
+ "detect_overlaps",
40
59
  "estimate_cement",
41
60
  "estimate_sum_delta_time",
42
61
  "estimate_delta_time",
@@ -44,21 +63,24 @@ __all__ = [
44
63
  "get_global_params_and_dates",
45
64
  "get_shale_fraction",
46
65
  "import_fractions",
47
- "ntg_to_shale_fraction",
66
+ "input_num_string_to_list",
67
+ "missing_num_areas",
68
+ "num_boolean_array",
48
69
  "possible_date_string",
49
- "read_geogrid",
50
- "read_ntg_grid",
51
70
  "read_pem_config",
52
71
  "read_sim_grid_props",
53
72
  "restore_dir",
54
73
  "reverse_filter_and_restore",
55
74
  "save_results",
56
75
  "to_masked_array",
76
+ "get_masked_array_mask",
77
+ "set_mask",
57
78
  "update_dict_list",
58
79
  "update_inactive_grid_cells",
80
+ "validate_zone_coverage",
59
81
  "DryRockProperties",
60
82
  "EffectiveFluidProperties",
61
- "MatrixProperties",
83
+ "EffectiveMineralProperties",
62
84
  "PressureProperties",
63
85
  "SaturatedRockProperties",
64
86
  "SimInitProperties",
@@ -1,19 +1,29 @@
1
1
  from dataclasses import asdict
2
- from typing import Tuple
3
2
 
4
- from .pem_config_validation import PemConfig
3
+ from .enum_defs import DifferenceAttribute, DifferenceMethod
5
4
 
6
5
 
7
- def calculate_diff_properties(props: list, conf_params: PemConfig) -> Tuple[list, list]:
6
+ def calculate_diff_properties(
7
+ props: list,
8
+ diff_dates: list[list[str]],
9
+ seis_dates: list[str],
10
+ diff_calculation: dict[DifferenceAttribute, list[DifferenceMethod]],
11
+ ) -> tuple[list, list]:
8
12
  """
9
13
  Function to calculate difference attributes between grid properties
10
14
 
11
- :param props: grid properties
12
- :param conf_params: configuration parameters
13
- :return: difference of time steps according to config file
15
+ Args:
16
+ props: grid properties
17
+ diff_dates: list of simulation model dates for difference calculation
18
+ seis_dates: list of simulation model dates
19
+ diff_calculation: dictionary of difference calculation attributes and methods
20
+
21
+ Returns:
22
+ diff_prop: difference properties
23
+ date_str: formatted string for difference dates
14
24
  """
15
- _verify_diff_inputs(props, conf_params)
16
- props = _filter_diff_inputs(props, conf_params)
25
+ _verify_diff_inputs(props, seis_dates, diff_dates)
26
+ props = _filter_diff_inputs(props, diff_calculation)
17
27
 
18
28
  def diff(x, y):
19
29
  return x - y
@@ -24,21 +34,16 @@ def calculate_diff_properties(props: list, conf_params: PemConfig) -> Tuple[list
24
34
  def ratio(x, y):
25
35
  return x / y
26
36
 
27
- lookup = dict(
28
- zip(
29
- conf_params.global_params.seis_dates, # type: ignore
30
- range(len(conf_params.global_params.seis_dates)), # type: ignore
31
- )
32
- )
37
+ lookup = dict(zip(seis_dates, range(len(seis_dates))))
33
38
  date_str = []
34
39
  diff_prop = []
35
40
  # Need to iterate over the lists in props, which contain the properties
36
41
  # for each date
37
- for monitor, base in conf_params.global_params.diff_dates: # type: ignore
42
+ for monitor, base in diff_dates: # type: ignore
38
43
  tmp_dict = {}
39
44
  for k, v_base in props[lookup[base]].items():
40
- if k.upper() in conf_params.diff_calculation:
41
- operations = conf_params.diff_calculation[k.upper()]
45
+ if k in diff_calculation:
46
+ operations = diff_calculation[k]
42
47
  v_monitor = props[lookup[monitor]][k]
43
48
  for op in operations:
44
49
  if op in locals():
@@ -54,7 +59,7 @@ def calculate_diff_properties(props: list, conf_params: PemConfig) -> Tuple[list
54
59
  return diff_prop, date_str
55
60
 
56
61
 
57
- def _verify_diff_inputs(prop_set, conf):
62
+ def _verify_diff_inputs(prop_set, seis_dates, diff_dates):
58
63
  if not isinstance(prop_set, list):
59
64
  raise ValueError(
60
65
  f"{__file__}: input grid properties must be contained in a list "
@@ -62,15 +67,13 @@ def _verify_diff_inputs(prop_set, conf):
62
67
  f"date in the inner lists"
63
68
  )
64
69
  for prop_list in prop_set:
65
- if len(prop_list) != len(conf.global_params.seis_dates):
70
+ if len(prop_list) != len(seis_dates):
66
71
  raise ValueError(
67
72
  f"{__file__}: mismatch between property sets and "
68
73
  f"simulation model dates: "
69
- f"{len(prop_list)} vs. {len(conf.global_params.seis_dates)}"
74
+ f"{len(prop_list)} vs. {len(seis_dates)}"
70
75
  )
71
- if not {a for ll in conf.global_params.diff_dates for a in ll}.issubset(
72
- set(conf.global_params.seis_dates)
73
- ):
76
+ if not {a for ll in diff_dates for a in ll}.issubset(set(seis_dates)):
74
77
  raise ValueError(
75
78
  f"{__file__}: trying to take difference between dates not saved from "
76
79
  f"simulation model"
@@ -78,27 +81,16 @@ def _verify_diff_inputs(prop_set, conf):
78
81
  return
79
82
 
80
83
 
81
- def _filter_diff_inputs(prop_list_list, conf):
84
+ def _filter_diff_inputs(prop_list_list, diff_calculation):
82
85
  # Filter out the properties that are not in the diff_calculation list.
83
86
  # Keep the time-step order in the list
84
87
  return_list = [{} for _ in range(len(prop_list_list[0]))]
85
88
  for prop_list in prop_list_list:
86
89
  for i, prop_set in enumerate(prop_list):
87
90
  tmp_dict = {
88
- k: v
89
- for k, v in asdict(prop_set).items()
90
- if k.upper() in conf.diff_calculation
91
+ k: v for k, v in asdict(prop_set).items() if k in diff_calculation
91
92
  }
92
93
  if tmp_dict:
93
94
  return_list[i].update(tmp_dict)
94
- if conf.global_params is None:
95
- raise ValueError(
96
- f"{__file__}: unable to calculate cumsum values, global "
97
- f"settings are missing"
98
- )
99
- if conf.global_params.seis_dates is None:
100
- raise ValueError(
101
- f"{__file__}: unable to calculate cumsum values, global "
102
- f"settings seismic dates are missing"
103
- )
95
+
104
96
  return return_list
@@ -1,5 +1,3 @@
1
- from typing import Dict, List, Union
2
-
3
1
  import numpy as np
4
2
 
5
3
  from .pem_class_definitions import (
@@ -7,12 +5,11 @@ from .pem_class_definitions import (
7
5
  SimInitProperties,
8
6
  TwoWayTime,
9
7
  )
10
- from .pem_config_validation import PemConfig
11
8
 
12
9
 
13
10
  def estimate_delta_time(
14
11
  delta_z: np.ma.MaskedArray, vp: np.ma.MaskedArray, vs: np.ma.MaskedArray
15
- ) -> Dict[str, np.ma.MaskedArray]:
12
+ ) -> dict[str, np.ma.MaskedArray]:
16
13
  """Estimate seismic TWT parameters - PP, PS, SS modes
17
14
 
18
15
  Args:
@@ -29,7 +26,7 @@ def estimate_delta_time(
29
26
  return {"twtpp": dt_pp, "twtss": dt_ss, "twtps": (dt_pp + dt_ss) / 2.0}
30
27
 
31
28
 
32
- def _verify_delta_t(arrays: List[np.ma.MaskedArray]) -> None:
29
+ def _verify_delta_t(arrays: list[np.ma.MaskedArray]) -> None:
33
30
  for arr in arrays:
34
31
  if not isinstance(arr, np.ma.MaskedArray):
35
32
  raise TypeError(
@@ -45,8 +42,8 @@ def _verify_delta_t(arrays: List[np.ma.MaskedArray]) -> None:
45
42
 
46
43
 
47
44
  def calculate_time_cumsum(
48
- props: Union[list, dict], conf_params: PemConfig
49
- ) -> list[Dict[str, np.ma.MaskedArray]]:
45
+ props: list | dict,
46
+ ) -> list[dict[str, np.ma.MaskedArray]]:
50
47
  """
51
48
  Function to calculate cumulative sum of time difference properties
52
49
 
@@ -81,15 +78,13 @@ def _verify_cumsum_inputs(input_set):
81
78
 
82
79
  def estimate_sum_delta_time(
83
80
  constant_props: SimInitProperties,
84
- sat_rock_props: List[SaturatedRockProperties],
85
- config: PemConfig,
86
- ) -> List[TwoWayTime]:
81
+ sat_rock_props: list[SaturatedRockProperties],
82
+ ) -> list[TwoWayTime]:
87
83
  """Calculate TWT (two-way-time) for seismic signal for each restart date
88
84
 
89
85
  Args:
90
86
  constant_props: constant properties, here the delta Z property of the eclipse
91
- grid is used sat_rock_props: effective properties for the saturated rock per
92
- restart date
87
+ grid is used
93
88
  sat_rock_props: effective properties for the saturated rock per restart date
94
89
  config: configuration parameters
95
90
 
@@ -100,5 +95,5 @@ def estimate_sum_delta_time(
100
95
  estimate_delta_time(constant_props.delta_z, sat_rock.vp, sat_rock.vs)
101
96
  for sat_rock in sat_rock_props
102
97
  ]
103
- cum_time_list = calculate_time_cumsum(delta_time, config)
98
+ cum_time_list = calculate_time_cumsum(delta_time)
104
99
  return [TwoWayTime(**time_set) for time_set in cum_time_list]