dopplergeist 0.1.1__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 (225) hide show
  1. dopplergeist-0.1.1/LICENSE +75 -0
  2. dopplergeist-0.1.1/MANIFEST.in +1 -0
  3. dopplergeist-0.1.1/PKG-INFO +105 -0
  4. dopplergeist-0.1.1/README.md +202 -0
  5. dopplergeist-0.1.1/docs/PYPI_README.md +64 -0
  6. dopplergeist-0.1.1/licenses/MIT-legacy.txt +21 -0
  7. dopplergeist-0.1.1/pyproject.toml +54 -0
  8. dopplergeist-0.1.1/setup.cfg +4 -0
  9. dopplergeist-0.1.1/setup.py +40 -0
  10. dopplergeist-0.1.1/src/dopplergeist/__init__.py +1 -0
  11. dopplergeist-0.1.1/src/dopplergeist/_native_acoustic.c +255 -0
  12. dopplergeist-0.1.1/src/dopplergeist/_native_cpa.c +184 -0
  13. dopplergeist-0.1.1/src/dopplergeist/_native_index.c +105 -0
  14. dopplergeist-0.1.1/src/dopplergeist/_native_ridge.c +632 -0
  15. dopplergeist-0.1.1/src/dopplergeist/acoustic_screen.py +200 -0
  16. dopplergeist-0.1.1/src/dopplergeist/audio.py +173 -0
  17. dopplergeist-0.1.1/src/dopplergeist/automatic.py +750 -0
  18. dopplergeist-0.1.1/src/dopplergeist/batch_ridge.py +344 -0
  19. dopplergeist-0.1.1/src/dopplergeist/checkpoint_resume.py +255 -0
  20. dopplergeist-0.1.1/src/dopplergeist/cli.py +378 -0
  21. dopplergeist-0.1.1/src/dopplergeist/coherent_discovery.py +67 -0
  22. dopplergeist-0.1.1/src/dopplergeist/confidence.py +491 -0
  23. dopplergeist-0.1.1/src/dopplergeist/contracts.py +348 -0
  24. dopplergeist-0.1.1/src/dopplergeist/data_access.py +1351 -0
  25. dopplergeist-0.1.1/src/dopplergeist/discovery.py +399 -0
  26. dopplergeist-0.1.1/src/dopplergeist/enf.py +105 -0
  27. dopplergeist-0.1.1/src/dopplergeist/episode_discovery.py +497 -0
  28. dopplergeist-0.1.1/src/dopplergeist/episodes.py +379 -0
  29. dopplergeist-0.1.1/src/dopplergeist/evaluation.py +169 -0
  30. dopplergeist-0.1.1/src/dopplergeist/finite_search.py +325 -0
  31. dopplergeist-0.1.1/src/dopplergeist/flight_payload.py +197 -0
  32. dopplergeist-0.1.1/src/dopplergeist/flight_selection.py +42 -0
  33. dopplergeist-0.1.1/src/dopplergeist/geography.py +289 -0
  34. dopplergeist-0.1.1/src/dopplergeist/geometry.py +512 -0
  35. dopplergeist-0.1.1/src/dopplergeist/guidance.py +158 -0
  36. dopplergeist-0.1.1/src/dopplergeist/index_compatibility.py +93 -0
  37. dopplergeist-0.1.1/src/dopplergeist/intake.py +198 -0
  38. dopplergeist-0.1.1/src/dopplergeist/jobs.py +383 -0
  39. dopplergeist-0.1.1/src/dopplergeist/matching.py +1080 -0
  40. dopplergeist-0.1.1/src/dopplergeist/native_acoustic.py +68 -0
  41. dopplergeist-0.1.1/src/dopplergeist/native_cpa.py +52 -0
  42. dopplergeist-0.1.1/src/dopplergeist/parallel_retention.py +91 -0
  43. dopplergeist-0.1.1/src/dopplergeist/parallel_tiles.py +322 -0
  44. dopplergeist-0.1.1/src/dopplergeist/pipeline.py +416 -0
  45. dopplergeist-0.1.1/src/dopplergeist/provenance.py +142 -0
  46. dopplergeist-0.1.1/src/dopplergeist/resource_usage.py +23 -0
  47. dopplergeist-0.1.1/src/dopplergeist/ridge_overlap.py +53 -0
  48. dopplergeist-0.1.1/src/dopplergeist/scoring_inputs.py +198 -0
  49. dopplergeist-0.1.1/src/dopplergeist/search.py +1100 -0
  50. dopplergeist-0.1.1/src/dopplergeist/service.py +147 -0
  51. dopplergeist-0.1.1/src/dopplergeist/spectral_grid.py +41 -0
  52. dopplergeist-0.1.1/src/dopplergeist/spectral_matching.py +326 -0
  53. dopplergeist-0.1.1/src/dopplergeist/terrain.py +299 -0
  54. dopplergeist-0.1.1/src/dopplergeist/tiled_search.py +1486 -0
  55. dopplergeist-0.1.1/src/dopplergeist/tracks.py +161 -0
  56. dopplergeist-0.1.1/src/dopplergeist/trial_prefix.py +228 -0
  57. dopplergeist-0.1.1/src/dopplergeist/web/__init__.py +1 -0
  58. dopplergeist-0.1.1/src/dopplergeist/web/app.js +475 -0
  59. dopplergeist-0.1.1/src/dopplergeist/web/index.html +37 -0
  60. dopplergeist-0.1.1/src/dopplergeist/web/leaflet-license.txt +26 -0
  61. dopplergeist-0.1.1/src/dopplergeist/web/leaflet.css +661 -0
  62. dopplergeist-0.1.1/src/dopplergeist/web/leaflet.js +6 -0
  63. dopplergeist-0.1.1/src/dopplergeist/web/style.css +13 -0
  64. dopplergeist-0.1.1/src/dopplergeist.egg-info/PKG-INFO +105 -0
  65. dopplergeist-0.1.1/src/dopplergeist.egg-info/SOURCES.txt +223 -0
  66. dopplergeist-0.1.1/src/dopplergeist.egg-info/dependency_links.txt +1 -0
  67. dopplergeist-0.1.1/src/dopplergeist.egg-info/entry_points.txt +2 -0
  68. dopplergeist-0.1.1/src/dopplergeist.egg-info/requires.txt +13 -0
  69. dopplergeist-0.1.1/src/dopplergeist.egg-info/top_level.txt +1 -0
  70. dopplergeist-0.1.1/tests/test_all_events.py +161 -0
  71. dopplergeist-0.1.1/tests/test_artifact_restore.py +60 -0
  72. dopplergeist-0.1.1/tests/test_association.py +83 -0
  73. dopplergeist-0.1.1/tests/test_audio.py +24 -0
  74. dopplergeist-0.1.1/tests/test_automatic.py +273 -0
  75. dopplergeist-0.1.1/tests/test_automatic_finite.py +97 -0
  76. dopplergeist-0.1.1/tests/test_automatic_profile.py +135 -0
  77. dopplergeist-0.1.1/tests/test_automatic_support.py +38 -0
  78. dopplergeist-0.1.1/tests/test_benchmark_timing.py +28 -0
  79. dopplergeist-0.1.1/tests/test_bounded_model_coverage.py +138 -0
  80. dopplergeist-0.1.1/tests/test_camera_capture.py +111 -0
  81. dopplergeist-0.1.1/tests/test_checkpoint_restore.py +109 -0
  82. dopplergeist-0.1.1/tests/test_ci_checkpoint_replay.py +219 -0
  83. dopplergeist-0.1.1/tests/test_cli_arguments.py +38 -0
  84. dopplergeist-0.1.1/tests/test_cli_input_errors.py +79 -0
  85. dopplergeist-0.1.1/tests/test_cli_regional_bounds.py +24 -0
  86. dopplergeist-0.1.1/tests/test_confidence.py +292 -0
  87. dopplergeist-0.1.1/tests/test_container_publish_metadata.py +157 -0
  88. dopplergeist-0.1.1/tests/test_contracts.py +176 -0
  89. dopplergeist-0.1.1/tests/test_data_access.py +240 -0
  90. dopplergeist-0.1.1/tests/test_decision_invariants.py +138 -0
  91. dopplergeist-0.1.1/tests/test_discovery.py +135 -0
  92. dopplergeist-0.1.1/tests/test_evaluation.py +130 -0
  93. dopplergeist-0.1.1/tests/test_filters.py +39 -0
  94. dopplergeist-0.1.1/tests/test_finite_bridge_independent.py +107 -0
  95. dopplergeist-0.1.1/tests/test_finite_evidence_independent.py +121 -0
  96. dopplergeist-0.1.1/tests/test_finite_search.py +119 -0
  97. dopplergeist-0.1.1/tests/test_geography_profiles.py +21 -0
  98. dopplergeist-0.1.1/tests/test_index_geometry_invariants.py +111 -0
  99. dopplergeist-0.1.1/tests/test_ingest_adsblol_day.py +70 -0
  100. dopplergeist-0.1.1/tests/test_intake.py +153 -0
  101. dopplergeist-0.1.1/tests/test_job_cancel_api_race.py +29 -0
  102. dopplergeist-0.1.1/tests/test_job_resume.py +71 -0
  103. dopplergeist-0.1.1/tests/test_local_cancel.py +276 -0
  104. dopplergeist-0.1.1/tests/test_locked_scoring.py +30 -0
  105. dopplergeist-0.1.1/tests/test_map_region.py +69 -0
  106. dopplergeist-0.1.1/tests/test_matching.py +288 -0
  107. dopplergeist-0.1.1/tests/test_methodology_verifier.py +37 -0
  108. dopplergeist-0.1.1/tests/test_missing_velocity.py +180 -0
  109. dopplergeist-0.1.1/tests/test_motion_support.py +148 -0
  110. dopplergeist-0.1.1/tests/test_mp3_smoke.py +23 -0
  111. dopplergeist-0.1.1/tests/test_multi_event_renderer.py +35 -0
  112. dopplergeist-0.1.1/tests/test_physics.py +79 -0
  113. dopplergeist-0.1.1/tests/test_pipeline_replay.py +79 -0
  114. dopplergeist-0.1.1/tests/test_process_peak_rss.py +30 -0
  115. dopplergeist-0.1.1/tests/test_provenance.py +168 -0
  116. dopplergeist-0.1.1/tests/test_real_acoustic_batch_cache.py +108 -0
  117. dopplergeist-0.1.1/tests/test_real_acoustic_screen.py +145 -0
  118. dopplergeist-0.1.1/tests/test_real_acoustic_screen_cache.py +209 -0
  119. dopplergeist-0.1.1/tests/test_real_acquisition_bounds.py +38 -0
  120. dopplergeist-0.1.1/tests/test_real_adaptive_tiles.py +154 -0
  121. dopplergeist-0.1.1/tests/test_real_analyze_upload_limit.py +33 -0
  122. dopplergeist-0.1.1/tests/test_real_association_budget.py +80 -0
  123. dopplergeist-0.1.1/tests/test_real_association_clock_window.py +62 -0
  124. dopplergeist-0.1.1/tests/test_real_batch_ceilings.py +238 -0
  125. dopplergeist-0.1.1/tests/test_real_batch_ridge.py +108 -0
  126. dopplergeist-0.1.1/tests/test_real_batch_scalar_parity.py +114 -0
  127. dopplergeist-0.1.1/tests/test_real_candidate_setup.py +119 -0
  128. dopplergeist-0.1.1/tests/test_real_cb996dc_checkpoint.py +157 -0
  129. dopplergeist-0.1.1/tests/test_real_checkpoint_upgrade.py +115 -0
  130. dopplergeist-0.1.1/tests/test_real_cli_watch.py +88 -0
  131. dopplergeist-0.1.1/tests/test_real_clock_batch.py +91 -0
  132. dopplergeist-0.1.1/tests/test_real_clock_partitions.py +143 -0
  133. dopplergeist-0.1.1/tests/test_real_coherent_discovery.py +34 -0
  134. dopplergeist-0.1.1/tests/test_real_compact_checkpoints.py +63 -0
  135. dopplergeist-0.1.1/tests/test_real_complete_batch_cache.py +224 -0
  136. dopplergeist-0.1.1/tests/test_real_cpa_clock_neighborhood.py +89 -0
  137. dopplergeist-0.1.1/tests/test_real_cpa_edge.py +71 -0
  138. dopplergeist-0.1.1/tests/test_real_cpa_preparation.py +122 -0
  139. dopplergeist-0.1.1/tests/test_real_cpa_spatial_sieve.py +105 -0
  140. dopplergeist-0.1.1/tests/test_real_discovery_normalization.py +142 -0
  141. dopplergeist-0.1.1/tests/test_real_dual_provenance.py +75 -0
  142. dopplergeist-0.1.1/tests/test_real_early_unsupported_clock.py +111 -0
  143. dopplergeist-0.1.1/tests/test_real_empty_tile.py +41 -0
  144. dopplergeist-0.1.1/tests/test_real_empty_worker_retention.py +179 -0
  145. dopplergeist-0.1.1/tests/test_real_episode_artifact.py +122 -0
  146. dopplergeist-0.1.1/tests/test_real_episode_cli.py +81 -0
  147. dopplergeist-0.1.1/tests/test_real_episode_motion.py +36 -0
  148. dopplergeist-0.1.1/tests/test_real_explicit_terrain_workers.py +226 -0
  149. dopplergeist-0.1.1/tests/test_real_fine_resume.py +101 -0
  150. dopplergeist-0.1.1/tests/test_real_fixed_clock_filter.py +49 -0
  151. dopplergeist-0.1.1/tests/test_real_fixed_clock_pair_screen.py +66 -0
  152. dopplergeist-0.1.1/tests/test_real_fixed_clock_single_trial.py +42 -0
  153. dopplergeist-0.1.1/tests/test_real_flight_payload.py +126 -0
  154. dopplergeist-0.1.1/tests/test_real_flight_selection.py +132 -0
  155. dopplergeist-0.1.1/tests/test_real_geometry_kinematics.py +149 -0
  156. dopplergeist-0.1.1/tests/test_real_harmonic_ambiguity.py +53 -0
  157. dopplergeist-0.1.1/tests/test_real_index_columns.py +92 -0
  158. dopplergeist-0.1.1/tests/test_real_index_hash_cache.py +132 -0
  159. dopplergeist-0.1.1/tests/test_real_index_staging.py +20 -0
  160. dopplergeist-0.1.1/tests/test_real_legacy_batch_cache.py +28 -0
  161. dopplergeist-0.1.1/tests/test_real_metamorphic_runner.py +117 -0
  162. dopplergeist-0.1.1/tests/test_real_motion_interval_cpa.py +368 -0
  163. dopplergeist-0.1.1/tests/test_real_motion_support_batch.py +154 -0
  164. dopplergeist-0.1.1/tests/test_real_native_acoustic.py +192 -0
  165. dopplergeist-0.1.1/tests/test_real_native_acoustic_pipeline.py +92 -0
  166. dopplergeist-0.1.1/tests/test_real_native_convergence.py +67 -0
  167. dopplergeist-0.1.1/tests/test_real_native_cpa.py +185 -0
  168. dopplergeist-0.1.1/tests/test_real_native_index.py +165 -0
  169. dopplergeist-0.1.1/tests/test_real_native_prefix_integration.py +148 -0
  170. dopplergeist-0.1.1/tests/test_real_native_ridge.py +246 -0
  171. dopplergeist-0.1.1/tests/test_real_native_ridge_batch.py +152 -0
  172. dopplergeist-0.1.1/tests/test_real_native_ridge_long.py +72 -0
  173. dopplergeist-0.1.1/tests/test_real_native_validation.py +443 -0
  174. dopplergeist-0.1.1/tests/test_real_overloaded_distance_sieve.py +68 -0
  175. dopplergeist-0.1.1/tests/test_real_pair_fixed_clock.py +32 -0
  176. dopplergeist-0.1.1/tests/test_real_parallel_index.py +41 -0
  177. dopplergeist-0.1.1/tests/test_real_parallel_retention.py +363 -0
  178. dopplergeist-0.1.1/tests/test_real_parallel_terrain_adoption.py +42 -0
  179. dopplergeist-0.1.1/tests/test_real_partition_query.py +187 -0
  180. dopplergeist-0.1.1/tests/test_real_performance_helpers.py +145 -0
  181. dopplergeist-0.1.1/tests/test_real_prepared_compatibility.py +33 -0
  182. dopplergeist-0.1.1/tests/test_real_prepared_geometry_compatibility.py +71 -0
  183. dopplergeist-0.1.1/tests/test_real_prepared_index.py +304 -0
  184. dopplergeist-0.1.1/tests/test_real_prepared_measurements.py +105 -0
  185. dopplergeist-0.1.1/tests/test_real_refinement_lookup.py +116 -0
  186. dopplergeist-0.1.1/tests/test_real_refinement_reuse.py +248 -0
  187. dopplergeist-0.1.1/tests/test_real_retention_batch.py +167 -0
  188. dopplergeist-0.1.1/tests/test_real_retention_floor.py +30 -0
  189. dopplergeist-0.1.1/tests/test_real_retention_index.py +67 -0
  190. dopplergeist-0.1.1/tests/test_real_retention_lock.py +49 -0
  191. dopplergeist-0.1.1/tests/test_real_ridge_backend.py +68 -0
  192. dopplergeist-0.1.1/tests/test_real_scalar_terrain.py +143 -0
  193. dopplergeist-0.1.1/tests/test_real_score_ceiling_validation.py +110 -0
  194. dopplergeist-0.1.1/tests/test_real_scoring_inputs.py +268 -0
  195. dopplergeist-0.1.1/tests/test_real_search_workers.py +39 -0
  196. dopplergeist-0.1.1/tests/test_real_shared_ridge_scoring.py +233 -0
  197. dopplergeist-0.1.1/tests/test_real_single_pass_sieve.py +144 -0
  198. dopplergeist-0.1.1/tests/test_real_terrain_cache_hits.py +64 -0
  199. dopplergeist-0.1.1/tests/test_real_terrain_resume_hash.py +79 -0
  200. dopplergeist-0.1.1/tests/test_real_terrain_tile_seams.py +54 -0
  201. dopplergeist-0.1.1/tests/test_real_tiled_cpa_edge.py +64 -0
  202. dopplergeist-0.1.1/tests/test_real_track_cache.py +230 -0
  203. dopplergeist-0.1.1/tests/test_real_trial_prefix.py +337 -0
  204. dopplergeist-0.1.1/tests/test_real_trial_vectors.py +162 -0
  205. dopplergeist-0.1.1/tests/test_real_unsupported_clock.py +140 -0
  206. dopplergeist-0.1.1/tests/test_real_unsupported_distance.py +56 -0
  207. dopplergeist-0.1.1/tests/test_real_upload_terminal_controls.py +66 -0
  208. dopplergeist-0.1.1/tests/test_real_upload_verification.py +55 -0
  209. dopplergeist-0.1.1/tests/test_real_whole_track_sieve.py +51 -0
  210. dopplergeist-0.1.1/tests/test_refinement_geographic_bounds.py +36 -0
  211. dopplergeist-0.1.1/tests/test_ridge_fit_cache.py +188 -0
  212. dopplergeist-0.1.1/tests/test_scoring_assessment.py +92 -0
  213. dopplergeist-0.1.1/tests/test_scoring_chunk_validation.py +17 -0
  214. dopplergeist-0.1.1/tests/test_scoring_workers.py +92 -0
  215. dopplergeist-0.1.1/tests/test_search_invariants.py +92 -0
  216. dopplergeist-0.1.1/tests/test_service.py +142 -0
  217. dopplergeist-0.1.1/tests/test_terrain.py +21 -0
  218. dopplergeist-0.1.1/tests/test_tile_worker_affinity.py +115 -0
  219. dopplergeist-0.1.1/tests/test_tiled_search.py +349 -0
  220. dopplergeist-0.1.1/tests/test_tiled_support.py +203 -0
  221. dopplergeist-0.1.1/tests/test_trajectory_motion_audit.py +87 -0
  222. dopplergeist-0.1.1/tests/test_unknown_score_bounds.py +167 -0
  223. dopplergeist-0.1.1/tests/test_upload_concurrency.py +116 -0
  224. dopplergeist-0.1.1/tests/test_verify_bounded_search.py +207 -0
  225. dopplergeist-0.1.1/tests/test_verify_upload_http.py +983 -0
