gwpy 4.0.0rc2__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 (467) hide show
  1. gwpy-4.0.0rc2/.gitattributes +1 -0
  2. gwpy-4.0.0rc2/.github/copilot-instructions.md +94 -0
  3. gwpy-4.0.0rc2/.gitignore +56 -0
  4. gwpy-4.0.0rc2/.gitlab/ci/compatibility.yml +82 -0
  5. gwpy-4.0.0rc2/.gitlab/ci/coverage.yml +32 -0
  6. gwpy-4.0.0rc2/.gitlab/ci/init-creds.sh +28 -0
  7. gwpy-4.0.0rc2/.gitlab/ci/platforms.yml +44 -0
  8. gwpy-4.0.0rc2/.gitlab/ci/python-base.yml +31 -0
  9. gwpy-4.0.0rc2/.gitlab/ci/python-dist.yml +45 -0
  10. gwpy-4.0.0rc2/.gitlab/ci/qa.yml +143 -0
  11. gwpy-4.0.0rc2/.gitlab/ci/rstcheck.py +113 -0
  12. gwpy-4.0.0rc2/.gitlab/ci/rules.yml +85 -0
  13. gwpy-4.0.0rc2/.gitlab/ci/sphinx.yml +65 -0
  14. gwpy-4.0.0rc2/.gitlab/ci/test-job.yml +95 -0
  15. gwpy-4.0.0rc2/.gitlab/ci/test.yml +458 -0
  16. gwpy-4.0.0rc2/.gitlab/ci/twine.yml +69 -0
  17. gwpy-4.0.0rc2/.gitlab/issue_templates/Example.md +30 -0
  18. gwpy-4.0.0rc2/.gitlab-ci.yml +76 -0
  19. gwpy-4.0.0rc2/.readthedocs.yaml +22 -0
  20. gwpy-4.0.0rc2/CHANGELOG.rst +1037 -0
  21. gwpy-4.0.0rc2/CODE_OF_CONDUCT.rst +2 -0
  22. gwpy-4.0.0rc2/CONTRIBUTING.md +160 -0
  23. gwpy-4.0.0rc2/LICENSE +674 -0
  24. gwpy-4.0.0rc2/MANIFEST.in +5 -0
  25. gwpy-4.0.0rc2/PKG-INFO +130 -0
  26. gwpy-4.0.0rc2/README.md +51 -0
  27. gwpy-4.0.0rc2/docs/.gitignore +49 -0
  28. gwpy-4.0.0rc2/docs/_references.rst +140 -0
  29. gwpy-4.0.0rc2/docs/_static/css/gwpy-sphinx.css +81 -0
  30. gwpy-4.0.0rc2/docs/_static/favicon.png +0 -0
  31. gwpy-4.0.0rc2/docs/_static/gwpy_white_24.png +0 -0
  32. gwpy-4.0.0rc2/docs/_templates/autoclass/class.rst +55 -0
  33. gwpy-4.0.0rc2/docs/_templates/autosummary/base.rst +10 -0
  34. gwpy-4.0.0rc2/docs/_templates/autosummary/class.rst +65 -0
  35. gwpy-4.0.0rc2/docs/_templates/autosummary/module.rst +41 -0
  36. gwpy-4.0.0rc2/docs/about.rst +18 -0
  37. gwpy-4.0.0rc2/docs/astro/index.rst +28 -0
  38. gwpy-4.0.0rc2/docs/changelog.rst +1037 -0
  39. gwpy-4.0.0rc2/docs/citing.rst +88 -0
  40. gwpy-4.0.0rc2/docs/cli/examples.ini +217 -0
  41. gwpy-4.0.0rc2/docs/cli/index.rst +74 -0
  42. gwpy-4.0.0rc2/docs/concepts.rst +457 -0
  43. gwpy-4.0.0rc2/docs/conf.py +333 -0
  44. gwpy-4.0.0rc2/docs/contributing.rst +2 -0
  45. gwpy-4.0.0rc2/docs/detector/channel.rst +88 -0
  46. gwpy-4.0.0rc2/docs/dev/release.rst +145 -0
  47. gwpy-4.0.0rc2/docs/env.rst +101 -0
  48. gwpy-4.0.0rc2/docs/environment.yaml +11 -0
  49. gwpy-4.0.0rc2/docs/external/framecpp.rst +30 -0
  50. gwpy-4.0.0rc2/docs/external/framel.rst +30 -0
  51. gwpy-4.0.0rc2/docs/external/index.rst +17 -0
  52. gwpy-4.0.0rc2/docs/external/lalsuite.rst +107 -0
  53. gwpy-4.0.0rc2/docs/external/nds2.rst +26 -0
  54. gwpy-4.0.0rc2/docs/getting-started.rst +107 -0
  55. gwpy-4.0.0rc2/docs/guide.rst +39 -0
  56. gwpy-4.0.0rc2/docs/gwpy-logo.png +0 -0
  57. gwpy-4.0.0rc2/docs/index.rst +112 -0
  58. gwpy-4.0.0rc2/docs/install.rst +190 -0
  59. gwpy-4.0.0rc2/docs/license.rst +16 -0
  60. gwpy-4.0.0rc2/docs/logging.rst +95 -0
  61. gwpy-4.0.0rc2/docs/plot/colorbars.rst +89 -0
  62. gwpy-4.0.0rc2/docs/plot/colors.rst +108 -0
  63. gwpy-4.0.0rc2/docs/plot/filter.rst +37 -0
  64. gwpy-4.0.0rc2/docs/plot/gps.rst +97 -0
  65. gwpy-4.0.0rc2/docs/plot/index.rst +117 -0
  66. gwpy-4.0.0rc2/docs/plot/legend.rst +60 -0
  67. gwpy-4.0.0rc2/docs/plot/log.rst +43 -0
  68. gwpy-4.0.0rc2/docs/quickstart.rst +340 -0
  69. gwpy-4.0.0rc2/docs/reference/gwpy.astro.rst +14 -0
  70. gwpy-4.0.0rc2/docs/reference/gwpy.detector.rst +14 -0
  71. gwpy-4.0.0rc2/docs/reference/gwpy.frequencyseries.rst +15 -0
  72. gwpy-4.0.0rc2/docs/reference/gwpy.io.cache.rst +7 -0
  73. gwpy-4.0.0rc2/docs/reference/gwpy.io.datafind.rst +7 -0
  74. gwpy-4.0.0rc2/docs/reference/gwpy.io.gwf.rst +7 -0
  75. gwpy-4.0.0rc2/docs/reference/gwpy.io.hdf5.rst +7 -0
  76. gwpy-4.0.0rc2/docs/reference/gwpy.io.kerberos.rst +7 -0
  77. gwpy-4.0.0rc2/docs/reference/gwpy.io.ligolw.rst +7 -0
  78. gwpy-4.0.0rc2/docs/reference/gwpy.io.nds2.rst +7 -0
  79. gwpy-4.0.0rc2/docs/reference/gwpy.io.pelican.rst +7 -0
  80. gwpy-4.0.0rc2/docs/reference/gwpy.io.registry.rst +7 -0
  81. gwpy-4.0.0rc2/docs/reference/gwpy.io.remote.rst +7 -0
  82. gwpy-4.0.0rc2/docs/reference/gwpy.io.root.rst +7 -0
  83. gwpy-4.0.0rc2/docs/reference/gwpy.io.rst +65 -0
  84. gwpy-4.0.0rc2/docs/reference/gwpy.io.scitokens.rst +7 -0
  85. gwpy-4.0.0rc2/docs/reference/gwpy.io.utils.rst +7 -0
  86. gwpy-4.0.0rc2/docs/reference/gwpy.log.rst +14 -0
  87. gwpy-4.0.0rc2/docs/reference/gwpy.plot.rst +14 -0
  88. gwpy-4.0.0rc2/docs/reference/gwpy.segments.rst +15 -0
  89. gwpy-4.0.0rc2/docs/reference/gwpy.signal.filter_design.rst +7 -0
  90. gwpy-4.0.0rc2/docs/reference/gwpy.signal.qtransform.rst +14 -0
  91. gwpy-4.0.0rc2/docs/reference/gwpy.signal.rst +26 -0
  92. gwpy-4.0.0rc2/docs/reference/gwpy.signal.spectral.rst +7 -0
  93. gwpy-4.0.0rc2/docs/reference/gwpy.signal.window.rst +7 -0
  94. gwpy-4.0.0rc2/docs/reference/gwpy.spectrogram.rst +15 -0
  95. gwpy-4.0.0rc2/docs/reference/gwpy.table.rst +15 -0
  96. gwpy-4.0.0rc2/docs/reference/gwpy.time.rst +14 -0
  97. gwpy-4.0.0rc2/docs/reference/gwpy.timeseries.rst +15 -0
  98. gwpy-4.0.0rc2/docs/reference/gwpy.types.rst +7 -0
  99. gwpy-4.0.0rc2/docs/reference/gwpy.utils.decorators.rst +8 -0
  100. gwpy-4.0.0rc2/docs/reference/gwpy.utils.lal.rst +13 -0
  101. gwpy-4.0.0rc2/docs/reference/gwpy.utils.rst +16 -0
  102. gwpy-4.0.0rc2/docs/reference/index.rst +34 -0
  103. gwpy-4.0.0rc2/docs/segments/dqsegdb.rst +43 -0
  104. gwpy-4.0.0rc2/docs/segments/index.rst +238 -0
  105. gwpy-4.0.0rc2/docs/segments/io.rst +181 -0
  106. gwpy-4.0.0rc2/docs/segments/thresholding.rst +32 -0
  107. gwpy-4.0.0rc2/docs/signal/index.rst +142 -0
  108. gwpy-4.0.0rc2/docs/spectrogram/index.rst +106 -0
  109. gwpy-4.0.0rc2/docs/spectrum/filtering.rst +19 -0
  110. gwpy-4.0.0rc2/docs/spectrum/index.rst +108 -0
  111. gwpy-4.0.0rc2/docs/spectrum/io.rst +141 -0
  112. gwpy-4.0.0rc2/docs/table/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  113. gwpy-4.0.0rc2/docs/table/filter.rst +163 -0
  114. gwpy-4.0.0rc2/docs/table/histogram.rst +25 -0
  115. gwpy-4.0.0rc2/docs/table/index.rst +67 -0
  116. gwpy-4.0.0rc2/docs/table/io.rst +784 -0
  117. gwpy-4.0.0rc2/docs/table/plot.rst +53 -0
  118. gwpy-4.0.0rc2/docs/table/rate.rst +59 -0
  119. gwpy-4.0.0rc2/docs/time/index.rst +36 -0
  120. gwpy-4.0.0rc2/docs/timeseries/get.rst +287 -0
  121. gwpy-4.0.0rc2/docs/timeseries/index.rst +109 -0
  122. gwpy-4.0.0rc2/docs/timeseries/io.rst +400 -0
  123. gwpy-4.0.0rc2/docs/timeseries/plot.rst +103 -0
  124. gwpy-4.0.0rc2/docs/timeseries/statevector.rst +241 -0
  125. gwpy-4.0.0rc2/docs/tools/rds.rst +19 -0
  126. gwpy-4.0.0rc2/docs/tools/tconvert.rst +17 -0
  127. gwpy-4.0.0rc2/examples/README.rst +20 -0
  128. gwpy-4.0.0rc2/examples/frequencyseries/README.rst +5 -0
  129. gwpy-4.0.0rc2/examples/frequencyseries/coherence.py +103 -0
  130. gwpy-4.0.0rc2/examples/frequencyseries/hoff.py +82 -0
  131. gwpy-4.0.0rc2/examples/frequencyseries/inject-fs.py +98 -0
  132. gwpy-4.0.0rc2/examples/frequencyseries/percentiles.py +86 -0
  133. gwpy-4.0.0rc2/examples/frequencyseries/rayleigh.py +83 -0
  134. gwpy-4.0.0rc2/examples/frequencyseries/variance.py +76 -0
  135. gwpy-4.0.0rc2/examples/miscellaneous/README.rst +5 -0
  136. gwpy-4.0.0rc2/examples/miscellaneous/open-data-spectrogram.py +121 -0
  137. gwpy-4.0.0rc2/examples/miscellaneous/range-spectrogram.py +76 -0
  138. gwpy-4.0.0rc2/examples/miscellaneous/range-timeseries.py +77 -0
  139. gwpy-4.0.0rc2/examples/segments/README.rst +5 -0
  140. gwpy-4.0.0rc2/examples/segments/open-data.py +78 -0
  141. gwpy-4.0.0rc2/examples/signal/README.rst +5 -0
  142. gwpy-4.0.0rc2/examples/signal/gw150914.py +186 -0
  143. gwpy-4.0.0rc2/examples/spectrogram/README.rst +5 -0
  144. gwpy-4.0.0rc2/examples/spectrogram/coherencegram.py +94 -0
  145. gwpy-4.0.0rc2/examples/spectrogram/plot.py +72 -0
  146. gwpy-4.0.0rc2/examples/spectrogram/ratio.py +76 -0
  147. gwpy-4.0.0rc2/examples/spectrogram/rayleighgram.py +59 -0
  148. gwpy-4.0.0rc2/examples/spectrogram/spectrogram2.py +79 -0
  149. gwpy-4.0.0rc2/examples/table/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  150. gwpy-4.0.0rc2/examples/table/README.rst +5 -0
  151. gwpy-4.0.0rc2/examples/table/histogram.py +52 -0
  152. gwpy-4.0.0rc2/examples/table/rate.py +67 -0
  153. gwpy-4.0.0rc2/examples/table/rate_binned.py +77 -0
  154. gwpy-4.0.0rc2/examples/table/scatter.py +71 -0
  155. gwpy-4.0.0rc2/examples/table/tiles.py +68 -0
  156. gwpy-4.0.0rc2/examples/test_examples.py +156 -0
  157. gwpy-4.0.0rc2/examples/timeseries/README.rst +5 -0
  158. gwpy-4.0.0rc2/examples/timeseries/blrms.py +79 -0
  159. gwpy-4.0.0rc2/examples/timeseries/inject.py +130 -0
  160. gwpy-4.0.0rc2/examples/timeseries/public.py +70 -0
  161. gwpy-4.0.0rc2/examples/timeseries/pycbc-snr.py +121 -0
  162. gwpy-4.0.0rc2/examples/timeseries/qscan.py +71 -0
  163. gwpy-4.0.0rc2/examples/timeseries/statevector.py +62 -0
  164. gwpy-4.0.0rc2/examples/timeseries/whiten.py +113 -0
  165. gwpy-4.0.0rc2/gwpy/__init__.py +81 -0
  166. gwpy-4.0.0rc2/gwpy/_version.py +34 -0
  167. gwpy-4.0.0rc2/gwpy/astro/__init__.py +40 -0
  168. gwpy-4.0.0rc2/gwpy/astro/range.py +910 -0
  169. gwpy-4.0.0rc2/gwpy/astro/tests/__init__.py +18 -0
  170. gwpy-4.0.0rc2/gwpy/astro/tests/test_range.py +219 -0
  171. gwpy-4.0.0rc2/gwpy/cli/__init__.py +51 -0
  172. gwpy-4.0.0rc2/gwpy/cli/cliproduct.py +1282 -0
  173. gwpy-4.0.0rc2/gwpy/cli/coherence.py +159 -0
  174. gwpy-4.0.0rc2/gwpy/cli/coherencegram.py +136 -0
  175. gwpy-4.0.0rc2/gwpy/cli/gwpy_plot.py +166 -0
  176. gwpy-4.0.0rc2/gwpy/cli/qtransform.py +330 -0
  177. gwpy-4.0.0rc2/gwpy/cli/spectrogram.py +277 -0
  178. gwpy-4.0.0rc2/gwpy/cli/spectrum.py +187 -0
  179. gwpy-4.0.0rc2/gwpy/cli/tests/__init__.py +19 -0
  180. gwpy-4.0.0rc2/gwpy/cli/tests/base.py +428 -0
  181. gwpy-4.0.0rc2/gwpy/cli/tests/test_coherence.py +60 -0
  182. gwpy-4.0.0rc2/gwpy/cli/tests/test_coherencegram.py +45 -0
  183. gwpy-4.0.0rc2/gwpy/cli/tests/test_gwpy_plot.py +58 -0
  184. gwpy-4.0.0rc2/gwpy/cli/tests/test_qtransform.py +94 -0
  185. gwpy-4.0.0rc2/gwpy/cli/tests/test_spectrogram.py +84 -0
  186. gwpy-4.0.0rc2/gwpy/cli/tests/test_spectrum.py +84 -0
  187. gwpy-4.0.0rc2/gwpy/cli/tests/test_timeseries.py +43 -0
  188. gwpy-4.0.0rc2/gwpy/cli/tests/test_transferfunction.py +103 -0
  189. gwpy-4.0.0rc2/gwpy/cli/timeseries.py +136 -0
  190. gwpy-4.0.0rc2/gwpy/cli/transferfunction.py +264 -0
  191. gwpy-4.0.0rc2/gwpy/conftest.py +69 -0
  192. gwpy-4.0.0rc2/gwpy/detector/__init__.py +36 -0
  193. gwpy-4.0.0rc2/gwpy/detector/channel.py +1045 -0
  194. gwpy-4.0.0rc2/gwpy/detector/connect.py +81 -0
  195. gwpy-4.0.0rc2/gwpy/detector/io/__init__.py +27 -0
  196. gwpy-4.0.0rc2/gwpy/detector/io/cis.py +161 -0
  197. gwpy-4.0.0rc2/gwpy/detector/io/clf.py +227 -0
  198. gwpy-4.0.0rc2/gwpy/detector/io/omega.py +220 -0
  199. gwpy-4.0.0rc2/gwpy/detector/tests/__init__.py +18 -0
  200. gwpy-4.0.0rc2/gwpy/detector/tests/test_channel.py +705 -0
  201. gwpy-4.0.0rc2/gwpy/detector/tests/test_tz.py +58 -0
  202. gwpy-4.0.0rc2/gwpy/detector/tests/test_units.py +88 -0
  203. gwpy-4.0.0rc2/gwpy/detector/tz.py +91 -0
  204. gwpy-4.0.0rc2/gwpy/detector/units.py +291 -0
  205. gwpy-4.0.0rc2/gwpy/frequencyseries/__init__.py +28 -0
  206. gwpy-4.0.0rc2/gwpy/frequencyseries/_fdcommon.py +82 -0
  207. gwpy-4.0.0rc2/gwpy/frequencyseries/connect.py +146 -0
  208. gwpy-4.0.0rc2/gwpy/frequencyseries/frequencyseries.py +576 -0
  209. gwpy-4.0.0rc2/gwpy/frequencyseries/hist.py +388 -0
  210. gwpy-4.0.0rc2/gwpy/frequencyseries/io/__init__.py +27 -0
  211. gwpy-4.0.0rc2/gwpy/frequencyseries/io/ascii.py +26 -0
  212. gwpy-4.0.0rc2/gwpy/frequencyseries/io/hdf5.py +30 -0
  213. gwpy-4.0.0rc2/gwpy/frequencyseries/io/ligolw.py +28 -0
  214. gwpy-4.0.0rc2/gwpy/frequencyseries/tests/__init__.py +18 -0
  215. gwpy-4.0.0rc2/gwpy/frequencyseries/tests/test_frequencyseries.py +414 -0
  216. gwpy-4.0.0rc2/gwpy/frequencyseries/tests/test_hist.py +178 -0
  217. gwpy-4.0.0rc2/gwpy/io/__init__.py +21 -0
  218. gwpy-4.0.0rc2/gwpy/io/cache.py +625 -0
  219. gwpy-4.0.0rc2/gwpy/io/datafind.py +1056 -0
  220. gwpy-4.0.0rc2/gwpy/io/ffldatafind.py +420 -0
  221. gwpy-4.0.0rc2/gwpy/io/gwf/__init__.py +42 -0
  222. gwpy-4.0.0rc2/gwpy/io/gwf/backend.py +191 -0
  223. gwpy-4.0.0rc2/gwpy/io/gwf/core.py +362 -0
  224. gwpy-4.0.0rc2/gwpy/io/gwf/framecpp.py +727 -0
  225. gwpy-4.0.0rc2/gwpy/io/gwf/lalframe.py +330 -0
  226. gwpy-4.0.0rc2/gwpy/io/hdf5.py +293 -0
  227. gwpy-4.0.0rc2/gwpy/io/kerberos.py +499 -0
  228. gwpy-4.0.0rc2/gwpy/io/ligolw.py +785 -0
  229. gwpy-4.0.0rc2/gwpy/io/nds2.py +814 -0
  230. gwpy-4.0.0rc2/gwpy/io/pelican.py +390 -0
  231. gwpy-4.0.0rc2/gwpy/io/registry.py +889 -0
  232. gwpy-4.0.0rc2/gwpy/io/remote.py +331 -0
  233. gwpy-4.0.0rc2/gwpy/io/root.py +69 -0
  234. gwpy-4.0.0rc2/gwpy/io/scitokens.py +297 -0
  235. gwpy-4.0.0rc2/gwpy/io/tests/__init__.py +18 -0
  236. gwpy-4.0.0rc2/gwpy/io/tests/test_cache.py +310 -0
  237. gwpy-4.0.0rc2/gwpy/io/tests/test_datafind.py +303 -0
  238. gwpy-4.0.0rc2/gwpy/io/tests/test_ffldatafind.py +228 -0
  239. gwpy-4.0.0rc2/gwpy/io/tests/test_gwf.py +173 -0
  240. gwpy-4.0.0rc2/gwpy/io/tests/test_gwf_backend.py +86 -0
  241. gwpy-4.0.0rc2/gwpy/io/tests/test_gwf_framecpp.py +82 -0
  242. gwpy-4.0.0rc2/gwpy/io/tests/test_kerberos.py +275 -0
  243. gwpy-4.0.0rc2/gwpy/io/tests/test_ligolw.py +347 -0
  244. gwpy-4.0.0rc2/gwpy/io/tests/test_nds2.py +528 -0
  245. gwpy-4.0.0rc2/gwpy/io/tests/test_pelican.py +83 -0
  246. gwpy-4.0.0rc2/gwpy/io/tests/test_registry.py +33 -0
  247. gwpy-4.0.0rc2/gwpy/io/tests/test_remote.py +85 -0
  248. gwpy-4.0.0rc2/gwpy/io/tests/test_root.py +63 -0
  249. gwpy-4.0.0rc2/gwpy/io/tests/test_scitokens.py +244 -0
  250. gwpy-4.0.0rc2/gwpy/io/tests/test_utils.py +137 -0
  251. gwpy-4.0.0rc2/gwpy/io/utils.py +382 -0
  252. gwpy-4.0.0rc2/gwpy/log/__init__.py +183 -0
  253. gwpy-4.0.0rc2/gwpy/log/tests/__init__.py +18 -0
  254. gwpy-4.0.0rc2/gwpy/log/tests/test_log.py +131 -0
  255. gwpy-4.0.0rc2/gwpy/plot/__init__.py +52 -0
  256. gwpy-4.0.0rc2/gwpy/plot/axes.py +789 -0
  257. gwpy-4.0.0rc2/gwpy/plot/bode.py +386 -0
  258. gwpy-4.0.0rc2/gwpy/plot/colorbar.py +416 -0
  259. gwpy-4.0.0rc2/gwpy/plot/colors.py +157 -0
  260. gwpy-4.0.0rc2/gwpy/plot/gps.py +602 -0
  261. gwpy-4.0.0rc2/gwpy/plot/legend.py +82 -0
  262. gwpy-4.0.0rc2/gwpy/plot/log.py +194 -0
  263. gwpy-4.0.0rc2/gwpy/plot/plot.py +711 -0
  264. gwpy-4.0.0rc2/gwpy/plot/rc.py +189 -0
  265. gwpy-4.0.0rc2/gwpy/plot/segments.py +636 -0
  266. gwpy-4.0.0rc2/gwpy/plot/tests/__init__.py +18 -0
  267. gwpy-4.0.0rc2/gwpy/plot/tests/test_axes.py +340 -0
  268. gwpy-4.0.0rc2/gwpy/plot/tests/test_bode.py +97 -0
  269. gwpy-4.0.0rc2/gwpy/plot/tests/test_colors.py +96 -0
  270. gwpy-4.0.0rc2/gwpy/plot/tests/test_gps.py +258 -0
  271. gwpy-4.0.0rc2/gwpy/plot/tests/test_log.py +96 -0
  272. gwpy-4.0.0rc2/gwpy/plot/tests/test_plot.py +168 -0
  273. gwpy-4.0.0rc2/gwpy/plot/tests/test_rc.py +62 -0
  274. gwpy-4.0.0rc2/gwpy/plot/tests/test_segments.py +223 -0
  275. gwpy-4.0.0rc2/gwpy/plot/tests/test_tex.py +126 -0
  276. gwpy-4.0.0rc2/gwpy/plot/tests/test_text.py +95 -0
  277. gwpy-4.0.0rc2/gwpy/plot/tests/test_units.py +55 -0
  278. gwpy-4.0.0rc2/gwpy/plot/tests/test_utils.py +67 -0
  279. gwpy-4.0.0rc2/gwpy/plot/tests/utils.py +86 -0
  280. gwpy-4.0.0rc2/gwpy/plot/tex.py +197 -0
  281. gwpy-4.0.0rc2/gwpy/plot/text.py +81 -0
  282. gwpy-4.0.0rc2/gwpy/plot/units.py +74 -0
  283. gwpy-4.0.0rc2/gwpy/plot/utils.py +96 -0
  284. gwpy-4.0.0rc2/gwpy/segments/__init__.py +40 -0
  285. gwpy-4.0.0rc2/gwpy/segments/connect.py +294 -0
  286. gwpy-4.0.0rc2/gwpy/segments/flag.py +1687 -0
  287. gwpy-4.0.0rc2/gwpy/segments/io/__init__.py +28 -0
  288. gwpy-4.0.0rc2/gwpy/segments/io/hdf5.py +458 -0
  289. gwpy-4.0.0rc2/gwpy/segments/io/json.py +109 -0
  290. gwpy-4.0.0rc2/gwpy/segments/io/ligolw.py +195 -0
  291. gwpy-4.0.0rc2/gwpy/segments/io/segwizard.py +221 -0
  292. gwpy-4.0.0rc2/gwpy/segments/segments.py +239 -0
  293. gwpy-4.0.0rc2/gwpy/segments/tests/__init__.py +18 -0
  294. gwpy-4.0.0rc2/gwpy/segments/tests/test_flag.py +1182 -0
  295. gwpy-4.0.0rc2/gwpy/segments/tests/test_segments.py +212 -0
  296. gwpy-4.0.0rc2/gwpy/signal/__init__.py +26 -0
  297. gwpy-4.0.0rc2/gwpy/signal/filter_design.py +1920 -0
  298. gwpy-4.0.0rc2/gwpy/signal/qtransform.py +885 -0
  299. gwpy-4.0.0rc2/gwpy/signal/spectral/__init__.py +85 -0
  300. gwpy-4.0.0rc2/gwpy/signal/spectral/_lal.py +511 -0
  301. gwpy-4.0.0rc2/gwpy/signal/spectral/_median_mean.py +55 -0
  302. gwpy-4.0.0rc2/gwpy/signal/spectral/_pycbc.py +119 -0
  303. gwpy-4.0.0rc2/gwpy/signal/spectral/_registry.py +91 -0
  304. gwpy-4.0.0rc2/gwpy/signal/spectral/_scipy.py +337 -0
  305. gwpy-4.0.0rc2/gwpy/signal/spectral/_ui.py +550 -0
  306. gwpy-4.0.0rc2/gwpy/signal/spectral/_utils.py +58 -0
  307. gwpy-4.0.0rc2/gwpy/signal/tests/__init__.py +18 -0
  308. gwpy-4.0.0rc2/gwpy/signal/tests/test_coherence.py +116 -0
  309. gwpy-4.0.0rc2/gwpy/signal/tests/test_filter_design.py +360 -0
  310. gwpy-4.0.0rc2/gwpy/signal/tests/test_qtransform.py +209 -0
  311. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_lal.py +138 -0
  312. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_median_mean.py +69 -0
  313. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_pycbc.py +72 -0
  314. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_registry.py +46 -0
  315. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_scipy.py +55 -0
  316. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_ui.py +106 -0
  317. gwpy-4.0.0rc2/gwpy/signal/tests/test_spectral_utils.py +43 -0
  318. gwpy-4.0.0rc2/gwpy/signal/tests/test_window.py +100 -0
  319. gwpy-4.0.0rc2/gwpy/signal/window.py +306 -0
  320. gwpy-4.0.0rc2/gwpy/spectrogram/__init__.py +35 -0
  321. gwpy-4.0.0rc2/gwpy/spectrogram/coherence.py +220 -0
  322. gwpy-4.0.0rc2/gwpy/spectrogram/connect.py +84 -0
  323. gwpy-4.0.0rc2/gwpy/spectrogram/io/__init__.py +26 -0
  324. gwpy-4.0.0rc2/gwpy/spectrogram/io/ascii.py +25 -0
  325. gwpy-4.0.0rc2/gwpy/spectrogram/io/hdf5.py +26 -0
  326. gwpy-4.0.0rc2/gwpy/spectrogram/spectrogram.py +838 -0
  327. gwpy-4.0.0rc2/gwpy/spectrogram/tests/__init__.py +18 -0
  328. gwpy-4.0.0rc2/gwpy/spectrogram/tests/test_spectrogram.py +287 -0
  329. gwpy-4.0.0rc2/gwpy/table/__init__.py +41 -0
  330. gwpy-4.0.0rc2/gwpy/table/connect.py +287 -0
  331. gwpy-4.0.0rc2/gwpy/table/filter.py +319 -0
  332. gwpy-4.0.0rc2/gwpy/table/filters.py +81 -0
  333. gwpy-4.0.0rc2/gwpy/table/gravityspy.py +299 -0
  334. gwpy-4.0.0rc2/gwpy/table/io/__init__.py +44 -0
  335. gwpy-4.0.0rc2/gwpy/table/io/cwb.py +190 -0
  336. gwpy-4.0.0rc2/gwpy/table/io/gravityspy.py +284 -0
  337. gwpy-4.0.0rc2/gwpy/table/io/gstlal.py +326 -0
  338. gwpy-4.0.0rc2/gwpy/table/io/gwf.py +253 -0
  339. gwpy-4.0.0rc2/gwpy/table/io/gwosc.py +260 -0
  340. gwpy-4.0.0rc2/gwpy/table/io/hacr.py +564 -0
  341. gwpy-4.0.0rc2/gwpy/table/io/ligolw.py +611 -0
  342. gwpy-4.0.0rc2/gwpy/table/io/omega.py +101 -0
  343. gwpy-4.0.0rc2/gwpy/table/io/omicron.py +60 -0
  344. gwpy-4.0.0rc2/gwpy/table/io/pycbc.py +430 -0
  345. gwpy-4.0.0rc2/gwpy/table/io/reg.py +104 -0
  346. gwpy-4.0.0rc2/gwpy/table/io/root.py +263 -0
  347. gwpy-4.0.0rc2/gwpy/table/io/snax.py +143 -0
  348. gwpy-4.0.0rc2/gwpy/table/io/sql.py +414 -0
  349. gwpy-4.0.0rc2/gwpy/table/io/utils.py +210 -0
  350. gwpy-4.0.0rc2/gwpy/table/table.py +681 -0
  351. gwpy-4.0.0rc2/gwpy/table/tests/__init__.py +18 -0
  352. gwpy-4.0.0rc2/gwpy/table/tests/test_gravityspy.py +117 -0
  353. gwpy-4.0.0rc2/gwpy/table/tests/test_io_cwb.py +123 -0
  354. gwpy-4.0.0rc2/gwpy/table/tests/test_io_gstlal.py +234 -0
  355. gwpy-4.0.0rc2/gwpy/table/tests/test_io_gwf.py +92 -0
  356. gwpy-4.0.0rc2/gwpy/table/tests/test_io_gwosc.py +62 -0
  357. gwpy-4.0.0rc2/gwpy/table/tests/test_io_hacr.py +199 -0
  358. gwpy-4.0.0rc2/gwpy/table/tests/test_io_hdf5.py +56 -0
  359. gwpy-4.0.0rc2/gwpy/table/tests/test_io_ligolw.py +356 -0
  360. gwpy-4.0.0rc2/gwpy/table/tests/test_io_omega.py +90 -0
  361. gwpy-4.0.0rc2/gwpy/table/tests/test_io_omicron.py +64 -0
  362. gwpy-4.0.0rc2/gwpy/table/tests/test_io_pycbc.py +280 -0
  363. gwpy-4.0.0rc2/gwpy/table/tests/test_io_root.py +163 -0
  364. gwpy-4.0.0rc2/gwpy/table/tests/test_io_snax.py +144 -0
  365. gwpy-4.0.0rc2/gwpy/table/tests/test_io_sql.py +81 -0
  366. gwpy-4.0.0rc2/gwpy/table/tests/test_table.py +382 -0
  367. gwpy-4.0.0rc2/gwpy/table/tests/utils.py +99 -0
  368. gwpy-4.0.0rc2/gwpy/testing/__init__.py +18 -0
  369. gwpy-4.0.0rc2/gwpy/testing/data/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  370. gwpy-4.0.0rc2/gwpy/testing/data/HLV-HW100916-968654552-1.gwf +0 -0
  371. gwpy-4.0.0rc2/gwpy/testing/data/HLV-HW100916-968654552-1.hdf +0 -0
  372. gwpy-4.0.0rc2/gwpy/testing/data/X1-GWPY_TEST_SEGMENTS-0-10.txt +4 -0
  373. gwpy-4.0.0rc2/gwpy/testing/data/X1-GWPY_TEST_SEGMENTS-0-10.xml.gz +0 -0
  374. gwpy-4.0.0rc2/gwpy/testing/errors.py +132 -0
  375. gwpy-4.0.0rc2/gwpy/testing/fixtures.py +200 -0
  376. gwpy-4.0.0rc2/gwpy/testing/marks.py +41 -0
  377. gwpy-4.0.0rc2/gwpy/testing/mocks.py +218 -0
  378. gwpy-4.0.0rc2/gwpy/testing/utils.py +408 -0
  379. gwpy-4.0.0rc2/gwpy/time/__init__.py +54 -0
  380. gwpy-4.0.0rc2/gwpy/time/__main__.py +102 -0
  381. gwpy-4.0.0rc2/gwpy/time/_ligotimegps.py +73 -0
  382. gwpy-4.0.0rc2/gwpy/time/_tconvert.py +379 -0
  383. gwpy-4.0.0rc2/gwpy/time/tests/__init__.py +18 -0
  384. gwpy-4.0.0rc2/gwpy/time/tests/test_main.py +40 -0
  385. gwpy-4.0.0rc2/gwpy/time/tests/test_time.py +153 -0
  386. gwpy-4.0.0rc2/gwpy/timeseries/__init__.py +42 -0
  387. gwpy-4.0.0rc2/gwpy/timeseries/connect.py +918 -0
  388. gwpy-4.0.0rc2/gwpy/timeseries/core.py +1887 -0
  389. gwpy-4.0.0rc2/gwpy/timeseries/io/__init__.py +31 -0
  390. gwpy-4.0.0rc2/gwpy/timeseries/io/ascii.py +105 -0
  391. gwpy-4.0.0rc2/gwpy/timeseries/io/cache.py +110 -0
  392. gwpy-4.0.0rc2/gwpy/timeseries/io/gwdatafind.py +493 -0
  393. gwpy-4.0.0rc2/gwpy/timeseries/io/gwf/__init__.py +52 -0
  394. gwpy-4.0.0rc2/gwpy/timeseries/io/gwf/core.py +709 -0
  395. gwpy-4.0.0rc2/gwpy/timeseries/io/gwf/framecpp.py +675 -0
  396. gwpy-4.0.0rc2/gwpy/timeseries/io/gwf/framel.py +274 -0
  397. gwpy-4.0.0rc2/gwpy/timeseries/io/gwf/lalframe.py +334 -0
  398. gwpy-4.0.0rc2/gwpy/timeseries/io/gwf/utils.py +91 -0
  399. gwpy-4.0.0rc2/gwpy/timeseries/io/hdf5.py +168 -0
  400. gwpy-4.0.0rc2/gwpy/timeseries/io/losc.py +781 -0
  401. gwpy-4.0.0rc2/gwpy/timeseries/io/nds2.py +592 -0
  402. gwpy-4.0.0rc2/gwpy/timeseries/io/wav.py +174 -0
  403. gwpy-4.0.0rc2/gwpy/timeseries/statevector.py +1146 -0
  404. gwpy-4.0.0rc2/gwpy/timeseries/tests/__init__.py +18 -0
  405. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_core.py +742 -0
  406. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_cache.py +70 -0
  407. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_gwf_framecpp.py +80 -0
  408. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_gwf_lalframe.py +229 -0
  409. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_gwf_utils.py +83 -0
  410. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_hdf5.py +82 -0
  411. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_losc.py +69 -0
  412. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_io_pelican.py +48 -0
  413. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_statevector.py +555 -0
  414. gwpy-4.0.0rc2/gwpy/timeseries/tests/test_timeseries.py +2062 -0
  415. gwpy-4.0.0rc2/gwpy/timeseries/timeseries.py +3126 -0
  416. gwpy-4.0.0rc2/gwpy/tools/__init__.py +18 -0
  417. gwpy-4.0.0rc2/gwpy/tools/_utils.py +280 -0
  418. gwpy-4.0.0rc2/gwpy/tools/rds.py +292 -0
  419. gwpy-4.0.0rc2/gwpy/tools/tests/__init__.py +18 -0
  420. gwpy-4.0.0rc2/gwpy/tools/tests/test_rds.py +41 -0
  421. gwpy-4.0.0rc2/gwpy/types/__init__.py +38 -0
  422. gwpy-4.0.0rc2/gwpy/types/array.py +611 -0
  423. gwpy-4.0.0rc2/gwpy/types/array2d.py +530 -0
  424. gwpy-4.0.0rc2/gwpy/types/connect.py +174 -0
  425. gwpy-4.0.0rc2/gwpy/types/index.py +141 -0
  426. gwpy-4.0.0rc2/gwpy/types/io/__init__.py +26 -0
  427. gwpy-4.0.0rc2/gwpy/types/io/ascii.py +169 -0
  428. gwpy-4.0.0rc2/gwpy/types/io/hdf5.py +344 -0
  429. gwpy-4.0.0rc2/gwpy/types/io/ligolw.py +257 -0
  430. gwpy-4.0.0rc2/gwpy/types/series.py +1453 -0
  431. gwpy-4.0.0rc2/gwpy/types/sliceutils.py +211 -0
  432. gwpy-4.0.0rc2/gwpy/types/tests/__init__.py +18 -0
  433. gwpy-4.0.0rc2/gwpy/types/tests/test_array.py +310 -0
  434. gwpy-4.0.0rc2/gwpy/types/tests/test_array2d.py +311 -0
  435. gwpy-4.0.0rc2/gwpy/types/tests/test_index.py +84 -0
  436. gwpy-4.0.0rc2/gwpy/types/tests/test_series.py +675 -0
  437. gwpy-4.0.0rc2/gwpy/typing.py +48 -0
  438. gwpy-4.0.0rc2/gwpy/utils/__init__.py +27 -0
  439. gwpy-4.0.0rc2/gwpy/utils/decorators.py +178 -0
  440. gwpy-4.0.0rc2/gwpy/utils/enum.py +64 -0
  441. gwpy-4.0.0rc2/gwpy/utils/env.py +79 -0
  442. gwpy-4.0.0rc2/gwpy/utils/lal.py +495 -0
  443. gwpy-4.0.0rc2/gwpy/utils/misc.py +170 -0
  444. gwpy-4.0.0rc2/gwpy/utils/mp.py +193 -0
  445. gwpy-4.0.0rc2/gwpy/utils/progress.py +57 -0
  446. gwpy-4.0.0rc2/gwpy/utils/sphinx/__init__.py +19 -0
  447. gwpy-4.0.0rc2/gwpy/utils/sphinx/gallery.py +178 -0
  448. gwpy-4.0.0rc2/gwpy/utils/tests/__init__.py +18 -0
  449. gwpy-4.0.0rc2/gwpy/utils/tests/test_decorators.py +75 -0
  450. gwpy-4.0.0rc2/gwpy/utils/tests/test_enum.py +70 -0
  451. gwpy-4.0.0rc2/gwpy/utils/tests/test_env.py +68 -0
  452. gwpy-4.0.0rc2/gwpy/utils/tests/test_lal.py +164 -0
  453. gwpy-4.0.0rc2/gwpy/utils/tests/test_misc.py +61 -0
  454. gwpy-4.0.0rc2/gwpy/utils/tests/test_mp.py +66 -0
  455. gwpy-4.0.0rc2/gwpy/utils/tests/test_sphinx_gallery.py +92 -0
  456. gwpy-4.0.0rc2/gwpy.egg-info/PKG-INFO +130 -0
  457. gwpy-4.0.0rc2/gwpy.egg-info/SOURCES.txt +465 -0
  458. gwpy-4.0.0rc2/gwpy.egg-info/dependency_links.txt +1 -0
  459. gwpy-4.0.0rc2/gwpy.egg-info/entry_points.txt +4 -0
  460. gwpy-4.0.0rc2/gwpy.egg-info/requires.txt +65 -0
  461. gwpy-4.0.0rc2/gwpy.egg-info/top_level.txt +1 -0
  462. gwpy-4.0.0rc2/pyproject.toml +463 -0
  463. gwpy-4.0.0rc2/setup.cfg +4 -0
  464. gwpy-4.0.0rc2/typings/README.md +9 -0
  465. gwpy-4.0.0rc2/typings/lal.pyi +321 -0
  466. gwpy-4.0.0rc2/typings/lalframe.pyi +147 -0
  467. gwpy-4.0.0rc2/typings/nds2.pyi +167 -0
