riptide-ffa 0.2.4__tar.gz → 0.2.6__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.
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/.coveragerc +1 -4
- riptide_ffa-0.2.6/.github/workflows/CI.yml +32 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/.gitignore +15 -9
- riptide_ffa-0.2.6/.readthedocs.yaml +15 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/CHANGELOG.md +24 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/Makefile +4 -7
- riptide_ffa-0.2.6/PKG-INFO +120 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/README.md +3 -3
- riptide_ffa-0.2.6/pyproject.toml +60 -0
- riptide_ffa-0.2.6/riptide/cpp/transforms_advanced_LEGACY.hpp +248 -0
- riptide_ffa-0.2.6/setup.cfg +4 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/setup.py +19 -3
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/__init__.py +17 -27
- riptide_ffa-0.2.6/src/riptide/_version.py +24 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/apps/rseek.py +72 -60
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/candidate.py +76 -53
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/clustering.py +5 -8
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/downsample.hpp +7 -3
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/python_bindings.cpp +23 -11
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/ffautils.py +1 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/folding.py +10 -6
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/libffa.py +17 -17
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/metadata.py +35 -29
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/peak_detection.py +50 -32
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/periodogram.py +27 -20
- riptide_ffa-0.2.6/src/riptide/pipeline/config_validation.py +259 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/dmiter.py +78 -42
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/harmonic_testing.py +37 -26
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/peak_cluster.py +27 -17
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/pipeline.py +127 -100
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/worker_pool.py +14 -17
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/reading/presto.py +49 -46
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/reading/sigproc.py +38 -33
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/running_medians.py +4 -2
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/search.py +23 -12
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/serialization.py +40 -39
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/time_series.py +70 -54
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/timing.py +3 -2
- riptide_ffa-0.2.6/src/riptide_ffa.egg-info/PKG-INFO +120 -0
- riptide_ffa-0.2.6/src/riptide_ffa.egg-info/SOURCES.txt +78 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide_ffa.egg-info/entry_points.txt +0 -1
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide_ffa.egg-info/requires.txt +1 -1
- riptide_ffa-0.2.6/src/riptide_ffa.egg-info/scm_file_list.json +88 -0
- riptide_ffa-0.2.6/src/riptide_ffa.egg-info/scm_version.json +8 -0
- riptide_ffa-0.2.6/tests/__init__.py +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/presto_generation.py +17 -6
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_ffa_base_functions.py +43 -43
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_ffa_search_pgram.py +25 -22
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_pipeline.py +51 -38
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_rseek.py +27 -14
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_running_median.py +11 -11
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_snr.py +9 -9
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/test_time_series.py +37 -29
- riptide-ffa-0.2.4/.readthedocs.yaml +0 -21
- riptide-ffa-0.2.4/.travis.yml +0 -30
- riptide-ffa-0.2.4/PKG-INFO +0 -287
- riptide-ffa-0.2.4/pyproject.toml +0 -11
- riptide-ffa-0.2.4/riptide/_version.py +0 -5
- riptide-ffa-0.2.4/riptide/pipeline/config_validation.py +0 -198
- riptide-ffa-0.2.4/riptide/tests/__init__.py +0 -1
- riptide-ffa-0.2.4/riptide/tests/run_tests.py +0 -11
- riptide-ffa-0.2.4/riptide_ffa.egg-info/PKG-INFO +0 -287
- riptide-ffa-0.2.4/riptide_ffa.egg-info/SOURCES.txt +0 -78
- riptide-ffa-0.2.4/riptide_ffa.egg-info/not-zip-safe +0 -1
- riptide-ffa-0.2.4/setup.cfg +0 -51
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/LICENSE +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6}/MANIFEST.in +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/README.md +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/block.hpp +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/kernels.hpp +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/periodogram.hpp +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/running_median.hpp +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/snr.hpp +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/cpp/transforms.hpp +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/__init__.py +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/pipeline/config/example.yaml +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide/reading/__init__.py +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide_ffa.egg-info/dependency_links.txt +0 -0
- {riptide-ffa-0.2.4 → riptide_ffa-0.2.6/src}/riptide_ffa.egg-info/top_level.txt +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/README.md +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_presto_radio.dat +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_presto_radio.inf +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_presto_radio_breaks.dat +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_presto_radio_breaks.inf +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_presto_xray.dat +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_presto_xray.inf +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_sigproc_float32.tim +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_sigproc_int8.tim +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_sigproc_uint8.tim +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/data/fake_sigproc_uint8_nosignedkey.tim +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/pipeline_config_A.yml +0 -0
- {riptide-ffa-0.2.4/riptide → riptide_ffa-0.2.6}/tests/pipeline_config_B.yml +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
- push
|
|
5
|
+
- pull_request
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
# See: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-running-a-job-within-a-container
|
|
9
|
+
continuous-integration:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
19
|
+
uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
- name: Install
|
|
23
|
+
run: |
|
|
24
|
+
python -m pip install --upgrade pip
|
|
25
|
+
make install
|
|
26
|
+
- name: Test
|
|
27
|
+
run: |
|
|
28
|
+
make tests
|
|
29
|
+
- name: Upload coverage reports to Codecov
|
|
30
|
+
uses: codecov/codecov-action@v5
|
|
31
|
+
env:
|
|
32
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
dist
|
|
2
|
+
build
|
|
3
|
+
.egg
|
|
4
|
+
.nox
|
|
5
5
|
.vscode
|
|
6
|
-
*.egg-info
|
|
7
6
|
.coverage
|
|
8
|
-
|
|
7
|
+
__pycache__
|
|
8
|
+
.mypy_cache
|
|
9
|
+
docs/_build
|
|
9
10
|
.pytest_cache
|
|
10
|
-
tmp
|
|
11
|
-
build
|
|
12
|
-
dist
|
|
13
11
|
pip-wheel-metadata
|
|
12
|
+
.ipynb_checkpoints
|
|
13
|
+
src/riptide/_version.py
|
|
14
|
+
|
|
15
|
+
*.o
|
|
16
|
+
*.so
|
|
17
|
+
*.egg
|
|
18
|
+
*.py[cod]
|
|
19
|
+
*.egg-info
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Read the Docs configuration file for Sphinx projects
|
|
2
|
+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
|
3
|
+
version: 2
|
|
4
|
+
|
|
5
|
+
build:
|
|
6
|
+
os: ubuntu-22.04
|
|
7
|
+
tools:
|
|
8
|
+
python: "3.12"
|
|
9
|
+
|
|
10
|
+
python:
|
|
11
|
+
install:
|
|
12
|
+
- requirements: docs/requirements.txt
|
|
13
|
+
|
|
14
|
+
sphinx:
|
|
15
|
+
configuration: docs/source/conf.py
|
|
@@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## 0.2.6 - 2026-09-10
|
|
8
|
+
|
|
9
|
+
This version modernises the project layout and packaging, and fixes issues in candidate plotting and downsampled variance calculations.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Candidate plots now normalise each sub-integration independently for better contrast,
|
|
14
|
+
contributed by Dejiang Yin.
|
|
15
|
+
- Corrected the downsampled variance calculation for factors very close to an integer,
|
|
16
|
+
thanks to Francesco Coti Zelati for reporting the issue.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
## 0.2.5 - 2023-12-23
|
|
20
|
+
|
|
21
|
+
This version fixes an installation error on recent OSX versions, and a segmentation fault that triggers in some edge cases.
|
|
22
|
+
|
|
23
|
+
Thanks to Francesco Coti Zelati for [reporting the original issue](https://github.com/v-morello/riptide/issues/4) that led to both fixes.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Fixed a serious bug where some intermediate output arrays were unexpectedly allocated with a size one element smaller than expected, causing segmentation faults. This was found to be a side effect of the compilation flag `-freciprocal-math`. See issue [#4](https://github.com/v-morello/riptide/issues/4) for a detailed explanation. The set of compilation flags for the C++ extensions has been reviewed and adjusted.
|
|
28
|
+
- The C++ extensions can now be built with the C++17 standard enabled without throwing any errors or warnings. Recent `clang` versions (the default compiler on OSX) would throw a number of narrowing conversion errors, which would in turn make the installation of riptide fail with a cryptic error message.
|
|
29
|
+
|
|
30
|
+
|
|
7
31
|
## 0.2.4 - 2022-02-03
|
|
8
32
|
|
|
9
33
|
This version fixes a bug where all the functions in the python bindings to the C++ code (exposed in `riptide.libcpp` on the Python side) assume that their input numpy arrays are contiguous in memory. In practice, passing a column slice of a two-dimensional `float32` array to `fast_running_median` was found to produce incorrect results: the rather than reading `data[:, col_index]`, the code read `data[0, col_index:col_index+num_cols]`. The issue would only trigger on the `float32` type, because otherwise an implicit copy (contiguous in memory) of the input was created.
|
|
@@ -4,13 +4,10 @@ PKG = riptide-ffa
|
|
|
4
4
|
dist: ## Build source distribution, must have installed 'develop' extra dependencies
|
|
5
5
|
python -m build --sdist
|
|
6
6
|
|
|
7
|
-
docker: ## Build riptide-ffa docker image
|
|
8
|
-
docker build --file docker/Dockerfile --tag ${PKG} .
|
|
9
|
-
|
|
10
7
|
# NOTE: -e installs in "Development Mode"
|
|
11
8
|
# See: https://packaging.python.org/tutorials/installing-packages/
|
|
12
|
-
install: ## Install the package in
|
|
13
|
-
pip install -e .
|
|
9
|
+
install: ## Install the package in editable mode with dev dependencies
|
|
10
|
+
pip install -e .[dev]
|
|
14
11
|
|
|
15
12
|
# NOTE: remove the .egg-info directory
|
|
16
13
|
uninstall: ## Uninstall the package
|
|
@@ -35,6 +32,6 @@ clean: ## Remove all python cache and build files
|
|
|
35
32
|
rm -f .coverage
|
|
36
33
|
|
|
37
34
|
tests: ## Run the unit tests and print a coverage report
|
|
38
|
-
pytest --cov --verbose --cov-report term-missing
|
|
35
|
+
pytest --cov --verbose --cov-report term-missing tests
|
|
39
36
|
|
|
40
|
-
.PHONY: dist
|
|
37
|
+
.PHONY: dist install uninstall help clean tests
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: riptide-ffa
|
|
3
|
+
Version: 0.2.6
|
|
4
|
+
Summary: Pulsar searching with the Fast Folding Algorithm (FFA)
|
|
5
|
+
Author-email: Vincent Morello <vmorello@gmail.com>
|
|
6
|
+
Maintainer-email: Vincent Morello <vmorello@gmail.com>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2017-2021 Vincent Morello
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
Project-URL: homepage, https://github.com/vmorello/riptide
|
|
30
|
+
Project-URL: documentation, https://riptide-ffa.readthedocs.io
|
|
31
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Programming Language :: C
|
|
37
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
38
|
+
Classifier: Operating System :: Unix
|
|
39
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
40
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
41
|
+
Requires-Python: >=3.9
|
|
42
|
+
Description-Content-Type: text/markdown
|
|
43
|
+
License-File: LICENSE
|
|
44
|
+
Requires-Dist: astropy
|
|
45
|
+
Requires-Dist: pandas
|
|
46
|
+
Requires-Dist: schema
|
|
47
|
+
Requires-Dist: pyyaml
|
|
48
|
+
Requires-Dist: threadpoolctl
|
|
49
|
+
Requires-Dist: pytest
|
|
50
|
+
Requires-Dist: pytest-cov
|
|
51
|
+
Requires-Dist: matplotlib
|
|
52
|
+
Requires-Dist: numpy
|
|
53
|
+
Provides-Extra: dev
|
|
54
|
+
Requires-Dist: build; extra == "dev"
|
|
55
|
+
Requires-Dist: twine; extra == "dev"
|
|
56
|
+
Dynamic: license-file
|
|
57
|
+
|
|
58
|
+
[](https://arxiv.org/abs/2004.03701)    [](https://codecov.io/gh/v-morello/riptide)
|
|
59
|
+
|
|
60
|
+
# riptide
|
|
61
|
+
|
|
62
|
+
__riptide__ ("sea**r**ch**i**ng for **p**ulsars in the **ti**me **d**omain") is a pulsar searching package implementing the Fast Folding Algorithm (FFA), the theoretically optimal search method for periodic signals. Its interface is entirely in python while the core algorithms are implemented in C. riptide provides:
|
|
63
|
+
|
|
64
|
+
* A library of functions and classes to use interactively to process dedispersed time series
|
|
65
|
+
* A pipeline executable to process a set of DM trials and output a list of candidate files and other useful data products
|
|
66
|
+
|
|
67
|
+
## Citation
|
|
68
|
+
|
|
69
|
+
If using ``riptide`` contributes to a project that leads to a scientific publication, please cite the article:
|
|
70
|
+
["Optimal periodicity searching: Revisiting the Fast Folding Algorithm for large scale pulsar surveys"](https://arxiv.org/abs/2004.03701)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
## Sensitivity of the FFA
|
|
74
|
+
|
|
75
|
+
The article covers the topic of the FFA's sensitivity in theory, here is a practical example on a faint source. Below is an L-band observation of [PSR J1932-3655](https://www.atnf.csiro.au/people/joh414/ppdata/1932-3655.html) from the [SUPERB survey](https://arxiv.org/abs/1706.04459), significantly offset from the true position of the source. The first plot was obtained by folding the observation using the known ephemeris of the pulsar with [PSRCHIVE](http://psrchive.sourceforge.net/). This is one of the faintest known pulsar instances identifiable in the survey.
|
|
76
|
+
|
|
77
|
+

|
|
78
|
+
|
|
79
|
+
And below is a blind detection of the pulsar, running `riptide` on the same observation:
|
|
80
|
+

|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## Documentation
|
|
84
|
+
|
|
85
|
+
A quickstart guide, a pipeline configuration tutorial and the full API documentation can be found [here](https://riptide-ffa.readthedocs.io).
|
|
86
|
+
|
|
87
|
+
## Installation
|
|
88
|
+
|
|
89
|
+
The easiest method is to use pip install, which pulls the latest release from the python package index and installs all required dependencies:
|
|
90
|
+
```
|
|
91
|
+
pip install riptide-ffa
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The alternative is to clone the repository, especially if you want the absolute latest version:
|
|
95
|
+
```bash
|
|
96
|
+
git clone https://github.com/v-morello/riptide
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
And then in the base directory of `riptide` run
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
make install
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
This simply runs ``pip install`` in [editable mode](https://pip.pypa.io/en/latest/reference/pip_install/#editable-installs), which means you can freely edit the code. It also installs any required dependencies with ``pip`` that are not present already. The installer also adds links to two command-line apps in your python environment using [console_scripts entry points](https://python-packaging.readthedocs.io/en/latest/command-line-scripts.html):
|
|
106
|
+
|
|
107
|
+
* `rffa`: The full end-to-end pipeline to search multiple DM trials, see below for details on how to use it.
|
|
108
|
+
* `rseek`: A lightweight app to search a single time series and print significant candidates found, useful for quick data checks.
|
|
109
|
+
|
|
110
|
+
You may check that it all works by typing:
|
|
111
|
+
```
|
|
112
|
+
rffa -h
|
|
113
|
+
rseek -h
|
|
114
|
+
```
|
|
115
|
+
And you should see the full help of both applications.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
[](https://arxiv.org/abs/2004.03701)  
|
|
1
|
+
[](https://arxiv.org/abs/2004.03701)    [](https://codecov.io/gh/v-morello/riptide)
|
|
2
2
|
|
|
3
3
|
# riptide
|
|
4
4
|
|
|
@@ -17,10 +17,10 @@ If using ``riptide`` contributes to a project that leads to a scientific publica
|
|
|
17
17
|
|
|
18
18
|
The article covers the topic of the FFA's sensitivity in theory, here is a practical example on a faint source. Below is an L-band observation of [PSR J1932-3655](https://www.atnf.csiro.au/people/joh414/ppdata/1932-3655.html) from the [SUPERB survey](https://arxiv.org/abs/1706.04459), significantly offset from the true position of the source. The first plot was obtained by folding the observation using the known ephemeris of the pulsar with [PSRCHIVE](http://psrchive.sourceforge.net/). This is one of the faintest known pulsar instances identifiable in the survey.
|
|
19
19
|
|
|
20
|
-

|
|
20
|
+

|
|
21
21
|
|
|
22
22
|
And below is a blind detection of the pulsar, running `riptide` on the same observation:
|
|
23
|
-

|
|
23
|
+

|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
## Documentation
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "setuptools.build_meta"
|
|
3
|
+
requires = [
|
|
4
|
+
"setuptools>=42",
|
|
5
|
+
"wheel",
|
|
6
|
+
"setuptools_scm[toml]>=3.4",
|
|
7
|
+
"pybind11>=2.6.0",
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
[project]
|
|
11
|
+
name = "riptide-ffa"
|
|
12
|
+
authors = [{name = "Vincent Morello", email = "vmorello@gmail.com"}]
|
|
13
|
+
description = "Pulsar searching with the Fast Folding Algorithm (FFA)"
|
|
14
|
+
dynamic = ["version"]
|
|
15
|
+
license = {file = "LICENSE"}
|
|
16
|
+
maintainers = [{name = "Vincent Morello", email = "vmorello@gmail.com"}]
|
|
17
|
+
readme = "README.md"
|
|
18
|
+
requires-python = ">=3.9"
|
|
19
|
+
|
|
20
|
+
classifiers = [
|
|
21
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: C",
|
|
27
|
+
"License :: OSI Approved :: MIT License",
|
|
28
|
+
"Operating System :: Unix",
|
|
29
|
+
"Operating System :: MacOS :: MacOS X",
|
|
30
|
+
"Topic :: Scientific/Engineering :: Astronomy",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
dependencies = [
|
|
34
|
+
"astropy",
|
|
35
|
+
"pandas",
|
|
36
|
+
"schema",
|
|
37
|
+
"pyyaml",
|
|
38
|
+
"threadpoolctl",
|
|
39
|
+
"pytest",
|
|
40
|
+
"pytest-cov",
|
|
41
|
+
"matplotlib",
|
|
42
|
+
"numpy",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
dev = [
|
|
47
|
+
"build",
|
|
48
|
+
"twine",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.scripts]
|
|
52
|
+
rffa = "riptide.pipeline.pipeline:main"
|
|
53
|
+
rseek = "riptide.apps.rseek:main"
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
homepage = "https://github.com/vmorello/riptide"
|
|
57
|
+
documentation = "https://riptide-ffa.readthedocs.io"
|
|
58
|
+
|
|
59
|
+
[tool.setuptools_scm]
|
|
60
|
+
write_to = "src/riptide/_version.py"
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
#ifndef TRANSFORMS_ADVANCED_HPP
|
|
2
|
+
#define TRANSFORMS_ADVANCED_HPP
|
|
3
|
+
|
|
4
|
+
#include <cstddef> // size_t
|
|
5
|
+
|
|
6
|
+
#include "transforms_blocked.hpp"
|
|
7
|
+
|
|
8
|
+
namespace riptide::advanced
|
|
9
|
+
{
|
|
10
|
+
using riptide::direct::merge_radix2;
|
|
11
|
+
using riptide::blocked::integer_log2;
|
|
12
|
+
|
|
13
|
+
constexpr size_t SMALL_INPUT_MAX_SIZE = 1UL << 18;
|
|
14
|
+
|
|
15
|
+
size_t head_size(const size_t rows)
|
|
16
|
+
{
|
|
17
|
+
return rows / 2;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
size_t tail_size(const size_t rows)
|
|
21
|
+
{
|
|
22
|
+
return rows - head_size(rows);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/// @brief Represents a 2D vertical slice of a TransformCube.
|
|
26
|
+
/// @tparam DataType Numerical type of the data being wrapped.
|
|
27
|
+
template <typename DataType>
|
|
28
|
+
class VerticalSlice
|
|
29
|
+
{
|
|
30
|
+
public:
|
|
31
|
+
// Pointer to the start of the first row of the slice
|
|
32
|
+
DataType *data;
|
|
33
|
+
|
|
34
|
+
// number of planes within the original TransformCube spanned by this vertical slice
|
|
35
|
+
const size_t planes;
|
|
36
|
+
|
|
37
|
+
// number of bins across the pulse profiles (last dimension)
|
|
38
|
+
const size_t cols;
|
|
39
|
+
|
|
40
|
+
// offset between consecutive planes in number of data points
|
|
41
|
+
const size_t stride;
|
|
42
|
+
|
|
43
|
+
// the row index along which this slice was taken within the original TransformCube
|
|
44
|
+
const size_t row_index;
|
|
45
|
+
|
|
46
|
+
// The plane index within the original TransformCube where this slice starts.
|
|
47
|
+
const size_t plane_index;
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
/// @brief Create a new VerticalSlice from a raw data pointer
|
|
51
|
+
/// Note that plane_index = 0 by default. Non-zero plane indices are
|
|
52
|
+
/// only used during the recursion of small FFA transforms.
|
|
53
|
+
VerticalSlice(DataType *data, size_t planes, size_t cols, size_t stride, size_t row_index, size_t plane_index = 0)
|
|
54
|
+
: data(data), planes(planes), cols(cols), stride(stride), row_index(row_index), plane_index(plane_index)
|
|
55
|
+
{
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
VerticalSlice<DataType> head() const
|
|
59
|
+
{
|
|
60
|
+
return VerticalSlice<DataType>(
|
|
61
|
+
data, head_size(planes), cols, stride, row_index, plane_index);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
VerticalSlice<DataType> tail() const
|
|
65
|
+
{
|
|
66
|
+
const size_t h = head_size(planes);
|
|
67
|
+
const size_t t = tail_size(planes);
|
|
68
|
+
return VerticalSlice<DataType>(
|
|
69
|
+
data + h * stride, t, cols, stride, row_index, plane_index + h);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}; // class VerticalPlane
|
|
73
|
+
|
|
74
|
+
/// @brief Represents a 2D horizontal plane of a TransformCube
|
|
75
|
+
/// @tparam DataType
|
|
76
|
+
template <typename DataType>
|
|
77
|
+
class Plane
|
|
78
|
+
{
|
|
79
|
+
public:
|
|
80
|
+
DataType *data;
|
|
81
|
+
const size_t rows;
|
|
82
|
+
const size_t cols;
|
|
83
|
+
|
|
84
|
+
public:
|
|
85
|
+
Plane(DataType *data, size_t rows, size_t cols)
|
|
86
|
+
: data(data), rows(rows), cols(cols)
|
|
87
|
+
{
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
Plane<DataType> head() const
|
|
91
|
+
{
|
|
92
|
+
return Plane<DataType>(data, head_size(rows), cols);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
Plane<DataType> tail() const
|
|
96
|
+
{
|
|
97
|
+
return Plane<DataType>(data + head_size(rows) * cols, tail_size(rows), cols);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}; // class Plane
|
|
101
|
+
|
|
102
|
+
/// @brief Represents data that has been FFA transformed by blocks.
|
|
103
|
+
/// 'planes' is the number of blocks of data that have been FFA transformed independently.
|
|
104
|
+
/// 'rows' is the number of rows inside each transformed block.
|
|
105
|
+
/// 'cols' is the number of columns = number bins across a pulse profile.
|
|
106
|
+
/// Special cases:
|
|
107
|
+
/// planes = N, rows = 1 is raw data, pre-transform.
|
|
108
|
+
/// planes = 1, rows = N is fully FFA-transformed data.
|
|
109
|
+
/// @tparam DataType Numerical type of the data being wrapped.
|
|
110
|
+
template <typename DataType>
|
|
111
|
+
class TransformCube
|
|
112
|
+
{
|
|
113
|
+
public:
|
|
114
|
+
DataType *data;
|
|
115
|
+
const size_t planes;
|
|
116
|
+
const size_t rows;
|
|
117
|
+
const size_t cols;
|
|
118
|
+
const size_t plane_stride;
|
|
119
|
+
|
|
120
|
+
public:
|
|
121
|
+
TransformCube(DataType *data, size_t planes, size_t rows, size_t cols)
|
|
122
|
+
: data(data), planes(planes), rows(rows), cols(cols), plane_stride(rows * cols)
|
|
123
|
+
{
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/// @brief Return a view of one of the planes
|
|
127
|
+
Plane<DataType> getPlane(size_t index) const
|
|
128
|
+
{
|
|
129
|
+
return Plane<DataType>(data + index * plane_stride, rows, cols);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/// @brief Return a view of a group of rows within a given plane
|
|
133
|
+
Plane<DataType> getSubPlane(size_t plane_index, size_t start_row_index, size_t num_rows) const
|
|
134
|
+
{
|
|
135
|
+
const size_t offset = plane_index * plane_stride + start_row_index * cols;
|
|
136
|
+
return Plane<DataType>(data + offset, num_rows, cols);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/// @brief Return a VerticalSlice spanning all the planes, along given row index
|
|
140
|
+
VerticalSlice<DataType> getVerticalSlice(size_t row_index) const
|
|
141
|
+
{
|
|
142
|
+
return VerticalSlice<DataType>(
|
|
143
|
+
data + row_index * cols, planes, cols, plane_stride, row_index);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// @brief Return a view of a group of consecutive planes
|
|
147
|
+
TransformCube<DataType> getSubCube(size_t start_plane_index, size_t num_planes) const
|
|
148
|
+
{
|
|
149
|
+
const size_t offset = start_plane_index * plane_stride;
|
|
150
|
+
return TransformCube<DataType>(data + offset, num_planes, rows, cols);
|
|
151
|
+
}
|
|
152
|
+
}; // class TransformCube
|
|
153
|
+
|
|
154
|
+
template <typename DataType>
|
|
155
|
+
void transform_vertical_slice(
|
|
156
|
+
VerticalSlice<DataType> vslice,
|
|
157
|
+
DataType *__restrict__ swap,
|
|
158
|
+
DataType *__restrict__ out)
|
|
159
|
+
{
|
|
160
|
+
if (vslice.planes == 1)
|
|
161
|
+
{
|
|
162
|
+
const size_t shift = vslice.plane_index * vslice.row_index;
|
|
163
|
+
rollback(vslice.data, vslice.cols, shift, out);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// NOTE: Use output as swap space, and swap space as intermediate
|
|
168
|
+
// storage
|
|
169
|
+
const size_t offset = head_size(vslice.planes) * vslice.cols;
|
|
170
|
+
transform_vertical_slice(vslice.head(), out, swap);
|
|
171
|
+
transform_vertical_slice(vslice.tail(), out + offset, swap + offset);
|
|
172
|
+
merge_radix2(swap, swap + offset, vslice.planes / 2, vslice.cols, out);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/// @brief The maximum number of rows that should be transformed
|
|
176
|
+
/// within a small FFA transform. It is chosen such that the small FFA
|
|
177
|
+
/// input size does not exceed SMALL_INPUT_MAX_SIZE.
|
|
178
|
+
/// Returns a power of two that is >= 2.
|
|
179
|
+
template <typename DataType>
|
|
180
|
+
size_t small_transform_num_rows(const size_t cols)
|
|
181
|
+
{
|
|
182
|
+
const size_t max_size_elements = SMALL_INPUT_MAX_SIZE / sizeof(DataType);
|
|
183
|
+
const size_t max_rows = 1UL << integer_log2(max_size_elements / cols);
|
|
184
|
+
return std::max(max_rows, 2UL);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
template <typename DataType>
|
|
188
|
+
TransformCube<DataType> transform_until(
|
|
189
|
+
TransformCube<DataType> incube, // 8 planes, 32 rows/plane
|
|
190
|
+
const size_t target_num_planes, // 2
|
|
191
|
+
DataType *__restrict__ swap,
|
|
192
|
+
DataType *__restrict__ temp,
|
|
193
|
+
DataType *__restrict__ out) // 2 planes, 256 rows/plane
|
|
194
|
+
{
|
|
195
|
+
if (incube.planes <= target_num_planes)
|
|
196
|
+
{
|
|
197
|
+
return incube;
|
|
198
|
+
}
|
|
199
|
+
const size_t merge_factor = std::min(
|
|
200
|
+
small_transform_num_rows<DataType>(incube.cols),
|
|
201
|
+
incube.planes / target_num_planes); // 4
|
|
202
|
+
|
|
203
|
+
// First obtain a cube whose number of planes is 'merge_factor' times
|
|
204
|
+
// larger than the target
|
|
205
|
+
// NOTE: use 'out' as the intermediate storage for the recursion level below
|
|
206
|
+
TransformCube<DataType> midcube = transform_until(incube, target_num_planes * merge_factor, swap, out, temp);
|
|
207
|
+
|
|
208
|
+
// Prepare output cube view with adequate dimensions
|
|
209
|
+
TransformCube<DataType> outcube = TransformCube(out, target_num_planes, midcube.rows * merge_factor, midcube.cols);
|
|
210
|
+
|
|
211
|
+
// Group planes of 'midcube' by groups of 'merge_factor' planes
|
|
212
|
+
// In other words, split 'midcube' into 'merge_factor' sub-cubes
|
|
213
|
+
// Each sub-cube can be directly transformed into an output plane
|
|
214
|
+
for (size_t i = 0; i < target_num_planes; ++i)
|
|
215
|
+
{
|
|
216
|
+
TransformCube<DataType> sub_midcube = midcube.getSubCube(i * merge_factor, merge_factor);
|
|
217
|
+
|
|
218
|
+
for (size_t j = 0; j < sub_midcube.rows; ++j)
|
|
219
|
+
{
|
|
220
|
+
transform_vertical_slice(
|
|
221
|
+
sub_midcube.getVerticalSlice(j),
|
|
222
|
+
swap,
|
|
223
|
+
outcube.getSubPlane(i, j * merge_factor, merge_factor).data);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return outcube;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
template <typename DataType>
|
|
230
|
+
void transform(
|
|
231
|
+
DataType *__restrict__ data,
|
|
232
|
+
const size_t total_rows,
|
|
233
|
+
const size_t cols,
|
|
234
|
+
DataType *__restrict__ swap,
|
|
235
|
+
DataType *__restrict__ temp,
|
|
236
|
+
DataType *__restrict__ out)
|
|
237
|
+
{
|
|
238
|
+
transform_until(
|
|
239
|
+
TransformCube<DataType>(data, total_rows, 1, cols),
|
|
240
|
+
1,
|
|
241
|
+
swap,
|
|
242
|
+
temp,
|
|
243
|
+
out);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
} // namespace riptide
|
|
247
|
+
|
|
248
|
+
#endif // TRANSFORMS_ADVANCED_HPP
|
|
@@ -3,6 +3,22 @@ from setuptools import setup
|
|
|
3
3
|
# Available at setup time due to pyproject.toml
|
|
4
4
|
from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
5
5
|
|
|
6
|
+
# WARNING: Enabling -freciprocal-math (which is also enabled by
|
|
7
|
+
# -funsafe-math-optimizations or -ffast-math) causes surprising inconsistencies
|
|
8
|
+
# when calculating the size of the output periodogram, and the size of the
|
|
9
|
+
# buffers to store data downsampled by a real-valued factor.
|
|
10
|
+
# In turn, this can cause segmentation faults (code attempts to write past the
|
|
11
|
+
# end of these arrays).
|
|
12
|
+
# The flags below provide the same speedups as -ffast-math, without the risks.
|
|
13
|
+
SAFE_FAST_MATH_FLAGS = [
|
|
14
|
+
"-fassociative-math",
|
|
15
|
+
"-fno-math-errno",
|
|
16
|
+
"-ffinite-math-only",
|
|
17
|
+
"-fno-rounding-math",
|
|
18
|
+
"-fno-signed-zeros",
|
|
19
|
+
"-fno-trapping-math",
|
|
20
|
+
]
|
|
21
|
+
|
|
6
22
|
# The main interface is through Pybind11Extension.
|
|
7
23
|
# * You can add cxx_std=11/14/17, and then build_ext can be removed.
|
|
8
24
|
# * You can set include_pybind11=false to add the include directory yourself,
|
|
@@ -13,9 +29,9 @@ from pybind11.setup_helpers import Pybind11Extension, build_ext
|
|
|
13
29
|
# reproducible builds (https://github.com/pybind/python_example/pull/53)
|
|
14
30
|
ext_modules = [
|
|
15
31
|
Pybind11Extension(
|
|
16
|
-
|
|
17
|
-
sorted([
|
|
18
|
-
extra_compile_args=[
|
|
32
|
+
"riptide.libcpp",
|
|
33
|
+
sorted(["src/riptide/cpp/python_bindings.cpp"]),
|
|
34
|
+
extra_compile_args=["-O3", "-march=native"] + SAFE_FAST_MATH_FLAGS,
|
|
19
35
|
),
|
|
20
36
|
]
|
|
21
37
|
|