py4tsa 3.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. py4tsa-3.2.0/.github/prompts/review-library.prompt.md +15 -0
  2. py4tsa-3.2.0/.github/workflows/ci.yml +101 -0
  3. py4tsa-3.2.0/.github/workflows/wheels.yml +91 -0
  4. py4tsa-3.2.0/.gitignore +23 -0
  5. py4tsa-3.2.0/.readthedocs.yaml +33 -0
  6. py4tsa-3.2.0/AGENTS.md +33 -0
  7. py4tsa-3.2.0/CHANGELOG.md +171 -0
  8. py4tsa-3.2.0/CITATION.cff +104 -0
  9. py4tsa-3.2.0/CMakeLists.txt +125 -0
  10. py4tsa-3.2.0/CONTRIBUTING.md +84 -0
  11. py4tsa-3.2.0/LICENSE +674 -0
  12. py4tsa-3.2.0/PKG-INFO +310 -0
  13. py4tsa-3.2.0/README.md +282 -0
  14. py4tsa-3.2.0/cmake/FindSphinx.cmake +11 -0
  15. py4tsa-3.2.0/conda-recipe/conda_build_config.yaml +20 -0
  16. py4tsa-3.2.0/conda-recipe/meta.yaml +59 -0
  17. py4tsa-3.2.0/docs/CMakeLists.txt +59 -0
  18. py4tsa-3.2.0/docs/Doxyfile.in +2460 -0
  19. py4tsa-3.2.0/docs/_static/.gitkeep +0 -0
  20. py4tsa-3.2.0/docs/conf.py +247 -0
  21. py4tsa-3.2.0/docs/index.rst +45 -0
  22. py4tsa-3.2.0/docs/make.bat +35 -0
  23. py4tsa-3.2.0/docs/requirements.txt +4 -0
  24. py4tsa-3.2.0/docs/structure/contact.rst +24 -0
  25. py4tsa-3.2.0/docs/structure/installation.rst +81 -0
  26. py4tsa-3.2.0/docs/structure/libs/AR2.rst +5 -0
  27. py4tsa-3.2.0/docs/structure/libs/AR2Parcor.rst +5 -0
  28. py4tsa-3.2.0/docs/structure/libs/ARMAFilter.rst +5 -0
  29. py4tsa-3.2.0/docs/structure/libs/ARMAView.rst +5 -0
  30. py4tsa-3.2.0/docs/structure/libs/ARMAfit.rst +5 -0
  31. py4tsa-3.2.0/docs/structure/libs/AlgoBase.rst +5 -0
  32. py4tsa-3.2.0/docs/structure/libs/AlgoExceptions.rst +5 -0
  33. py4tsa-3.2.0/docs/structure/libs/ArBurgEstimator.rst +5 -0
  34. py4tsa-3.2.0/docs/structure/libs/ArDurbinEstimator.rst +5 -0
  35. py4tsa-3.2.0/docs/structure/libs/Arma2Psd.rst +5 -0
  36. py4tsa-3.2.0/docs/structure/libs/Arma2TF.rst +5 -0
  37. py4tsa-3.2.0/docs/structure/libs/BLInterpolation.rst +5 -0
  38. py4tsa-3.2.0/docs/structure/libs/BartlettWindow.rst +5 -0
  39. py4tsa-3.2.0/docs/structure/libs/BaseFFT.rst +5 -0
  40. py4tsa-3.2.0/docs/structure/libs/BaseView.rst +5 -0
  41. py4tsa-3.2.0/docs/structure/libs/BaseWindow.rst +5 -0
  42. py4tsa-3.2.0/docs/structure/libs/BisquareWindow.rst +5 -0
  43. py4tsa-3.2.0/docs/structure/libs/ButterworthFilter.rst +5 -0
  44. py4tsa-3.2.0/docs/structure/libs/ClusterizedEventFullFeatured.rst +5 -0
  45. py4tsa-3.2.0/docs/structure/libs/ComplexFFT.rst +5 -0
  46. py4tsa-3.2.0/docs/structure/libs/CreateDvector.rst +5 -0
  47. py4tsa-3.2.0/docs/structure/libs/Cs2HammingWindow.rst +5 -0
  48. py4tsa-3.2.0/docs/structure/libs/Cs2HannWindow.rst +5 -0
  49. py4tsa-3.2.0/docs/structure/libs/DCT.rst +5 -0
  50. py4tsa-3.2.0/docs/structure/libs/DST.rst +5 -0
  51. py4tsa-3.2.0/docs/structure/libs/DoubleWhitening.rst +5 -0
  52. py4tsa-3.2.0/docs/structure/libs/EventDescription.rst +5 -0
  53. py4tsa-3.2.0/docs/structure/libs/EventFullFeatured.rst +5 -0
  54. py4tsa-3.2.0/docs/structure/libs/ExtraWaveletFamilies.rst +4 -0
  55. py4tsa-3.2.0/docs/structure/libs/FrameIChannel.rst +5 -0
  56. py4tsa-3.2.0/docs/structure/libs/FrameIStream.rst +5 -0
  57. py4tsa-3.2.0/docs/structure/libs/IDCT.rst +5 -0
  58. py4tsa-3.2.0/docs/structure/libs/InverseRealFFT.rst +5 -0
  59. py4tsa-3.2.0/docs/structure/libs/KaiserWindow.rst +5 -0
  60. py4tsa-3.2.0/docs/structure/libs/LSLLearning.rst +5 -0
  61. py4tsa-3.2.0/docs/structure/libs/LSLfilter.rst +5 -0
  62. py4tsa-3.2.0/docs/structure/libs/LatticeFilter.rst +5 -0
  63. py4tsa-3.2.0/docs/structure/libs/LatticeView.rst +5 -0
  64. py4tsa-3.2.0/docs/structure/libs/LeastSquaresLattice.rst +5 -0
  65. py4tsa-3.2.0/docs/structure/libs/MYWE.rst +5 -0
  66. py4tsa-3.2.0/docs/structure/libs/NotchWidrow.rst +5 -0
  67. py4tsa-3.2.0/docs/structure/libs/Parcor2AR.rst +5 -0
  68. py4tsa-3.2.0/docs/structure/libs/RLSCanceler.rst +5 -0
  69. py4tsa-3.2.0/docs/structure/libs/RealFFT.rst +5 -0
  70. py4tsa-3.2.0/docs/structure/libs/SelectionOrderCriteria.rst +5 -0
  71. py4tsa-3.2.0/docs/structure/libs/SeqView.rst +5 -0
  72. py4tsa-3.2.0/docs/structure/libs/TF2Psd.rst +5 -0
  73. py4tsa-3.2.0/docs/structure/libs/TFView.rst +5 -0
  74. py4tsa-3.2.0/docs/structure/libs/TukeyHannWindow.rst +5 -0
  75. py4tsa-3.2.0/docs/structure/libs/TukeyWindow.rst +5 -0
  76. py4tsa-3.2.0/docs/structure/libs/Util.rst +5 -0
  77. py4tsa-3.2.0/docs/structure/libs/ViewUtil.rst +5 -0
  78. py4tsa-3.2.0/docs/structure/libs/WDF2Classify.rst +5 -0
  79. py4tsa-3.2.0/docs/structure/libs/WDF2Reconstruct.rst +5 -0
  80. py4tsa-3.2.0/docs/structure/libs/WavReconstruction.rst +5 -0
  81. py4tsa-3.2.0/docs/structure/libs/WaveletThreshold.rst +5 -0
  82. py4tsa-3.2.0/docs/structure/libs/WaveletTransform.rst +5 -0
  83. py4tsa-3.2.0/docs/structure/libs/WelchWindow.rst +5 -0
  84. py4tsa-3.2.0/docs/structure/libs/WindowFactory.rst +5 -0
  85. py4tsa-3.2.0/docs/structure/libs/fparser.rst +5 -0
  86. py4tsa-3.2.0/docs/structure/libs/fpconfig.rst +5 -0
  87. py4tsa-3.2.0/docs/structure/libs/fptypes.rst +5 -0
  88. py4tsa-3.2.0/docs/structure/libs/tsaLog.rst +5 -0
  89. py4tsa-3.2.0/docs/structure/libs/tsaTraits.rst +5 -0
  90. py4tsa-3.2.0/docs/structure/libs/tsaTypes.rst +5 -0
  91. py4tsa-3.2.0/docs/structure/libs/tsaUtilityFunctions.rst +5 -0
  92. py4tsa-3.2.0/docs/structure/source_code.rst +72 -0
  93. py4tsa-3.2.0/include/AR2.hpp +152 -0
  94. py4tsa-3.2.0/include/AR2Parcor.hpp +140 -0
  95. py4tsa-3.2.0/include/ARMAFilter.hpp +168 -0
  96. py4tsa-3.2.0/include/ARMAView.hpp +385 -0
  97. py4tsa-3.2.0/include/ARMAfit.hpp +163 -0
  98. py4tsa-3.2.0/include/AlgoBase.hpp +122 -0
  99. py4tsa-3.2.0/include/AlgoExceptions.hpp +247 -0
  100. py4tsa-3.2.0/include/ArBurgEstimator.hpp +242 -0
  101. py4tsa-3.2.0/include/ArDurbinEstimator.hpp +161 -0
  102. py4tsa-3.2.0/include/Arma2Psd.hpp +170 -0
  103. py4tsa-3.2.0/include/Arma2TF.hpp +180 -0
  104. py4tsa-3.2.0/include/BLInterpolation.hpp +311 -0
  105. py4tsa-3.2.0/include/BartlettWindow.hpp +234 -0
  106. py4tsa-3.2.0/include/BaseFFT.hpp +294 -0
  107. py4tsa-3.2.0/include/BaseView.hpp +182 -0
  108. py4tsa-3.2.0/include/BaseWindow.hpp +206 -0
  109. py4tsa-3.2.0/include/BisquareWindow.hpp +226 -0
  110. py4tsa-3.2.0/include/ButterworthFilter.hpp +160 -0
  111. py4tsa-3.2.0/include/CerealPersistence.hpp +165 -0
  112. py4tsa-3.2.0/include/Cholesky.hpp +174 -0
  113. py4tsa-3.2.0/include/ClusterizedEventFullFeatured.hpp +124 -0
  114. py4tsa-3.2.0/include/ComplexFFT.hpp +201 -0
  115. py4tsa-3.2.0/include/CreateDvector.hpp +79 -0
  116. py4tsa-3.2.0/include/Cs2HammingWindow.hpp +239 -0
  117. py4tsa-3.2.0/include/Cs2HannWindow.hpp +229 -0
  118. py4tsa-3.2.0/include/DCT.hpp +204 -0
  119. py4tsa-3.2.0/include/DST.hpp +204 -0
  120. py4tsa-3.2.0/include/DoubleWhitening.hpp +296 -0
  121. py4tsa-3.2.0/include/EventDescription.hpp +226 -0
  122. py4tsa-3.2.0/include/EventFullFeatured.hpp +140 -0
  123. py4tsa-3.2.0/include/ExtraWaveletFamilies.hpp +50 -0
  124. py4tsa-3.2.0/include/FifoBuffer.hpp +291 -0
  125. py4tsa-3.2.0/include/FrameIChannel.hpp +191 -0
  126. py4tsa-3.2.0/include/FrameIStream.hpp +804 -0
  127. py4tsa-3.2.0/include/IDCT.hpp +204 -0
  128. py4tsa-3.2.0/include/InverseRealFFT.hpp +203 -0
  129. py4tsa-3.2.0/include/KaiserWindow.hpp +254 -0
  130. py4tsa-3.2.0/include/LSLLearning.hpp +257 -0
  131. py4tsa-3.2.0/include/LSLfilter.hpp +315 -0
  132. py4tsa-3.2.0/include/LatticeFilter.hpp +214 -0
  133. py4tsa-3.2.0/include/LatticeView.hpp +252 -0
  134. py4tsa-3.2.0/include/LeastSquaresLattice.hpp +162 -0
  135. py4tsa-3.2.0/include/MYWE.hpp +164 -0
  136. py4tsa-3.2.0/include/NotchWidrow.hpp +193 -0
  137. py4tsa-3.2.0/include/Parcor2AR.hpp +144 -0
  138. py4tsa-3.2.0/include/RLSCanceler.hpp +209 -0
  139. py4tsa-3.2.0/include/RealFFT.hpp +208 -0
  140. py4tsa-3.2.0/include/SelectionOrderCriteria.hpp +209 -0
  141. py4tsa-3.2.0/include/SeqView.hpp +556 -0
  142. py4tsa-3.2.0/include/TF2Psd.hpp +204 -0
  143. py4tsa-3.2.0/include/TFView.hpp +216 -0
  144. py4tsa-3.2.0/include/TukeyHannWindow.hpp +246 -0
  145. py4tsa-3.2.0/include/TukeyWindow.hpp +268 -0
  146. py4tsa-3.2.0/include/Util.hpp +193 -0
  147. py4tsa-3.2.0/include/VArma2TF.hpp +159 -0
  148. py4tsa-3.2.0/include/ViewUtil.hpp +250 -0
  149. py4tsa-3.2.0/include/WDF2Classify.hpp +288 -0
  150. py4tsa-3.2.0/include/WDF2Reconstruct.hpp +268 -0
  151. py4tsa-3.2.0/include/WavReconstruction.hpp +163 -0
  152. py4tsa-3.2.0/include/WaveletThreshold.hpp +280 -0
  153. py4tsa-3.2.0/include/WaveletTransform.hpp +228 -0
  154. py4tsa-3.2.0/include/WelchWindow.hpp +244 -0
  155. py4tsa-3.2.0/include/WindowFactory.hpp +80 -0
  156. py4tsa-3.2.0/include/fparser.hpp +164 -0
  157. py4tsa-3.2.0/include/fpconfig.hpp +56 -0
  158. py4tsa-3.2.0/include/fptypes.hpp +113 -0
  159. py4tsa-3.2.0/include/tsa.hpp +70 -0
  160. py4tsa-3.2.0/include/tsaLog.hpp +89 -0
  161. py4tsa-3.2.0/include/tsaSerialize.hpp +60 -0
  162. py4tsa-3.2.0/include/tsaTraits.hpp +137 -0
  163. py4tsa-3.2.0/include/tsaTypes.hpp +128 -0
  164. py4tsa-3.2.0/include/tsaUtilityFunctions.hpp +335 -0
  165. py4tsa-3.2.0/index.rst +20 -0
  166. py4tsa-3.2.0/pyproject.toml +60 -0
  167. py4tsa-3.2.0/python-wrapper/examples/WDFConfig.ini +19 -0
  168. py4tsa-3.2.0/python-wrapper/examples/WavWdfETG.py +179 -0
  169. py4tsa-3.2.0/python-wrapper/examples/Whitening.ini +11 -0
  170. py4tsa-3.2.0/python-wrapper/examples/Whitening.py +64 -0
  171. py4tsa-3.2.0/python-wrapper/examples/data/dati.wav +0 -0
  172. py4tsa-3.2.0/python-wrapper/py4tsa.cpp +3589 -0
  173. py4tsa-3.2.0/python-wrapper/pytest.ini +4 -0
  174. py4tsa-3.2.0/python-wrapper/setup.cfg +5 -0
  175. py4tsa-3.2.0/python-wrapper/setup.py +112 -0
  176. py4tsa-3.2.0/python-wrapper/tests/data/make_fixture.c +46 -0
  177. py4tsa-3.2.0/python-wrapper/tests/data/test_ramp.gwf +0 -0
  178. py4tsa-3.2.0/python-wrapper/tests/test_01.py +10 -0
  179. py4tsa-3.2.0/python-wrapper/tests/test_02_persistence.py +62 -0
  180. py4tsa-3.2.0/python-wrapper/tests/test_03_block_threshold.py +77 -0
  181. py4tsa-3.2.0/python-wrapper/tests/test_04_frame_io.py +48 -0
  182. py4tsa-3.2.0/requirements.txt +2 -0
  183. py4tsa-3.2.0/src/AR2.cpp +48 -0
  184. py4tsa-3.2.0/src/AR2Parcor.cpp +52 -0
  185. py4tsa-3.2.0/src/ARMAFilter.cpp +76 -0
  186. py4tsa-3.2.0/src/ARMAfit.cpp +56 -0
  187. py4tsa-3.2.0/src/ArBurgEstimator.cpp +215 -0
  188. py4tsa-3.2.0/src/ArDurbinEstimator.cpp +54 -0
  189. py4tsa-3.2.0/src/Arma2Psd.cpp +131 -0
  190. py4tsa-3.2.0/src/Arma2TF.cpp +131 -0
  191. py4tsa-3.2.0/src/BLInterpolation.cpp +293 -0
  192. py4tsa-3.2.0/src/BaseWindow.cpp +132 -0
  193. py4tsa-3.2.0/src/ButterworthFilter.cpp +96 -0
  194. py4tsa-3.2.0/src/Cholesky.cpp +102 -0
  195. py4tsa-3.2.0/src/ClusterizedEventFullFeatured.cpp +62 -0
  196. py4tsa-3.2.0/src/ComplexFFT.cpp +80 -0
  197. py4tsa-3.2.0/src/CreateDvector.cpp +28 -0
  198. py4tsa-3.2.0/src/DCT.cpp +117 -0
  199. py4tsa-3.2.0/src/DST.cpp +114 -0
  200. py4tsa-3.2.0/src/DoubleWhitening.cpp +185 -0
  201. py4tsa-3.2.0/src/EventDescription.cpp +10 -0
  202. py4tsa-3.2.0/src/EventFullFeatured.cpp +87 -0
  203. py4tsa-3.2.0/src/ExtraWaveletFamilies.cpp +172 -0
  204. py4tsa-3.2.0/src/FifoBuffer.cpp +107 -0
  205. py4tsa-3.2.0/src/FrameIChannel.cpp +205 -0
  206. py4tsa-3.2.0/src/FrameIStream.cpp +855 -0
  207. py4tsa-3.2.0/src/IDCT.cpp +117 -0
  208. py4tsa-3.2.0/src/InverseRealFFT.cpp +147 -0
  209. py4tsa-3.2.0/src/LSLLearning.cpp +156 -0
  210. py4tsa-3.2.0/src/LSLfilter.cpp +118 -0
  211. py4tsa-3.2.0/src/LatticeFilter.cpp +76 -0
  212. py4tsa-3.2.0/src/LeastSquaresLattice.cpp +55 -0
  213. py4tsa-3.2.0/src/MYWE.cpp +91 -0
  214. py4tsa-3.2.0/src/NotchWidrow.cpp +134 -0
  215. py4tsa-3.2.0/src/Parcor2AR.cpp +59 -0
  216. py4tsa-3.2.0/src/RLSCanceler.cpp +211 -0
  217. py4tsa-3.2.0/src/RealFFT.cpp +146 -0
  218. py4tsa-3.2.0/src/SelectionOrderCriteria.cpp +84 -0
  219. py4tsa-3.2.0/src/VArma2TF.cpp +120 -0
  220. py4tsa-3.2.0/src/ViewUtil.cpp +1299 -0
  221. py4tsa-3.2.0/src/WDF2Classify.cpp +236 -0
  222. py4tsa-3.2.0/src/WDF2Reconstruct.cpp +212 -0
  223. py4tsa-3.2.0/src/WavReconstruction.cpp +46 -0
  224. py4tsa-3.2.0/src/WaveletThreshold.cpp +220 -0
  225. py4tsa-3.2.0/src/WaveletTransform.cpp +288 -0
  226. py4tsa-3.2.0/src/WindowFactory.cpp +76 -0
  227. py4tsa-3.2.0/src/fparser.cpp +1443 -0
  228. py4tsa-3.2.0/src/fparser.os +0 -0
  229. py4tsa-3.2.0/src/fpoptimizer.cpp +1885 -0
  230. py4tsa-3.2.0/src/fpoptimizer.os +0 -0
  231. py4tsa-3.2.0/src/tsaLog.cpp +105 -0
  232. py4tsa-3.2.0/src/tsaSerialize.cpp +22 -0
  233. py4tsa-3.2.0/src/tsaUtilityFunctions.cpp +39 -0
  234. py4tsa-3.2.0/test/test.py +2 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ mode: ask
