Skip to content

Commit 04ec4cf

Browse files
committed
Refactor GIFtools parameters to use BASE_PARAMETERS for consistency
1 parent 5dd1ffe commit 04ec4cf

4 files changed

Lines changed: 127 additions & 155 deletions

File tree

geoh5py/groups/giftools/__init__.py

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,3 @@
1616
# You should have received a copy of the GNU Lesser General Public License '
1717
# along with geoh5py. If not, see <https://www.gnu.org/licenses/>. '
1818
# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
19-
"""
20-
GIFtools application groups.
21-
22-
How to add support for a new GIFtools group:
23-
-----
24-
25-
1. Create a GIFtools group in Geoscience ANALYST (the outer GIFtools group, and the inner group you
26-
would like to add support for within that)
27-
28-
2. Copy its parameters using (from the actual "GIFtools" group, not the inner one) into
29-
a module-level ``<NAME>_PARAMETERS`` dict. For example, if you want to add support for the group
30-
named "maginv3d_60", copy from the parameters of the object with the named "GIFtools" and not the
31-
object with the name "maginv3d_60".
32-
33-
Keep the form exactly as ANALYST writes it. Object selectors such as ``mesh``
34-
rely on the rich form (notably ``meshType``) to bind and auto-select the stored entity.
35-
36-
3. Reset instance-specific fields (``uuid``, ``working_directory`` and the object
37-
``value`` entries) to empty.
38-
39-
4. Subclass :obj:`~geoh5py.groups.giftools.base.BaseGIFtoolsGroup` and set
40-
``_TYPE_UID``, ``_default_name`` and ``_default_parameters``.
41-
42-
5. Export the class from :mod:`geoh5py.groups` so it is registered for
43-
read/write.
44-
45-
6. Add the class to ``tests/groups/giftools_test.py`` with the mesh type it
46-
expects (octree groups -> :obj:`~geoh5py.objects.Octree`; tensor-mesh groups
47-
-> :obj:`~geoh5py.objects.BlockModel`, etc.).
48-
"""

geoh5py/groups/giftools/magnetics_inversion.py

Lines changed: 9 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323
from uuid import UUID
2424

2525
from geoh5py.groups.giftools.base import BaseGIFtoolsGroup
26+
from geoh5py.groups.giftools.parameters import BASE_PARAMETERS, merge_field
2627

2728

2829
# Default parameters for the maginv3d_60 inversion group.
2930
# Note -- as we add support for more GIFtools groups, these may be able to be restructured to avoid
3031
# some redundancy between groups.
3132

