trajmod 0.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.
- trajmod-0.1.0/CITATION.cff +22 -0
- trajmod-0.1.0/LICENSE +21 -0
- trajmod-0.1.0/MANIFEST.in +19 -0
- trajmod-0.1.0/PKG-INFO +378 -0
- trajmod-0.1.0/README.md +341 -0
- trajmod-0.1.0/pyproject.toml +60 -0
- trajmod-0.1.0/requirements.txt +13 -0
- trajmod-0.1.0/setup.cfg +4 -0
- trajmod-0.1.0/src/trajmod/__init__.py +21 -0
- trajmod-0.1.0/src/trajmod/config/__init__.py +5 -0
- trajmod-0.1.0/src/trajmod/config/modelconfig.py +79 -0
- trajmod-0.1.0/src/trajmod/design/__init__.py +2 -0
- trajmod-0.1.0/src/trajmod/design/matrix.py +99 -0
- trajmod-0.1.0/src/trajmod/events/__init__.py +15 -0
- trajmod-0.1.0/src/trajmod/events/amplitude_threshold_selector.py +149 -0
- trajmod-0.1.0/src/trajmod/events/event_selection.py +574 -0
- trajmod-0.1.0/src/trajmod/events/events.py +170 -0
- trajmod-0.1.0/src/trajmod/example.py +198 -0
- trajmod-0.1.0/src/trajmod/model/__init__.py +6 -0
- trajmod-0.1.0/src/trajmod/model/model.py +1014 -0
- trajmod-0.1.0/src/trajmod/model/model_selection.py +274 -0
- trajmod-0.1.0/src/trajmod/model/results.py +63 -0
- trajmod-0.1.0/src/trajmod/model/uncertainty_quantification.py +266 -0
- trajmod-0.1.0/src/trajmod/preprocessing/__init__.py +4 -0
- trajmod-0.1.0/src/trajmod/preprocessing/geodetic_utils.py +63 -0
- trajmod-0.1.0/src/trajmod/preprocessing/preprocessing.py +65 -0
- trajmod-0.1.0/src/trajmod/preprocessing/time_utils.py +95 -0
- trajmod-0.1.0/src/trajmod/strategies/__init__.py +17 -0
- trajmod-0.1.0/src/trajmod/strategies/fitting.py +99 -0
- trajmod-0.1.0/src/trajmod/templates/__init__.py +5 -0
- trajmod-0.1.0/src/trajmod/templates/templates.py +124 -0
- trajmod-0.1.0/src/trajmod/visualization.py +309 -0
- trajmod-0.1.0/src/trajmod.egg-info/PKG-INFO +378 -0
- trajmod-0.1.0/src/trajmod.egg-info/SOURCES.txt +35 -0
- trajmod-0.1.0/src/trajmod.egg-info/dependency_links.txt +1 -0
- trajmod-0.1.0/src/trajmod.egg-info/requires.txt +12 -0
- trajmod-0.1.0/src/trajmod.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use this software, please cite it as below."
|
|
3
|
+
authors:
|
|
4
|
+
- family-names: Costantino
|
|
5
|
+
given-names: Giuseppe
|
|
6
|
+
title: "trajmod: Simple GNSS Trajectory Modeling"
|
|
7
|
+
version: 0.1.0
|
|
8
|
+
date-released: 2026-02-10
|
|
9
|
+
url: "https://github.com/gcostantino/trajmod"
|
|
10
|
+
license: MIT
|
|
11
|
+
repository-code: "https://github.com/gcostantino/trajmod"
|
|
12
|
+
keywords:
|
|
13
|
+
- GNSS
|
|
14
|
+
- geodesy
|
|
15
|
+
- trajectory modeling
|
|
16
|
+
- postseismic relaxation
|
|
17
|
+
- time series analysis
|
|
18
|
+
abstract: >
|
|
19
|
+
A Python library for modeling GNSS displacement time series
|
|
20
|
+
with advanced multi-tier postseismic filtering, supporting
|
|
21
|
+
earthquake co-seismic offsets, postseismic relaxation, slow
|
|
22
|
+
slip events, and event-type discrimination.
|
trajmod-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Giuseppe Costantino
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Include documentation and license
|
|
2
|
+
include README.md
|
|
3
|
+
include LICENSE
|
|
4
|
+
include CITATION.cff
|
|
5
|
+
include requirements.txt
|
|
6
|
+
|
|
7
|
+
# Include all package data
|
|
8
|
+
recursive-include trajmod *.py
|
|
9
|
+
recursive-include trajmod *.json
|
|
10
|
+
recursive-include trajmod *.yaml
|
|
11
|
+
|
|
12
|
+
# Exclude development files
|
|
13
|
+
exclude .gitignore
|
|
14
|
+
exclude .flake8
|
|
15
|
+
exclude .mypy.ini
|
|
16
|
+
recursive-exclude tests *
|
|
17
|
+
recursive-exclude docs *
|
|
18
|
+
recursive-exclude * __pycache__
|
|
19
|
+
recursive-exclude * *.py[co]
|
trajmod-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: trajmod
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Simple GNSS trajectory modeling
|
|
5
|
+
Author: Giuseppe Costantino
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gcostantino/trajmod
|
|
8
|
+
Project-URL: Documentation, https://github.com/gcostantino/trajmod#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/gcostantino/trajmod
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/gcostantino/trajmod/issues
|
|
11
|
+
Keywords: GNSS,geodesy,trajectory,postseismic,time-series
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
License-File: LICENSE
|
|
25
|
+
Requires-Dist: numpy>=1.20
|
|
26
|
+
Requires-Dist: scipy>=1.7
|
|
27
|
+
Requires-Dist: matplotlib>=3.3
|
|
28
|
+
Requires-Dist: scikit-learn>=1.0
|
|
29
|
+
Requires-Dist: pyproj>=3.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-cov>=3.0; extra == "dev"
|
|
33
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=0.950; extra == "dev"
|
|
35
|
+
Requires-Dist: flake8>=4.0; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
# trajmod
|
|
39
|
+
|
|
40
|
+
**Simple GNSS time series Trajectory Modeling**
|
|
41
|
+
|
|
42
|
+
A Python library for modeling GNSS position time series with support for:
|
|
43
|
+
- Secular trends, acceleration and seasonal components
|
|
44
|
+
- Slow Slip Events (SSE) with raised-cosine templates
|
|
45
|
+
- Earthquake co-seismic offsets and postseismic relaxation
|
|
46
|
+
- **Advanced multi-tier postseismic filtering** (magnitude, amplitude, sign consistency, statistical tests)
|
|
47
|
+
- Event-type support (earthquakes vs. antenna changes)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Features
|
|
52
|
+
|
|
53
|
+
### Core Capabilities
|
|
54
|
+
- **Flexible design matrix construction** with polynomial trends, seasonal terms, and transient events
|
|
55
|
+
- **Automated postseismic selection** using magnitude thresholds, step amplitude filters, sign consistency checks, and AIC/BIC/F-test criteria
|
|
56
|
+
- **Event-type discrimination**: Distinguish between earthquakes (with postseismic) and equipment changes (step only)
|
|
57
|
+
- **Uncertainty quantification** with covariance matrices, confidence intervals, and VIF-based multicollinearity detection
|
|
58
|
+
- **Multiple fitting strategies**: OLS, LASSO, ElasticNet, iterative outlier removal
|
|
59
|
+
|
|
60
|
+
### Advanced Postseismic Filtering
|
|
61
|
+
|
|
62
|
+
trajmod implements a **4-tier filtering system** to prevent overfitting:
|
|
63
|
+
|
|
64
|
+
1. **Magnitude threshold**: Only earthquakes ≥ M6.5 (configurable) are considered
|
|
65
|
+
2. **Step amplitude threshold**: Only events with |step| ≥ 2mm (configurable) get postseismic
|
|
66
|
+
3. **Sign consistency**: Postseismic decay must have the same sign as co-seismic step
|
|
67
|
+
4. **Statistical significance**: ΔAIC < -2 (or BIC/F-test) required to include postseismic
|
|
68
|
+
|
|
69
|
+
This ensures physically meaningful postseismic signals are retained while suppressing noise fitting.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
### From source:
|
|
76
|
+
```bash
|
|
77
|
+
pip install trajmod
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Requirements:
|
|
81
|
+
- Python ≥ 3.9
|
|
82
|
+
- numpy ≥ 1.20
|
|
83
|
+
- scipy ≥ 1.7
|
|
84
|
+
- matplotlib ≥ 3.3
|
|
85
|
+
- scikit-learn ≥ 1.0
|
|
86
|
+
- pyproj ≥ 3.0
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Quick Start
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import numpy as np
|
|
94
|
+
from datetime import datetime, timedelta
|
|
95
|
+
from trajmod.model import TrajectoryModel
|
|
96
|
+
from trajmod.config import ModelConfig
|
|
97
|
+
|
|
98
|
+
# Generate synthetic data
|
|
99
|
+
t0 = datetime(2020, 1, 1)
|
|
100
|
+
times = np.array([t0 + timedelta(days=i) for i in range(365)])
|
|
101
|
+
data = np.random.randn(365) * 2.0 # 2mm noise
|
|
102
|
+
errors = np.ones(365) * 2.0
|
|
103
|
+
|
|
104
|
+
# Define earthquake catalog
|
|
105
|
+
eq_catalog = [
|
|
106
|
+
{
|
|
107
|
+
'date': datetime(2020, 3, 15),
|
|
108
|
+
'lat': 40.0,
|
|
109
|
+
'lon': -120.0,
|
|
110
|
+
'magnitude': 7.2
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
'date': datetime(2020, 8, 1),
|
|
114
|
+
'event_type': 'antenna_change' # No postseismic for equipment changes
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
# Configure model with multi-tier postseismic filtering
|
|
119
|
+
config = ModelConfig(
|
|
120
|
+
d_param=1.0, # Spatial filtering
|
|
121
|
+
include_seasonal=True, # Annual + semi-annual
|
|
122
|
+
postseismic_mag_threshold=6.5, # Tier 1: Magnitude filter
|
|
123
|
+
postseismic_min_step_amplitude=2.0, # Tier 2: Step amplitude filter
|
|
124
|
+
enforce_postseismic_sign_consistency=True, # Tier 3: Sign check
|
|
125
|
+
postseismic_selection_criterion='aic', # Tier 4: Statistical test
|
|
126
|
+
postseismic_selection_threshold=-2.0, # ΔAIC < -2 required
|
|
127
|
+
tau_grid=[7, 14, 30, 60, 90, 180, 1800] # Optimize τ per event
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Create and fit model
|
|
131
|
+
model = TrajectoryModel(
|
|
132
|
+
t=times,
|
|
133
|
+
y=data,
|
|
134
|
+
sigma_y=errors,
|
|
135
|
+
station_lat=40.0,
|
|
136
|
+
station_lon=-120.0,
|
|
137
|
+
eq_catalog=eq_catalog,
|
|
138
|
+
config=config
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# Build design matrix (applies multi-tier filtering)
|
|
142
|
+
model.build_design_matrix()
|
|
143
|
+
|
|
144
|
+
# Fit model
|
|
145
|
+
results = model.fit(compute_uncertainty=True)
|
|
146
|
+
|
|
147
|
+
# Inspect results
|
|
148
|
+
print(f"RMS: {results.rms:.3f} mm")
|
|
149
|
+
print(f"Coefficients: {results.coeffs}")
|
|
150
|
+
print(f"Template names: {results.template_names}")
|
|
151
|
+
|
|
152
|
+
# Get uncertainty estimates
|
|
153
|
+
print(f"Standard errors: {results.uncertainty['standard_errors']}")
|
|
154
|
+
|
|
155
|
+
# Predict at new times
|
|
156
|
+
future_times = np.array([t0 + timedelta(days=i) for i in range(365, 730)])
|
|
157
|
+
predictions = model.predict(future_times)
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Configuration Options
|
|
163
|
+
|
|
164
|
+
### ModelConfig Parameters
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
ModelConfig(
|
|
168
|
+
# Spatial filtering
|
|
169
|
+
d_param=1.0, # Empirical scaling in radius law (None = no filtering)
|
|
170
|
+
|
|
171
|
+
# Baseline model
|
|
172
|
+
include_seasonal=True, # Annual + semi-annual terms
|
|
173
|
+
acceleration_term=True, # Quadratic trend
|
|
174
|
+
|
|
175
|
+
# Postseismic filtering (4 tiers)
|
|
176
|
+
fit_postseismic_decay=True, # Enable postseismic templates
|
|
177
|
+
postseismic_mag_threshold=6.5, # Tier 1: Min magnitude for postseismic
|
|
178
|
+
postseismic_min_step_amplitude=2.0, # Tier 2: Min step amplitude (mm)
|
|
179
|
+
enforce_postseismic_sign_consistency=True, # Tier 3: Post must match step sign
|
|
180
|
+
postseismic_selection_criterion='aic', # Tier 4: 'aic', 'bic', 'ftest', 'always'
|
|
181
|
+
postseismic_selection_threshold=-2.0, # ΔAIC/ΔBIC threshold (or p-value for F-test)
|
|
182
|
+
fit_best_postseismic_tau=True, # Optimize τ per event from tau_grid
|
|
183
|
+
tau_grid=[7, 14, 30, 60, 90, 180, 1800], # Candidate τ values (days)
|
|
184
|
+
|
|
185
|
+
# Event merging
|
|
186
|
+
merge_earthquakes_same_day=False, # Merge EQs on same day
|
|
187
|
+
merge_close_sse=False, # Merge temporally close SSEs
|
|
188
|
+
gap_merge_threshold=5 # Days threshold for merging
|
|
189
|
+
)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Event-Type Support
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
eq_catalog = [
|
|
196
|
+
# Regular earthquake → gets step + postseismic (if passes filters)
|
|
197
|
+
{'date': datetime(2020, 3, 1), 'lat': 40.0, 'lon': -120.0, 'magnitude': 7.2},
|
|
198
|
+
|
|
199
|
+
# Antenna change → gets step only, NO postseismic
|
|
200
|
+
{'date': datetime(2020, 8, 15), 'event_type': 'antenna_change'},
|
|
201
|
+
|
|
202
|
+
# Equipment change → gets step only
|
|
203
|
+
{'date': datetime(2021, 2, 10), 'event_type': 'equipment_change'},
|
|
204
|
+
]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Supported event types:
|
|
208
|
+
- `'earthquake'` (default): Co-seismic step + postseismic (if passes filters)
|
|
209
|
+
- `'antenna_change'`: Step only, no postseismic
|
|
210
|
+
- `'equipment_change'`: Step only, no postseismic
|
|
211
|
+
- `'monument_change'`: Step only, no postseismic
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Example Log Output
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
INFO: Initialized model: 1095 time points, 0 SSEs, 3 EQs
|
|
219
|
+
INFO: Baseline design matrix: 1095 × 28
|
|
220
|
+
INFO: Baseline SSR: 1245.67
|
|
221
|
+
INFO: EQ 1 (antenna_change): event type excludes postseismic → SKIPPED
|
|
222
|
+
INFO: Filtered to 2/3 candidate EQs (criterion: aic)
|
|
223
|
+
INFO: EQ 0 (M7.2, step=8.5mm): τ=90d, ΔAIC=-15.3 → KEPT
|
|
224
|
+
INFO: EQ 2 (M6.8, step=4.1mm): τ=60d, ΔAIC=-8.2 → KEPT
|
|
225
|
+
INFO: Final design matrix: 1095 × 30 (2/2 postseismic)
|
|
226
|
+
INFO: Fit complete: RMS = 1.854 mm
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Advanced Usage
|
|
232
|
+
|
|
233
|
+
### Custom fitting strategies
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
from trajmod.strategies.fitting import LassoFitter, IterativeRefinementFitter
|
|
237
|
+
|
|
238
|
+
# LASSO with automatic regularization
|
|
239
|
+
lasso_fitter = LassoFitter(cv=5, positive=False)
|
|
240
|
+
results = model.fit(method=lasso_fitter)
|
|
241
|
+
|
|
242
|
+
# Iterative outlier removal
|
|
243
|
+
robust_fitter = IterativeRefinementFitter(max_iterations=10, threshold=3.0)
|
|
244
|
+
results = model.fit(method=robust_fitter)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Event selection/filtering
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
from trajmod.events.event_selection import KneeEventSelector
|
|
251
|
+
|
|
252
|
+
# Automatic SSE selection using knee detection
|
|
253
|
+
selector = KneeEventSelector(
|
|
254
|
+
criterion='bic',
|
|
255
|
+
method='knee',
|
|
256
|
+
smooth_curve=True,
|
|
257
|
+
min_amplitude=1.0 # Minimum 1mm amplitude
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
selected_indices = model.select_events(
|
|
261
|
+
selector=selector,
|
|
262
|
+
event_type='sse',
|
|
263
|
+
plot=True,
|
|
264
|
+
save_plot='sse_selection.png'
|
|
265
|
+
)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Visualization
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from trajmod.visualization import plot_trajectory_decomposition
|
|
272
|
+
|
|
273
|
+
# Plot data with model components
|
|
274
|
+
plot_trajectory_decomposition(
|
|
275
|
+
model,
|
|
276
|
+
results,
|
|
277
|
+
save_path='trajectory_fit.png',
|
|
278
|
+
show_residuals=True,
|
|
279
|
+
show_components=True
|
|
280
|
+
)
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## API Reference
|
|
286
|
+
|
|
287
|
+
### Core Classes
|
|
288
|
+
|
|
289
|
+
- **`TrajectoryModel`**: Main model class
|
|
290
|
+
- `build_design_matrix()`: Construct design matrix with multi-tier filtering
|
|
291
|
+
- `fit()`: Fit model with OLS or custom strategy
|
|
292
|
+
- `predict()`: Predict at new time points
|
|
293
|
+
- `select_events()`: Automatic event selection
|
|
294
|
+
|
|
295
|
+
- **`ModelConfig`**: Configuration dataclass
|
|
296
|
+
- All model parameters with validation
|
|
297
|
+
|
|
298
|
+
- **`ModelResults`**: Results container
|
|
299
|
+
- Coefficients, fitted values, residuals, uncertainties
|
|
300
|
+
|
|
301
|
+
### Template Functions
|
|
302
|
+
|
|
303
|
+
- **`TemplateFunctions`**: Basis functions
|
|
304
|
+
- `offset()`, `trend()`, `acceleration()`
|
|
305
|
+
- `seasonal_sin()`, `seasonal_cos()`
|
|
306
|
+
- `step()`: Heaviside step for earthquakes
|
|
307
|
+
- `log_decay()`: Logarithmic postseismic decay
|
|
308
|
+
- `raised_cosine()`: SSE template
|
|
309
|
+
|
|
310
|
+
### Fitting Strategies
|
|
311
|
+
|
|
312
|
+
- **`OLSFitter`**: Ordinary least squares
|
|
313
|
+
- **`LassoFitter`**: LASSO with CV
|
|
314
|
+
- **`ElasticNetFitter`**: ElasticNet with CV
|
|
315
|
+
- **`IterativeRefinementFitter`**: Robust fitting with outlier removal
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Testing
|
|
320
|
+
|
|
321
|
+
Run tests with:
|
|
322
|
+
```bash
|
|
323
|
+
pytest tests/
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Run with coverage:
|
|
327
|
+
```bash
|
|
328
|
+
pytest --cov=trajmod tests/
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## Citation
|
|
334
|
+
|
|
335
|
+
If you use this code in your research, please cite:
|
|
336
|
+
|
|
337
|
+
```bibtex
|
|
338
|
+
@software{trajmod2026,
|
|
339
|
+
author = {Costantino, Giuseppe},
|
|
340
|
+
title = {trajmod: Simple GNSS Trajectory Modeling},
|
|
341
|
+
year = {2026},
|
|
342
|
+
url = {https://github.com/gcostantino/trajmod}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## License
|
|
349
|
+
|
|
350
|
+
MIT License - see LICENSE file for details.
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## Contributing
|
|
355
|
+
|
|
356
|
+
Contributions are welcome! Please:
|
|
357
|
+
1. Fork the repository
|
|
358
|
+
2. Create a feature branch
|
|
359
|
+
3. Add tests for new features
|
|
360
|
+
4. Run `black` formatter and `flake8` linter
|
|
361
|
+
5. Submit a pull request
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Acknowledgments
|
|
366
|
+
|
|
367
|
+
This package implements trajectory modeling techniques commonly used in GNSS geodesy, with particular focus on:
|
|
368
|
+
- Multi-tier postseismic filtering to prevent overfitting
|
|
369
|
+
- Event-type discrimination for equipment changes
|
|
370
|
+
- Automated model selection with information criteria
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Contact
|
|
375
|
+
|
|
376
|
+
Giuseppe Costantino - [giuseppe.costantino@ens.fr]
|
|
377
|
+
|
|
378
|
+
Project Link: [https://github.com/gcostantino/trajmod](https://github.com/gcostantino/trajmod)
|