gsolve 5.6.0__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.
gsolve/__init__.py ADDED
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib.metadata as _im
4
+
5
+ try:
6
+ __version__ = _im.version("gsolve")
7
+ except _im.PackageNotFoundError:
8
+ __version__ = "5.6.0" # pragma: no cover
9
+
10
+ from gsolve.meter_conversion import LaCosteRombergDialConverter
11
+ from gsolve.observations import GravityObservations, GravitySurvey
12
+ from gsolve.reductions.anomalies import GravityAnomalies
13
+ from gsolve.reductions.corrections import (
14
+ GravityCorrectionParameters,
15
+ GravityCorrectionProvider,
16
+ )
17
+ from gsolve.reductions.terrain_corrections import (
18
+ TerrainCorrectionData,
19
+ TerrainCorrectionParameters,
20
+ TerrainCorrector,
21
+ )
22
+ from gsolve.reports import GSolveReport
23
+ from gsolve.sites import GravitySites, ReferenceGravity
24
+
25
+ __all__ = [
26
+ "GravityObservations",
27
+ "GravitySurvey",
28
+ "GravitySites",
29
+ "ReferenceGravity",
30
+ "LaCosteRombergDialConverter",
31
+ "GSolveReport",
32
+ "GravityCorrectionProvider",
33
+ "GravityCorrectionParameters",
34
+ "GravityAnomalies",
35
+ "TerrainCorrectionParameters",
36
+ "TerrainCorrector",
37
+ "TerrainCorrectionData",
38
+ ]
gsolve/__main__.py ADDED
@@ -0,0 +1,190 @@
1
+ # GSolve - gravity processing software.
2
+ # Copyright (c) 2026 Earth Sciences New Zealand.
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ # SPDX-License-Identifier: GPLv3
16
+
17
+ # Copyright (c) 2025 Earth Sciences New Zealand.
18
+ import argparse
19
+
20
+ from gsolve import GravitySurvey, LaCosteRombergDialConverter, ReferenceGravity
21
+ from gsolve.reports import GSolveReport
22
+ from gsolve.tide.earth_tide import LongmanTidalCorrection
23
+
24
+
25
+ def parse_args(*args: str) -> argparse.Namespace:
26
+ __app_name__ = "gsolve-cli"
27
+ args_parser = argparse.ArgumentParser(
28
+ prog=__app_name__,
29
+ description=(
30
+ f"{__app_name__} - CLI utility to process relative gravimetric measurements"
31
+ ),
32
+ epilog=None,
33
+ add_help=False,
34
+ formatter_class=argparse.RawTextHelpFormatter,
35
+ )
36
+
37
+ # Input parameters
38
+ input = args_parser.add_argument_group("Input")
39
+
40
+ input.add_argument(
41
+ "-is",
42
+ "--input-survey",
43
+ action="store",
44
+ required=True,
45
+ metavar="file",
46
+ help=(
47
+ "[Required] Input survey .xlsx-file name with gravimeter readings "
48
+ "and site information."
49
+ ),
50
+ )
51
+
52
+ # Optional parameters
53
+ input.add_argument(
54
+ "-ref",
55
+ "--reference",
56
+ action="store",
57
+ metavar="file",
58
+ default=None,
59
+ help="[Optional] Input file with reference gravity. Default: None",
60
+ )
61
+ input.add_argument(
62
+ "-ct",
63
+ "--conversion-table-file",
64
+ action="store",
65
+ metavar="file",
66
+ default=None,
67
+ help="[Optional] Input file with conversion table. Default: None",
68
+ )
69
+
70
+ # Output parameter
71
+ output = args_parser.add_argument_group("Output")
72
+
73
+ output.add_argument(
74
+ "-or",
75
+ "--output-report",
76
+ action="store",
77
+ required=True,
78
+ metavar="file",
79
+ help=(
80
+ "[Required] Output report .xlsx-file name with adjusted gravity "
81
+ "and observations values."
82
+ ),
83
+ )
84
+
85
+ # Processing options
86
+ proc = args_parser.add_argument_group("Processing options")
87
+
88
+ proc.add_argument(
89
+ "-m",
90
+ "--method",
91
+ type=int,
92
+ action="store",
93
+ default=2,
94
+ choices=range(1, 4),
95
+ metavar="value",
96
+ help="[Optional] Absolute gravity constrain method: {1, 2, 3}. Default: 2",
97
+ )
98
+ proc.add_argument(
99
+ "-cf",
100
+ "--calibration-factor",
101
+ action="store",
102
+ metavar="value",
103
+ type=float,
104
+ default=1,
105
+ help="[Optional] Define calibration factor. Default: 1.0",
106
+ )
107
+ proc.add_argument(
108
+ "-pc",
109
+ "--percentile-clipping",
110
+ type=float,
111
+ default=100,
112
+ metavar="value",
113
+ help="[Optional] Clip data by percentile value. Default: 100",
114
+ )
115
+ proc.add_argument(
116
+ "--use-loops",
117
+ action="store_true",
118
+ default=False,
119
+ help="[Optional] Use individual loops in the adjustment process. Default: False",
120
+ )
121
+ proc.add_argument(
122
+ "--calculate-calibration-factor",
123
+ action="store_true",
124
+ default=False,
125
+ help="[Optional] Claculate calibration factor. Default: False",
126
+ )
127
+
128
+ # Help function
129
+ args_parser.add_argument(
130
+ "-h", "--help", action="help", help="Show help message and exit"
131
+ )
132
+
133
+ if args:
134
+ return args_parser.parse_args(args=args)
135
+ return args_parser.parse_args()
136
+
137
+
138
+ def processing(args: argparse.Namespace) -> None:
139
+ # Read survey information
140
+ survey = GravitySurvey.from_excel(fname=args.input_survey)
141
+
142
+ # Read in list reference (i.e. absolute) stations
143
+ if args.reference is not None:
144
+ ref_sites = ReferenceGravity.from_csv(csv_file=args.reference)
145
+ # set stations with known reference gravity values
146
+ survey.set_reference_gravity(ref_grav=ref_sites)
147
+
148
+ # Convert gravimeter readings
149
+ if args.conversion_table_file is not None:
150
+ g106converter = LaCosteRombergDialConverter.from_csv(
151
+ fname=args.conversion_table_file
152
+ )
153
+ # apply dial conversion to convert values to mGal.
154
+ survey.apply_dial_to_mgal(converter=g106converter)
155
+
156
+ # Apply calibration factor
157
+ survey.set_calibration_factor(calibration_factor=args.calibration_factor)
158
+
159
+ # Calculate the earth tide correction
160
+ survey.apply_earth_tide_correction(tide_corrector=LongmanTidalCorrection())
161
+
162
+ # Calculate corrected gravity
163
+ survey.calculate_tide_corrected_gravity()
164
+
165
+ # Perform adjustment
166
+ results = survey.solve_lstsq(
167
+ method=args.method,
168
+ use_loops=args.use_loops,
169
+ calculate_calibration_factor=args.calculate_calibration_factor,
170
+ percentile_clipping=args.percentile_clipping,
171
+ )
172
+
173
+ # Save output files
174
+ output_report = args.output_report
175
+ report = GSolveReport(
176
+ observations=survey.observations, sites=survey.sites, results=results
177
+ )
178
+ report.to_excel(filename=output_report)
179
+
180
+
181
+ def main() -> None:
182
+ try:
183
+ args = parse_args()
184
+ processing(args)
185
+ except Exception as e:
186
+ print(e)
187
+
188
+
189
+ if __name__ == "__main__":
190
+ main()
File without changes
@@ -0,0 +1,57 @@
1
+ # GSolve - gravity processing software.
2
+ # Copyright (c) 2026 Earth Sciences New Zealand.
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ # SPDX-License-Identifier: GPLv3
16
+
17
+ # Copyright (c) 2025 Earth Sciences New Zealand.
18
+
19
+ """Funtions used in generating summary statistics for various GSolve classes."""
20
+
21
+ import pandas as _pd
22
+
23
+
24
+ def stdev_ugal(x: _pd.Series) -> float:
25
+ return round(x.std() * 1000, 2)
26
+
27
+
28
+ def range_ugal(x: _pd.Series) -> float:
29
+ return round((x.max() - x.min()) * 1000, 2)
30
+
31
+
32
+ def n(x: _pd.Series) -> int:
33
+ return x.size
34
+
35
+
36
+ def n_inactive(x: _pd.Series) -> int:
37
+ return x.eq(False).sum()
38
+
39
+
40
+ def n_sites(x: _pd.Series) -> int:
41
+ return x.nunique()
42
+
43
+
44
+ def starttime_utc(x: _pd.Series) -> _pd.Timestamp:
45
+ return x.min()
46
+
47
+
48
+ def endtime_utc(x: _pd.Series) -> _pd.Timestamp:
49
+ return x.max()
50
+
51
+
52
+ def duration_hr(x: _pd.Series) -> float:
53
+ return round((x.max() - x.min()).total_seconds() / 3600, 2)
54
+
55
+
56
+ def in_loops(x: _pd.Series) -> str:
57
+ return ",".join(sorted(x.unique()))
gsolve/core/_typing.py ADDED
@@ -0,0 +1,120 @@
1
+ # GSolve - gravity processing software.
2
+ # Copyright (c) 2026 Earth Sciences New Zealand.
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
15
+ # SPDX-License-Identifier: GPLv3
16
+
17
+ # Copyright (c) 2025 Earth Sciences New Zealand.
18
+
19
+
20
+ from __future__ import annotations
21
+
22
+ import datetime
23
+ from collections.abc import Callable, Hashable, Mapping, Sequence
24
+ from os import PathLike
25
+ from typing import Any, Literal, Protocol, TypeAlias, Union, runtime_checkable
26
+
27
+ import numpy as np
28
+ import pandas as pd
29
+ import xarray as xr
30
+ from numpy.typing import ArrayLike, NDArray
31
+ from pandas import DataFrame, DatetimeIndex, Index, Series, Timestamp
32
+ from pandas.api.typing import NaTType
33
+ from pylab import ndarray
34
+
35
+ # from pandas.api.typing.aliases import TimedeltaConvertibleTypes
36
+
37
+ __all__ = [
38
+ "AllowedTimestampResolution",
39
+ "AllowedTimestampRoundingMethods",
40
+ "IfWorkbookExists",
41
+ "IfSheetExists",
42
+ "GSolveSolverMethod",
43
+ "GSolveSolverReturn",
44
+ "Renamer",
45
+ "DatetimeScalar",
46
+ "DatetimeArray",
47
+ "DatetimeScalarOrArray",
48
+ "FilePath",
49
+ "DatasetOrArray",
50
+ "ArrayOrCoords",
51
+ "Points2D",
52
+ "Points3D",
53
+ "TCorrDistanceMaskType",
54
+ ]
55
+
56
+ # Aliases by gsolve for various functions arguments
57
+ AllowedTimestampResolution: TypeAlias = Literal[
58
+ "year", "month", "day", "hour", "minute", "second", "microsecond", "nanosecond"
59
+ ]
60
+ AllowedTimestampRoundingMethods: TypeAlias = Literal["round", "floor", "ceil"]
61
+
62
+ IfWorkbookExists: TypeAlias = Literal["error", "replace", "append"]
63
+ IfSheetExists: TypeAlias = Literal["error", "replace", "new"]
64
+
65
+ GSolveSolverMethod: TypeAlias = Literal[1, 2, 3]
66
+
67
+ GSolveSolverReturn: TypeAlias = tuple[
68
+ NDArray, NDArray, NDArray, NDArray, NDArray, float | np.float64 | None, NDArray
69
+ ]
70
+
71
+ FilePath: TypeAlias = str | PathLike
72
+
73
+ # The following type aliases are copied/adapted from pandas to ensure
74
+ # function parameters are compatible with pandas methods they are passed to
75
+
76
+ Renamer: TypeAlias = Union[Mapping[Any, Hashable], Callable[[Any], Hashable]]
77
+
78
+
79
+ DateTimeConvertibleTypes: TypeAlias = Union[
80
+ str,
81
+ int,
82
+ float,
83
+ datetime.timedelta,
84
+ list,
85
+ tuple,
86
+ range,
87
+ ArrayLike,
88
+ Index,
89
+ Series,
90
+ ]
91
+ DatetimeScalar: TypeAlias = (
92
+ int | float | str | datetime.date | np.datetime64 | pd.Timestamp
93
+ )
94
+
95
+ DatetimeArray: TypeAlias = list | tuple | ndarray | Series | Index | DatetimeIndex
96
+ DatetimeScalarOrArray: TypeAlias = DatetimeScalar | DatetimeArray
97
+
98
+ TimedeltaScalar: TypeAlias = str | int | float | pd.Timedelta | datetime.timedelta
99
+
100
+ SiteIDArray: TypeAlias = Sequence[str] | Series | Index | NDArray[np.str_]
101
+ FloatArray: TypeAlias = Sequence[float] | Series | Index | NDArray[np.floating]
102
+ StringArray: TypeAlias = Sequence[str] | Series | Index | NDArray[np.str_]
103
+ BoolArray: TypeAlias = Sequence[bool] | Series | Index | NDArray[np.bool_]
104
+
105
+ # aliases used in terrain correction
106
+ DatasetOrArray: TypeAlias = xr.DataArray | xr.Dataset
107
+ ArrayOrCoords: TypeAlias = DatasetOrArray | Sequence[ArrayLike]
108
+ Points2D: TypeAlias = tuple[FloatArray, FloatArray]
109
+ Points3D: TypeAlias = tuple[FloatArray, FloatArray, FloatArray]
110
+ TCorrDistanceMaskType: TypeAlias = Literal["radial", "rectangular"]
111
+
112
+
113
+ # protocols for select Gsolve classes
114
+ @runtime_checkable
115
+ class SitesLike(Protocol):
116
+ data: pd.DataFrame
117
+
118
+ def get_points(
119
+ self, xcol: str, ycol: str, zcol: str
120
+ ) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]: ...