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.
Files changed (37) hide show
  1. trajmod-0.1.0/CITATION.cff +22 -0
  2. trajmod-0.1.0/LICENSE +21 -0
  3. trajmod-0.1.0/MANIFEST.in +19 -0
  4. trajmod-0.1.0/PKG-INFO +378 -0
  5. trajmod-0.1.0/README.md +341 -0
  6. trajmod-0.1.0/pyproject.toml +60 -0
  7. trajmod-0.1.0/requirements.txt +13 -0
  8. trajmod-0.1.0/setup.cfg +4 -0
  9. trajmod-0.1.0/src/trajmod/__init__.py +21 -0
  10. trajmod-0.1.0/src/trajmod/config/__init__.py +5 -0
  11. trajmod-0.1.0/src/trajmod/config/modelconfig.py +79 -0
  12. trajmod-0.1.0/src/trajmod/design/__init__.py +2 -0
  13. trajmod-0.1.0/src/trajmod/design/matrix.py +99 -0
  14. trajmod-0.1.0/src/trajmod/events/__init__.py +15 -0
  15. trajmod-0.1.0/src/trajmod/events/amplitude_threshold_selector.py +149 -0
  16. trajmod-0.1.0/src/trajmod/events/event_selection.py +574 -0
  17. trajmod-0.1.0/src/trajmod/events/events.py +170 -0
  18. trajmod-0.1.0/src/trajmod/example.py +198 -0
  19. trajmod-0.1.0/src/trajmod/model/__init__.py +6 -0
  20. trajmod-0.1.0/src/trajmod/model/model.py +1014 -0
  21. trajmod-0.1.0/src/trajmod/model/model_selection.py +274 -0
  22. trajmod-0.1.0/src/trajmod/model/results.py +63 -0
  23. trajmod-0.1.0/src/trajmod/model/uncertainty_quantification.py +266 -0
  24. trajmod-0.1.0/src/trajmod/preprocessing/__init__.py +4 -0
  25. trajmod-0.1.0/src/trajmod/preprocessing/geodetic_utils.py +63 -0
  26. trajmod-0.1.0/src/trajmod/preprocessing/preprocessing.py +65 -0
  27. trajmod-0.1.0/src/trajmod/preprocessing/time_utils.py +95 -0
  28. trajmod-0.1.0/src/trajmod/strategies/__init__.py +17 -0
  29. trajmod-0.1.0/src/trajmod/strategies/fitting.py +99 -0
  30. trajmod-0.1.0/src/trajmod/templates/__init__.py +5 -0
  31. trajmod-0.1.0/src/trajmod/templates/templates.py +124 -0
  32. trajmod-0.1.0/src/trajmod/visualization.py +309 -0
  33. trajmod-0.1.0/src/trajmod.egg-info/PKG-INFO +378 -0
  34. trajmod-0.1.0/src/trajmod.egg-info/SOURCES.txt +35 -0
  35. trajmod-0.1.0/src/trajmod.egg-info/dependency_links.txt +1 -0
  36. trajmod-0.1.0/src/trajmod.egg-info/requires.txt +12 -0
  37. 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)