pywiggle 0.1.3__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.
- pywiggle-0.1.3/.github/ISSUE_TEMPLATE.md +16 -0
- pywiggle-0.1.3/.github/workflows/build.yml +187 -0
- pywiggle-0.1.3/LICENSE +32 -0
- pywiggle-0.1.3/PKG-INFO +165 -0
- pywiggle-0.1.3/README.rst +145 -0
- pywiggle-0.1.3/meson.build +38 -0
- pywiggle-0.1.3/pyproject.toml +32 -0
- pywiggle-0.1.3/pywiggle/__init__.py +15 -0
- pywiggle-0.1.3/pywiggle/core.py +1291 -0
- pywiggle-0.1.3/pywiggle/tests/__init__.py +0 -0
- pywiggle-0.1.3/pywiggle/tests/test_utils.py +127 -0
- pywiggle-0.1.3/pywiggle/tests/test_wiggle.py +108 -0
- pywiggle-0.1.3/pywiggle/tests/test_wignerd.py +57 -0
- pywiggle-0.1.3/pywiggle/utils.py +265 -0
- pywiggle-0.1.3/src/wiggle.cpp +312 -0
- pywiggle-0.1.3/src/wiggle.hpp +55 -0
- pywiggle-0.1.3/src/wiggle_bindings.cpp +330 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
* pywiggle version:
|
|
2
|
+
* Python version:
|
|
3
|
+
* Operating System:
|
|
4
|
+
|
|
5
|
+
### Description
|
|
6
|
+
|
|
7
|
+
Describe what you were trying to get done.
|
|
8
|
+
Tell us what happened, what went wrong, and what you expected to happen.
|
|
9
|
+
|
|
10
|
+
### What I Did
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
Paste the command(s) you ran and the output.
|
|
14
|
+
If there was a crash, please include the traceback here.
|
|
15
|
+
For long outputs, use https://pastebin.com/
|
|
16
|
+
```
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
|
|
7
|
+
test-linux:
|
|
8
|
+
name: "Run tests on Linux"
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python: ["3.13", "3.12", "3.11", "3.10"]
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: ${{ matrix.python }}
|
|
20
|
+
|
|
21
|
+
- name: Run Tests (Linux)
|
|
22
|
+
run: |
|
|
23
|
+
python -m pip install --upgrade pip setuptools wheel meson ninja meson-python numpy scipy pybind11
|
|
24
|
+
python -m pip install --no-build-isolation --editable '.[test]'
|
|
25
|
+
pytest --cov --cov-report html --cov-report xml --cov-report annotate -sx
|
|
26
|
+
|
|
27
|
+
- uses: codecov/codecov-action@v2
|
|
28
|
+
with:
|
|
29
|
+
verbose: true # optional (default = false)
|
|
30
|
+
|
|
31
|
+
build_wheels_ubuntu:
|
|
32
|
+
name: Build wheels on ${{ matrix.os }}
|
|
33
|
+
runs-on: ${{ matrix.os }}
|
|
34
|
+
strategy:
|
|
35
|
+
matrix:
|
|
36
|
+
# macos-13 is an intel runner, macos-14 is apple silicon
|
|
37
|
+
os: [ubuntu-latest]
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- uses: actions/checkout@v4
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
- name: Build wheels
|
|
44
|
+
uses: pypa/cibuildwheel@v2.23.3
|
|
45
|
+
env:
|
|
46
|
+
CIBW_SKIP: "pp* *-musllinux*" # TODO: Temporary
|
|
47
|
+
|
|
48
|
+
- uses: actions/upload-artifact@v4
|
|
49
|
+
with:
|
|
50
|
+
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
|
|
51
|
+
path: ./wheelhouse/*.whl
|
|
52
|
+
|
|
53
|
+
build_wheels_macos:
|
|
54
|
+
runs-on: ${{ matrix.os }}
|
|
55
|
+
strategy:
|
|
56
|
+
fail-fast: false
|
|
57
|
+
matrix:
|
|
58
|
+
include:
|
|
59
|
+
- os: macos-13 # Intel → x86_64 wheel
|
|
60
|
+
cibw_arch: x86_64
|
|
61
|
+
- os: macos-14 # Apple-Silicon → arm64 wheel
|
|
62
|
+
cibw_arch: arm64
|
|
63
|
+
|
|
64
|
+
steps:
|
|
65
|
+
- uses: actions/checkout@v4
|
|
66
|
+
|
|
67
|
+
# ---------- 1 · compiler + single OpenMP runtime ---------- #
|
|
68
|
+
- name: Install LLVM + libomp
|
|
69
|
+
run: |
|
|
70
|
+
brew install llvm libomp # unversioned, current LLVM 18.x
|
|
71
|
+
LLVM_PREFIX="$(brew --prefix llvm)"
|
|
72
|
+
|
|
73
|
+
# put clang/clang++ first in PATH
|
|
74
|
+
echo "PATH=${LLVM_PREFIX}/bin:$PATH" >> "$GITHUB_ENV"
|
|
75
|
+
echo "CC=${LLVM_PREFIX}/bin/clang" >> "$GITHUB_ENV"
|
|
76
|
+
echo "CXX=${LLVM_PREFIX}/bin/clang++" >> "$GITHUB_ENV"
|
|
77
|
+
|
|
78
|
+
# headers & linker path for the system libomp
|
|
79
|
+
echo "CPPFLAGS=-I${LLVM_PREFIX}/include" >> "$GITHUB_ENV"
|
|
80
|
+
echo "LDFLAGS=-L${LLVM_PREFIX}/lib -lomp \
|
|
81
|
+
-Wl,-rpath,@loader_path \
|
|
82
|
+
-Wl,-rpath,${LLVM_PREFIX}/lib" >> "$GITHUB_ENV"
|
|
83
|
+
|
|
84
|
+
# ---------- 2 · build wheel & leave libomp OUT ---------- #
|
|
85
|
+
- name: Build wheels
|
|
86
|
+
uses: pypa/cibuildwheel@v2.23.3
|
|
87
|
+
env:
|
|
88
|
+
CIBW_ARCHS_MACOS: ${{ matrix.cibw_arch }}
|
|
89
|
+
CIBW_SKIP: "pp*" # TODO: Temporary
|
|
90
|
+
|
|
91
|
+
# compile with OpenMP flags
|
|
92
|
+
CIBW_ENVIRONMENT_MACOS: |
|
|
93
|
+
CFLAGS="-O3 -fopenmp"
|
|
94
|
+
CXXFLAGS="-O3 -fopenmp"
|
|
95
|
+
FFLAGS="-O3 -fopenmp=libomp"
|
|
96
|
+
LDFLAGS="${LDFLAGS}"
|
|
97
|
+
|
|
98
|
+
CIBW_REPAIR_WHEEL_COMMAND_MACOS: >
|
|
99
|
+
delocate-wheel -w {dest_dir}
|
|
100
|
+
-e libomp.dylib
|
|
101
|
+
--require-archs x86_64,arm64
|
|
102
|
+
{wheel}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
MACOSX_DEPLOYMENT_TARGET: "13.0"
|
|
106
|
+
|
|
107
|
+
with:
|
|
108
|
+
output-dir: wheelhouse
|
|
109
|
+
|
|
110
|
+
# ---------- 3 · upload artefact ---------- #
|
|
111
|
+
- uses: actions/upload-artifact@v4
|
|
112
|
+
with:
|
|
113
|
+
name: wheels-${{ matrix.os }}-${{ matrix.cibw_arch }}
|
|
114
|
+
path: wheelhouse/*.whl
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
build_sdist:
|
|
118
|
+
name: Build source distribution
|
|
119
|
+
runs-on: ubuntu-latest
|
|
120
|
+
steps:
|
|
121
|
+
- uses: actions/checkout@v4
|
|
122
|
+
|
|
123
|
+
- uses: actions/setup-python@v5
|
|
124
|
+
name: Install Python
|
|
125
|
+
with:
|
|
126
|
+
python-version: '3.10'
|
|
127
|
+
|
|
128
|
+
- name: Build sdist
|
|
129
|
+
run: |
|
|
130
|
+
python -m pip install -U pip
|
|
131
|
+
python -m pip install -U setuptools
|
|
132
|
+
python -m pip install --upgrade pip setuptools wheel
|
|
133
|
+
python -m pip install numpy pybind11 scipy
|
|
134
|
+
python -m pip install build
|
|
135
|
+
python -m build . --sdist
|
|
136
|
+
|
|
137
|
+
- uses: actions/upload-artifact@v4
|
|
138
|
+
with:
|
|
139
|
+
name: cibw-sdist
|
|
140
|
+
path: dist/*.tar.gz
|
|
141
|
+
|
|
142
|
+
upload_pypi:
|
|
143
|
+
needs: [build_wheels_ubuntu, build_sdist, build_wheels_macos]
|
|
144
|
+
runs-on: ubuntu-latest
|
|
145
|
+
# upload to PyPI on every tag starting with 'v'
|
|
146
|
+
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
|
|
147
|
+
# alternatively, to publish when a GitHub Release is created, use the following rule:
|
|
148
|
+
# if: github.event_name == 'release' && github.event.action == 'published'
|
|
149
|
+
steps:
|
|
150
|
+
- uses: actions/download-artifact@v4
|
|
151
|
+
with:
|
|
152
|
+
pattern: cibw-*
|
|
153
|
+
path: dist
|
|
154
|
+
merge-multiple: true
|
|
155
|
+
|
|
156
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
157
|
+
with:
|
|
158
|
+
user: __token__
|
|
159
|
+
password: ${{ secrets.PYPI_TOKEN }}
|
|
160
|
+
# To test: repository_url: https://test.pypi.org/legacy/
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
test-wheel:
|
|
164
|
+
needs: [upload_pypi]
|
|
165
|
+
name: "Run tests on ${{ matrix.os }} with uploaded wheels"
|
|
166
|
+
runs-on: ${{ matrix.os }}
|
|
167
|
+
|
|
168
|
+
strategy:
|
|
169
|
+
matrix:
|
|
170
|
+
os: [ubuntu-latest, macos-13, macos-14]
|
|
171
|
+
python: ["3.13", "3.12", "3.11", "3.10"]
|
|
172
|
+
|
|
173
|
+
steps:
|
|
174
|
+
- uses: actions/checkout@v4
|
|
175
|
+
|
|
176
|
+
- uses: actions/setup-python@v5
|
|
177
|
+
with:
|
|
178
|
+
python-version: ${{ matrix.python }}
|
|
179
|
+
|
|
180
|
+
- name: Install test dependencies and wheel from PyPI
|
|
181
|
+
run: |
|
|
182
|
+
python -m pip install --upgrade pip setuptools wheel pytest
|
|
183
|
+
python -m pip install pywiggle
|
|
184
|
+
|
|
185
|
+
- name: Run Tests
|
|
186
|
+
run: |
|
|
187
|
+
pytest --pyargs pywiggle.tests
|
pywiggle-0.1.3/LICENSE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
BSD License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2025-2035, Mathew Syriac Madhavacheril.
|
|
6
|
+
All rights reserved.
|
|
7
|
+
|
|
8
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
9
|
+
are permitted provided that the following conditions are met:
|
|
10
|
+
|
|
11
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
12
|
+
list of conditions and the following disclaimer.
|
|
13
|
+
|
|
14
|
+
* Redistributions in binary form must reproduce the above copyright notice, this
|
|
15
|
+
list of conditions and the following disclaimer in the documentation and/or
|
|
16
|
+
other materials provided with the distribution.
|
|
17
|
+
|
|
18
|
+
* Neither the name of the copyright holder nor the names of its
|
|
19
|
+
contributors may be used to endorse or promote products derived from this
|
|
20
|
+
software without specific prior written permission.
|
|
21
|
+
|
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
23
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
24
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
25
|
+
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
26
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
27
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
28
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
29
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
30
|
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
|
31
|
+
OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
32
|
+
|
pywiggle-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pywiggle
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Fast angular power spectrum estimator
|
|
5
|
+
Author-Email: Mathew Madhavacheril <mathewsyriac@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/msyriac/wiggle
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: numpy
|
|
10
|
+
Requires-Dist: pybind11>=2.11
|
|
11
|
+
Requires-Dist: healpy
|
|
12
|
+
Requires-Dist: fastgl>=0.1.10
|
|
13
|
+
Requires-Dist: scipy>=1.0
|
|
14
|
+
Provides-Extra: test
|
|
15
|
+
Requires-Dist: pytest-cov>=2.6; extra == "test"
|
|
16
|
+
Requires-Dist: coveralls>=1.5; extra == "test"
|
|
17
|
+
Requires-Dist: pytest>=4.6; extra == "test"
|
|
18
|
+
Requires-Dist: threadpoolctl; extra == "test"
|
|
19
|
+
Description-Content-Type: text/x-rst
|
|
20
|
+
|
|
21
|
+
``wiggle``
|
|
22
|
+
==========
|
|
23
|
+
|
|
24
|
+
.. image:: https://github.com/msyriac/wiggle/workflows/Build/badge.svg
|
|
25
|
+
:target: https://github.com/msyriac/wiggle/actions?query=workflow%3ABuild
|
|
26
|
+
|
|
27
|
+
.. image:: https://readthedocs.org/projects/pywiggle/badge/?version=latest
|
|
28
|
+
:target: https://pywiggle.readthedocs.io/en/latest/?badge=latest
|
|
29
|
+
:alt: Documentation Status
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
``wiggle`` stands for the WIGner Gauss-Legendre Estimator. This Python package provides a fast implementation of unbiased angular power spectrum estimation of spin-0 and spin-2 fields on the sphere, most commonly encountered in the context of cosmological data analysis.
|
|
33
|
+
|
|
34
|
+
Typically, estimates of the power spectrum of masked fields involve products of Wigner-3j symbols, which can be factorized into products of Wigner-d matrices and integrated exactly using Gauss-Legendre quadrature. This code provides efficient implementations of this approach to mode decoupling for exact power spectrum estimation, which in the case of binned spectra can be orders of magnitude faster than other approaches (often around a second of compute-time at most).
|
|
35
|
+
|
|
36
|
+
* Free software: BSD license
|
|
37
|
+
* Documentation: https://pywiggle.readthedocs.io.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
Installing
|
|
42
|
+
----------
|
|
43
|
+
|
|
44
|
+
Make sure your ``pip`` tool is up-to-date. To install ``wiggle``, run:
|
|
45
|
+
|
|
46
|
+
.. code-block:: console
|
|
47
|
+
|
|
48
|
+
$ pip install pywiggle --user
|
|
49
|
+
|
|
50
|
+
This will install a pre-compiled binary suitable for your system (only Linux and Mac OS X with Python>=3.9 are supported). After installation, make sure to run a test with:
|
|
51
|
+
|
|
52
|
+
.. code-block:: console
|
|
53
|
+
|
|
54
|
+
$ pytest --pyargs pywiggle.tests
|
|
55
|
+
|
|
56
|
+
If you require more control over your installation, e.g. using Intel compilers, please see the section below on compiling from source.
|
|
57
|
+
|
|
58
|
+
Compiling from source (advanced / development workflow)
|
|
59
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
60
|
+
|
|
61
|
+
The easiest way to install from source is to use the ``pip`` tool,
|
|
62
|
+
with the ``--no-binary`` flag. This will download the source distribution
|
|
63
|
+
and compile it for you. Don't forget to make sure you have CXX set
|
|
64
|
+
if you have any problems.
|
|
65
|
+
|
|
66
|
+
For all other cases, below are general instructions.
|
|
67
|
+
|
|
68
|
+
First, download the source distribution or ``git clone`` this repository. You
|
|
69
|
+
can work from ``master`` or checkout one of the released version tags (see the
|
|
70
|
+
Releases section on Github). Then change into the cloned/source directory.
|
|
71
|
+
|
|
72
|
+
Once downloaded, you can install using ``pip install .`` inside the project
|
|
73
|
+
directory. We use the ``meson`` build system, which should be understood by
|
|
74
|
+
``pip`` (it will build in an isolated environment).
|
|
75
|
+
|
|
76
|
+
We suggest you then test the installation by running the unit tests. You
|
|
77
|
+
can do this by running ``pytest``.
|
|
78
|
+
|
|
79
|
+
To run an editable install, you will need to do so in a way that does not
|
|
80
|
+
have build isolation (as the backend build system, `meson` and `ninja`, actually
|
|
81
|
+
perform micro-builds on usage in this case):
|
|
82
|
+
|
|
83
|
+
.. code-block:: console
|
|
84
|
+
|
|
85
|
+
$ pip install --upgrade pip meson ninja meson-python cython numpy pybind11
|
|
86
|
+
$ pip install --no-build-isolation --editable .
|
|
87
|
+
|
|
88
|
+
After installation, make sure to run a test with:
|
|
89
|
+
|
|
90
|
+
.. code-block:: console
|
|
91
|
+
|
|
92
|
+
$ pytest
|
|
93
|
+
|
|
94
|
+
Quick Usage
|
|
95
|
+
-----------
|
|
96
|
+
|
|
97
|
+
Accurate power spectrum estimation requires you to first convert a pixelated and masked map to its spherical harmonic coefficients. ``wiggle`` does not provide tools for SHTs and expects you to have the ``alm`` coefficients both for the masked fields and the mask itself already in hand. These can be obtained using a code like ``healpy`` in the case of HEALPix maps or a code like ``pixell`` in the case of rectangular pixelization maps.
|
|
98
|
+
|
|
99
|
+
If you are interested in accurate power spectra out to some maximum multipole ``lmax``, we recommend you evaluate SHTs out to ``lmax`` for the masked fields, but out to ``2 lmax`` for the mask itself. With these in hand, you can obtain unbiased power spectra as follows, in the case of a spin-0 field for example:
|
|
100
|
+
|
|
101
|
+
.. code-block:: python
|
|
102
|
+
|
|
103
|
+
> import pywiggle
|
|
104
|
+
> import numpy as np
|
|
105
|
+
|
|
106
|
+
> lmax = 4000
|
|
107
|
+
> bin_edges = np.arange(40,lmax,40)
|
|
108
|
+
|
|
109
|
+
> dcls, th_filt = pywiggle.alm2auto_power_spin0(lmax,alm,mask_alm,bin_edges = bin_edges)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
Here ``dcls`` is the mode-decoupled unbiased power spectrum and ``th_filt`` is a matrix that can be dotted with a theory spectrum to obtain the binned theory to compare the power spectrum to (e.g. for inference):
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
.. code-block:: python
|
|
116
|
+
|
|
117
|
+
> chisquare = get_chisquare(dcls,th_filt @ theory_cls,cinv)
|
|
118
|
+
|
|
119
|
+
While the above function ``alm2auto_power_spin0`` is intended for the auto-spectra of a spin-0 field, many additional convenience functions are provided:
|
|
120
|
+
|
|
121
|
+
* ``alm2cross_power_spin0``: Cross-power of spin-0 fields (:math:`T_1` x :math:`T_2`)
|
|
122
|
+
* ``alm2auto_power_spin2``: Auto-power of E/B decomposition of spin-2 fields (EE and BB)
|
|
123
|
+
* ``alm2auto_power_spin02``: Auto-power of scalar,E,B fields along with the scalar-E power (TT, EE, BB, TE)
|
|
124
|
+
* ``alm2cross_power_spin2``: Cross-power of E/B decomposition of spin-2 fields (:math:`E_1` x :math:`E_2` and :math:`B_1` x :math:`B_2`)
|
|
125
|
+
* ``alm2cross_power_spin02``: Cross-power of scalar,E/B fields along with the scalar-E power (:math:`T_1` x :math:`T_2`, :math:`E_1` x :math:`E_2` and :math:`B_1` x :math:`B_2`, :math:`T_1` x :math:`E_2`, :math:`T_2` x :math:`E_1`)
|
|
126
|
+
|
|
127
|
+
Cached workflow
|
|
128
|
+
~~~~~~~~~~~~~~~
|
|
129
|
+
|
|
130
|
+
The above functions are convenience wrappers around the core class ``Wiggle``, which can be used directly if speed and efficient re-use of cached mode-coupling matrices is important. For example,
|
|
131
|
+
|
|
132
|
+
.. code-block:: python
|
|
133
|
+
|
|
134
|
+
> w = Wiggle(lmax, bin_edges=bin_edges)
|
|
135
|
+
# Register the SHT of a mask and identify it with a key
|
|
136
|
+
> w.add_mask('mt1', mask_alm_t1)
|
|
137
|
+
# Register another mask
|
|
138
|
+
> w.add_mask('mt2', mask_alm_p2)
|
|
139
|
+
# Register a beam to deconvolve from both fields
|
|
140
|
+
> g.add_beam('b1', beam_fl)
|
|
141
|
+
# Get the decoupled cross-Cls from the masked field SHTs
|
|
142
|
+
> ret_TT = g.decoupled_cl(alm_t1, alm_t2, 'mt1', 'mt2', spectype='TT',
|
|
143
|
+
return_theory_filter=False,
|
|
144
|
+
beam_id1='b1', beam_id2='b1')
|
|
145
|
+
|
|
146
|
+
This object can then be reused if the same masks are being re-used, which avoids re-calculation of mode-coupling matrices. The interface to ``decoupled_cl`` is flexible enough to allow all auto- and cross- spectra of spin-0 and spin-2 fields.
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
Coming soon
|
|
150
|
+
~~~~~~~~~~~
|
|
151
|
+
|
|
152
|
+
TB and EB spectra as well as mode-decoupling for purified E/B fiels have not been implemented yet, but are planned to in a future release.
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
Contributions
|
|
156
|
+
-------------
|
|
157
|
+
|
|
158
|
+
If you have write access to this repository, please:
|
|
159
|
+
|
|
160
|
+
1. create a new branch
|
|
161
|
+
2. push your changes to that branch
|
|
162
|
+
3. merge or rebase to get in sync with master
|
|
163
|
+
4. submit a pull request on github
|
|
164
|
+
|
|
165
|
+
If you do not have write access, create a fork of this repository and proceed as described above.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
``wiggle``
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
.. image:: https://github.com/msyriac/wiggle/workflows/Build/badge.svg
|
|
5
|
+
:target: https://github.com/msyriac/wiggle/actions?query=workflow%3ABuild
|
|
6
|
+
|
|
7
|
+
.. image:: https://readthedocs.org/projects/pywiggle/badge/?version=latest
|
|
8
|
+
:target: https://pywiggle.readthedocs.io/en/latest/?badge=latest
|
|
9
|
+
:alt: Documentation Status
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
``wiggle`` stands for the WIGner Gauss-Legendre Estimator. This Python package provides a fast implementation of unbiased angular power spectrum estimation of spin-0 and spin-2 fields on the sphere, most commonly encountered in the context of cosmological data analysis.
|
|
13
|
+
|
|
14
|
+
Typically, estimates of the power spectrum of masked fields involve products of Wigner-3j symbols, which can be factorized into products of Wigner-d matrices and integrated exactly using Gauss-Legendre quadrature. This code provides efficient implementations of this approach to mode decoupling for exact power spectrum estimation, which in the case of binned spectra can be orders of magnitude faster than other approaches (often around a second of compute-time at most).
|
|
15
|
+
|
|
16
|
+
* Free software: BSD license
|
|
17
|
+
* Documentation: https://pywiggle.readthedocs.io.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Installing
|
|
22
|
+
----------
|
|
23
|
+
|
|
24
|
+
Make sure your ``pip`` tool is up-to-date. To install ``wiggle``, run:
|
|
25
|
+
|
|
26
|
+
.. code-block:: console
|
|
27
|
+
|
|
28
|
+
$ pip install pywiggle --user
|
|
29
|
+
|
|
30
|
+
This will install a pre-compiled binary suitable for your system (only Linux and Mac OS X with Python>=3.9 are supported). After installation, make sure to run a test with:
|
|
31
|
+
|
|
32
|
+
.. code-block:: console
|
|
33
|
+
|
|
34
|
+
$ pytest --pyargs pywiggle.tests
|
|
35
|
+
|
|
36
|
+
If you require more control over your installation, e.g. using Intel compilers, please see the section below on compiling from source.
|
|
37
|
+
|
|
38
|
+
Compiling from source (advanced / development workflow)
|
|
39
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
40
|
+
|
|
41
|
+
The easiest way to install from source is to use the ``pip`` tool,
|
|
42
|
+
with the ``--no-binary`` flag. This will download the source distribution
|
|
43
|
+
and compile it for you. Don't forget to make sure you have CXX set
|
|
44
|
+
if you have any problems.
|
|
45
|
+
|
|
46
|
+
For all other cases, below are general instructions.
|
|
47
|
+
|
|
48
|
+
First, download the source distribution or ``git clone`` this repository. You
|
|
49
|
+
can work from ``master`` or checkout one of the released version tags (see the
|
|
50
|
+
Releases section on Github). Then change into the cloned/source directory.
|
|
51
|
+
|
|
52
|
+
Once downloaded, you can install using ``pip install .`` inside the project
|
|
53
|
+
directory. We use the ``meson`` build system, which should be understood by
|
|
54
|
+
``pip`` (it will build in an isolated environment).
|
|
55
|
+
|
|
56
|
+
We suggest you then test the installation by running the unit tests. You
|
|
57
|
+
can do this by running ``pytest``.
|
|
58
|
+
|
|
59
|
+
To run an editable install, you will need to do so in a way that does not
|
|
60
|
+
have build isolation (as the backend build system, `meson` and `ninja`, actually
|
|
61
|
+
perform micro-builds on usage in this case):
|
|
62
|
+
|
|
63
|
+
.. code-block:: console
|
|
64
|
+
|
|
65
|
+
$ pip install --upgrade pip meson ninja meson-python cython numpy pybind11
|
|
66
|
+
$ pip install --no-build-isolation --editable .
|
|
67
|
+
|
|
68
|
+
After installation, make sure to run a test with:
|
|
69
|
+
|
|
70
|
+
.. code-block:: console
|
|
71
|
+
|
|
72
|
+
$ pytest
|
|
73
|
+
|
|
74
|
+
Quick Usage
|
|
75
|
+
-----------
|
|
76
|
+
|
|
77
|
+
Accurate power spectrum estimation requires you to first convert a pixelated and masked map to its spherical harmonic coefficients. ``wiggle`` does not provide tools for SHTs and expects you to have the ``alm`` coefficients both for the masked fields and the mask itself already in hand. These can be obtained using a code like ``healpy`` in the case of HEALPix maps or a code like ``pixell`` in the case of rectangular pixelization maps.
|
|
78
|
+
|
|
79
|
+
If you are interested in accurate power spectra out to some maximum multipole ``lmax``, we recommend you evaluate SHTs out to ``lmax`` for the masked fields, but out to ``2 lmax`` for the mask itself. With these in hand, you can obtain unbiased power spectra as follows, in the case of a spin-0 field for example:
|
|
80
|
+
|
|
81
|
+
.. code-block:: python
|
|
82
|
+
|
|
83
|
+
> import pywiggle
|
|
84
|
+
> import numpy as np
|
|
85
|
+
|
|
86
|
+
> lmax = 4000
|
|
87
|
+
> bin_edges = np.arange(40,lmax,40)
|
|
88
|
+
|
|
89
|
+
> dcls, th_filt = pywiggle.alm2auto_power_spin0(lmax,alm,mask_alm,bin_edges = bin_edges)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
Here ``dcls`` is the mode-decoupled unbiased power spectrum and ``th_filt`` is a matrix that can be dotted with a theory spectrum to obtain the binned theory to compare the power spectrum to (e.g. for inference):
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
.. code-block:: python
|
|
96
|
+
|
|
97
|
+
> chisquare = get_chisquare(dcls,th_filt @ theory_cls,cinv)
|
|
98
|
+
|
|
99
|
+
While the above function ``alm2auto_power_spin0`` is intended for the auto-spectra of a spin-0 field, many additional convenience functions are provided:
|
|
100
|
+
|
|
101
|
+
* ``alm2cross_power_spin0``: Cross-power of spin-0 fields (:math:`T_1` x :math:`T_2`)
|
|
102
|
+
* ``alm2auto_power_spin2``: Auto-power of E/B decomposition of spin-2 fields (EE and BB)
|
|
103
|
+
* ``alm2auto_power_spin02``: Auto-power of scalar,E,B fields along with the scalar-E power (TT, EE, BB, TE)
|
|
104
|
+
* ``alm2cross_power_spin2``: Cross-power of E/B decomposition of spin-2 fields (:math:`E_1` x :math:`E_2` and :math:`B_1` x :math:`B_2`)
|
|
105
|
+
* ``alm2cross_power_spin02``: Cross-power of scalar,E/B fields along with the scalar-E power (:math:`T_1` x :math:`T_2`, :math:`E_1` x :math:`E_2` and :math:`B_1` x :math:`B_2`, :math:`T_1` x :math:`E_2`, :math:`T_2` x :math:`E_1`)
|
|
106
|
+
|
|
107
|
+
Cached workflow
|
|
108
|
+
~~~~~~~~~~~~~~~
|
|
109
|
+
|
|
110
|
+
The above functions are convenience wrappers around the core class ``Wiggle``, which can be used directly if speed and efficient re-use of cached mode-coupling matrices is important. For example,
|
|
111
|
+
|
|
112
|
+
.. code-block:: python
|
|
113
|
+
|
|
114
|
+
> w = Wiggle(lmax, bin_edges=bin_edges)
|
|
115
|
+
# Register the SHT of a mask and identify it with a key
|
|
116
|
+
> w.add_mask('mt1', mask_alm_t1)
|
|
117
|
+
# Register another mask
|
|
118
|
+
> w.add_mask('mt2', mask_alm_p2)
|
|
119
|
+
# Register a beam to deconvolve from both fields
|
|
120
|
+
> g.add_beam('b1', beam_fl)
|
|
121
|
+
# Get the decoupled cross-Cls from the masked field SHTs
|
|
122
|
+
> ret_TT = g.decoupled_cl(alm_t1, alm_t2, 'mt1', 'mt2', spectype='TT',
|
|
123
|
+
return_theory_filter=False,
|
|
124
|
+
beam_id1='b1', beam_id2='b1')
|
|
125
|
+
|
|
126
|
+
This object can then be reused if the same masks are being re-used, which avoids re-calculation of mode-coupling matrices. The interface to ``decoupled_cl`` is flexible enough to allow all auto- and cross- spectra of spin-0 and spin-2 fields.
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
Coming soon
|
|
130
|
+
~~~~~~~~~~~
|
|
131
|
+
|
|
132
|
+
TB and EB spectra as well as mode-decoupling for purified E/B fiels have not been implemented yet, but are planned to in a future release.
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
Contributions
|
|
136
|
+
-------------
|
|
137
|
+
|
|
138
|
+
If you have write access to this repository, please:
|
|
139
|
+
|
|
140
|
+
1. create a new branch
|
|
141
|
+
2. push your changes to that branch
|
|
142
|
+
3. merge or rebase to get in sync with master
|
|
143
|
+
4. submit a pull request on github
|
|
144
|
+
|
|
145
|
+
If you do not have write access, create a fork of this repository and proceed as described above.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
project('pywiggle',
|
|
2
|
+
['cpp'],
|
|
3
|
+
default_options : ['cpp_std=c++17'])
|
|
4
|
+
|
|
5
|
+
py = import('python').find_installation(pure: false)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# Get pybind11 include paths dynamically
|
|
9
|
+
pybind_includes = run_command(py, '-m', 'pybind11', '--includes').stdout().strip().split()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
inc = include_directories('src')
|
|
13
|
+
|
|
14
|
+
sources = files(
|
|
15
|
+
'src/wiggle.cpp',
|
|
16
|
+
'src/wiggle_bindings.cpp', # pybind11 glue
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# --- find OpenMP ----------------
|
|
20
|
+
omp_dep = dependency('openmp')
|
|
21
|
+
|
|
22
|
+
# Enable OpenMP for C++ manually
|
|
23
|
+
add_project_arguments('-fopenmp', language: 'cpp')
|
|
24
|
+
add_project_link_arguments('-fopenmp', language: 'cpp')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
extension = py.extension_module(
|
|
28
|
+
'_wiggle',
|
|
29
|
+
sources : sources,
|
|
30
|
+
dependencies : [omp_dep],
|
|
31
|
+
cpp_args : pybind_includes + ['-O3', '-fopenmp'],
|
|
32
|
+
include_directories : inc,
|
|
33
|
+
subdir : 'pywiggle',
|
|
34
|
+
install : true,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
# Install the pure-Python package tree itself
|
|
38
|
+
install_subdir('pywiggle', install_dir : py.get_install_dir())
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["meson-python>=0.15", "pybind11>=2.11", "build", "pytest"]
|
|
3
|
+
build-backend = "mesonpy"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pywiggle"
|
|
7
|
+
version = "0.1.3"
|
|
8
|
+
description = "Fast angular power spectrum estimator"
|
|
9
|
+
authors = [{name = "Mathew Madhavacheril", email = "mathewsyriac@gmail.com"}]
|
|
10
|
+
readme = "README.rst"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
|
|
14
|
+
dependencies = [
|
|
15
|
+
'numpy',
|
|
16
|
+
"pybind11>=2.11",
|
|
17
|
+
"healpy",
|
|
18
|
+
'fastgl>=0.1.10',
|
|
19
|
+
'scipy>=1.0'
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
test = [
|
|
24
|
+
'pytest-cov>=2.6',
|
|
25
|
+
'coveralls>=1.5',
|
|
26
|
+
'pytest>=4.6',
|
|
27
|
+
'threadpoolctl'
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/msyriac/wiggle"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
from importlib import import_module as _import_module
|
|
3
|
+
import sys as _sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
from . import _wiggle
|
|
7
|
+
from .core import *
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from importlib.metadata import version as _get_version
|
|
13
|
+
__version__ = _get_version(__name__)
|
|
14
|
+
except Exception: # pragma: no cover
|
|
15
|
+
__version__ = "0.0.0"
|