@@ -0,0 +1,75 @@
1
+ # PolyForm Noncommercial License 1.0.0
2
+
3
+ <https://polyformproject.org/licenses/noncommercial/1.0.0>
4
+
5
+ Required Notice: Copyright 2026 Cinna Davis
6
+
7
+ ## Acceptance
8
+
9
+ In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
10
+
11
+ ## Copyright License
12
+
13
+ The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
14
+
15
+ ## Distribution License
16
+
17
+ The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
18
+
19
+ ## Notices
20
+
21
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
22
+
23
+ > Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
24
+
25
+ ## Changes and New Works License
26
+
27
+ The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
28
+
29
+ ## Patent License
30
+
31
+ The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
32
+
33
+ ## Noncommercial Purposes
34
+
35
+ Any noncommercial purpose is a permitted purpose.
36
+
37
+ ## Personal Uses
38
+
39
+ Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
40
+
41
+ ## Noncommercial Organizations
42
+
43
+ Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
44
+
45
+ ## Fair Use
46
+
47
+ You may have "fair use" rights for the software under the law. These terms do not limit them.
48
+
49
+ ## No Other Rights
50
+
51
+ These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
52
+
53
+ ## Patent Defense
54
+
55
+ If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
56
+
57
+ ## Violations
58
+
59
+ The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
60
+
61
+ ## No Liability
62
+
63
+ ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
64
+
65
+ ## Definitions
66
+
67
+ The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
68
+
69
+ **You** refers to the individual or entity agreeing to these terms.
70
+
71
+ **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
72
+
73
+ **Your licenses** are all the licenses granted to you for the software under these terms.
74
+
75
+ **Use** means anything you do with the software requiring one of your licenses.
@@ -0,0 +1 @@
1
+ prune evidence
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.4
2
+ Name: dopplergeist
3
+ Version: 0.1.1
4
+ Summary: Aircraft Doppler audio geolocation using historical flight tracks
5
+ License-Expression: PolyForm-Noncommercial-1.0.0
6
+ Project-URL: Homepage, https://github.com/1337isnot1337/DOPPLERGEIST
7
+ Project-URL: Documentation, https://github.com/1337isnot1337/DOPPLERGEIST/tree/main/docs
8
+ Project-URL: Source, https://github.com/1337isnot1337/DOPPLERGEIST
9
+ Project-URL: Issues, https://github.com/1337isnot1337/DOPPLERGEIST/issues
10
+ Project-URL: Releases, https://github.com/1337isnot1337/DOPPLERGEIST/releases
11
+ Keywords: aircraft,doppler,acoustic-geolocation,audio-forensics,ads-b,signal-processing
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Programming Language :: Python :: Implementation :: CPython
21
+ Classifier: Topic :: Scientific/Engineering :: Physics
22
+ Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
23
+ Requires-Python: >=3.11
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ License-File: licenses/MIT-legacy.txt
27
+ License-File: src/dopplergeist/web/leaflet-license.txt
28
+ Requires-Dist: numpy
29
+ Requires-Dist: scipy
30
+ Requires-Dist: pandas
31
+ Requires-Dist: soundfile
32
+ Requires-Dist: pyproj
33
+ Requires-Dist: rasterio
34
+ Requires-Dist: matplotlib
35
+ Requires-Dist: requests
36
+ Requires-Dist: pyarrow
37
+ Requires-Dist: shapely>=2.0
38
+ Provides-Extra: test
39
+ Requires-Dist: pytest>=8; extra == "test"
40
+ Dynamic: license-file
41
+
42
+ # DOPPLERGEIST
43
+
44
+ ![DOPPLERGEIST — aircraft Doppler audio geolocation](https://raw.githubusercontent.com/1337isnot1337/DOPPLERGEIST/main/assets/dopplergeist-banner.svg)
45
+
46
+ **DOPPLERGEIST** is a Python CLI and local web application for aircraft Doppler audio geolocation. It detects candidate flyover signals in recordings, retrieves historical ADS-B flight tracks, models acoustic propagation, and ranks possible recording locations.
47
+
48
+ ![Automatic MP3 flyover analysis and ranked aircraft search](https://raw.githubusercontent.com/1337isnot1337/DOPPLERGEIST/main/assets/livermore-automatic-mp3.png)
49
+
50
+ The illustrated real-recording experiment ranked a location 476 m from an *inferred* reference within a constrained search. The reference was not surveyed ground truth; independent blind geolocation accuracy has not been established. [Read the experiment](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/LIVERMORE_DEMO.md).
51
+
52
+ ## Install
53
+
54
+ Requires **Python 3.11+**. Install **FFmpeg** separately so that both `ffmpeg` and `ffprobe` are on your `PATH`.
55
+
56
+ For the CLI:
57
+
58
+ ```sh
59
+ pipx install dopplergeist
60
+ dopplergeist --help
61
+ ```
62
+
63
+ For a Python environment:
64
+
65
+ ```sh
66
+ python -m pip install dopplergeist
67
+ ```
68
+
69
+ ## Use
70
+
71
+ Detect candidate acoustic events without flight-data downloads:
72
+
73
+ ```sh
74
+ dopplergeist discover recording.mp3 --output results/discovery
75
+ ```
76
+
77
+ Launch the locally hosted upload interface:
78
+
79
+ ```sh
80
+ dopplergeist serve --jobs jobs --online --port 8765
81
+ ```
82
+
83
+ Open `http://127.0.0.1:8765`. For historical flight matching, a **defensible UTC window for the first audio sample** is required; the recording upload timestamp is not sufficient. Geographic searches can consume substantial time, storage, and downloaded aircraft/terrain data.
84
+
85
+ For CLI analysis with an independently supported recording clock:
86
+
87
+ ```sh
88
+ dopplergeist analyze recording.mp3 --jobs jobs \
89
+ --start-utc "2026-01-01T00:00:00Z" \
90
+ --end-utc "2026-01-01T00:10:00Z" \
91
+ --time-source "replace with independently supported clock evidence" \
92
+ --online
93
+ ```
94
+
95
+ ## Documentation
96
+
97
+ - [Source code and full README](https://github.com/1337isnot1337/DOPPLERGEIST)
98
+ - [Installation and reproducibility](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/SETUP.md)
99
+ - [How the geolocation pipeline works](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/METHODOLOGY.md)
100
+ - [Validation and limitations](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/CONFIDENCE.md)
101
+ - [Issues and feature requests](https://github.com/1337isnot1337/DOPPLERGEIST/issues)
102
+
103
+ ## License
104
+
105
+ **PolyForm Noncommercial License 1.0.0.** Noncommercial uses are permitted under the terms of that license; commercial uses that are not otherwise authorized need a separate agreement with the applicable copyright holders. Earlier MIT-licensed releases retain the permissions originally granted for those versions. [Commercial licensing details](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/COMMERCIAL-LICENSING.md).
@@ -0,0 +1,202 @@
1
+
2
+ <h1 align="center">DOPPLERGEIST</h1>
3
+ <p align="center">Aircraft Doppler Audio Geolocation</p>
4
+ <p align="center">
5
+ <img src="assets/dopplergeist-banner.svg" alt="DOPPLERGEIST — Acoustic geolocation through Doppler analysis" width="100%">
6
+ </p>
7
+
8
+ **DOPPLERGEIST** is a source-available Python toolkit for aircraft Doppler audio geolocation. It detects acoustic flyover patterns in recordings, matches them against historical ADS-B flight trajectories, and ranks possible recording locations.
9
+
10
+ The project provides automatic audio discovery, aircraft-data acquisition, geographic search, and a locally hosted browser interface. It is built for acoustic geolocation research, audio forensics, and studying location information carried by background sound.
11
+
12
+ <h3 align="center">Example: automatic MP3 analysis</h3>
13
+
14
+ ![Automatic MP3 flyover and ranked aircraft search](assets/livermore-automatic-mp3.png)
15
+
16
+ <sub>A real MP3 was analyzed without manually supplied event windows, frequency bands, or flight IDs. DOPPLERGEIST selected 466 nearby aircraft from a historical flight archive and ranked 105 candidate locations. The leading candidate was **476 m from an inferred reference** in a city-sized search with an approximately 10-second recording-time window. The reference is not surveyed ground truth, and the run remained inconclusive. [View the full experiment and ranking.](docs/LIVERMORE_DEMO.md#all-aircraft-archive-mp3-ranking)</sub>
17
+
18
+ [Capabilities](#capabilities) · [Quickstart](#quickstart) · [How it works](#how-it-works) · [FAQ](#frequently-asked-questions) · [Results](#validation-and-results) · [Documentation](#documentation-and-references)
19
+
20
+ ## Is Colsto's airplane Doppler geolocation code available?
21
+
22
+ Colsto did not release the original tools or source code from his [aircraft Doppler geolocation demonstration](https://www.youtube.com/watch?v=UytYrhYLOKI).
23
+
24
+ **DOPPLERGEIST is an independent implementation**, inspired by the approach in that video. It contains independently written code and is not affiliated with Colsto. If you want to experiment with aircraft Doppler signatures and historical flight-track matching, you can install and run DOPPLERGEIST locally.
25
+
26
+ ## Capabilities
27
+
28
+ | Capability | What DOPPLERGEIST provides |
29
+ | --- | --- |
30
+ | **Automatic acoustic discovery** | Scans an entire recording for moving frequency tracks and groups related harmonics, without manually selecting event windows or frequency bands. |
31
+ | **Historical aircraft data** | Acquires and indexes ADSB.lol flight archives; caches reusable trajectory, terrain, and geoid inputs. |
32
+ | **Location search** | Compares predicted Doppler and sound-arrival patterns across candidate receiver locations, including evidence from multiple independent flyovers. |
33
+ | **Geographic profiles** | Search profiles for the contiguous United States, Germany, Spain, and metropolitan France (including Corsica), with optional user-provided regional bounds. |
34
+ | **Local browser application** | Recording uploads, persistent analysis jobs, inspectable results, progress monitoring, and supported resume/cancellation workflows. |
35
+ | **Research and reproducibility** | Configured measurement/replay commands, documented experiments, diagnostic artifacts, and decision rules for unresolved searches. |
36
+
37
+ The integrated application and command-line workflow are available on `main`. See [how it works](#how-it-works) and [validation and results](#validation-and-results) for the distinction between a ranked hypothesis and an accepted location.
38
+
39
+ ## Quickstart
40
+
41
+ **PyPI distribution:** Once the first PyPI release is published, install the CLI without cloning the repository:
42
+
43
+ ```bash
44
+ pipx install dopplergeist
45
+ dopplergeist --help
46
+ ```
47
+
48
+ To use the Python package in an existing environment instead, run `python -m pip install dopplergeist`. Install **FFmpeg** separately; `ffmpeg` and `ffprobe` must be available on `PATH`. See [PyPI release status and setup](docs/PYPI.md). The examples below use `.venv/bin/dopplergeist`; users of the `pipx` installation can run `dopplergeist` directly.
49
+
50
+ **Source checkout (available now):**
51
+
52
+ Requirements: **Python 3.11+**, **FFmpeg** (`ffmpeg` and `ffprobe` on `PATH`), and Git. These commands target Linux and macOS:
53
+
54
+ ```bash
55
+ git clone https://github.com/1337isnot1337/DOPPLERGEIST.git
56
+ cd DOPPLERGEIST
57
+ python -m venv .venv
58
+ .venv/bin/python -m pip install .
59
+ .venv/bin/dopplergeist --version
60
+ ```
61
+
62
+ A compatible C compiler enables optional native acceleration; Python fallbacks are available. For environment checks and alternative installation methods, see [Setup](docs/SETUP.md), [Performance](docs/PERFORMANCE.md), and [Docker](docs/DOCKER.md).
63
+
64
+ ### Option A: use the browser interface
65
+
66
+ ```bash
67
+ .venv/bin/dopplergeist serve --jobs jobs --online --max-runtime 14400 --port 8765
68
+ ```
69
+
70
+ Open **http://127.0.0.1:8765** and upload a recording. For historical flight matching, supply a supported UTC time window for the **first audio sample**. The interface runs locally; `--online` permits downloading public aircraft and terrain data.
71
+
72
+ ### Option B: analyze a recording from the CLI
73
+
74
+ ```bash
75
+ .venv/bin/dopplergeist analyze path/to/recording.mp3 --jobs jobs
76
+ ```
77
+
78
+ This creates a persistent job and runs acoustic analysis. To enable historical matching, provide `--start-utc`, `--end-utc`, and `--time-source` with the evidence for the recording clock, plus `--online` if the required data is not already configured locally. Without a defensible recording time, the job reports `needs_input` rather than assuming a date.
79
+
80
+ For a full online regional analysis, allow enough time for both historical-data acquisition and search. The job limit defaults to **one hour**; initial acquisition can take longer. Replace the sample clock window, source description, and Berlin bounds below with independent evidence for your recording, and increase `--max-runtime` if your data and search scope require it:
81
+
82
+ ```bash
83
+ .venv/bin/dopplergeist analyze path/to/recording.mp3 \
84
+ --start-utc "2026-01-01T00:00:00Z" \
85
+ --end-utc "2026-01-01T00:10:00Z" \
86
+ --time-source "replace with the source establishing the first-sample clock" \
87
+ --country DE --bounds 13.0 52.0 14.0 53.0 \
88
+ --online --max-runtime 21600
89
+ ```
90
+
91
+ To check progress after the job ID is printed:
92
+
93
+ ```bash
94
+ .venv/bin/dopplergeist job JOB_ID --jobs jobs --watch
95
+ ```
96
+
97
+ The progress percentage is stage-based and can remain unchanged during long tile subdivisions. Recent search-file activity is a liveness clue, not proof that the queue is shrinking or that a location was found.
98
+
99
+ The default country profile is `US` (contiguous United States); use `--country DE` for Germany, `--country ES` for Spain, or `--country FR` for metropolitan France including Corsica. Spain and France use broad geographic envelopes without country polygons, so add independently justified `--bounds WEST SOUTH EAST NORTH` for a regional search. The France profile excludes overseas territories. See [country profiles](docs/COUNTRIES.md) and the [local upload workflow](docs/PRODUCT.md) for request options, cancellation, resuming jobs, and upload limits.
100
+
101
+ **Data requirements:** Initial online acquisition may take hours and tens of gigabytes of disk space, depending on the recording time and search region. Downloads and caches are reusable; the application does not enforce an automatic disk-space cap.
102
+
103
+ ### Option C: discover acoustic events without flight data
104
+
105
+ ```bash
106
+ .venv/bin/dopplergeist discover \
107
+ path/to/recording.mp3 \
108
+ --output results/my-discovery
109
+ ```
110
+
111
+ This scans the full recording locally without downloading ADS-B archives. Inspect `results/my-discovery/summary.json` and the saved `discovery/` diagnostics. See [Automatic audio discovery](docs/AUDIO_DISCOVERY.md) for detector details and options.
112
+
113
+ For configured research workflows, `dopplergeist run` and `dopplergeist measure` remain available; see [Methodology](docs/METHODOLOGY.md).
114
+
115
+ ## How it works
116
+
117
+ 1. **Detect the signal.** Decode the recording, identify moving spectral tracks, and group harmonics that may belong to one flyover.
118
+ 2. **Prepare flight history.** Retrieve or load aircraft trajectories for the recording's supported time window, tracking gaps in available data.
119
+ 3. **Predict the audio.** Model Doppler shifts and sound-arrival delays from flight paths, receiver geometry, and acoustic propagation.
120
+ 4. **Rank locations.** Compare modeled and observed signals across geographic candidates and multiple flyovers; preserve alternative explanations when evidence is insufficient.
121
+
122
+ The software records diagnostic evidence and can return an inconclusive result rather than selecting an unsupported coordinate. The underlying models are described in [Methodology](docs/METHODOLOGY.md) and [Confidence and decision rules](docs/CONFIDENCE.md).
123
+
124
+ ## Frequently asked questions
125
+
126
+ ### Can I geolocate an MP3 recording?
127
+
128
+ DOPPLERGEIST accepts MP3 recordings and can automatically detect candidate aircraft Doppler events. With a justified recording-time window and appropriate flight data, it can search and rank possible recording locations. A successful location determination is not guaranteed.
129
+
130
+ ### Do I need to know when the recording was made?
131
+
132
+ **Yes, for historical flight matching.** The software needs a defensible UTC time or bounded time window for the first audio sample. Without that information, it can still analyze the sound, but geographic matching returns `needs_input`.
133
+
134
+ ### Can DOPPLERGEIST run offline?
135
+
136
+ **Yes, for acoustic discovery.** Location search also works with appropriately configured historical flight and terrain data already available locally. The `--online` flag allows the program to acquire missing public data.
137
+
138
+ ### How accurate is DOPPLERGEIST?
139
+
140
+ In a constrained real-MP3 demonstration, the highest-ranked location was **476 m from an inferred reference**, not a surveyed microphone position. Independent blind accuracy on real recordings has not yet been established. See [validation and results](#validation-and-results) for both successful fits and unsuccessful evaluations.
141
+
142
+ ### Can I upload an audio file in a browser?
143
+
144
+ **Yes.** Run `dopplergeist serve` after installation and open the local interface. It is a self-hosted application, not a public cloud upload service.
145
+
146
+ ### Is DOPPLERGEIST free and open source?
147
+
148
+ DOPPLERGEIST is **source-available, not OSI-approved open source**. It is licensed under [PolyForm Noncommercial 1.0.0](LICENSE), which permits use, modification, and distribution for permitted noncommercial purposes, subject to its terms. Commercial use outside those permissions requires separate authorization; see [Commercial licensing](COMMERCIAL-LICENSING.md).
149
+
150
+ ## Validation and results
151
+
152
+ DOPPLERGEIST has been exercised on synthetic fixtures, real aircraft recordings, historical flight tracks, and browser/API workflows. These experiments demonstrate components of the pipeline; **no independently accepted blind real-recording localization has yet been established**.
153
+
154
+ | Experiment | Observed result | How to interpret it |
155
+ | --- | --- | --- |
156
+ | **Automatic Livermore MP3, regional all-aircraft archive** | Selected and searched 466 nearby aircraft and returned 105 ranked locations; the first was **476 m from an inferred reference**. | Fully automatic event selection, but a constrained region and approximate 10-second clock window; the reference is not surveyed truth and the result was inconclusive. [Details](docs/LIVERMORE_DEMO.md#all-aircraft-archive-mp3-ranking). |
157
+ | **Configured two-flyover real-audio replay** | Leading location **43.86 m from a public reference**. | Used source-informed events and geographic bounds; the reference is not surveyed, and the model did not accept a location. [Clean replay](docs/verification/CLEAN_REPLAY.md). |
158
+ | **40 real smartphone aircraft recordings** | Automatic discovery produced candidate acoustic groups in **36 of 40** files. | These are acoustic proposals, not verified aircraft detections or geolocation successes. [Discovery results](docs/AUDIO_DISCOVERY.md). |
159
+ | **Five public field recordings** | Three returned rankings, with no retained candidate within 1 km of the publisher-reported sites; two returned no candidate. | Recorder clocks and exact microphone positions were not confirmed, so these are development outcomes rather than a calibrated accuracy benchmark. [Experiment](docs/PUBLIC_RECORDING_EXPERIMENT_2026-11-03.md). |
160
+ | **NASA and WSU measured-trajectory recordings** | Produced mixed detection results and no validated automatic location. | Original real-data tests, including unsuccessful cases. [Verification](docs/verification/WORKER_E2E_2026-11-03.md) and [NASA benchmark](benchmarks/README.md#real-nasa-supplied-trajectory-session-benchmark). |
161
+
162
+ Searches depend on acoustic evidence, reliable recording-time information, sufficient historical flight coverage, and physical-model support. A ranked score is not a calibrated location probability, and incomplete or competing hypotheses may lead to an **inconclusive** decision. Full experimental conditions, negative findings, and reproducibility records remain available in the linked reports.
163
+
164
+ ### Performance engineering
165
+
166
+ Optional native backends, reuse of acoustic calculations, and checkpointed search are implemented and measured. In one pinned bounded regional HTTP replay, optimizations reduced elapsed time from **62.03 seconds to 37.19 seconds (1.67×)** without changing the compared scientific outputs. This is a workload-specific result, not a general national-search runtime claim. See [measured performance and reproduction](docs/PERFORMANCE.md#measured-native-computation-and-bounded-reuse) and [data/search architecture](docs/DATA_AND_SCALE.md).
167
+
168
+ ## Documentation and references
169
+
170
+ - [Local upload workflow](docs/PRODUCT.md) — browser UI, API, job monitoring, limits, cancellation, and resume.
171
+ - [Methodology](docs/METHODOLOGY.md) — Doppler geometry, trajectory fitting, and acoustic propagation.
172
+ - [Automatic audio discovery](docs/AUDIO_DISCOVERY.md) — acoustic detector design and evaluation.
173
+ - [Data acquisition and geographic search](docs/DATA_AND_SCALE.md) — ADS-B archives, indexing, terrain, coverage, and search.
174
+ - [Country profiles](docs/COUNTRIES.md) — supported search domains and regional configuration.
175
+ - [Confidence and decision rules](docs/CONFIDENCE.md) — candidate interpretation and inconclusive outcomes.
176
+ - [Performance](docs/PERFORMANCE.md) and [pipeline measurements](docs/PIPELINE_PERFORMANCE_2026-11-03.md) — measured optimizations and comparisons.
177
+ - [Livermore demonstration](docs/LIVERMORE_DEMO.md), [real-data verification](docs/verification/WORKER_E2E_2026-11-03.md), and [benchmark instructions](benchmarks/README.md) — recorded experiments and reproduction.
178
+ - [Finite-search evidence](docs/FINITE_SEARCH_PRODUCER.md) and [scoring assessment](docs/SCORING_ASSESSMENT.md) — candidate accounting and coverage of evaluated hypotheses.
179
+ - [Setup](docs/SETUP.md), [Docker](docs/DOCKER.md), and [data provenance](docs/DATA_SOURCES.md) — installation, deployment, and third-party data terms.
180
+
181
+ ## License
182
+
183
+ DOPPLERGEIST is distributed under the **[PolyForm Noncommercial License 1.0.0](LICENSE)** (`PolyForm-Noncommercial-1.0.0`). It is **source-available, not OSI-approved open-source software**. Noncommercial uses, modification, and distribution are permitted subject to the license. Commercial use not otherwise permitted requires authorization from the relevant rights holders. See [Commercial licensing](COMMERCIAL-LICENSING.md).
184
+
185
+ Recordings, aircraft archives, terrain datasets, and other third-party materials retain their own licenses, rights, and attribution requirements.
186
+
187
+ ## Contributing and development
188
+
189
+ Contributions, reproducible test recordings with appropriate permissions, documentation improvements, and independently verifiable evaluations are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md), the [issue tracker](https://github.com/1337isnot1337/DOPPLERGEIST/issues), and the [development discussion](https://github.com/1337isnot1337/DOPPLERGEIST/discussions/39).
190
+
191
+ Created by **Cinna Davis** with extensive AI-assisted development. Thanks to @henriklied, @EirikAskheim, @kleindotc, and other contributors. Follow updates on [X](https://x.com/1337isnot1337) or [LinkedIn](https://www.linkedin.com/in/cinna-davis/).
192
+
193
+ ## Star history
194
+
195
+ <p align="center">
196
+ <a href="https://www.star-history.com/#1337isnot1337/DOPPLERGEIST&Date">
197
+ <picture>
198
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=1337isnot1337/DOPPLERGEIST&type=Date&theme=dark" />
199
+ <img alt="DOPPLERGEIST star history" src="https://api.star-history.com/svg?repos=1337isnot1337/DOPPLERGEIST&type=Date" width="650" />
200
+ </picture>
201
+ </a>
202
+ </p>
@@ -0,0 +1,64 @@
1
+ # DOPPLERGEIST
2
+
3
+ ![DOPPLERGEIST — aircraft Doppler audio geolocation](https://raw.githubusercontent.com/1337isnot1337/DOPPLERGEIST/main/assets/dopplergeist-banner.svg)
4
+
5
+ **DOPPLERGEIST** is a Python CLI and local web application for aircraft Doppler audio geolocation. It detects candidate flyover signals in recordings, retrieves historical ADS-B flight tracks, models acoustic propagation, and ranks possible recording locations.
6
+
7
+ ![Automatic MP3 flyover analysis and ranked aircraft search](https://raw.githubusercontent.com/1337isnot1337/DOPPLERGEIST/main/assets/livermore-automatic-mp3.png)
8
+
9
+ The illustrated real-recording experiment ranked a location 476 m from an *inferred* reference within a constrained search. The reference was not surveyed ground truth; independent blind geolocation accuracy has not been established. [Read the experiment](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/LIVERMORE_DEMO.md).
10
+
11
+ ## Install
12
+
13
+ Requires **Python 3.11+**. Install **FFmpeg** separately so that both `ffmpeg` and `ffprobe` are on your `PATH`.
14
+
15
+ For the CLI:
16
+
17
+ ```sh
18
+ pipx install dopplergeist
19
+ dopplergeist --help
20
+ ```
21
+
22
+ For a Python environment:
23
+
24
+ ```sh
25
+ python -m pip install dopplergeist
26
+ ```
27
+
28
+ ## Use
29
+
30
+ Detect candidate acoustic events without flight-data downloads:
31
+
32
+ ```sh
33
+ dopplergeist discover recording.mp3 --output results/discovery
34
+ ```
35
+
36
+ Launch the locally hosted upload interface:
37
+
38
+ ```sh
39
+ dopplergeist serve --jobs jobs --online --port 8765
40
+ ```
41
+
42
+ Open `http://127.0.0.1:8765`. For historical flight matching, a **defensible UTC window for the first audio sample** is required; the recording upload timestamp is not sufficient. Geographic searches can consume substantial time, storage, and downloaded aircraft/terrain data.
43
+
44
+ For CLI analysis with an independently supported recording clock:
45
+
46
+ ```sh
47
+ dopplergeist analyze recording.mp3 --jobs jobs \
48
+ --start-utc "2026-01-01T00:00:00Z" \
49
+ --end-utc "2026-01-01T00:10:00Z" \
50
+ --time-source "replace with independently supported clock evidence" \
51
+ --online
52
+ ```
53
+
54
+ ## Documentation
55
+
56
+ - [Source code and full README](https://github.com/1337isnot1337/DOPPLERGEIST)
57
+ - [Installation and reproducibility](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/SETUP.md)
58
+ - [How the geolocation pipeline works](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/METHODOLOGY.md)
59
+ - [Validation and limitations](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/docs/CONFIDENCE.md)
60
+ - [Issues and feature requests](https://github.com/1337isnot1337/DOPPLERGEIST/issues)
61
+
62
+ ## License
63
+
64
+ **PolyForm Noncommercial License 1.0.0.** Noncommercial uses are permitted under the terms of that license; commercial uses that are not otherwise authorized need a separate agreement with the applicable copyright holders. Earlier MIT-licensed releases retain the permissions originally granted for those versions. [Commercial licensing details](https://github.com/1337isnot1337/DOPPLERGEIST/blob/main/COMMERCIAL-LICENSING.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cinna Davis
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,54 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.3"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dopplergeist"
7
+ version = "0.1.1"
8
+ description = "Aircraft Doppler audio geolocation using historical flight tracks"
9
+ readme = "docs/PYPI_README.md"
10
+ keywords = ["aircraft", "doppler", "acoustic-geolocation", "audio-forensics", "ads-b", "signal-processing"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Environment :: Console",
14
+ "Intended Audience :: Science/Research",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
20
+ "Programming Language :: Python :: Implementation :: CPython",
21
+ "Topic :: Scientific/Engineering :: Physics",
22
+ "Topic :: Multimedia :: Sound/Audio :: Analysis",
23
+ ]
24
+ license = "PolyForm-Noncommercial-1.0.0"
25
+ license-files = ["LICENSE", "licenses/MIT-legacy.txt", "src/dopplergeist/web/leaflet-license.txt"]
26
+ requires-python = ">=3.11"
27
+ dependencies = ["numpy", "scipy", "pandas", "soundfile", "pyproj", "rasterio", "matplotlib", "requests", "pyarrow", "shapely>=2.0"]
28
+
29
+ [project.urls]
30
+ Homepage = "https://github.com/1337isnot1337/DOPPLERGEIST"
31
+ Documentation = "https://github.com/1337isnot1337/DOPPLERGEIST/tree/main/docs"
32
+ Source = "https://github.com/1337isnot1337/DOPPLERGEIST"
33
+ Issues = "https://github.com/1337isnot1337/DOPPLERGEIST/issues"
34
+ Releases = "https://github.com/1337isnot1337/DOPPLERGEIST/releases"
35
+
36
+ [project.optional-dependencies]
37
+ test = ["pytest>=8"]
38
+
39
+ [project.scripts]
40
+ dopplergeist = "dopplergeist.cli:main"
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+
45
+ [tool.setuptools.package-data]
46
+ "dopplergeist.web" = ["*.html", "*.js", "*.css", "leaflet-license.txt"]
47
+
48
+ [tool.pytest.ini_options]
49
+ testpaths = ["tests"]
50
+
51
+ [tool.cibuildwheel]
52
+ build = "cp311-* cp312-* cp313-* cp314-*"
53
+ skip = "*-musllinux_*"
54
+ test-command = "dopplergeist --help && python -c \"from importlib.resources import files; assert files('dopplergeist.web').joinpath('index.html').is_file()\""
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,40 @@
1
+ import os
2
+
3
+ from setuptools import Extension, setup
4
+
5
+
6
+ extension = Extension(
7
+ "dopplergeist._native_ridge",
8
+ ["src/dopplergeist/_native_ridge.c"],
9
+ optional=True,
10
+ extra_compile_args=["/O2", "/fp:strict"] if os.name == "nt" else
11
+ ["-O3", "-ffp-contract=off", "-fno-fast-math"],
12
+ libraries=[] if os.name == "nt" else ["m"],
13
+ )
14
+
15
+ acoustic_extension = Extension(
16
+ "dopplergeist._native_acoustic",
17
+ ["src/dopplergeist/_native_acoustic.c"],
18
+ optional=True,
19
+ extra_compile_args=["/O2", "/fp:strict"] if os.name == "nt" else
20
+ ["-O3", "-ffp-contract=off", "-fno-fast-math"],
21
+ libraries=[] if os.name == "nt" else ["m"],
22
+ )
23
+
24
+ cpa_extension = Extension(
25
+ "dopplergeist._native_cpa",
26
+ ["src/dopplergeist/_native_cpa.c"],
27
+ optional=True,
28
+ extra_compile_args=["/O2", "/fp:strict"] if os.name == "nt" else
29
+ ["-O3", "-ffp-contract=off", "-fno-fast-math"],
30
+ libraries=[] if os.name == "nt" else ["m"],
31
+ )
32
+
33
+ index_extension = Extension(
34
+ "dopplergeist._native_index",
35
+ ["src/dopplergeist/_native_index.c"],
36
+ optional=True,
37
+ extra_compile_args=["/O2"] if os.name == "nt" else ["-O3"],
38
+ )
39
+
40
+ setup(ext_modules=[extension, acoustic_extension, cpa_extension, index_extension])
@@ -0,0 +1 @@
1
+ """Aircraft-acoustic geolocation reproduction."""