32-
# pylint: disable=duplicate-code
3333
MAGINV3D_PARAMETERS: dict[str, Any] = {
3434
"Lp_model": {
3535
"association": "Cell",
@@ -79,19 +79,7 @@
7979
"property": "",
8080
"value": 2,
8181
},
82-
"active_model": {
83-
"association": "Cell",
84-
"dataType": ["Integer", "Boolean"],
85-
"default": "",
86-
"enabled": False,
87-
"group": "Model parameters",
88-
"label": "Active model",
89-
"main": False,
90-
"optional": True,
91-
"parent": "mesh",
92-
"suffix": ".act",
93-
"value": "",
94-
},
82+
"active_model": merge_field(BASE_PARAMETERS["active_model"], main=False),
9583
"auto_threshold": {
9684
"choiceList": ["Relative error", "Specify value"],
9785
"default": "Relative error",
@@ -125,19 +113,7 @@
125113
"property": "",
126114
"value": 10,
127115
},
128-
"cell_weight": {
129-
"association": "Cell",
130-
"dataType": "Float",
131-
"default": "",
132-
"enabled": False,
133-
"group": "Model objective function",
134-
"label": "Weights (Ws)",
135-
"ndv": 1,
136-
"optional": True,
137-
"parent": "mesh",
138-
"suffix": ".wgt",
139-
"value": "",
140-
},
116+
"cell_weight": BASE_PARAMETERS["cell_weight"],
141117
"data": {
142118
"default": "",
143119
"gifType": ["MAGdata", "MAGAMPdata"],
@@ -177,31 +153,8 @@
177153
"min": 0,
178154
"value": 0,
179155
},
180-
"face_weight": {
181-
"association": "Face",
182-
"dataType": "Float",
183-
"default": "",
184-
"enabled": False,
185-
"group": "Model objective function",
186-
"label": "Weights (Wxyz)",
187-
"ndv": 1,
188-
"optional": True,
189-
"parent": "mesh",
190-
"suffix": ".wgt",
191-
"value": "",
192-
},
193-
"initial_model": {
194-
"association": "Cell",
195-
"dataType": "Float",
196-
"default": 0.0010000000474974513,
197-
"group": "Model parameters",
198-
"isValue": True,
199-
"label": "Initial model",
200-
"main": False,
201-
"parent": "mesh",
202-
"property": "",
203-
"value": 0.0010000000474974513,
204-
},
156+
"face_weight": BASE_PARAMETERS["face_weight"],
157+
"initial_model": BASE_PARAMETERS["initial_model"],
205158
"inversion_mode": {
206159
"choiceList": ["Chifactor", "Single beta"],
207160
"default": "Chifactor",
@@ -288,14 +241,8 @@
288241
"property": "",
289242
"value": 0,
290243
},
291-
"results_loaded": False,
292-
"smooth_mod": {
293-
"default": False,
294-
"group": "Model objective function",
295-
"label": "Reference model in Wxyz",
296-
"tooltip": "Wxyz(m-mref): SMOOTH_MOD_DIF option",
297-
"value": False,
298-
},
244+
"results_loaded": BASE_PARAMETERS["results_loaded"],
245+
"smooth_mod": BASE_PARAMETERS["smooth_mod"],
299246
"threshold": {
300247
"default": 0.05000000074505806,
301248
"enabled": True,
@@ -313,7 +260,7 @@
313260
"optional": True,
314261
"value": "",
315262
},
316-
"uuid": "",
263+
"uuid": BASE_PARAMETERS["uuid"],
317264
"version": "6",
318265
"wavelet": {
319266
"choiceList": [
@@ -343,7 +290,7 @@
343290
"main": False,
344291
"value": False,
345292
},
346-
"working_directory": "",
293+
"working_directory": BASE_PARAMETERS["working_directory"],
347294
"xy_localize": {
348295
"default": False,
349296
"label": "Localize coordinates",

geoh5py/groups/giftools/octree_base.py

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,15 @@
2121

2222
from typing import Any
2323

24+
from geoh5py.groups.giftools.parameters import BASE_PARAMETERS, merge_field
25+
2426

2527
# Parameters shared by the GIFtools octree inversion groups.
2628
# Note -- this will likely be restructured as we know more about what the commonalities and
2729
# differences are between different GIFtools/GIFtools octree/GIFtools inversion groups.
28-
# pylint: disable=duplicate-code
30+
2931
OCTREE_INVERSION_PARAMETERS: dict[str, Any] = {
30-
"active_model": {
31-
"association": "Cell",
32-
"dataType": ["Integer", "Boolean"],
33-
"default": "",
34-
"enabled": False,
35-
"group": "Model parameters",
36-
"label": "Active model",
37-
"optional": True,
38-
"parent": "mesh",
39-
"suffix": ".act",
40-
"value": "",
41-
},
32+
"active_model": BASE_PARAMETERS["active_model"],
4233
"assignConRes": {
4334
"alternateLabel": "Resistivity",
4435
"group": "Model parameters",
@@ -75,39 +66,15 @@
7566
"label": "No bounds",
7667
"value": True,
7768
},
78-
"cell_weight": {
79-
"association": "Cell",
80-
"dataType": "Float",
81-
"default": "",
82-
"enabled": False,
83-
"group": "Model objective function",
84-
"label": "Weights (Ws)",
85-
"ndv": 1,
86-
"optional": True,
87-
"parent": "mesh",
88-
"suffix": ".wgt",
89-
"value": "",
90-
},
69+
"cell_weight": BASE_PARAMETERS["cell_weight"],
9170
"delta_beta": {
9271
"default": -1234567,
9372
"dependency": "beta_given",
9473
"group": "Inversion parameters",
9574
"label": "Beta step",
9675
"value": 0.25,
9776
},
98-
"face_weight": {
99-
"association": "Face",
100-
"dataType": "Float",
101-
"default": "",
102-
"enabled": False,
103-
"group": "Model objective function",
104-
"label": "Weights (Wxyz)",
105-
"ndv": 1,
106-
"optional": True,
107-
"parent": "mesh",
108-
"suffix": ".wgt",
109-
"value": "",
110-
},
77+
"face_weight": BASE_PARAMETERS["face_weight"],
11178
"global_weight": {
11279
"association": "Cell",
11380
"dataType": "Float",
@@ -126,20 +93,12 @@
12693
"label": "Solver tolerance",
12794
"value": 0.009999999776482582,
12895
},
129-
"initial_model": {
130-
"association": "Cell",
131-
"dataType": "Float",
132-
"default": 0.0010000000474974513,
133-
"group": "Model parameters",
134-
"isValue": True,
135-
"label": "Initial model",
136-
"main": False,
137-
"max": 100000000,
138-
"min": 9.99999993922529e-09,
139-
"parent": "mesh",
140-
"property": "",
141-
"value": 0.0010000000474974513,
142-
},
96+
# initial_model shares the common base and octree adds max/min bounds.
97+
"initial_model": merge_field(
98+
BASE_PARAMETERS["initial_model"],
99+
max=100000000,
100+
min=9.99999993922529e-09,
101+
),
143102
"inversion_chifact": {
144103
"default": 1,
145104
"group": "Inversion parameters",
@@ -231,14 +190,8 @@
231190
"property": "",
232191
"value": 0.0010000000474974513,
233192
},
234-
"results_loaded": False,
235-
"smooth_mod": {
236-
"default": False,
237-
"group": "Model objective function",
238-
"label": "Reference model in Wxyz",
239-
"tooltip": "Wxyz(m-mref): SMOOTH_MOD_DIF option",
240-
"value": False,
241-
},
193+
"results_loaded": BASE_PARAMETERS["results_loaded"],
194+
"smooth_mod": BASE_PARAMETERS["smooth_mod"],
242195
"topography": {
243196
"association": "Cell",
244197
"dataType": ["Integer", "Boolean"],
@@ -273,7 +226,7 @@
273226
"property": "",
274227
"value": 10,
275228
},
276-
"uuid": "",
229+
"uuid": BASE_PARAMETERS["uuid"],
277230
"version": "",
278-
"working_directory": "",
231+
"working_directory": BASE_PARAMETERS["working_directory"],
279232
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
2+
# Copyright (c) 2026 Mira Geoscience Ltd. '
3+
# '
4+
# This file is part of geoh5py. '
5+
# '
6+
# geoh5py is free software: you can redistribute it and/or modify '
7+
# it under the terms of the GNU Lesser General Public License as published by '
8+
# the Free Software Foundation, either version 3 of the License, or '
9+
# (at your option) any later version. '
10+
# '
11+
# geoh5py is distributed in the hope that it will be useful, '
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of '
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the '
14+
# GNU Lesser General Public License for more details. '
15+
# '
16+
# You should have received a copy of the GNU Lesser General Public License '
17+
# along with geoh5py. If not, see <https://www.gnu.org/licenses/>. '
18+
# ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
19+
import copy
20+
from typing import Any
21+
22+
23+
def merge_field(base_field: dict[str, Any], **overrides: Any) -> dict[str, Any]:
24+
"""
25+
Return a deep copy of a :data:`BASE_PARAMETERS` field with ``overrides`` applied.
26+
27+
Can be used when a group shares a field with the common base, but needs a small
28+
difference (an extra key or a changed value). The deep copy ensures the per-group dict
29+
never aliases the shared ``BASE_PARAMETERS`` template, so in-place edits
30+
cannot leak between groups.
31+
32+
:param base_field: The shared field taken from :data:`BASE_PARAMETERS`.
33+
:param overrides: Keys to add or override on the copied field.
34+
:return: A new field dict, safe to embed in a group's parameter dict.
35+
"""
36+
field = copy.deepcopy(base_field)
37+
field.update(overrides)
38+
return field
39+
40+
41+
BASE_PARAMETERS: dict[str, Any] = {
42+
"active_model": {
43+
"association": "Cell",
44+
"dataType": ["Integer", "Boolean"],
45+
"default": "",
46+
"enabled": False,
47+
"group": "Model parameters",
48+
"label": "Active model",
49+
"optional": True,
50+
"parent": "mesh",
51+
"suffix": ".act",
52+
"value": "",
53+
},
54+
"cell_weight": {
55+
"association": "Cell",
56+
"dataType": "Float",
57+
"default": "",
58+
"enabled": False,
59+
"group": "Model objective function",
60+
"label": "Weights (Ws)",
61+
"ndv": 1,
62+
"optional": True,
63+
"parent": "mesh",
64+
"suffix": ".wgt",
65+
"value": "",
66+
},
67+
"face_weight": {
68+
"association": "Face",
69+
"dataType": "Float",
70+
"default": "",
71+
"enabled": False,
72+
"group": "Model objective function",
73+
"label": "Weights (Wxyz)",
74+
"ndv": 1,
75+
"optional": True,
76+
"parent": "mesh",
77+
"suffix": ".wgt",
78+
"value": "",
79+
},
80+
"initial_model": {
81+
"association": "Cell",
82+
"dataType": "Float",
83+
"default": 0.0010000000474974513,
84+
"group": "Model parameters",
85+
"isValue": True,
86+
"label": "Initial model",
87+
"main": False,
88+
"parent": "mesh",
89+
"property": "",
90+
"value": 0.0010000000474974513,
91+
},
92+
"results_loaded": False,
93+
"smooth_mod": {
94+
"default": False,
95+
"group": "Model objective function",
96+
"label": "Reference model in Wxyz",
97+
"tooltip": "Wxyz(m-mref): SMOOTH_MOD_DIF option",
98+
"value": False,
99+
},
100+
"uuid": "",
101+
"working_directory": "",
102+
}

0 commit comments

Comments
 (0)