3
+ description: Review changes in the p4TSA C++/pybind11 library for correctness, build impact, test coverage, and API stability.
4
+ ---
5
+
6
+ Review the current change set in this repository as if you were preparing a code review for p4TSA.
7
+
8
+ Focus on:
9
+ - correctness and numerical stability in the C++ core
10
+ - pybind11 binding changes and Python compatibility
11
+ - build and packaging impact, including native dependencies and CMake changes
12
+ - regressions in wavelet, WDF, or persistence-related logic
13
+ - missing or weak tests and any risky assumptions
14
+
15
+ Provide a concise review with findings, severity, and suggested next actions.
@@ -0,0 +1,101 @@
1
+ name: CI
2
+
3
+ # Every pull request into master must pass this before it can be merged. The
4
+ # branch-protection rule that enforces it names the jobs below as required
5
+ # status checks -- see CONTRIBUTING.md.
6
+ #
7
+ # Replaces the old .travis.yml (2026-08-03): Travis CI's free tier for open
8
+ # source was retired years ago, and that config no longer matched this
9
+ # repo's actual build (it predated the scikit-build-core/CMake packaging
10
+ # build -- see CMakeLists.txt's own header comment). GitHub Actions runs on
11
+ # every push/PR for free on a public repo, no separate service to configure.
12
+
13
+ on:
14
+ push:
15
+ branches: [master]
16
+ pull_request:
17
+ branches: [master]
18
+ workflow_dispatch:
19
+
20
+ jobs:
21
+ build-and-test:
22
+ name: Build + test (Python ${{ matrix.python-version }})
23
+ runs-on: ubuntu-latest
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ python-version: ["3.10", "3.11", "3.12"]
28
+ steps:
29
+ - uses: actions/checkout@v5
30
+
31
+ # Same dependency set as conda-recipe/meta.yaml's host/build
32
+ # requirements -- keep the two in sync if either changes.
33
+ - name: Set up build environment
34
+ uses: mamba-org/setup-micromamba@v3
35
+ with:
36
+ micromamba-version: latest
37
+ environment-name: p4tsa-ci
38
+ init-shell: bash
39
+ create-args: >-
40
+ -c conda-forge
41
+ python=${{ matrix.python-version }}
42
+ pip
43
+ cxx-compiler
44
+ cmake>=3.28
45
+ make
46
+ scikit-build-core>=0.10
47
+ pybind11>=2.12
48
+ numpy
49
+ scipy
50
+ gsl
51
+ fftw
52
+ framel
53
+ libboost-headers
54
+ cereal
55
+ pytest
56
+
57
+ - name: Build and install p4TSA (editable, no build isolation)
58
+ shell: bash -el {0}
59
+ run: pip install -e . --no-build-isolation -v
60
+
61
+ - name: Import smoke test
62
+ shell: bash -el {0}
63
+ run: python -c "import py4tsa; print('py4tsa OK:', py4tsa.__file__)"
64
+
65
+ - name: Run tests
66
+ shell: bash -el {0}
67
+ run: pytest python-wrapper/tests/ -v
68
+
69
+ docs:
70
+ name: Docs build check
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - uses: actions/checkout@v5
74
+
75
+ - name: Set up build environment
76
+ uses: mamba-org/setup-micromamba@v3
77
+ with:
78
+ micromamba-version: latest
79
+ environment-name: p4tsa-docs-ci
80
+ init-shell: bash
81
+ create-args: >-
82
+ -c conda-forge
83
+ python=3.11
84
+ doxygen
85
+
86
+ - name: Install docs Python requirements
87
+ shell: bash -el {0}
88
+ run: pip install -r docs/requirements.txt
89
+
90
+ # docs/conf.py runs Doxygen itself on every build, which is why doxygen
91
+ # is in the environment above.
92
+ #
93
+ # Not -W: every `doxygenfile` page re-emits the declarations its header
94
+ # shares with the others, so Breathe warns once per page about a
95
+ # duplicate C++ declaration. That is the price of documenting headers
96
+ # that carry free functions and typedefs rather than a class, and it is
97
+ # not something a contributor can fix. Real breakage -- a ConfigError, a
98
+ # bad directive, a missing Doxygen -- still fails the build outright.
99
+ - name: Build Sphinx docs (Doxygen + Breathe)
100
+ shell: bash -el {0}
101
+ run: sphinx-build -b html docs docs/_build/html
@@ -0,0 +1,91 @@
1
+ name: wheels
2
+
3
+ # Builds the manylinux wheels for PyPI. What to build and how to test it is in
4
+ # pyproject.toml, [tool.cibuildwheel], so a local `cibuildwheel` run does the
5
+ # same thing. Not on every push: it compiles the C++ core once per Python.
6
+
7
+ on:
8
+ push:
9
+ tags: ["v*"]
10
+ release:
11
+ types: [published]
12
+ workflow_dispatch:
13
+ inputs:
14
+ publish:
15
+ description: "Publish to PyPI when the wheels pass"
16
+ type: boolean
17
+ default: false
18
+
19
+ jobs:
20
+ build:
21
+ name: Build wheels (manylinux x86_64)
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - uses: actions/checkout@v5
25
+ - uses: pypa/cibuildwheel@v4.2.1
26
+ - uses: actions/upload-artifact@v4
27
+ with:
28
+ name: wheels
29
+ path: wheelhouse/*.whl
30
+
31
+ sdist:
32
+ name: Build sdist
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v5
36
+ - run: pipx run build --sdist
37
+ - uses: actions/upload-artifact@v4
38
+ with:
39
+ name: sdist
40
+ path: dist/*.tar.gz
41
+
42
+ # The wheel installed where it will be used: a plain runner, with none of
43
+ # the libraries it needs present on the system.
44
+ verify:
45
+ name: Install the wheel on a plain runner
46
+ needs: build
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - uses: actions/checkout@v5
50
+ - uses: actions/setup-python@v5
51
+ with:
52
+ python-version: "3.12"
53
+ - uses: actions/download-artifact@v4
54
+ with:
55
+ name: wheels
56
+ path: wheelhouse
57
+
58
+ # --no-index: the wheel just built, never one already on PyPI.
59
+ - name: Install it
60
+ run: |
61
+ pip install pytest numpy scipy
62
+ pip install --no-index --find-links wheelhouse py4tsa
63
+
64
+ - name: Show what it links against
65
+ run: |
66
+ so=$(python -c "import py4tsa; print(py4tsa.__file__)")
67
+ echo "$so"
68
+ ldd "$so"
69
+ ! ldd "$so" | grep -q "not found"
70
+
71
+ # From outside the checkout, so only the installed wheel is importable.
72
+ - name: Run the tests against it
73
+ working-directory: /tmp
74
+ run: pytest "$GITHUB_WORKSPACE/python-wrapper/tests" -q
75
+
76
+ # An upload cannot be taken back, so the `pypi` environment holds the run
77
+ # for a human whatever triggered it.
78
+ publish:
79
+ name: Publish to PyPI
80
+ needs: [build, sdist, verify]
81
+ if: github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.publish)
82
+ runs-on: ubuntu-latest
83
+ environment: pypi
84
+ permissions:
85
+ id-token: write # trusted publishing; no token is stored here
86
+ steps:
87
+ - uses: actions/download-artifact@v4
88
+ with:
89
+ path: dist
90
+ merge-multiple: true
91
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,23 @@
1
+ generate_rst.py
2
+
3
+ # Build artifacts (CMake / scikit-build-core)
4
+ build/
5
+ python-wrapper/build/
6
+ python-wrapper/tmp/
7
+ *.so
8
+ *.pyd
9
+ *.o
10
+
11
+ # Python
12
+ __pycache__/
13
+ *.pyc
14
+ .pytest_cache/
15
+ *.egg-info/
16
+
17
+ # Docs (generated -- Doxyfile is templated from Doxyfile.in, _build is Sphinx output)
18
+ docs/Doxyfile
19
+ docs/_build/
20
+
21
+ # Editors / OS
22
+ .DS_Store
23
+ *.swp
@@ -0,0 +1,33 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ # Required
6
+ version: 2
7
+
8
+ # Set the version of Python and other tools you might need
9
+ build:
10
+ os: ubuntu-22.04
11
+ tools:
12
+ python: "3.11"
13
+ # docs/conf.py runs doxygen and feeds its XML to breathe; without it every
14
+ # C++ API page renders empty.
15
+ apt_packages:
16
+ - doxygen
17
+ # You can also specify other tool versions:
18
+ # nodejs: "19"
19
+ # rust: "1.64"
20
+ # golang: "1.19"
21
+
22
+ # Build documentation in the docs/ directory with Sphinx
23
+ sphinx:
24
+ configuration: docs/conf.py
25
+
26
+ # If using Sphinx, optionally build your docs in additional formats such as PDF
27
+ # formats:
28
+ # - pdf
29
+
30
+ # Optionally declare the Python requirements required to build your docs
31
+ python:
32
+ install:
33
+ - requirements: docs/requirements.txt
py4tsa-3.2.0/AGENTS.md ADDED
@@ -0,0 +1,33 @@
1
+ # AGENTS instructions for p4TSA
2
+
3
+ ## Project snapshot
4
+ - p4TSA is a C++ time-series analysis library with a Python interface exposed as the py4tsa module through pybind11.
5
+ - The core implementation lives in the C++ headers under [include](include) and the corresponding sources under [src](src).
6
+ - The Python-facing binding entry point is [python-wrapper/py4tsa.cpp](python-wrapper/py4tsa.cpp), and regression tests live under [python-wrapper/tests](python-wrapper/tests).
7
+ - The packaging/build flow is defined by [CMakeLists.txt](CMakeLists.txt), [pyproject.toml](pyproject.toml), and the installation guidance in [README.md](README.md).
8
+
9
+ ## Working conventions
10
+ - Keep changes compatible with the repository’s existing C++14 style and the current pybind11 binding patterns.
11
+ - Prefer small, focused changes and preserve the current API shape unless the task explicitly requires a breaking change.
12
+ - For numerical and wavelet-related code, be conservative: these components are sensitive to regression and should be tested rather than “fixed” by intuition alone.
13
+ - When adding or changing behavior, update or add tests under [python-wrapper/tests](python-wrapper/tests) when practical.
14
+
15
+ ## Build and test commands
16
+ - Configure and build the native extension:
17
+ - `cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$CONDA_PREFIX"`
18
+ - `cmake --build build -j"$(nproc)"`
19
+ - `cmake --install build`
20
+ - Run the Python regression tests:
21
+ - `pytest python-wrapper/tests/ -v`
22
+ - Smoke-test the installed module:
23
+ - `python -c "import py4tsa; print(py4tsa.__file__)"`
24
+
25
+ ## Review priorities
26
+ - For review-oriented work, focus on correctness, build impact, test coverage, and API stability rather than style-only changes.
27
+ - Pay special attention to the C++/Python boundary, memory ownership, and any change touching wavelet transforms, WDF classification/reconstruction, or persistence logic.
28
+ - Call out missing tests, risky assumptions, and any changes that would be hard to validate without native-library availability.
29
+
30
+ ## References
31
+ - Start with [README.md](README.md) for installation and dependency notes.
32
+ - Use [CMakeLists.txt](CMakeLists.txt) and [pyproject.toml](pyproject.toml) when evaluating packaging or build changes.
33
+ - Use [python-wrapper/tests](python-wrapper/tests) as the baseline for expected behavior.
@@ -0,0 +1,171 @@
1
+ # Changelog
2
+
3
+ ## 3.2.0
4
+
5
+ ### Added
6
+
7
+ - **`pip install py4tsa`.** Wheels for CPython 3.10 to 3.13,
8
+ `manylinux_2_28_x86_64`, with GSL, FFTW3 and FrameL inside them, so nothing
9
+ has to be installed first. The build takes FrameL from the system when it is
10
+ there, and otherwise compiles it from its own source
11
+ (git.ligo.org/virgo/virgoapp/Fr, 8.50.2).
12
+ - `test_04_frame_io.py`, which reads a frame through `FrameIChannel` and
13
+ checks the samples against an 8 kB fixture.
14
+
15
+ ### Changed
16
+
17
+ - CMake 3.28 is now the minimum, for `FetchContent`'s `EXCLUDE_FROM_ALL`.
18
+ - Wheels are built and tested by a separate workflow, on tags and releases and
19
+ by hand, rather than on every push. Publishing waits for a person.
20
+ - Metadata for the index: classifiers, `Source`, `Issues` and `Changelog`
21
+ links, and `requires-python >= 3.10`, the range the wheels are built for.
22
+
23
+ ## 3.1.0
24
+
25
+ ### Changed
26
+
27
+ - **BREAKING: the Python module is now `py4tsa`, not `pytsa`.** Every
28
+ `import pytsa` / `from pytsa.tsa import ...` becomes `import py4tsa` /
29
+ `from py4tsa.tsa import ...`. The old name on PyPI belongs to an unrelated
30
+ project, which would shadow this extension for anyone holding both. The C++
31
+ library keeps the name p4TSA; the Python module and the distribution name
32
+ change.
33
+ - **The block rule is the default of `WDF2Classify`.** A classifier built
34
+ without a thresholding rule used `cuoco`, the universal threshold with the
35
+ sigma given from outside; it now uses `block`. Callers that pass the rule
36
+ explicitly are unaffected.
37
+
38
+ ### Added
39
+
40
+ - **A block rule for the wavelet coefficients of a window.**
41
+ `WaveletThreshold::block` judges contiguous coefficients of one level
42
+ together (Cai 1999): a block of L is kept whole when its energy exceeds
43
+ lambda L sigma^2, and zeroed whole otherwise, with sigma read from the
44
+ window's median as for the universal threshold. A signal spread over
45
+ neighbouring coefficients, each below sqrt(2 ln N) sigma, survives as a
46
+ block where no single coefficient would; a lone noise excursion does not
47
+ carry its block over the line. `SetBlock(length, lambda)` sets the two
48
+ parameters, defaulting to ln N and 4.505. On the merger window of GW150914
49
+ in H1 the rule keeps 18 coefficients where the universal threshold keeps
50
+ five, twelve of them in 32-128 Hz, and fires on fewer windows of noise at
51
+ the same EnWDF threshold.
52
+
53
+ ## 3.0.1
54
+
55
+ ### Fixed
56
+
57
+ - **The package declares the version it is tagged with.** `pyproject.toml`, the
58
+ conda recipe and the changelog heading still read 2.2.0 when 3.0.0 was tagged,
59
+ so an installed package reported a version its archive was not built from and
60
+ the changelog attributed the trigger-scale changes to a release that predates
61
+ them.
62
+
63
+ - **`CITATION.cff` carries the author ORCID, the version and the release date.**
64
+ Zenodo builds the record for an archived release from that file; without those
65
+ fields the archived record names an author with no identifier behind it.
66
+
67
+ ## 3.0.0
68
+
69
+ ### Changed
70
+
71
+ - **`WaveletThreshold` defaults to hard thresholding.** Both `operator()`
72
+ overloads took `ThresholdingMode m = soft`, so every caller that omitted the
73
+ argument -- including `WDF2Classify` -- shrank each surviving coefficient by
74
+ the threshold, biasing amplitudes low by an amount that grows with the number
75
+ of coefficients a signal is spread over. Soft thresholding minimises the mean
76
+ square error of a denoised reconstruction; a detection statistic and a
77
+ parameter estimate are read off the amplitude instead, so the survivors are
78
+ now left unchanged.
79
+
80
+ - **`WDF2Classify`'s statistic is the coefficient norm on the noise scale.** The
81
+ division by the window length was removed, so `mSNR` is
82
+ `sqrt(sum c_i^2) / sigma`. The candidate bases are orthonormal, so that is the
83
+ matched-filter signal-to-noise ratio of the reconstructed transient, and a
84
+ configured threshold carries the units it appears to have. Previously the
85
+ statistic scaled as the inverse square root of the window length.
86
+
87
+ - **`WDF2Classify` exports the noise scale that produced the statistic.**
88
+ `EventFullFeatured::mSigma` carries the winning basis's own per-window
89
+ estimate, so a downstream consumer can recompute the signal-to-noise ratio
90
+ under the convention that decided the trigger rather than a separately frozen
91
+ one.
92
+
93
+ - **The candidate basis list goes from 19 bases to 10.** Plain and centered
94
+ Daubechies of the same order are the same filter taps up to a phase shift, so
95
+ keeping both spent roughly half the list's compute on no real diversity; the
96
+ plain family and every other centered order were dropped. Coiflet (orders 1
97
+ and 2) and Symlet (orders 4 and 8) were added in their place as genuinely
98
+ different shapes -- Symlet only begins to differ from Daubechies at order 4,
99
+ and Coiflet has vanishing moments for the scaling function as well as for the
100
+ wavelet. The biorthogonal B-spline family stays excluded: it is not
101
+ orthonormal, so Parseval does not hold for it and `mSNR` would not be the
102
+ signal-to-noise ratio of the reconstruction.
103
+
104
+ - **New `ExtraWaveletFamilies.hpp`.** Coiflet and Symlet are plugged into GSL's
105
+ own extensible `gsl_wavelet_type` mechanism rather than by patching GSL or
106
+ taking on another wavelet library. Filter coefficients were cross-checked
107
+ against PyWavelets for orthonormality and for tap order, which the two
108
+ libraries store in opposite conventions.
109
+
110
+ ### Removed
111
+
112
+ - **`eternity` is gone, replaced by Cereal.** The vendored 1999--2003 XML
113
+ persistence layer was a real compiled dependency, not dead code. All eight
114
+ persistable classes (`ArBurgEstimator`, `LatticeView`, `ARMAView`,
115
+ `DoubleWhitening`, `FifoBuffer`, `LatticeFilter`, `LSLfilter`, `LSLLearning`)
116
+ now use Cereal through the new `CerealPersistence.hpp`, whose
117
+ `DvectorProxy`/`DmatrixProxy`/`VDmatrixProxy` types exist to sidestep a real
118
+ ambiguity: `boost::numeric::ublas` vectors and matrices already carry an
119
+ inherited Boost.Serialization `serialize()` member, which clashes with any
120
+ free save/load pair added for the same type. Save/load round-trips are
121
+ verified byte-exact against freshly estimated filter state. Cereal is a new
122
+ header-only dependency (conda-forge). The legacy ENV_ROOT-era build files,
123
+ unused by the CMake packaging build, were removed at the same time.
124
+
125
+ ### Infrastructure
126
+
127
+ - **CI moved from Travis to GitHub Actions.** Travis's free tier for open
128
+ source was retired years ago and its configuration predated the current build
129
+ system entirely.
130
+
131
+ - **The Sphinx documentation build was broken and now works.** `conf.py` used
132
+ an `intersphinx_mapping` shorthand that modern Sphinx rejects outright;
133
+ `docs/requirements.txt` was missing Sphinx itself and the theme; the
134
+ list-form `source_suffix` silently parsed `index.md` as reStructuredText with
135
+ no Markdown parser registered; and `index.md` and `index.rst` both existed as
136
+ master-document candidates, with Sphinx picking the stale one.
137
+ `structure/installation.rst` still described the pre-packaging build.
138
+
139
+ - **The C++ API reference was rendering empty and now has content.** Doxygen ran
140
+ only on Read the Docs, and `breathe_default_project` named a key that was
141
+ never added to `breathe_projects` anywhere else, so all 66 class pages came
142
+ out blank with one breathe warning each. Doxygen now runs on every build and
143
+ the project key is defined once; `.readthedocs.yaml` installs `doxygen`
144
+ through `apt_packages`, which it was never asked to do, so the published
145
+ pages had no Doxygen XML to render from either. Twelve pages asked
146
+ `doxygenclass` for a class their header does not declare (`tsaTypes`,
147
+ `WindowFactory`, `fparser`, ...) and now use `doxygenfile`; nine pages were
148
+ in no toctree; `armafit.rst` duplicated `ARMAfit.rst`. The build goes from 78
149
+ warnings to 9.
150
+
151
+ - **Documentation points at `wdflow`, not the retired `wdf`.** `docs/index.rst`
152
+ linked the old project's repository and site, both being retired.
153
+ `README.rst`, an unreferenced duplicate of `README.md` predating the
154
+ PyPI-collision warning and the contact change, was removed.
155
+
156
+ - **A `.gitignore` covering build artifacts, Python cache and generated docs**
157
+ replaces the previous one-line file.
158
+
159
+ ### Notes for downstream users
160
+
161
+ Trigger values change. `mSNR` from a run before this release is not comparable
162
+ with one after it: it is larger, having lost the window-length division, and no
163
+ longer biased low by shrinkage. Thresholds tuned against the old scale must be
164
+ re-tuned against a measured background. Triggers also no longer report a
165
+ biorthogonal winning basis, and the set of names that can appear in `mWave` is
166
+ the ten listed above.
167
+
168
+ `pytsa` on PyPI is an unrelated package (a Python decorator library). p4TSA's
169
+ own `pytsa` module is never published there and is only ever built from this
170
+ repository's source; install it with `pip install .` from a checkout, which
171
+ builds the extension through scikit-build-core and CMake.
@@ -0,0 +1,104 @@
1
+ cff-version: 1.2.0
2
+ title: "p4TSA: package for Time Series Analysis"
3
+ message: >-
4
+ Use of this software in published work requires citation of the references
5
+ listed below: the method paper for the Wavelet Detection Filter, and the
6
+ papers describing the autoregressive time-domain whitening that the
7
+ conditioning stage implements.
8
+ type: software
9
+ authors:
10
+ - family-names: Cuoco
11
+ given-names: Elena
12
+ orcid: "https://orcid.org/0000-0002-6528-3449"
13
+ email: elena.cuoco@unibo.it
14
+ affiliation: "Alma Mater Studiorum -- Università di Bologna"
15
+ license: GPL-3.0-or-later
16
+ repository-code: "https://github.com/elenacuoco/p4TSA"
17
+ version: "3.2.0"
18
+ date-released: "2026-09-17"
19
+
20
+ preferred-citation:
21
+ type: article
22
+ status: preprint
23
+ title: >-
24
+ The Wavelet Detection Filter: A Real Time Unmodeled Pipeline for
25
+ Gravitational Wave Transients, Ranking Coincidences with a Graph
26
+ Neural Network
27
+ authors:
28
+ - family-names: Cuoco
29
+ given-names: Elena
30
+ orcid: "https://orcid.org/0000-0002-6528-3449"
31
+ year: 2026
32
+ month: 9
33
+ doi: "10.48550/arXiv.2609.12797"
34
+ url: "https://arxiv.org/html/2609.12797v1"
35
+
36
+ references:
37
+ - type: conference-paper
38
+ title: "Wavelet-based classification of transient signals for gravitational wave detectors"
39
+ authors:
40
+ - family-names: Cuoco
41
+ given-names: Elena
42
+ - family-names: Razzano
43
+ given-names: Massimiliano
44
+ - family-names: Utina
45
+ given-names: Andrei
46
+ collection-title: "2018 26th European Signal Processing Conference (EUSIPCO)"
47
+ publisher:
48
+ name: EURASIP
49
+ year: 2018
50
+ start: 2648
51
+ end: 2652
52
+ doi: "10.23919/EUSIPCO.2018.8553393"
53
+ - type: article
54
+ title: >-
55
+ On-line power spectra identification and whitening for the noise in
56
+ interferometric gravitational wave detectors
57
+ authors:
58
+ - family-names: Cuoco
59
+ given-names: Elena
60
+ - family-names: Calamai
61
+ given-names: G.
62
+ - family-names: Fabbroni
63
+ given-names: L.
64
+ - family-names: Losurdo
65
+ given-names: G.
66
+ - family-names: Mazzoni
67
+ given-names: M.
68
+ - family-names: Stanga
69
+ given-names: R.
70
+ - family-names: Vetrano
71
+ given-names: F.
72
+ journal: "Classical and Quantum Gravity"
73
+ volume: 18
74
+ start: 1727
75
+ end: 1751
76
+ year: 2001
77
+ doi: "10.1088/0264-9381/18/9/309"
78
+
79
+ - type: article
80
+ title: >-
81
+ Noise parametric identification and whitening for LIGO 40-m
82
+ interferometer data
83
+ authors:
84
+ - family-names: Cuoco
85
+ given-names: Elena
86
+ - family-names: Losurdo
87
+ given-names: G.
88
+ - family-names: Calamai
89
+ given-names: G.
90
+ - family-names: Fabbroni
91
+ given-names: L.
92
+ - family-names: Mazzoni
93
+ given-names: M.
94
+ - family-names: Stanga
95
+ given-names: R.
96
+ - family-names: Guidi
97
+ given-names: G.
98
+ - family-names: Vetrano
99
+ given-names: F.
100
+ journal: "Physical Review D"
101
+ volume: 64
102
+ start: 122002
103
+ year: 2001
104
+ doi: "10.1103/PhysRevD.64.122002"