@@ -0,0 +1 @@
1
+ gwpy/_version.py export-subst
@@ -0,0 +1,94 @@
1
+ # GWpy
2
+
3
+ GWpy is a Python library toolkit for gravitational-wave astrophysics.
4
+ See the `README.md` file for basic information and the `docs/` folder for
5
+ user and developer documentation.
6
+
7
+ ## Tech stack
8
+
9
+ - **Programming Language**: Python 3.10+ (development uses Python 3.12)
10
+
11
+ - **Platform support**: Linux, macOS, Windows
12
+
13
+ - **Versioning**: `setuptools_scm`
14
+
15
+ - **Packaging**: `pyproject.toml` installable with `pip`/`uv` with extra dependency-groups
16
+ for non-Python dependencies installable with `conda`.
17
+
18
+ - **Testing**: `pytest` (config in `pyproject.toml`)
19
+
20
+ - **Linting/formatting**: `ruff` (config in `pyproject.toml`), plus `mypy` settings
21
+
22
+ - **Documentation**: Sphinx sources under `docs/` and `examples/`
23
+
24
+ - **CLI entry points**: Defined in `pyproject.toml` (e.g., `gwpy-plot`)
25
+
26
+ ## Repository layout (high level)
27
+
28
+ - `gwpy/` — main package.
29
+ Each subfolder (e.g., `gwpy/astro/`) is a subpackage with its own
30
+ `__init__.py` and `tests/` folder.
31
+
32
+ - `docs/` — user/developer documentation (Sphinx).
33
+
34
+ - `examples/` — runnable examples and a lightweight integration test (`test_examples.py`).
35
+
36
+ - `tests` are colocated inside package subfolders (e.g. `gwpy/astro/tests/`).
37
+
38
+ - The `worktrees/` directory may be present to hold multiple git worktrees -
39
+ ignore it during repo-wide scans and analysis.
40
+
41
+ ## Coding guidelines
42
+
43
+ - **Style: follow PEP 8 with opinionated `ruff` rules in `pyproject.toml`.
44
+ The project runs `ruff` in CI and locally via `python -m ruff .`.
45
+ All features should uses the latest syntax supported by the minimum Python
46
+ version.
47
+
48
+ - **Type checking**: all code should include comprehensive type annotations following
49
+ PEP 563, 585, and 604.
50
+ `mypy` is configured to check typing.
51
+
52
+ - **Documentation**: all public classes, methods, and functions should include
53
+ docstrings following the NumPy/SciPy docstring standard.
54
+ Use Sphinx-compatible reStructuredText markup and follow SemBR (https://sembr.org/)
55
+ where appropriate.
56
+ Docstrings should include type hints even if the function is already annotated.
57
+
58
+ - **Tests**: use `pytest`. New code must include unit tests.
59
+ Run tests locally via:
60
+
61
+ ```shell
62
+ uv pip install . --group dev
63
+ uv run pytest gwpy/ examples/
64
+ ```
65
+
66
+ - Keep tests small and focused; prefer `pytest.mark.parametrize` or separate tests
67
+ over large tests with multiple independent assertions.
68
+ Use mocking where appropriate to avoid slow or flaky tests.
69
+
70
+ - Tests that require optional dependencies should be marked using `@pytest.mark.requires`.
71
+
72
+ ## Commands & quick-start (recommended)
73
+
74
+ - Preferred quick dev setup (isolated environment):
75
+
76
+ Use `uv` to manage virtual environments (https://pypa.github.io/uv/).
77
+
78
+ # create & activate venv
79
+ uv venv --seed
80
+ . .venv/bin/activate
81
+
82
+ # install editable package with dev extras (per `CONTRIBUTING.md`)
83
+ uv pip install . --group dev
84
+
85
+ - Run tests (fast subset):
86
+
87
+ python -m pytest gwpy/ -q
88
+
89
+ - Run ruff locally:
90
+
91
+ python -m ruff .
92
+
93
+ - If you need reproducible, CI-like envs, prefer conda + conda-forge binaries
94
+ (especially when `lalsuite` or other heavy scientific packages are required).
@@ -0,0 +1,56 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+
5
+ # C extensions
6
+ *.so
7
+
8
+ # Distribution / packaging
9
+ .Python
10
+ env/
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ eggs/
15
+ /gwpy/_version.py
16
+ lib/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ venv/
22
+ *.egg-info/
23
+ .installed.cfg
24
+ *.egg
25
+ MANIFEST
26
+ Portfile
27
+ .coverage
28
+ .eggs/
29
+
30
+ # Installer logs
31
+ pip-log.txt
32
+ pip-delete-this-directory.txt
33
+
34
+ # Sphinx documentation
35
+ # -- see /docs/.gitignore
36
+
37
+ # OS/editor files
38
+ *.swp
39
+ .DS_Store
40
+ .idea
41
+ .vscode
42
+
43
+ # Examples output
44
+ /examples/*.png
45
+ /examples/*/*.png
46
+
47
+ # Patches
48
+ /*.patch
49
+
50
+ # py.test cache dir
51
+ /.cache
52
+ /.pytest_cache/
53
+
54
+ # dqsegdb files
55
+ __dqsegdb*.json
56
+ __segments*.json
@@ -0,0 +1,82 @@
1
+ # -- Check dependency compatibility
2
+ #
3
+ # These jobs check that the minimum versions are well specified,
4
+ # and that this project is compatible with the new pre-relase
5
+ # versions of anything we can find.
6
+ #
7
+
8
+ spec:
9
+ inputs:
10
+ stage:
11
+ default: test
12
+ description: "Pipeline stage in which to add jobs"
13
+ type: string
14
+ pytest_options:
15
+ default: ""
16
+ description: "Extra options to pass to pytest"
17
+ type: string
18
+ minimum_python_version:
19
+ default: "3.11"
20
+ description: "Python version for minimum dependency compatibility check"
21
+ type: string
22
+ experimental_python_version:
23
+ default: "3.12"
24
+ description: "Python version for experimental dependency compatibility check"
25
+ type: string
26
+
27
+ ---
28
+
29
+ include:
30
+ - local: .gitlab/ci/rules.yml
31
+
32
+ # configure minimum dependency compatibility job
33
+ - local: .gitlab/ci/test-job.yml
34
+ inputs:
35
+ stage: $[[ inputs.stage ]]
36
+ job_name: "compat_minimum"
37
+ install_target: "."
38
+ pip_cmd: "uv pip"
39
+ pip_options: "--group test --resolution lowest-direct"
40
+ pytest_options: $[[ inputs.pytest_options ]]
41
+
42
+ # configure experimental dependency compatibility job
43
+ - local: .gitlab/ci/test-job.yml
44
+ inputs:
45
+ stage: $[[ inputs.stage ]]
46
+ job_name: "compat_experimental"
47
+ install_target: "."
48
+ pip_cmd: "uv pip"
49
+ pip_options: "--group dev --upgrade --resolution highest --prerelease allow"
50
+ pytest_options: $[[ inputs.pytest_options ]]
51
+
52
+ .compat:
53
+ needs: []
54
+ rules:
55
+ - if: '$CI_COMMIT_MESSAGE =~ /\[skip compat\]/'
56
+ when: never
57
+ - !reference [.rules_nightly, rules]
58
+ - !reference [.rules_full_test, rules]
59
+ before_script:
60
+ - uv venv --python ${PYTHON_VERSION}
61
+ - source .venv/bin/activate
62
+
63
+ # test against the minimum specified requirements
64
+ compat_minimum:
65
+ extends:
66
+ - .compat_minimum
67
+ - .compat
68
+ image: "ghcr.io/astral-sh/uv:python$[[ inputs.minimum_python_version ]]-bookworm"
69
+ variables:
70
+ PYTHON_VERSION: $[[ inputs.minimum_python_version ]]
71
+ artifacts:
72
+ paths:
73
+ - .coverage*
74
+
75
+ # test against latest/pre-release versions
76
+ compat_experimental:
77
+ extends:
78
+ - .compat_experimental
79
+ - .compat
80
+ image: "ghcr.io/astral-sh/uv:python$[[ inputs.experimental_python_version ]]-bookworm"
81
+ variables:
82
+ PYTHON_VERSION: $[[ inputs.experimental_python_version ]]
@@ -0,0 +1,32 @@
1
+ # -- Python test coverage measurements
2
+
3
+ spec:
4
+ inputs:
5
+
6
+ ---
7
+
8
+ include:
9
+ - local: .gitlab/ci/rules.yml
10
+
11
+ coverage:
12
+ stage: .post
13
+ image: python
14
+ rules: !reference [.rules_full_test, rules]
15
+ script:
16
+ # install coverage (with toml parsing extra)
17
+ - python -m pip install coverage[toml]
18
+ # combine coverage files from other jobs
19
+ - python -m coverage combine .coverage*
20
+ # write an HTML report
21
+ - python -m coverage html -d htmlcov
22
+ # print a report (for the record)
23
+ - python -m coverage report -m
24
+ allow_failure: true
25
+ artifacts:
26
+ name: htmlcov
27
+ expose_as: Coverage report
28
+ paths:
29
+ - htmlcov/index.html
30
+ - htmlcov
31
+ # report coverage here, now that we have all of the information
32
+ coverage: '/^TOTAL\s+.*\s+(\d+\.?\d*)%/'
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ #
3
+ # Initialise credentials for jobs
4
+ #
5
+
6
+ if [ "${KERBEROS_KEYTAB}" = "" ]; then
7
+ echo -e "\x1B[94mNo KERBEROS_KEYTAB configured, skipping credential init.\x1B[0m"
8
+ exit 0
9
+ fi
10
+
11
+ # install tooling
12
+ conda install -c conda-forge -q -y ciecplib krb5
13
+
14
+ # unpack keytab
15
+ export KRB5_KTNAME="${CI_PROJECT_DIR}/.keytab"
16
+ echo "${KERBEROS_KEYTAB}" | base64 -d > ${KRB5_KTNAME}
17
+ chmod 0600 "${KRB5_KTNAME}"
18
+
19
+ # find principal
20
+ export KRB5_PRINCIPAL="$(klist -k ${KRB5_KTNAME} | tail -n 1 | awk '{print $2}')"
21
+
22
+ # get Kerberos TGT
23
+ kinit "${KRB5_PRINCIPAL}" -k -t "${KRB5_KTNAME}"
24
+ klist
25
+
26
+ # get LIGO.ORG X.509
27
+ ecp-get-cert -i login.ligo.org --kerberos
28
+ ecp-cert-info
@@ -0,0 +1,44 @@
1
+ spec:
2
+ inputs:
3
+
4
+ ---
5
+
6
+ .linux:
7
+ rules:
8
+ - if: '$CI_COMMIT_MESSAGE =~ /\[skip linux\]/'
9
+ when: never
10
+ tags:
11
+ - saas-linux-medium-amd64
12
+
13
+ .macos:
14
+ rules:
15
+ # Only run macOS jobs inside the GWpy namespace where
16
+ # macOS runners are available
17
+ - if: '$CI_PROJECT_ROOT_NAMESPACE != "gwpy"'
18
+ when: never
19
+ - if: '$CI_COMMIT_MESSAGE =~ /\[skip macos\]/'
20
+ when: never
21
+ tags:
22
+ - saas-macos-medium-m1
23
+ image: macos-15-xcode-16
24
+ retry:
25
+ # retry all windows jobs up to 2 times on failure, they are flaky
26
+ max: 2
27
+ when: always
28
+
29
+ .windows:
30
+ rules:
31
+ - if: '$CI_COMMIT_MESSAGE =~ /\[skip windows\]/'
32
+ when: never
33
+ variables:
34
+ # windows gitlab runners don't support symbolic links, so we can't
35
+ # run the tests that rely upon them
36
+ PYTEST_ADDOPTS: "-k 'not table\\\\rate and not table\\\\tiles'"
37
+ # pytest-xdist doesn't auto-detect the number of CPUs sometimes
38
+ PYTEST_XDIST_AUTO_NUM_WORKERS: "2"
39
+ tags:
40
+ - saas-windows-medium-amd64
41
+ retry:
42
+ # retry all windows jobs up to 2 times on failure, they are flaky
43
+ max: 2
44
+ when: always
@@ -0,0 +1,31 @@
1
+ # Common elements for Python components
2
+
3
+ spec:
4
+ inputs:
5
+ cache_dir:
6
+ default: ".cache/pip"
7
+ description: "The path to cache to (relative to CI_PROJECT_DIR)"
8
+ image:
9
+ default: "python"
10
+ description: "The default image to use for jobs"
11
+ job_prefix:
12
+ default: ".python"
13
+ description: "Prefix to apply to all templates"
14
+
15
+ ---
16
+
17
+ $[[ inputs.job_prefix ]]_image:
18
+ image: $[[ inputs.image ]]
19
+
20
+ $[[ inputs.job_prefix ]]_cache:
21
+ variables:
22
+ PIP_CACHE_DIR: "${CI_PROJECT_DIR}/$[[ inputs.cache_dir ]]"
23
+ cache:
24
+ key: "pip-${CI_JOB_NAME_SLUG}"
25
+ paths:
26
+ - $[[ inputs.cache_dir ]]
27
+
28
+ $[[ inputs.job_prefix ]]_base:
29
+ extends:
30
+ - $[[ inputs.job_prefix ]]_image
31
+ - $[[ inputs.job_prefix ]]_cache
@@ -0,0 +1,45 @@
1
+ # -- Build Python project distributions
2
+
3
+ spec:
4
+ inputs:
5
+ stage:
6
+ default: build
7
+ description: "Pipeline stage in which to add jobs"
8
+ type: string
9
+
10
+ ---
11
+
12
+ include:
13
+ - local: .gitlab/ci/rules.yml
14
+
15
+ build:
16
+ rules: !reference [.rules_build, rules]
17
+ needs: []
18
+ stage: $[[ inputs.stage ]]
19
+ image: ghcr.io/astral-sh/uv:alpine
20
+ variables:
21
+ # get the full history for setuptools-scm
22
+ GIT_DEPTH: 0
23
+ # debug setuptools-scm
24
+ SETUPTOOLS_SCM_DEBUG: 1
25
+ before_script:
26
+ # need git for setuptools-scm
27
+ - apk add --no-cache git
28
+ script:
29
+ - uv venv
30
+ - uv pip install build
31
+ - source .venv/bin/activate
32
+ # if running a default branch push pipeline, strip the +g<HASH> suffix
33
+ # from the version to give something that test.pypi.org will accept
34
+ - |
35
+ if [ "${CI_COMMIT_TAG}" = "" ] && [ "${CI_PIPELINE_SOURCE}" = "push" ] && [ "${CI_COMMIT_REF_PROTECTED}" = "true" ]; then
36
+ export SETUPTOOLS_SCM_OVERRIDES_FOR_GWPY="{local_scheme='no-local-version'}";
37
+ fi
38
+ # generate the distributions
39
+ - python -m build . -o .
40
+ - python -m tarfile --list *.tar.*
41
+ - python -m zipfile --list *.whl
42
+ artifacts:
43
+ paths:
44
+ - "*.tar.*"
45
+ - "*.whl"
@@ -0,0 +1,143 @@
1
+ # -- Quality Assurance jobs
2
+
3
+ spec:
4
+ inputs:
5
+ stage:
6
+ default: test
7
+ description: "Pipeline stage in which to add jobs"
8
+ type: string
9
+ project_dir:
10
+ default: "."
11
+ description: "Project directory to scan"
12
+ type: string
13
+ requirements:
14
+ default: ""
15
+ description: "Extra requirements to install with pip"
16
+ type: string
17
+ ruff_options:
18
+ default: ""
19
+ description: "Extra options to pass to ruff check"
20
+ type: string
21
+ mypy_options:
22
+ default: ""
23
+ description: "Extra options to pass to mypy"
24
+ type: string
25
+ python_version:
26
+ default: "3.13"
27
+ description: "Python version to use for testing"
28
+ type: string
29
+ minimum_python_version:
30
+ default: "3.11"
31
+ description: "Python version for minimum dependency compatibility check"
32
+ type: string
33
+
34
+ ---
35
+
36
+ include:
37
+ - component: gitlab.com/components/dependency-scanning/main@~latest
38
+ inputs:
39
+ stage: $[[ inputs.stage ]]
40
+ job_name: "dependency-scanning"
41
+ - component: gitlab.com/components/sast/sast@~latest
42
+ inputs:
43
+ stage: $[[ inputs.stage ]]
44
+ run_advanced_sast: true
45
+ rules:
46
+ - if: '$GITLAB_FEATURES =~ /\bsast_advanced\b/'
47
+ - component: gitlab.com/components/sast/sast@~latest
48
+ inputs:
49
+ stage: $[[ inputs.stage ]]
50
+ run_advanced_sast: false
51
+ rules:
52
+ - if: '$GITLAB_FEATURES !~ /\bsast_advanced\b/'
53
+ - local: .gitlab/ci/rules.yml
54
+ - local: .gitlab/ci/python-base.yml
55
+
56
+ .qa:
57
+ extends: .rules_qa_security
58
+ stage: $[[ inputs.stage ]]
59
+ needs: []
60
+
61
+ gitlab-advanced-sast:
62
+ needs: !reference [.qa, needs]
63
+ rules:
64
+ # skip if we just can't run advanced sast
65
+ - if: '$GITLAB_FEATURES !~ /\bsast_advanced\b/'
66
+ when: never
67
+ - !reference [.qa, rules]
68
+
69
+ semgrep-sast:
70
+ needs: !reference [.qa, needs]
71
+ rules:
72
+ # skip if we can run advanced sast
73
+ - if: '$GITLAB_FEATURES =~ /\bsast_advanced\b/'
74
+ when: never
75
+ - !reference [.qa, rules]
76
+
77
+ ruff:
78
+ extends: .qa
79
+ image: ghcr.io/astral-sh/ruff:alpine
80
+ script:
81
+ - ruff check
82
+ $[[ inputs.project_dir ]]
83
+ $[[ inputs.ruff_options ]]
84
+ --exit-zero
85
+ - ruff check
86
+ $[[ inputs.project_dir ]]
87
+ $[[ inputs.ruff_options ]]
88
+ --exit-zero
89
+ --output-format gitlab
90
+ --output-file gl-ruff.json
91
+ artifacts:
92
+ reports:
93
+ codequality: gl-ruff.json
94
+
95
+ ty:
96
+ extends: .qa
97
+ image: ghcr.io/astral-sh/uv:debian
98
+ variables:
99
+ UV_MANAGED_PYTHON: 1
100
+ script:
101
+ # Install the project
102
+ - uv venv --python $[[ inputs.python_version ]]
103
+ - uv pip install -e . --group dev
104
+ # Run ty and format for gitlab
105
+ - uvx ty check
106
+ $[[ inputs.project_dir ]]
107
+ --exit-zero
108
+ --output-format gitlab
109
+ > gl-ty.json
110
+ # Run ty and print to console
111
+ - uvx ty check
112
+ $[[ inputs.project_dir ]]
113
+ --exit-zero
114
+ artifacts:
115
+ reports:
116
+ codequality: gl-ty.json
117
+
118
+ rstcheck:
119
+ extends:
120
+ - .python_base
121
+ - .qa
122
+ image: ghcr.io/astral-sh/uv:debian
123
+ script:
124
+ - uvx --with rstcheck[sphinx] python .gitlab/ci/rstcheck.py > gl-rstcheck.json
125
+ - uvx python -m json.tool gl-rstcheck.json
126
+ artifacts:
127
+ reports:
128
+ codequality: gl-rstcheck.json
129
+
130
+ uv.lock:
131
+ image: ghcr.io/astral-sh/uv:debian
132
+ extends:
133
+ - .qa
134
+ script:
135
+ # Generate uv.lock file with minimum dependencies
136
+ - uv venv --python $[[ inputs.minimum_python_version ]]
137
+ - uv lock --resolution lowest-direct
138
+ artifacts:
139
+ paths:
140
+ - uv.lock
141
+
142
+ dependency-scanning:
143
+ needs: ["uv.lock"]
@@ -0,0 +1,113 @@
1
+ """Run rstcheck and report output for codeclimate."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import re
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import (
11
+ TYPE_CHECKING,
12
+ TypedDict,
13
+ )
14
+
15
+ from rstcheck_core.config import RstcheckConfig
16
+ from rstcheck_core.runner import RstcheckMainRunner
17
+
18
+ if TYPE_CHECKING:
19
+ from typing import Literal
20
+
21
+ from rstcheck_core.types import LintError
22
+
23
+ Severity = Literal["info", "minor", "major", "critical", "blocker"]
24
+
25
+ MESSAGE_RE = re.compile(
26
+ r"\((?P<severity>[A-Z]+)/[0-9]+\)(\s+)(?P<message>.*)",
27
+ )
28
+ SEVERITY: dict[str, Severity] = {
29
+ "ERROR": "major",
30
+ "SEVERE": "major",
31
+ "INFO": "info",
32
+ "WARNING": "minor",
33
+ }
34
+
35
+
36
+ class CodeQualityLocation(TypedDict):
37
+ """Location parameter in a `CodeQualityItem`."""
38
+
39
+ path: str
40
+ lines: dict[str, int]
41
+
42
+
43
+ class CodeQualityItem(TypedDict):
44
+ """Gitlab Code Quality item.
45
+
46
+ See <https://docs.gitlab.com/ci/testing/code_quality/#code-quality-report-format>.
47
+ """
48
+
49
+ check_name: str
50
+ description: str
51
+ fingerprint: str
52
+ location: CodeQualityLocation
53
+ severity: Severity
54
+
55
+
56
+ def rstcheck(
57
+ config_path: Path,
58
+ check_paths: list[str | Path],
59
+ *,
60
+ recursive: bool = True,
61
+ ) -> RstcheckMainRunner:
62
+ """Create, execute, and return an `rstcheck_core.runner.RstcheckMainRunner`."""
63
+ config = RstcheckConfig(
64
+ config_path=config_path,
65
+ recursive=recursive,
66
+ )
67
+ runner = RstcheckMainRunner(
68
+ check_paths=list(map(Path, check_paths)),
69
+ rstcheck_config=config,
70
+ )
71
+ runner.check()
72
+ return runner
73
+
74
+
75
+ def codeclimate_item(item: LintError) -> CodeQualityItem:
76
+ """Construct a codeclimate item for this rstcheck lint error."""
77
+ fingerprint = hashlib.sha1(
78
+ "".join(map(str, item.values())).encode("utf-8"),
79
+ usedforsecurity=False,
80
+ ).hexdigest()
81
+ match = MESSAGE_RE.match(item["message"]).groupdict()
82
+ return CodeQualityItem({
83
+ "check_name": match["message"],
84
+ "description": match["message"],
85
+ "fingerprint": fingerprint,
86
+ "location": {
87
+ "path": str(item["source_origin"]),
88
+ "lines": {
89
+ "begin": (lineno := int(item["line_number"])),
90
+ "end": lineno,
91
+ },
92
+ },
93
+ "severity": SEVERITY.get(match["severity"], "info"),
94
+ })
95
+
96
+
97
+ def codeclimate(items: list[LintError]) -> list[CodeQualityItem]:
98
+ """Parse a list of errors for codeclimate."""
99
+ return [codeclimate_item(item) for item in items]
100
+
101
+
102
+ def main() -> None:
103
+ """Run `rstcheck` and print a codeclimate JSON report."""
104
+ results = rstcheck(
105
+ Path("pyproject.toml"),
106
+ ["docs"],
107
+ )
108
+ issues = codeclimate(results.errors)
109
+ json.dump(issues, sys.stdout)
110
+
111
+
112
+ if __name__ == "__main__":
113
+ main()