├── .github
└── workflows
│ ├── build-wheels.sh
│ └── test.yml
├── .gitignore
├── LICENSE
├── MANIFEST.in
├── README.rst
├── commit_www.bash
├── cosmolopy
├── EH
│ ├── LISCENSE
│ ├── README
│ ├── __init__.py
│ ├── power.c
│ ├── power.i
│ ├── tests
│ │ ├── test_power.py
│ │ └── test_tf_fit.py
│ ├── tf_fit.c
│ └── tf_fit.i
├── __init__.py
├── __version__.py
├── constants.py
├── density.py
├── distance.py
├── luminosityfunction.py
├── magnitudes.py
├── parameters.py
├── perturbation.py
├── reionization.py
├── saveable.py
└── utils.py
├── examples
└── plot_2d_distances.py
├── make_docs.bash
├── pypi_notes.txt
├── requirements.txt
├── setup.cfg
├── setup.py
├── tests
├── icosmo_testdata
│ ├── distances.txt
│ ├── growth.txt
│ ├── h_z.txt
│ ├── power_z0.1_nb.txt
│ ├── power_z0.5_nb.txt
│ ├── power_z0.txt
│ ├── power_z0_b.txt
│ ├── power_z0_nb.txt
│ ├── power_z1_nb.txt
│ ├── power_z3_nb.txt
│ ├── power_z4.9.txt
│ ├── power_z4.9_b.txt
│ └── power_z4.9_nb.txt
├── test_BrokenPowerlawSED.py
├── test_SFR_from_L_nu.py
├── test_age.py
├── test_distances.py
├── test_growth.py
├── test_plot_BKP.py
├── test_plot_HH.py
├── test_plot_Hogg.py
├── test_plot_clumping_factor_Chary.py
├── test_plot_optical_depth.py
├── test_plot_reionization.py
├── test_plot_reionization_BH.py
├── test_utils.py
├── test_wmap.py
└── testingutils.py
└── www
├── astrobetter.html
├── astrobetter_example.py
├── astropy.html
├── cosmolopy.css
├── docAPI
├── _tf_fit'-module.html
├── api-objects.txt
├── class-tree.html
├── cosmolopy-module.html
├── cosmolopy-pysrc.html
├── cosmolopy.EH-module.html
├── cosmolopy.EH-pysrc.html
├── cosmolopy.EH._power-module.html
├── cosmolopy.EH.download_EH_power-module.html
├── cosmolopy.EH.download_EH_power-pysrc.html
├── cosmolopy.EH.power-module.html
├── cosmolopy.EH.power-pysrc.html
├── cosmolopy.EH.tf_fit-module.html
├── cosmolopy.EH.tf_fit-pysrc.html
├── cosmolopy.constants-module.html
├── cosmolopy.constants-pysrc.html
├── cosmolopy.density-module.html
├── cosmolopy.density-pysrc.html
├── cosmolopy.distance-module.html
├── cosmolopy.distance-pysrc.html
├── cosmolopy.luminosityfunction-module.html
├── cosmolopy.luminosityfunction-pysrc.html
├── cosmolopy.luminosityfunction.BrokenPowerlawSED-class.html
├── cosmolopy.luminosityfunction.LFHistory-class.html
├── cosmolopy.magnitudes-module.html
├── cosmolopy.magnitudes-pysrc.html
├── cosmolopy.parameters-module.html
├── cosmolopy.parameters-pysrc.html
├── cosmolopy.perturbation-module.html
├── cosmolopy.perturbation-pysrc.html
├── cosmolopy.reionization-module.html
├── cosmolopy.reionization-pysrc.html
├── cosmolopy.saveable-module.html
├── cosmolopy.saveable-pysrc.html
├── cosmolopy.saveable.NullWriter-class.html
├── cosmolopy.saveable.Saveable-class.html
├── cosmolopy.utils-module.html
├── cosmolopy.utils-pysrc.html
├── cosmolopy.utils.AgeSpacedRedshift-class.html
├── cosmolopy.utils.Extrapolate1d-class.html
├── cosmolopy.utils.Normalize-class.html
├── cosmolopy.utils.PiecewisePowerlaw-class.html
├── crarr.png
├── epydoc.css
├── epydoc.js
├── frames.html
├── help.html
├── identifier-index.html
├── index.html
├── module-tree.html
├── redirect.html
├── toc-cosmolopy-module.html
├── toc-cosmolopy.EH-module.html
├── toc-cosmolopy.EH._power-module.html
├── toc-cosmolopy.EH.download_EH_power-module.html
├── toc-cosmolopy.EH.power-module.html
├── toc-cosmolopy.constants-module.html
├── toc-cosmolopy.density-module.html
├── toc-cosmolopy.distance-module.html
├── toc-cosmolopy.luminosityfunction-module.html
├── toc-cosmolopy.magnitudes-module.html
├── toc-cosmolopy.parameters-module.html
├── toc-cosmolopy.perturbation-module.html
├── toc-cosmolopy.reionization-module.html
├── toc-cosmolopy.saveable-module.html
├── toc-cosmolopy.utils-module.html
├── toc-everything.html
├── toc.html
├── uml_class_diagram_for_cosmolop.gif
├── uml_class_diagram_for_cosmolop_2.gif
├── uml_class_diagram_for_cosmolop_3.gif
├── uml_class_diagram_for_cosmolop_4.gif
└── uml_class_diagram_for_cosmolop_5.gif
├── figs
├── dist2d_D_A.png
├── dist2d_D_A_ony.png
├── dist2d_D_A_ony_small.png
├── dist2d_D_A_small.png
├── dist2d_D_M.png
├── dist2d_D_M_ony.png
├── dist2d_D_M_ony_small.png
├── dist2d_D_M_small.png
└── makefigs.bash
├── index.html
├── others.html
└── others.txt
/.github/workflows/build-wheels.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e -x
3 |
4 | # Install swig3
5 | yum localinstall -y http://springdale.math.ias.edu/data/puias/computational/6/x86_64//swig3012-3.0.12-3.sdl6.x86_64.rpm
6 | ln /usr/local/swig/3.0.12/bin/swig /usr/bin/swig --symbolic
7 | ln /usr/local/swig/3.0.12/bin/ccache-swig /usr/bin/ccache-swig --symbolic
8 |
9 | # Compile wheels
10 | for PYBIN in /opt/python/*[3][678]*/bin; do
11 | "${PYBIN}/pip" install -r /io/requirements.txt
12 | "${PYBIN}/pip" wheel /io/ -w wheelhouse/
13 | done
14 |
15 | # Bundle external shared libraries into the wheels
16 | for whl in wheelhouse/cosmolopy*.whl; do
17 | auditwheel repair "$whl" --plat $PLAT -w /io/wheelhouse/
18 | done
19 |
20 | # Install packages and test
21 | for PYBIN in /opt/python/*[3][678]*/bin/; do
22 | "${PYBIN}/pip" install cosmolopy --no-index -f /io/wheelhouse
23 | "${PYBIN}/python" -c "import cosmolopy; import cosmolopy.EH.power"
24 | done
25 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: Test
5 |
6 | on: [push, pull_request]
7 |
8 | jobs:
9 | ubuntu:
10 | name: ubuntu-latest
11 | runs-on: ubuntu-latest
12 | strategy:
13 | matrix:
14 | docker_image: [quay.io/pypa/manylinux2010_x86_64]
15 | platform: [manylinux2010_x86_64]
16 | fail-fast: false
17 |
18 | steps:
19 | - uses: actions/checkout@v2
20 | - name: Pull Docker image
21 | run: |
22 | docker pull ${{ matrix.docker_image }}
23 | - name: Run Docker image
24 | run: |
25 | docker run --rm -e PLAT=${{ matrix.platform }} -v `pwd`:/io ${{ matrix.docker_image }} $PRE_CMD /io/.github/workflows/build-wheels.sh
26 | - name: Deploy package
27 | if: ${{ success() && github.event_name == 'push' && github.ref == 'refs/heads/master' }}
28 | env:
29 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
30 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
31 | run: |
32 | pip install twine
33 | twine upload --skip-existing wheelhouse/cosmolopy*
34 |
35 | macosx:
36 | name: ${{ matrix.os }} ${{ matrix.architecture }}, Python ${{ matrix.python-version }}
37 | runs-on: ${{ matrix.os }}
38 | strategy:
39 | matrix:
40 | architecture: [x64]
41 | os: [macos-latest]
42 | python-version: [3.6, 3.7, 3.8]
43 | fail-fast: false
44 |
45 | steps:
46 | - uses: actions/checkout@v2
47 | - name: Set up Python ${{ matrix.python-version }} ${{ matrix.architecture }}
48 | uses: actions/setup-python@v2
49 | with:
50 | python-version: ${{ matrix.python-version }}
51 | architecture: ${{ matrix.architecture }}
52 | - name: Install dependencies
53 | run: |
54 | brew install swig@3
55 | brew link swig@3
56 | python -m pip install --upgrade pip setuptools wheel
57 | pip install -r requirements.txt
58 | - name: Create wheels
59 | run: |
60 | python setup.py sdist -d wheelhouse
61 | pip wheel . -w wheelhouse
62 | cd wheelhouse
63 | pip install cosmolopy --no-index -f .
64 | python -c "import cosmolopy; import cosmolopy.EH.power"
65 | cd ..
66 | - name: Deploy package
67 | if: ${{ success() && github.event_name == 'push' && github.ref == 'refs/heads/master' }}
68 | env:
69 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
70 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
71 | run: |
72 | pip install twine
73 | twine upload --skip-existing wheelhouse/cosmolopy*
74 |
75 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | .coverage
3 | *.pyc
4 | cosmolopy/EH/*.o
5 | cosmolopy/EH/*.so
6 | CosmoloPy.egg-info/
7 | build/
8 | dist/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2009-2010 Roban Hultman Kramer and contributors
4 | http://roban.github.com/CosmoloPy/
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
24 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LISCENSE
2 | include README.rst
3 | include MANIFEST.in
4 | include requirements*.txt
5 | include conftest.py
6 |
7 | exclude travis www
8 | recursive-exclude travis *
9 | recursive-exclude www *
10 | exclude *.yml
11 | exclude *.bash
12 | exclude pypi_notes.txt
13 | recursive-exclude * __pycache__
14 | recursive-exclude * *.py[co]
15 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | =========
2 | CosmoloPy
3 | =========
4 |
5 | A cosmology package for Python.
6 |
7 | For documentation and installation instructions, see
8 | http://roban.github.io/CosmoloPy/
9 |
10 | CosmoloPy is released under the MIT software liscense (see LISCENSE).
11 |
12 | Example
13 | -------
14 |
15 | Calculate the comoving distance to redshift 6.
16 |
17 | >>> import cosmolopy.distance as cd
18 | >>> cosmo = {'omega_M_0':0.3, 'omega_lambda_0':0.7, 'omega_k_0':0.0, 'h':0.72}
19 | >>> d_co = cd.comoving_distance(6., **cosmo)
20 | >>> print "Comoving distance to z=6 is %.1f Mpc" % (d_co)
21 | Comoving distance to z=6 is 8017.8 Mpc
22 |
23 |
24 | Prerequisites
25 | =============
26 |
27 | Python
28 | NumPy
29 | SciPy
30 |
31 | For tests (optional):
32 | nose
33 | matplotlib
34 |
35 | For power spectrum calculation (needed for most of perturbation module):
36 | python-dev
37 |
38 | Installation from PyPI
39 | ======================
40 |
41 | You can easily install the package directly from the Python Package
42 | Index with pip.
43 |
44 | Run with:
45 |
46 | > pip install cosmolopy
47 |
48 | Installation from Source
49 | ========================
50 |
51 | To install from source, you first need to install `SWIG `_ v3 or later.
52 | Then, download the CosmoloPy source and install it by running (in CosmoloPy folder)
53 |
54 | > pip install .
55 |
56 | Testing
57 | =======
58 |
59 | Note that currently the _udot integration appears to be failing in nosetests.
60 | The prefered way to run all tests is:
61 |
62 | > python setup.py nosetests --with-doctest
63 |
64 | Or if you don't want to run the doctests:
65 |
66 | > python setup.py nosetests
67 |
68 | If you don't have nose:
69 |
70 | > python setup.py test
71 | > python -m doctest cosmolopy/*.py
72 |
73 | Contributors
74 | ============
75 |
76 | - Python 3 implementation by @JohannesBuchner and @1313e
77 | - Automated PyPI deployment on GitHub Actions by @1313e
78 |
--------------------------------------------------------------------------------
/commit_www.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #From http://happygiraffe.net/blog/tag/git/
4 |
5 | parent_sha=$(git show-ref -s refs/heads/gh-pages)
6 | doc_sha=$(git ls-tree -d HEAD www | awk '{print $3}')
7 | new_commit=$(echo "Auto-update docs." | git commit-tree $doc_sha -p $parent_sha)
8 | git update-ref refs/heads/gh-pages $new_commit
--------------------------------------------------------------------------------
/cosmolopy/EH/LISCENSE:
--------------------------------------------------------------------------------
1 | power.c and tf_fit.f are redistributed under the MIT License with the permission of
2 | Wayne Hu
3 |
4 | http://background.uchicago.edu/~whu/transfer/transferpage.html
5 |
6 | and are described in Eisenstein, D. J., & Hu, W. "Power Spectra for
7 | Cold Dark Matter and Its Variants," 1999, ApJ, 511, 5
8 | [astro-ph/9710252], and Ibid. "Baryonic Features in
9 | the Matter Transfer Function," 1998, ApJ, 496, 605
10 | [astro-ph/9709112].
11 |
12 | Please cite these papers to acknowledge use of power spectrum calculations.
13 |
14 | The MIT License
15 |
16 | power.c is copyright (c) 1997 Wayne Hu and Daniel Eisenstein
17 | tf_fit.f is copyright (c) 1997 Wayne Hu and Daniel Eisenstein
18 |
19 | Permission is hereby granted, free of charge, to any person obtaining a copy
20 | of this software and associated documentation files (the "Software"), to deal
21 | in the Software without restriction, including without limitation the rights
22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23 | copies of the Software, and to permit persons to whom the Software is
24 | furnished to do so, subject to the following conditions:
25 |
26 | The above copyright notice and this permission notice shall be included in
27 | all copies or substantial portions of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
35 | THE SOFTWARE.
36 |
37 |
--------------------------------------------------------------------------------
/cosmolopy/EH/README:
--------------------------------------------------------------------------------
1 | =================================
2 | Eisenstein & Hu Fitting functions
3 | =================================
4 |
5 | Power spectra for CDM variants without baryonic effects
6 | =======================================================
7 |
8 | Original c code
9 | ---------------
10 |
11 | power.c is redistributed under the MIT License with the permission of
12 | Wayne Hu
13 |
14 | http://background.uchicago.edu/~whu/transfer/transferpage.html
15 |
16 | and is described in Eisenstein, D. J., & Hu, W. "Power Spectra for
17 | Cold Dark Matter and Its Variants," 1999, ApJ, 511, 5
18 | [astro-ph/9710252]. Please cite this paper to acknowledge use of power
19 | spectrum calculations.
20 |
21 | See LISCENSE file.
22 |
23 | Python Interface
24 | ----------------
25 |
26 | These notes are by Roban Kramer.
27 |
28 | I use swig to generate the python interface to `power.c`.
29 |
30 | `power_wrap.c` and `power.py` are created from `power.i` and `power.c`
31 | by runing:
32 |
33 | > swig -python power.i
34 |
35 | I used to let distutils run swig, but that stopped working for some
36 | reason. The code was:
37 |
38 | power_module = Extension('cosmolopy.EH._power',
39 | sources=[os.path.join(eh_dir, 'power.i'), os.path.join(eh_dir,
40 | 'power.c')])
41 |
42 | I still let distutils do the compiling to create `_power.so`. This has
43 | the advantage of not requiring the user to install swig.
44 |
45 | Power spectra with baryonic effects
46 | ===================================
47 |
48 | Original C code
49 | ---------------------
50 |
51 | tf_fit.c is redistributed under the MIT License
52 |
53 | http://background.uchicago.edu/~whu/transfer/transferpage.html
54 |
55 | and is described in Eisenstein, D. J., & Hu, W. "Baryonic Features in
56 | the Matter Transfer Function," 1998, ApJ, 496, 605
57 | [astro-ph/9709112]. Please cite this paper to acknowledge use of power
58 | spectrum calculations.
59 |
60 | See LISCENSE file.
61 |
62 | Python interface
63 | ----------------
64 |
65 | These notes are by Berian James.
66 |
67 | I use SWIG to generate the python interface to `tf_fit.c`, following
68 | Roban's method with a few modifications.
69 |
70 | `tf_fit_wrap.c` and `tf_fit.py` are created from `tf_fit.i` and `tf_fit.c`
71 | by running:
72 |
73 | > swig -python tf_fit.i
74 |
75 | As with power.c, these files will be preserved in distribution, so that the
76 | user does not need SWIG. I have added an analogous Extension object to
77 | setup.py which will compile the library during the cosmolopy build.
78 |
79 | Some modifications to the source code of tf_fit.c were required. In particular,
80 | tf_fit.TFfit_onek originally took several pointers among its arguments, which I
81 | have removed. I have also made the returned variable from that function a global.
82 | In all cases, I have left the original lines in the source code, commented with //.
--------------------------------------------------------------------------------
/cosmolopy/EH/__init__.py:
--------------------------------------------------------------------------------
1 | """See `cosmolopy.perturbation.transfer_function_EH`
2 |
3 | Eisenstein & Hu power spectrum transfer function used in
4 | `cosmolopy.perturbation.transfer_function_EH`.
5 |
6 | This package contains two modules:
7 |
8 | i. `power` (or `cosmolopy.EH.power`), which is a python wrapper of power.c
9 | from Eisenstein & Hu (1999 ApJ 511 5)
10 |
11 | ii. `tf_fit` (or `cosmolopy.EH.tf_fit`), which is a python wrapper of
12 | tf_fit.c from Eisenstein & Hu (1998 ApJ 496 605)
13 |
14 | The first module contains no baryonic features in the transfer function, but
15 | applies to wider range of CDM variants (e.g. including neutrinos). The second
16 | module applies more narrowly but possesses effects including the baryonic
17 | acoustic osciallations.
18 |
19 | See also: http://background.uchicago.edu/~whu/transfer/transferpage.html
20 |
21 | power.c is redistributed under the MIT License with the permission of
22 | Wayne Hu, and is described in Eisenstein, D. J., & Hu, W. "Power
23 | Spectra for Cold Dark Matter and Its Variants," 1999, ApJ, 511, 5
24 | [astro-ph/9710252]. Please cite this paper to acknowledge use of power
25 | spectrum calculations.
26 |
27 | See LISCENSE for additional information.
28 |
29 | """
30 |
31 | from __future__ import absolute_import, division, print_function
32 |
--------------------------------------------------------------------------------
/cosmolopy/EH/power.i:
--------------------------------------------------------------------------------
1 | /* power.i */
2 | %module power
3 | %{
4 | /* Put header files here or function declarations like below */
5 | extern int TFmdm_set_cosm(float omega_matter, float omega_baryon, float omega_hdm,
6 | int degen_hdm, float omega_lambda, float hubble,
7 | float redshift);
8 | extern float TFmdm_onek_mpc(float kk);
9 | extern float TFmdm_onek_hmpc(float kk );
10 | extern float tf_cbnu;
11 | %}
12 |
13 | extern int TFmdm_set_cosm(float omega_matter, float omega_baryon, float omega_hdm,
14 | int degen_hdm, float omega_lambda, float hubble,
15 | float redshift);
16 | extern float TFmdm_onek_mpc(float kk);
17 | extern float TFmdm_onek_hmpc(float kk );
18 |
19 | extern float tf_cbnu;
20 |
--------------------------------------------------------------------------------
/cosmolopy/EH/tests/test_power.py:
--------------------------------------------------------------------------------
1 | """Check that the power module is working."""
2 |
3 | from __future__ import absolute_import, division, print_function
4 |
5 | import numpy.testing.utils as ntest
6 |
7 | def test_power():
8 | """Check that the power module is working."""
9 | import cosmolopy.EH.power as power
10 | power.TFmdm_set_cosm(0.3, 0.04, 0.0, 0, 0.7, 0.72, 0.0)
11 | ntest.assert_approx_equal(power.TFmdm_onek_hmpc(100.0),
12 | 1.48236347286e-06)
13 |
--------------------------------------------------------------------------------
/cosmolopy/EH/tests/test_tf_fit.py:
--------------------------------------------------------------------------------
1 | """Check that the tf_fit module is working."""
2 |
3 | from __future__ import absolute_import, division, print_function
4 |
5 | import numpy.testing.utils as ntest
6 |
7 | def test_tf_fit():
8 | """Check that the tf_fit module is working."""
9 | import cosmolopy.EH.tf_fit as tf_fit
10 | tf_fit.TFset_parameters(0.136, 0.2, 2.728)
11 | ntest.assert_approx_equal( tf_fit.TFfit_onek(10.0),
12 | 3.69328954548e-05)
13 |
--------------------------------------------------------------------------------
/cosmolopy/EH/tf_fit.i:
--------------------------------------------------------------------------------
1 | /* tf_fit.i */
2 | %module tf_fit
3 | %{
4 | /* Put header files here or function declarations like below */
5 | extern void TFset_parameters(float omega0hh, float f_baryon, float Tcmb);
6 | extern float TFfit_onek(float k);
7 | extern float T_full;
8 | %}
9 |
10 | extern void TFset_parameters(float omega0hh, float f_baryon, float Tcmb);
11 | extern float TFfit_onek(float k);
12 | extern float T_full;
13 |
--------------------------------------------------------------------------------
/cosmolopy/__init__.py:
--------------------------------------------------------------------------------
1 | """CosmoloPy is a package of cosmology routines built on NumPy/SciPy.
2 |
3 | Capabilities include
4 | --------------------
5 |
6 | `cosmolopy.density`
7 | Various cosmological densities.
8 |
9 | `cosmolopy.distance`
10 | Various cosmological distance measures.
11 |
12 | `cosmolopy.luminosityfunction`
13 | Galaxy luminosity functions (Schecter functions).
14 |
15 | `cosmolopy.magnitudes`
16 | Conversion in and out of the AB magnitude system.
17 |
18 | `cosmolopy.parameters`
19 | Pre-defined sets of cosmological parameters (e.g. from WMAP).
20 |
21 | `cosmolopy.perturbation`
22 | Perturbation theory and the power spectrum.
23 |
24 | `cosmolopy.reionization`
25 | The reionization of the IGM.
26 |
27 | Functions take cosmological parameters (which can be numpy arrays)
28 | as keywords, and ignore any extra keywords. This means you can make a
29 | dictionary of all of your cosmological parameters and pass it to any
30 | function.
31 |
32 | The `parameters` module supplies some convenient pre-defined parameter sets.
33 |
34 | Usage
35 | -----
36 |
37 | The easiest way to use CosmoloPy is to create a dictionary of the
38 | cosmology parameters and pass it to each function using the ** syntax.
39 |
40 | >>> import cosmolopy.distance as cd
41 | >>> cosmo = {'omega_M_0':0.3, 'omega_lambda_0':0.7, 'omega_k_0':0.0, 'h':0.72}
42 | >>> d_co = cd.comoving_distance(6., **cosmo)
43 | >>> print "Comoving distance to z=6 is %.1f Mpc" % (d_co)
44 | Comoving distance to z=6 is 8017.8 Mpc
45 |
46 | The cosmolopy package also defines some convenient shortcuts,
47 | including a fiducial cosmology (currently the WMAP7+BAO+H0 mean), so
48 | you can just do this:
49 |
50 | >>> from cosmolopy import *
51 | >>> d_a = cd.angular_diameter_distance(6, **fidcosmo)
52 | >>> print "Angluar-diameter distance to z=6 is %.1f Mpc" % (d_a)
53 | Angluar-diameter distance to z=6 is 1209.9 Mpc
54 | >>> d_light = cd.light_travel_distance(6, **fidcosmo)
55 | >>> print "Light-travel distance to z=6 is %.1f Mpc" % (d_light)
56 | Light-travel distance to z=6 is 3922.9 Mpc
57 |
58 | Calculate the mass of a halo with Virial temperature of 10^4 kelvin,
59 | then verify the Virial temperature for a halo of that mass:
60 |
61 | >>> import cosmolopy.perturbation as cp
62 | >>> cosmo = {'omega_M_0' : 0.27,
63 | ... 'omega_lambda_0' : 1-0.27,
64 | ... 'omega_b_0' : 0.045,
65 | ... 'omega_n_0' : 0.0,
66 | ... 'N_nu' : 0,
67 | ... 'h' : 0.72,
68 | ... 'n' : 1.0,
69 | ... 'sigma_8' : 0.9
70 | ... }
71 | >>> mass = cp.virial_mass(1e4, 6.0, **cosmo)
72 | >>> temp = cp.virial_temp(mass, 6.0, **cosmo)
73 | >>> print "Mass = %.3g M_sun" % mass
74 | Mass = 1.68e+08 M_sun
75 | >>> print round(temp, 4)
76 | 10000.0
77 |
78 | Calculate the critical and matter densities:
79 |
80 | >>> from cosmolopy import *
81 | >>> 'rho_crit=%.3g Msun/Mpc^3, rho_0=%.3g Msun/Mpc^3' % cden.cosmo_densities(**fidcosmo)
82 | 'rho_crit=1.38e+11 Msun/Mpc^3, rho_0=3.75e+10 Msun/Mpc^3'
83 |
84 | Look in the tests/ and examples/ directories for more examples.
85 |
86 | """
87 |
88 | from __future__ import absolute_import, division, print_function
89 |
90 | from .__version__ import __version__
91 | from . import constants as cc
92 | from . import density as cden
93 | from . import distance as cd
94 | from . import perturbation as cp
95 | from . import reionization as cr
96 | from . import parameters as cparam
97 | from . import magnitudes as cmag
98 | from . import luminosityfunction as cl
99 |
100 | fidcosmo = cparam.WMAP7_BAO_H0_mean(flat=True, extras=True)
101 |
--------------------------------------------------------------------------------
/cosmolopy/__version__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | # %% VERSIONS
4 | # Default/Latest/Current version
5 | __version__ = '0.4.1'
6 |
--------------------------------------------------------------------------------
/cosmolopy/constants.py:
--------------------------------------------------------------------------------
1 | """Various constants used by CosmoloPy code.
2 |
3 | Unit abreviations are appended to the name, but powers are not
4 | specified. For instance, the gravitational constant has units "Mpc^3
5 | msun^-1 s^-2", but is called "G_const_Mpc_Msun_s".
6 |
7 | Most of these numbers are from google calculator.
8 |
9 | Constants are:
10 |
11 | ::
12 |
13 | """
14 |
15 | from __future__ import absolute_import, division, print_function
16 |
17 | ### If you add a constant, make sure to add a description too. ###
18 |
19 | doc = ""
20 |
21 | doc += " pc_cm: Parsec in cm\n"
22 | pc_cm = 3.08568025e18 #cm
23 |
24 | doc += " Mpc_cm: Megaparsec in cm\n"
25 | Mpc_cm = 3.08568025e24 # cm
26 |
27 | doc += " Mpc_km: Megaparsec in km\n"
28 | Mpc_km = Mpc_cm * 1.0e-5 # km
29 |
30 | doc += " angstrom_cm: Angstrom in cm\n"
31 | angstrom_cm = 1e-8 #cm
32 |
33 | doc += " yr_s: a year in s\n"
34 | yr_s = 365. * 24. * 60. * 60.
35 |
36 | doc += " Myr_s: Megayear in s\n"
37 | Myr_s = 1.e6 * yr_s
38 |
39 | doc += " Gyr_s: Gigayear in s\n"
40 | Gyr_s = 1.e9 * yr_s
41 |
42 | doc += " amu_g: atomic mass unit in g\n"
43 | amu_g = 1.66053886e-24 #g
44 |
45 | doc += " m_p_g: mass of a proton in g\n"
46 | m_p_g = 1.67262158e-24 # g
47 |
48 | doc += " m_H_g: mass of a hydrogen atom in g\n"
49 | m_H_g = 1.00794 * amu_g # g
50 |
51 | doc += " m_He_g: mass of a helium atom in g\n"
52 | m_He_g = 4.002602 * amu_g # g
53 |
54 | doc += " M_sun_g: Solar mass in grams.\n"
55 | M_sun_g = 1.98892e33 # g
56 |
57 | doc += " c_light_cm_s: Speed of light in Mpc/s (from google calculator)\n"
58 | c_light_cm_s = 29979245800. # cm/s
59 |
60 | doc += " c_light_Mpc_s: Speed of light in Mpc/s\n"
61 | c_light_Mpc_s = c_light_cm_s / Mpc_cm # Mpc / s
62 |
63 | doc += " c_light_Mpc_Gyr: Speed of light in Mpc/Gyr \n"
64 | c_light_Mpc_Gyr = Gyr_s * c_light_cm_s / Mpc_cm # Mpc / Gyr
65 |
66 | doc += " H100_s: 100 km s^-1 Mpc^-1 in s^-1\n"
67 | H100_s = 100. / Mpc_km # s^-1
68 |
69 | doc += " G_const_Mpc_Msun_s: Gravitational constant in Mpc^3 msun^-1 s^-2\n"
70 | G_const_Mpc_Msun_s = M_sun_g * (6.673e-8) / Mpc_cm**3. # Mpc^3 msun^-1 s^-2
71 |
72 | doc += " lambda_Lya_0: Central wavelength of H Lyman-alpha in Angstroms\n"
73 | lambda_Lya_0 = 1215.67 # Ang
74 |
75 | doc += " lambda_NY_0: Central wavelength of an NV doublet in Angstroms\n"
76 | lambda_NV_0 = 1240.81 # Ang
77 |
78 | doc += " alpha_B_cm_s_1e4: hydrogen recombination coefficient at T=10^4 K\n"
79 | alpha_B_cm_s_1e4 = 2.59e-13 # cm^3 s^-1
80 |
81 | doc += " sigma_T_cm: Thomson cross section in cm^2\n"
82 | sigma_T_cm = 6.6524586e-25 # cm^2
83 |
84 | doc += " sigma_T_cm: Thomson cross section in Mpc^2\n"
85 | sigma_T_Mpc = sigma_T_cm / (Mpc_cm ** 2.) # Mpc^2
86 |
87 | __doc__ += "\n".join(sorted(doc.split("\n")))
88 |
89 |
90 |
--------------------------------------------------------------------------------
/cosmolopy/density.py:
--------------------------------------------------------------------------------
1 | """Cosmological densities like matter density, baryon density, etc.
2 | """
3 |
4 | from __future__ import absolute_import, division, print_function
5 |
6 | import math
7 |
8 | import numpy
9 | import scipy
10 | import scipy.special
11 | import scipy.integrate as si
12 |
13 | from . import constants as cc
14 | from . import distance as cd
15 | from .distance import get_omega_k_0, set_omega_k_0
16 |
17 | def omega_M_z(z, **cosmo):
18 | """Matter density omega_M as a function of redshift z.
19 |
20 | Notes
21 | -----
22 |
23 | From Lahav et al. (1991, MNRAS 251, 128) equations 11b-c. This is
24 | equivalent to equation 10 of Eisenstein & Hu (1999 ApJ 511 5).
25 |
26 | """
27 | if get_omega_k_0(**cosmo) == 0:
28 | return 1.0 / (1. + (1. - cosmo['omega_M_0'])/
29 | (cosmo['omega_M_0'] * (1. + z)**3.))
30 | else:
31 | return (cosmo['omega_M_0'] * (1. + z)**3. /
32 | cd.e_z(z, **cosmo)**2.)
33 |
34 | def cosmo_densities(**cosmo):
35 | """The critical and mean densities of the universe.
36 |
37 | Returns
38 | -------
39 | rho_crit and rho_0 in solar masses per cubic Megaparsec.
40 |
41 | """
42 |
43 | omega_M_0 = cosmo['omega_M_0']
44 | h = cosmo['h']
45 |
46 | rho_crit = 3. * (h * cc.H100_s)**2. / (8. * math.pi * cc.G_const_Mpc_Msun_s)
47 | rho_0 = omega_M_0 * rho_crit
48 |
49 | #print " Critical density rho_crit = %.3g Msun/Mpc^3" % rho_crit
50 | #print " Matter density rho_0 = %.3g Msun/Mpc^3" % rho_0
51 |
52 | return rho_crit, rho_0
53 |
54 | def get_X_Y(**cosmo):
55 | """The fraction of baryonic mass in hydrogen and helium.
56 |
57 | Assumes X_H + Y_He = 1.
58 |
59 | You must specify either 'X_H', or 'Y_He', or both.
60 | """
61 | if 'X_H' in cosmo and 'Y_He' not in cosmo:
62 | X_H = cosmo['X_H']
63 | Y_He = 1. - X_H
64 | elif 'Y_He' in cosmo and 'X_H' not in cosmo:
65 | Y_He = cosmo['Y_He']
66 | X_H = 1. - Y_He
67 | else:
68 | X_H = cosmo['X_H']
69 | Y_He = cosmo['Y_He']
70 | return X_H, Y_He
71 |
72 | def baryon_densities(**cosmo):
73 | """Hydrogen number density at z=0.
74 |
75 | Parameters
76 | ----------
77 |
78 | cosmo: cosmological parameters
79 |
80 | parameters used: 'omega_b_0', 'X_H' and/or 'Y_He', plus those
81 | needed by cosmo_densities.
82 |
83 |
84 | Returns
85 | -------
86 |
87 | rho_crit, rho_0, n_He_0, n_H_0
88 |
89 | The first two are in units of solar masses per cubic
90 | Megaparsec. The later two are in number per cubic Megaparsec.
91 |
92 | """
93 |
94 | X_H, Y_He = get_X_Y(**cosmo)
95 |
96 | rho_crit, rho_0 = cosmo_densities(**cosmo)
97 |
98 | n_H_0 = (rho_crit * cosmo['omega_b_0'] * X_H * cc.M_sun_g /
99 | cc.m_H_g)
100 | n_He_0 = (rho_crit * cosmo['omega_b_0'] * Y_He * cc.M_sun_g /
101 | cc.m_He_g)
102 | # print " Hydrogen number density n_H_0 = %.4g (Mpc^-3)" % n_H_0
103 | return rho_crit, rho_0, n_He_0, n_H_0
104 |
--------------------------------------------------------------------------------
/cosmolopy/saveable.py:
--------------------------------------------------------------------------------
1 | """A Saveable class with methods to save and restore.
2 |
3 | Saveable is designed to be subclassed to create new types of objects
4 | that can easily be pickled and reloaded.
5 | """
6 |
7 | from __future__ import absolute_import, division, print_function
8 |
9 | import pickle
10 |
11 | class NullWriter:
12 | """Dummy file-like object that does nothing.
13 |
14 | From
15 | http://stackoverflow.com/questions/1809958/hide-stderr-output-in-unit-tests
16 |
17 | Used in Saveable.
18 | """
19 | def write(self, s):
20 | pass
21 |
22 |
23 | def loadSaveable(filename):
24 | """Return an instance of an object unpickled from a file.
25 | """
26 | picfile = open(filename)
27 | loaded = pickle.load(picfile)
28 | picfile.close()
29 | return loaded
30 |
31 | class Saveable(object):
32 | """An object with methods to save and restore.
33 |
34 | Unpickleable attributes will simply be deleted from the object.
35 | """
36 |
37 | def __init__(self, filename=None):
38 | if filename is not None:
39 | self.load(filename)
40 |
41 | def save(self, filename):
42 | """Save object to a file."""
43 | picfile = open(filename, 'w')
44 | pickle.dump(self, picfile)
45 | picfile.close()
46 |
47 | def load(self, filename):
48 | """Return an instance of an object unpickled from a file.
49 | """
50 | picfile = open(filename)
51 | loaded = pickle.load(picfile)
52 | picfile.close()
53 | self.__dict__.update(loaded.__dict__)
54 | return self
55 |
56 | def dumb_pickle_filter(self):
57 | """Filter out attributes that can't be pickled.
58 |
59 | Returns a copy of dict with
60 | """
61 | picfile = NullWriter()
62 | sdict = self.__dict__.copy()
63 | for k, v in list(sdict.items()):
64 | # Avoid self references (and thereby infinite recurion).
65 | if v is self:
66 | del sdict[k]
67 | continue
68 | # Remove any attributes that can't be pickled.
69 | try:
70 | pickle.dump(v, picfile)
71 | except (TypeError, pickle.PicklingError) as err:
72 | if hasattr(self, 'verbose') and self.verbose:
73 | print("Won't pickle", k, type(v), ": ")
74 | print("'", err, "'")
75 | del sdict[k]
76 | return sdict
77 | def __getstate__(self):
78 | """Prepare a state of pickling."""
79 | return self.dumb_pickle_filter()
80 |
81 | def __setstate__(self, dict):
82 | """Unpickle."""
83 | self.__dict__.update(dict)
84 |
--------------------------------------------------------------------------------
/examples/plot_2d_distances.py:
--------------------------------------------------------------------------------
1 | """Plot some distance measures versus redshift and omega_M.
2 |
3 | """
4 | from __future__ import absolute_import, division, print_function
5 |
6 | import sys
7 | import getopt
8 |
9 | import numpy
10 | import matplotlib.pyplot as pylab
11 | import matplotlib.cm as cm
12 |
13 | import cosmolopy.distance as cd
14 | import cosmolopy.constants as cc
15 |
16 | def plot_DM(filename):
17 | """The dimensionless proper motion distance DM/DH.
18 | """
19 |
20 | # Set up an array of redshift values.
21 | dz = 0.1
22 | z = numpy.arange(0., 10. + 1.1 * dz, dz)
23 |
24 | # Set up a cosmology dictionary, with an array of matter density values.
25 | cosmo = {}
26 | dom = 0.01
27 | om = numpy.atleast_2d(numpy.linspace(0.1, 1.0, (1.-0.1)/dom)).transpose()
28 | cosmo['omega_M_0'] = om
29 | cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
30 | cosmo['h'] = 0.701
31 | cosmo['omega_k_0'] = 0.0
32 |
33 | # Calculate the hubble distance.
34 | dh = cd.hubble_distance_z(0, **cosmo)
35 | # Calculate the comoving distance.
36 | dm = cd.comoving_distance_transverse(z, **cosmo)
37 |
38 | # Make plots.
39 | plot_dist(z, dz, om, dom, dm, dh, 'proper motion distance', r'D_M',
40 | filename)
41 | plot_dist_ony(z, dz, om, dom, dm, dh, 'proper motion distance', r'D_M',
42 | filename)
43 |
44 | def plot_DA(filename):
45 | """The dimensionless angular diameter distance DA/DH.
46 | """
47 |
48 | # Set up an array of redshift values.
49 | dz = 0.1
50 | z = numpy.arange(0., 10. + dz, dz)
51 |
52 | # Set up a cosmology dictionary, with an array of matter density values.
53 | cosmo = {}
54 | dom = 0.01
55 | om = numpy.atleast_2d(numpy.linspace(0.1, 1.0, (1.-0.1)/dom)).transpose()
56 | cosmo['omega_M_0'] = om
57 | cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
58 | cosmo['h'] = 0.701
59 | cosmo['omega_k_0'] = 0.0
60 |
61 | # Calculate the hubble distance.
62 | dh = cd.hubble_distance_z(0, **cosmo)
63 | # Calculate the angular diameter distance.
64 | da = cd.angular_diameter_distance(z, **cosmo)
65 |
66 | # Make plots.
67 | plot_dist(z, dz, om, dom, da, dh, 'angular diameter distance', r'D_A',
68 | filename)
69 | plot_dist_ony(z, dz, om, dom, da, dh, 'angular diameter distance', r'D_A',
70 | filename)
71 |
72 | def plot_dist(z, dz, om, dom, dist, dh, name, mathname, filename=None):
73 | """Make a 2-D plot of a distance versus redshift (x) and matter density (y).
74 | """
75 | # Grid of redshift and matter density values.
76 | x, y = numpy.meshgrid(z, om)
77 | pylab.figure(figsize=(5.5,4.5))
78 | pylab.imshow(dist/dh,
79 | extent=(z.min() - dz/2.,
80 | z.max() + dz/2.,
81 | om.max() + dom/2.,
82 | om.min() - dom/2.,
83 | ),
84 | interpolation='nearest',
85 | aspect = z.max()/om.max(),
86 | cmap = cm.Spectral,
87 | )
88 | cb = pylab.colorbar()
89 | cb.ax.set_ylabel(r'$' + mathname + '/D_H$')
90 |
91 | pylab.contour(x, y, dist/dh, 10, colors='k')
92 | pylab.xlim(z.min(), z.max())
93 | pylab.ylim(om.min(), om.max())
94 | pylab.xlabel("redshift z")
95 | pylab.ylabel(r"$\Omega_M = 1 - \Omega_\lambda$")
96 | pylab.title(name)
97 | if filename is not None:
98 | prefix, extension = filename.split('.')
99 | pylab.savefig(prefix + '_' + mathname + '.' + extension,
100 | bbox_inches="tight")
101 |
102 |
103 | def plot_dist_ony(z, dz, om, dom, dist, dh, name, mathname, filename=None):
104 | """Make a 2-D plot of matter density versus redshift (x) and distance (y)
105 | """
106 |
107 |
108 | dist = dist/dh
109 | z = z * numpy.ones(dist.shape)
110 | om = om * numpy.ones(dist.shape)
111 |
112 | pylab.figure(figsize=(5.5,4.5))
113 |
114 |
115 | pylab.contour(z, dist, om, 50)
116 | cb = pylab.colorbar()
117 | cb.ax.set_ylabel(r'$\Omega_M = 1 - \Omega_\lambda$')
118 |
119 | pylab.xlim(z.min(), z.max())
120 | pylab.ylim(dist.min(), dist.max())
121 | pylab.xlabel("redshift z")
122 | pylab.ylabel(name + r': $'+mathname+'/D_H$')
123 | pylab.title(name)
124 | if filename is not None:
125 | prefix, extension = filename.split('.')
126 | pylab.savefig(prefix + '_' + mathname + '_ony.' + extension,
127 | bbox_inches="tight")
128 |
129 | if __name__ == "__main__":
130 | if len(sys.argv)==1:
131 | print "Run with a filename argument to produce image files, e.g.:"
132 | print " python plot_2d_distances.py dist2d.png"
133 | print " python plot_2d_distances.py dist2d.eps"
134 | if len(sys.argv) > 1:
135 | filename = sys.argv[1]
136 | else:
137 | filename = None
138 |
139 | plot_DM(filename)
140 | plot_DA(filename)
141 |
142 | if filename is None:
143 | pylab.show()
144 |
145 |
--------------------------------------------------------------------------------
/make_docs.bash:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | epydoc --exclude='cosmolopy.EH._power' --exclude='cosmolopy.EH._tf_fit' --exclude='cosmolopy.EH.power' --exclude='cosmolopy.EH.tf_fit' -v --no-private --no-frames --html --docformat restructuredtext cosmolopy/ -o www/docAPI/
--------------------------------------------------------------------------------
/pypi_notes.txt:
--------------------------------------------------------------------------------
1 | To upload to PyPI:
2 |
3 | > python setup.py sdist upload
4 | > python setup.py bdist_egg upload
5 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | numpy>=1.12.0
2 | scipy>=1.0.0
3 |
4 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [bdist_wheel]
2 | universal = 0
3 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Future imports
3 |
4 | from __future__ import absolute_import, division, print_function
5 |
6 | import re
7 | import subprocess
8 | from setuptools import setup, find_packages, Extension
9 | from os import path
10 | import sys
11 |
12 | dirpath = path.abspath(path.dirname(__file__))
13 |
14 | eh_dir = path.join(dirpath,'cosmolopy','EH')
15 |
16 | ext_names = ['power', 'tf_fit']
17 |
18 | def generate_swig():
19 | print("Swigging sources")
20 | for d in ext_names:
21 | filename = path.join(eh_dir, d+'.i')
22 | p = subprocess.call(['swig', '-python', filename],
23 | cwd=dirpath)
24 | if p != 0:
25 | raise RuntimeError("Running swig failed!")
26 |
27 | # Generate swig if build is requested
28 | for command in ['develop', 'build', 'bdist_wheel', 'build_ext', 'build_src']:
29 | if command in sys.argv[1:]:
30 | generate_swig()
31 | break
32 |
33 | # Generate dict of all data files to include
34 | EH_files = []
35 | if 'sdist' in sys.argv[1:]:
36 | for name in ext_names:
37 | EH_files.extend(['%s.c' % (name), '%s.i' % (name)])
38 | package_data = {
39 | '': ['*.txt', '*.rst', 'LISCENSE'],
40 | 'cosmolopy.EH': EH_files}
41 |
42 | # Create extension modules
43 | ext_mods = []
44 | for name in ext_names:
45 | mod = Extension('cosmolopy.EH._%s' % (name),
46 | sources=[path.join(eh_dir, '%s_wrap.c' % (name)),
47 | path.join(eh_dir, '%s.c' % (name))])
48 | ext_mods.append(mod)
49 |
50 | # Get the requirements list
51 | with open(path.join(dirpath, 'requirements.txt'), 'r') as f:
52 | requirements = f.read().splitlines()
53 |
54 | # Read the __version__.py file
55 | with open(path.join(dirpath, 'cosmolopy/__version__.py'), 'r') as f:
56 | vf = f.read()
57 |
58 | # Obtain version from read-in __version__.py file
59 | version = re.search(r"^_*version_* = ['\"]([^'\"]*)['\"]", vf, re.M).group(1)
60 |
61 | setup(
62 | name = "cosmolopy",
63 | version = version,
64 | packages = find_packages(),
65 | install_requires = requirements,
66 |
67 | ext_modules = ext_mods,
68 |
69 | tests_require = ['nose', 'matplotlib'],
70 | test_suite = 'nose.collector',
71 | platforms=["Windows", "Linux", "Unix"],
72 |
73 | # metadata for upload to PyPI
74 | author = "Roban Hultman Kramer",
75 | author_email = "robanhk@gmail.com",
76 | description = "a cosmology package for Python.",
77 | url = "http://roban.github.com/CosmoloPy/", # project home page
78 | keywords = ("astronomy cosmology cosmological distance density galaxy" +
79 | "luminosity magnitude reionization Press-Schechter Schecter"),
80 | license = "MIT",
81 | python_requires = ">=3.6, <4",
82 | package_data=package_data,
83 | long_description = \
84 | """CosmoloPy is a package of cosmology routines built on NumPy/SciPy.
85 |
86 | Capabilities include
87 | --------------------
88 |
89 | `cosmolopy.density`
90 | Various cosmological densities.
91 |
92 | `cosmolopy.distance`
93 | Various cosmological distance measures.
94 |
95 | `cosmolopy.luminosityfunction`
96 | Galaxy luminosity functions (Schecter functions).
97 |
98 | `cosmolopy.magnitudes`
99 | Conversion in and out of the AB magnitude system.
100 |
101 | `cosmolopy.parameters`
102 | Pre-defined sets of cosmological parameters (e.g. from WMAP).
103 |
104 | `cosmolopy.perturbation`
105 | Perturbation theory and the power spectrum.
106 |
107 | `cosmolopy.reionization`
108 | The reionization of the IGM.
109 |
110 | """,
111 | classifiers = ['License :: OSI Approved :: MIT License',
112 | 'Programming Language :: Python',
113 | 'Programming Language :: Python :: 3',
114 | 'Programming Language :: Python :: 3.6',
115 | 'Programming Language :: Python :: 3.7',
116 | 'Programming Language :: Python :: 3.8',
117 | 'Topic :: Scientific/Engineering :: Astronomy',
118 | 'Operating System :: OS Independent'
119 | ]
120 | )
121 |
--------------------------------------------------------------------------------
/tests/test_BrokenPowerlawSED.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import absolute_import, division, print_function
3 |
4 | import numpy
5 |
6 | import cosmolopy.utils as utils
7 | from cosmolopy.luminosityfunction import BrokenPowerlawSED
8 |
9 | def test_BrokenPowerlawSED(plot=False):
10 | """Test that the BrokenPowerlawSED has the right break and normalization.
11 | """
12 | if plot: import pylab
13 | runtest_BrokenPowerlawSED(BrokenPowerlawSED(), plot=plot)
14 | runtest_BrokenPowerlawSED(BrokenPowerlawSED(s_ion=-2., s_red=-0.5), plot=plot)
15 | if plot: pylab.show()
16 |
17 | def runtest_BrokenPowerlawSED(sed, plot=False):
18 |
19 | nu_912 = sed.lambdanu(912.)
20 |
21 | ratio_1500_L_num = (sed(sed.lambdanu(1500.))/
22 | sed(sed.lambdanu(912. - 1e-10)))[0]
23 |
24 | # Test the magnitude of the break.
25 | assert numpy.abs(ratio_1500_L_num - sed.break_factor) < 1e-9
26 |
27 | # Test the normalization of the integral.
28 | numintegral = utils.logquad(sed, sed.lambdanu(3000.), sed.lambdanu(1e-6))[0]
29 | assert numpy.abs(numintegral - 1.) < 1e-6
30 |
31 | if plot:
32 | import pylab
33 | wav = numpy.arange(100.,2000.,1.0)
34 | nu = sed.lambdanu(wav)
35 | pylab.subplot(121)
36 | #norm = sed(nu_912 + 1e10)
37 | norm = 1.0
38 | pylab.plot(wav, sed(nu)/norm)
39 | #pylab.axhline(y=6, ls=':')
40 | #pylab.axvline(x=1500, ls=':')
41 | pylab.subplot(122)
42 | pylab.plot(nu, sed(nu)/norm)
43 |
44 | if __name__ == '__main__':
45 | test_BrokenPowerlawSED(True)
46 |
--------------------------------------------------------------------------------
/tests/test_SFR_from_L_nu.py:
--------------------------------------------------------------------------------
1 | """Test SFR - UV luminosity conversion.
2 | """
3 |
4 | from __future__ import absolute_import, division, print_function
5 |
6 | import numpy
7 |
8 | import cosmolopy.parameters as cparam
9 |
10 | import cosmolopy.magnitudes as magnitudes
11 | import cosmolopy.luminosityfunction as luminosityfunction
12 |
13 |
14 | def test_sfr():
15 | """Check that M = -18 -> SFR ~ 1 Msun/yr.
16 |
17 | From Oesch et al (2009 ApJ 690 1350).
18 | """
19 |
20 | mag = -18
21 | lum = magnitudes.L_nu_from_magAB(mag)
22 | sfr = luminosityfunction.sfr_from_L_nu(lum)
23 |
24 | print("M = %.3g -> L_nu = %.3g erg/s/Hz -> SFR = %.3g Msun/yr" % (mag,
25 | lum,
26 | sfr))
27 | assert numpy.round(sfr) == 1
28 |
29 | def test_sfrd():
30 | """ Check conversion of Lmin -> SFRD.
31 |
32 | At z=7:
33 | Lmin = 0.2 L*z=6 -> Mmin=-18.5 -> log(rho/erg/s/Hz/Mpc^3)=25.5 ->
34 | SFRD = 10^-2.32 Msun/yr^-1/Mpc^-3.
35 |
36 | From Oesch et al (2009 ApJ 690 1350).
37 | """
38 |
39 | cosmo = cparam.WMAP7_BAO_H0_mean(flat=True)
40 |
41 |
42 | # # From Bouwens 2008ApJ...686..230B
43 | # lfhist = luminosityfunction.LFHistory(params=luminosityfunction.B2008,
44 | # **cosmo)
45 |
46 | # mStarz6 = lfhist.params_z(6.0)['MStar']
47 |
48 | alpha = -1.74
49 | mStarz6 = -20.24
50 | mStarz7 = -19.7
51 | phiStar = 1.4e-3
52 |
53 | lStarz6 = magnitudes.L_nu_from_magAB(mStarz6)
54 | lmin = 0.2 * lStarz6
55 | magmin = magnitudes.magnitude_AB_from_L_nu(lmin)
56 | ltot = luminosityfunction.schechterCumuLM(magnitudeAB=magmin,
57 | MStar=mStarz7,
58 | phiStar=phiStar,
59 | alpha=alpha)
60 | sfrd = luminosityfunction.sfr_from_L_nu(ltot)
61 |
62 | print("""Lmin = 0.2 L*z=6 -> Lmin/erg/s/Hz = %.3g -> Mmin = %.3g ->
63 | log(rho/(erg/s/Hz/Mpc^3)) = %.3g -> log(SFRD/(MSun/yr)) = %.3g"""
64 | % (lmin, magmin, numpy.log10(ltot), numpy.log10(sfrd)))
65 |
66 | ltotz6 = luminosityfunction.schechterCumuLM(magnitudeAB=magmin,
67 | MStar=mStarz6,
68 | phiStar=phiStar,
69 | alpha=alpha)
70 |
71 | print("luminosity density increase from z=7 to z=6 is %.2g percent."
72 | % (100 * (1. - ltot/ltotz6)))
73 |
74 |
75 | assert numpy.abs(numpy.round(1. - ltot/ltotz6, 1) - 0.5) < 0.1
76 | assert numpy.round(magmin, 1) == -18.5
77 | assert numpy.abs(numpy.round(numpy.log10(ltot), 1) - 25.5) < 0.2
78 | assert numpy.abs(numpy.round(numpy.log10(sfrd), 1) - -2.32) < 0.05
79 |
80 | if __name__ == '__main__':
81 | test_sfr()
82 | test_sfrd()
83 |
84 |
85 |
--------------------------------------------------------------------------------
/tests/test_age.py:
--------------------------------------------------------------------------------
1 | """Test integrated age against analytical age."""
2 |
3 | from __future__ import absolute_import, division, print_function
4 |
5 | import numpy
6 | import numpy.testing.utils as ntest
7 | import matplotlib as mpl
8 | mpl.use('Agg')
9 |
10 | import matplotlib.pyplot as pylab
11 |
12 | import cosmolopy.distance as cd
13 | import cosmolopy.constants as cc
14 |
15 |
16 | def test_age():
17 | """Test integrated age against analytical age."""
18 | z = numpy.arange(0, 10.0, 0.05)
19 |
20 | cosmo = {}
21 | cosmo['omega_M_0'] = numpy.array([[0.99],[0.01],[0.3]])
22 | cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
23 | cosmo['h'] = 0.7
24 | cd.set_omega_k_0(cosmo)
25 |
26 | linestyle = ['-', ':', '--']
27 |
28 | gyr = 1e9 * cc.yr_s
29 |
30 | tl = cd.lookback_time(z, **cosmo)
31 | age = cd.age(z, **cosmo)
32 | age_ana = cd.age_flat(z, **cosmo)
33 |
34 | pylab.figure(figsize=(6,6))
35 | for i in range(len(linestyle)):
36 | pylab.plot(z, (tl/gyr)[i], ls=linestyle[i], color='0.5')
37 | pylab.plot(z, (age/gyr)[i], ls=linestyle[i], color='r')
38 | pylab.plot(z, (age_ana/gyr)[i], ls=linestyle[i], color='k')
39 | pylab.xlabel("redshift z")
40 | pylab.ylabel(r"age $t_L/$Gyr")
41 |
42 | pylab.figure(figsize=(6,6))
43 | for i in range(len(linestyle)):
44 | pylab.plot(z, ((age - age_ana)/age_ana)[i], ls=linestyle[i],
45 | color='k')
46 | # Make sure errors are small:
47 | ntest.assert_array_less((numpy.abs((age - age_ana)/age_ana)[i]),
48 | 3e-13)
49 | pylab.xlabel("redshift z")
50 | pylab.ylabel(r"age: (integral - analytical)/analytical")
51 |
52 | if __name__ == "__main__":
53 | test_age()
54 | pylab.show()
55 |
--------------------------------------------------------------------------------
/tests/test_distances.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import absolute_import, division, print_function
3 |
4 | import os
5 | import numpy
6 | import numpy.testing.utils as ntest
7 | import cosmolopy.distance as cd
8 | import cosmolopy.constants as cc
9 |
10 | import matplotlib.pyplot as pylab
11 |
12 | def cosmo_wmap_5():
13 | """Cosmology from Komatsu et al. 2008 (arXiv:0803.0547v1)"""
14 | cosmo = {}
15 | omega_c = 0.233 #+-0.013,
16 | cosmo['omega_b_0'] = 0.0462 #+-0.0015,
17 | cosmo['omega_M_0'] = omega_c + cosmo['omega_b_0'] # 0.2792
18 | cosmo['omega_k_0'] = 0.0
19 | cosmo['omega_lambda_0'] = (1. - cosmo['omega_M_0'] - cosmo['omega_k_0'])
20 | #cosmo['omega_lambda_0'] = 0.721 #+-0.015
21 | cosmo['h'] = 0.701 #+-0.0013
22 | cosmo['n'] = 0.960 #+0.014-0.013
23 | cosmo['sigma_8'] = 0.817 #+-0.026
24 | y_p = 0.240 # +- 0.006: the observed helium abundance
25 | cosmo['X_H'] = 1. / (1. + 1. / (4. * ((1. / y_p) - 1.)))
26 |
27 | cosmo['omega_n_0'] = 0.0
28 | cosmo['N_nu'] = 0
29 |
30 | return cosmo
31 |
32 | def test_distances(threshold = 1e-3):
33 | """Compare distance measures with calculations from http://icosmo.org/"""
34 | cosmo = cosmo_wmap_5()
35 |
36 | print("Comparing distances with calculations from http://icosmo.org/")
37 |
38 | # load external distance calculations
39 | # z DA(z) DT(z) DL(z)
40 | distance_file = os.path.dirname(os.path.abspath(__file__))
41 | distance_file = os.path.join(distance_file, 'icosmo_testdata',
42 | 'distances.txt')
43 | ic_dists = numpy.loadtxt(distance_file)
44 |
45 | z = ic_dists[:,0]
46 |
47 | cd_da = cd.angular_diameter_distance(z, **cosmo)
48 | cd_dt = cd.light_travel_distance(z, **cosmo)
49 | cd_dl = cd.luminosity_distance(z, **cosmo)
50 | cd_dm = cd.comoving_distance_transverse(z, **cosmo)
51 |
52 | cd_dists = numpy.vstack((cd_dm, cd_da, cd_dt, cd_dl))
53 |
54 | labels = [ r'$D_M$', r'$D_A$', r'$D_T$', r'$D_L$']
55 | threshold = [1e-7, 1e-7, 1e-3, 1e-7 ]
56 |
57 | pylab.figure()
58 | for i in range(len(labels)):
59 | pylab.plot(ic_dists[:,0], ic_dists[:,i+1],
60 | label=labels[i] +' IC', ls=':')
61 | pylab.plot(z, cd_dists[i], label=labels[i] +' distance.py', ls='-')
62 | pylab.legend(loc='best')
63 |
64 | pylab.figure()
65 |
66 | for i in range(len(labels)):
67 | diff = (cd_dists[i] - ic_dists[:,i+1]) / ic_dists[:,i+1]
68 | maxdiff = numpy.max(numpy.abs(diff[ic_dists[:,i+1] > 0]))
69 | print("Maximum fraction difference in %s is %e." % (labels[i],
70 | maxdiff))
71 | assert(numpy.all(maxdiff < threshold[i]))
72 | pylab.plot(ic_dists[:,0],
73 | diff,
74 | label=labels[i], ls='-')
75 |
76 | #pylab.plot(z, err2, label=labels[1] + ' err.', ls=':')
77 | #pylab.plot(z, err3, label=labels[2] + ' err.', ls=':')
78 | #pylab.plot(z, err5, label=labels[3] + ' err.', ls=':')
79 | #pylab.plot(z, err6, label=labels[0] + ' err.', ls=':')
80 |
81 | pylab.legend(loc='best')
82 |
83 | def test_hubble(threshold = 1e-7):
84 | cosmo = cosmo_wmap_5()
85 | print("Comparing hubble constant with calculations from "
86 | "http://icosmo.org/")
87 |
88 | # load external distance calculations
89 | # z H(z)
90 | hz_file = os.path.dirname(os.path.abspath(__file__))
91 | hz_file = os.path.join(hz_file, 'icosmo_testdata',
92 | 'h_z.txt')
93 | ic_hz = numpy.loadtxt(hz_file)
94 |
95 | z = ic_hz[:,0]
96 |
97 | cd_hz = cd.hubble_z(z, **cosmo) * cc.Mpc_km
98 |
99 | label = r"$H(z)$"
100 | pylab.figure()
101 | pylab.plot(z, ic_hz[:,1],
102 | label=label + ' IC', ls=':')
103 | pylab.plot(z, cd_hz, label=label + ' distance.py', ls='-')
104 | pylab.legend(loc='best')
105 |
106 | pylab.figure()
107 | diff = (ic_hz[:,1] - cd_hz) / ic_hz[:,1]
108 |
109 | maxdiff = numpy.max(numpy.abs(diff))
110 | print("Maximum fraction difference in %s is %e." % (label,
111 | maxdiff))
112 | if maxdiff > threshold:
113 | print("Warning: difference exceeds threshold %e !!!" % threshold)
114 | assert(maxdiff < threshold)
115 |
116 | pylab.plot(z,
117 | diff,
118 | label=label, ls='-')
119 | pylab.legend(loc='best')
120 |
121 |
122 | if __name__ == "__main__":
123 | test_distances()
124 | test_hubble()
125 | pylab.show()
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/tests/test_growth.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import absolute_import, division, print_function
3 |
4 | import os
5 | import numpy
6 | import numpy.testing.utils as ntest
7 | import cosmolopy.perturbation as cp
8 | import cosmolopy.constants as cc
9 |
10 | import matplotlib.pyplot as pylab
11 |
12 | def cosmo_wmap_5():
13 | """Cosmology from Komatsu et al. 2008 (arXiv:0803.0547v1)"""
14 | cosmo = {}
15 | omega_c = 0.233 #+-0.013,
16 | cosmo['omega_b_0'] = 0.0462 #+-0.0015,
17 | cosmo['omega_M_0'] = omega_c + cosmo['omega_b_0'] # 0.2792
18 | cosmo['omega_k_0'] = 0.0
19 | cosmo['omega_lambda_0'] = (1. - cosmo['omega_M_0'] - cosmo['omega_k_0'])
20 | #cosmo['omega_lambda_0'] = 0.721 #+-0.015
21 | cosmo['h'] = 0.701 #+-0.0013
22 | cosmo['n'] = 0.960 #+0.014-0.013
23 | cosmo['sigma_8'] = 0.817 #+-0.026
24 | y_p = 0.240 # +- 0.006: the observed helium abundance
25 | cosmo['X_H'] = 1. / (1. + 1. / (4. * ((1. / y_p) - 1.)))
26 |
27 | cosmo['omega_n_0'] = 0.0
28 | cosmo['N_nu'] = 0
29 |
30 | return cosmo
31 |
32 | def test_growth(cosmo=None):
33 | if cosmo is None:
34 | cosmo = cosmo_wmap_5()
35 | print("Comparing growth factor with calculations from http://icosmo.org/")
36 |
37 | # load external distance calculations
38 | # z D
39 | growth_file = os.path.dirname(os.path.abspath(__file__))
40 | growth_file = os.path.join(growth_file, 'icosmo_testdata', 'growth.txt')
41 | ic_growth = numpy.loadtxt(growth_file)
42 |
43 | z = ic_growth[:,0]
44 |
45 | cp_growth = cp.fgrowth(z, cosmo['omega_M_0'])
46 |
47 | label = r"$D(z)$"
48 | pylab.figure()
49 | pylab.plot(z, ic_growth[:,1],
50 | label=label + ' IC', ls=':')
51 | pylab.plot(z, cp_growth, label=label + ' perturbation.py', ls='-')
52 | pylab.legend(loc='best')
53 |
54 | pylab.figure()
55 | diff = (ic_growth[:,1] - cp_growth) / ic_growth[:,1]
56 |
57 | maxdiff = numpy.max(numpy.abs(diff))
58 | print("Maximum fraction difference in %s is %e." % (label,
59 | maxdiff))
60 | pylab.plot(z,
61 | diff,
62 | label=label, ls='-')
63 | pylab.legend(loc='best')
64 |
65 | ntest.assert_array_less(numpy.abs(diff), 5e-3)
66 |
67 | if __name__ == "__main__":
68 | test_growth()
69 | pylab.show()
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/tests/test_plot_BKP.py:
--------------------------------------------------------------------------------
1 | """Reionization consistency check with BK&P 2009MNRAS.397..971B"""
2 |
3 | from __future__ import absolute_import, division, print_function
4 |
5 | import numpy
6 | import numpy.testing.utils as ntest
7 | import matplotlib.pyplot as pylab
8 |
9 | import cosmolopy.perturbation as cp
10 | import cosmolopy.distance as cd
11 | import cosmolopy.density as cden
12 | import cosmolopy.reionization as cr
13 | import cosmolopy.constants as cc
14 | import cosmolopy.parameters as cparam
15 |
16 | def test_tau_BKP():
17 | """Reionization consistency check with BK&P 2009MNRAS.397..971B
18 |
19 | Bagla J.~S., Kulkarni G., Padmanabhan T., 2009 (2009MNRAS.397..971B).
20 |
21 | Take their cannonical set of cosmological parameters and ionization
22 | coefficients and make sure I get the same optical depth value.
23 |
24 | The first figure demonstrates the calculation of the ionization
25 | fraction and the optical depth (not shown in the paper).
26 |
27 | The second figure shows dependence of the f_* f_esc,gamma values on
28 | tau (actually calculated the other way around, f_* f_esc,gamma ->
29 | tau). The plotted point (x) marks the value from the paper. The
30 | agreement between the calculated optical depth and the WMAP tau value
31 | is printed in the text output.
32 |
33 | """
34 | N_gamma = 6804.
35 |
36 | # f_* f_esc N_gamma
37 | f_ion = numpy.transpose(numpy.atleast_2d(numpy.arange(10., 200., 10.)))
38 |
39 | alpha_B = 1e-13 # cm^3 s^-1
40 | m_min = 1e8 # M_sun
41 |
42 | x_ionHe = 2.0
43 |
44 | dz = 0.1
45 | z = numpy.arange(20., 6. - 1.5 * dz, -1. * dz)
46 | #z = numpy.arange(6., 20. + 1.5 * dz, dz)
47 |
48 | cosmos = [cparam.WMAP5_ML(flat=True),
49 | cparam.WMAP5_mean(flat=True)]
50 |
51 | pylab.figure(figsize=(8,8))
52 | colors=['r', 'k']
53 | names = ["WMAP5 ML", "WMAP5 mean"]
54 | i = -1
55 | for cosmo in cosmos:
56 | i += 1
57 |
58 | print("\n%s" % (names[i]))
59 | # calculate ionized fraction, including recombinations
60 | x_rec, w_rec, t = cr.integrate_ion_recomb_collapse(z, f_ion,
61 | m_min,
62 | passed_min_mass=True,
63 | alpha_B=alpha_B,
64 | **cosmo)
65 | # calculate the optical depth in this scenario
66 | tau_z0 = cr.optical_depth_instant(z[-1],
67 | x_ionH=1.0,
68 | x_ionHe=2.0,
69 | **cosmo)
70 |
71 | tau_later = cr.integrate_optical_depth(x_rec, x_ionHe * x_rec,
72 | z, **cosmo)
73 | tau_0 = tau_later[:, -1] + tau_z0
74 |
75 | tau = tau_later
76 |
77 | print("tau(WMAP) = %.3f" % (cosmo['tau']))
78 | for j in range(len(f_ion.flat)):
79 | if round(f_ion[j],1) != 50.0:
80 | continue
81 | print("with f_* f_esc_gamma N_gamma = %.1f:" % (f_ion[j]))
82 | pylab.plot(z, x_rec[j], ls='-', color=colors[i])
83 | pylab.plot(z, w_rec[j], ls=':', color=colors[i])
84 | #pylab.plot(z, 10. * tau[j], ls='--', color=colors[i])
85 | pylab.plot(z, 10. * (tau_0[j] - tau[j]), ls='--', color=colors[i])
86 | pylab.axhline(y=10. * tau_0[j], ls='--', color=colors[i])
87 | print("tau(z=0) = %.4f" % (tau_0[j]))
88 | print("fractional diff. = %.3g" % ((tau_0[j] - cosmo['tau']) /
89 | cosmo['tau']))
90 | if i==1:
91 | # Make sure we recover the WMAP value.
92 | ntest.assert_approx_equal(tau_0[j], cosmo['tau'], 2)
93 |
94 | pylab.ylim(0,1.01)
95 | pylab.xlabel("redshift z")
96 | pylab.ylabel(r"ionized fraction or optical depth $\tau \times 10$")
97 |
98 | pylab.figure(figsize=(8,8))
99 | pylab.plot(tau_0, f_ion / N_gamma, '-', color='k')
100 | pylab.plot([cosmo['tau']], [50.0 / N_gamma], 'x', color='b')
101 | pylab.xlim(0.06, 0.12)
102 | pylab.ylim(0., 0.022)
103 | pylab.xlabel(r'$\tau$')
104 | pylab.ylabel(r'$f_* f_{esc,\gamma}$')
105 |
106 | if __name__ == "__main__":
107 | test_tau_BKP()
108 | pylab.show()
109 |
110 |
--------------------------------------------------------------------------------
/tests/test_plot_HH.py:
--------------------------------------------------------------------------------
1 | """Reproduce collapse fraction plot from Haiman and Holder (2003)
2 |
3 | Haiman and Holder 2003ApJ...595....1H.
4 |
5 | """
6 |
7 | from __future__ import absolute_import, division, print_function
8 |
9 | import inspect
10 |
11 | import numpy
12 | import matplotlib.pyplot as pylab
13 |
14 | import cosmolopy.distance as cd
15 | import cosmolopy.constants as cc
16 | import cosmolopy.perturbation as cp
17 | import cosmolopy.reionization as cr
18 | import cosmolopy.parameters as cparams
19 |
20 | def hh_cosmo(flat=True, extras=True):
21 | """Cosmological parameters used in HH2003."""
22 | cosmo = {'omega_b_0' : 0.047,
23 | 'omega_M_0' : 0.29,
24 | 'omega_lambda_0' : 0.71,
25 | 'h' : 0.72,
26 | 'n' : 0.99,
27 | 'sigma_8' : 0.9
28 | }
29 | if flat:
30 | cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
31 | cosmo['omega_k_0'] = 0.0
32 | if extras:
33 | cparams.add_extras(cosmo)
34 | return cosmo
35 |
36 | def test_figure1():
37 | """Plot HH fig. 1: Evolution of the collapsed fraction (no quant. tests).
38 |
39 | "Evolution of the collapsed fraction of all baryons in halos in
40 | three different virial temperature ranges."
41 |
42 | Haiman and Holder 2003ApJ...595....1H.
43 |
44 | """
45 |
46 | dz = 1.
47 | z = numpy.arange(45., 0.0, -1. * dz)
48 |
49 | cosmo = hh_cosmo()
50 |
51 | T_min = numpy.array([[1.0e2],
52 | [1.0e4],
53 | [2.0e5]])
54 |
55 | linestyle = ['-', ':', '--']
56 |
57 | # Collapse fraction with the various minimum Virial temps.
58 | fc = cp.collapse_fraction(*cp.sig_del(T_min, z, **cosmo))
59 |
60 | # Calculate fraction of mass in halos in the ranges of min T.
61 | fc_diff = numpy.empty((T_min.shape[0], z.shape[0]))
62 | fc_diff[0:-1] = fc[0:-1] - fc[1:]
63 | fc_diff[-1] = fc[-1]
64 |
65 | pylab.figure(figsize=(6,6))
66 | for i in range(len(linestyle)):
67 | pylab.plot(z, fc_diff[i], ls=linestyle[i])
68 |
69 | pylab.xlabel(r"$\mathrm{z}$")
70 | pylab.ylabel(r"$\mathrm{F_{coll}}$")
71 |
72 | pylab.yscale('log')
73 | pylab.ylim(1e-5, 1.0)
74 | pylab.xlim(45.,0.)
75 |
76 | pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
77 | " H&H (2003ApJ...595....1H).")
78 |
79 | if __name__ == '__main__':
80 | test_figure1()
81 | pylab.show()
82 |
83 |
84 |
--------------------------------------------------------------------------------
/tests/test_plot_Hogg.py:
--------------------------------------------------------------------------------
1 | """Reproduce some plots from David Hogg's arXiv:astro-ph/9905116v4
2 |
3 | """
4 |
5 | from __future__ import absolute_import, division, print_function
6 |
7 | import inspect
8 |
9 | import numpy
10 | import matplotlib.pyplot as pylab
11 |
12 | import cosmolopy.distance as cd
13 | import cosmolopy.constants as cc
14 |
15 | def test_figure1():
16 | """Plot Hogg fig. 1: The dimensionless proper motion distance DM/DH.
17 |
18 | The three curves are for the three world models, Einstein-de
19 | Sitter (omega_M, omega_lambda) = (1, 0), solid; low-density,
20 | (0.05, 0), dotted; and high lambda, (0.2, 0.8), dashed.
21 |
22 | Hubble distance DH = c / H0
23 |
24 | z from 0--5
25 | DM / DH from 0--3
26 |
27 | """
28 |
29 | z = numpy.arange(0, 5.05, 0.05)
30 |
31 | cosmo = {}
32 | cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]])
33 | cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]])
34 | cosmo['h'] = 0.5
35 | cd.set_omega_k_0(cosmo)
36 |
37 | linestyle = ['-', ':', '--']
38 |
39 | dh = cd.hubble_distance_z(0, **cosmo)
40 | dm = cd.comoving_distance_transverse(z, **cosmo)
41 |
42 | pylab.figure(figsize=(6,6))
43 | for i in range(len(linestyle)):
44 | pylab.plot(z, (dm/dh)[i], ls=linestyle[i])
45 | #pylab.plot(z, (dm_err/dh)[i], ls=linestyle[i])
46 | pylab.xlim(0,5)
47 | pylab.ylim(0,3)
48 | pylab.xlabel("redshift z")
49 | pylab.ylabel(r"proper motion distance $D_M/D_H$")
50 | pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
51 | " (astro-ph/9905116v4)")
52 |
53 | def test_figure2():
54 | """Plot Hogg fig. 2: The dimensionless angular diameter distance DA/DH.
55 |
56 | The three curves are for the three world models,
57 |
58 | - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid]
59 |
60 | : Low-density (0.05, 0) [dotted]
61 |
62 | -- High lambda, (0.2, 0.8) [dashed]
63 |
64 | Hubble distance DH = c / H0
65 |
66 | z from 0--5
67 | DA / DH from 0--0.5
68 |
69 | """
70 |
71 | z = numpy.arange(0, 5.05, 0.05)
72 |
73 | cosmo = {}
74 | cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]])
75 | cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]])
76 | cosmo['h'] = 0.5
77 | cd.set_omega_k_0(cosmo)
78 |
79 | linestyle = ['-', ':', '--']
80 |
81 | dh = cd.hubble_distance_z(0, **cosmo)
82 | da = cd.angular_diameter_distance(z, **cosmo)
83 |
84 | # Also test the pathway with non-zero z0
85 | da2 = cd.angular_diameter_distance(z, z0=1e-8, **cosmo)
86 |
87 | pylab.figure(figsize=(6,6))
88 | for i in range(len(linestyle)):
89 | pylab.plot(z, (da/dh)[i], ls=linestyle[i])
90 | pylab.plot(z, (da2/dh)[i], ls=linestyle[i])
91 | pylab.xlim(0,5)
92 | pylab.ylim(0,0.5)
93 | pylab.xlabel("redshift z")
94 | pylab.ylabel(r"angular diameter distance $D_A/D_H$")
95 | pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
96 | " (astro-ph/9905116v4)")
97 |
98 | def test_figure3():
99 | """Plot Hogg fig. 3: The dimensionless luminosity distance DL/DH
100 |
101 | The three curves are for the three world models,
102 |
103 | - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid]
104 |
105 | : Low-density (0.05, 0) [dotted]
106 |
107 | -- High lambda, (0.2, 0.8) [dashed]
108 |
109 | Hubble distance DH = c / H0
110 |
111 | z from 0--5
112 | DL / DH from 0--16
113 |
114 | """
115 |
116 | z = numpy.arange(0, 5.05, 0.05)
117 |
118 | cosmo = {}
119 | cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]])
120 | cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]])
121 | cosmo['h'] = 0.5
122 | cd.set_omega_k_0(cosmo)
123 |
124 | linestyle = ['-', ':', '--']
125 |
126 | dh = cd.hubble_distance_z(0, **cosmo)
127 | dl = cd.luminosity_distance(z, **cosmo)
128 |
129 | pylab.figure(figsize=(6,6))
130 | for i in range(len(linestyle)):
131 | pylab.plot(z, (dl/dh)[i], ls=linestyle[i])
132 | pylab.xlim(0,5)
133 | pylab.ylim(0,16)
134 | pylab.xlabel("redshift z")
135 | pylab.ylabel(r"luminosity distance $D_L/D_H$")
136 | pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
137 | " (astro-ph/9905116v4)")
138 |
139 |
140 | def test_figure5():
141 | """Plot Hogg fig. 5: The dimensionless comoving volume element (1/DH)^3(dVC/dz).
142 |
143 | The three curves are for the three world models, (omega_M, omega_lambda) =
144 | (1, 0), solid; (0.05, 0), dotted; and (0.2, 0.8), dashed.
145 |
146 | """
147 | z = numpy.arange(0, 5.05, 0.05)
148 |
149 | cosmo = {}
150 | cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]])
151 | cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]])
152 | cosmo['h'] = 0.5
153 | cd.set_omega_k_0(cosmo)
154 |
155 | linestyle = ['-', ':', '--']
156 |
157 | dh = cd.hubble_distance_z(0, **cosmo)
158 |
159 | dVc = cd.diff_comoving_volume(z, **cosmo)
160 | dVc_normed = dVc/(dh**3.)
161 |
162 | Vc = cd.comoving_volume(z, **cosmo)
163 | dz = z[1:] - z[:-1]
164 | dVc_numerical = (Vc[:,1:] - Vc[:,:-1])/dz/(4. * numpy.pi)
165 | dVc_numerical_normed = dVc_numerical/(dh**3.)
166 |
167 | pylab.figure(figsize=(6,6))
168 | for i in range(len(linestyle)):
169 | pylab.plot(z, dVc_normed[i], ls=linestyle[i], lw=2.)
170 | pylab.plot(z[:-1], dVc_numerical_normed[i], ls=linestyle[i],
171 | c='k', alpha=0.1)
172 | pylab.xlim(0,5)
173 | pylab.ylim(0,1.1)
174 | pylab.xlabel("redshift z")
175 | pylab.ylabel(r"comoving volume element $[1/D_H^3]$ $dV_c/dz/d\Omega$")
176 | pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
177 | " (astro-ph/9905116v4)")
178 |
179 | def test_figure6():
180 | """Plot Hogg fig. 6: The dimensionless lookback time t_L/t_H and age t/t_H.
181 |
182 | The three curves are for the three world models,
183 |
184 | - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid]
185 |
186 | : Low-density (0.05, 0) [dotted]
187 |
188 | -- High lambda, (0.2, 0.8) [dashed]
189 |
190 | Hubble distance DH = c / H0
191 |
192 | z from 0--5
193 | t/th from 0--1.2
194 |
195 | """
196 |
197 | z = numpy.arange(0, 5.05, 0.05)
198 |
199 | cosmo = {}
200 | cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]])
201 | cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]])
202 | cosmo['h'] = 0.5
203 | cd.set_omega_k_0(cosmo)
204 |
205 | linestyle = ['-', ':', '--']
206 |
207 | th = 1/ cd.hubble_z(0, **cosmo)
208 |
209 | tl = cd.lookback_time(z, **cosmo)
210 | age = cd.age(z, **cosmo)
211 |
212 | pylab.figure(figsize=(6,6))
213 | for i in range(len(linestyle)):
214 | pylab.plot(z, (tl/th)[i], ls=linestyle[i])
215 | pylab.plot(z, (age/th)[i], ls=linestyle[i])
216 | pylab.xlim(0,5)
217 | pylab.ylim(0,1.2)
218 | pylab.xlabel("redshift z")
219 | pylab.ylabel(r"lookback timne $t_L/t_H$")
220 | pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
221 | " (astro-ph/9905116v4)")
222 |
223 | if __name__ == "__main__":
224 |
225 | test_figure1()
226 | test_figure2()
227 | test_figure3()
228 | test_figure5()
229 | test_figure6()
230 | pylab.show()
231 |
232 |
--------------------------------------------------------------------------------
/tests/test_plot_clumping_factor_Chary.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import absolute_import, division, print_function
3 |
4 | import sys
5 |
6 | import numpy
7 | import pylab
8 |
9 | import cosmolopy.reionization as cr
10 |
11 | def plot_clumping_factor_Chary():
12 | """Plot clumping factor from Chary paper.
13 | """
14 | z = numpy.linspace(5,15,500)
15 | cf = cr.clumping_factor_Chary(z)
16 |
17 | pylab.plot(z,cf)
18 | pylab.yscale('log')
19 | pylab.xlim(5,15)
20 | pylab.ylim(1,100)
21 |
22 | if __name__ == "__main__":
23 | if len(sys.argv)==1:
24 | print("Run with a filename argument to produce image files, e.g.:")
25 | if len(sys.argv) > 1:
26 | filename = sys.argv[1]
27 | else:
28 | filename = None
29 |
30 | plot_clumping_factor_Chary()
31 |
32 | ### Plot output code. ###
33 | if filename is None:
34 | pylab.show()
35 | else:
36 | from matplotlib import _pylab_helpers
37 | for manager in _pylab_helpers.Gcf.get_all_fig_managers():
38 | fig = manager.canvas.figure
39 | if len(fig.get_label()) > 0:
40 | label = fig.get_label()
41 | else:
42 | label = 'clumpFig' + str(manager.num)
43 | newfilename = prefix + '_' + label + extension
44 | fig.savefig(newfilename, bbox_inches="tight")
45 |
--------------------------------------------------------------------------------
/tests/test_plot_optical_depth.py:
--------------------------------------------------------------------------------
1 | """Test that analytical and numerical optical depth calculations agree.
2 |
3 | Also reproduces a figure from Griffiths et al. astro-ph/9812125v3
4 | (don't use the published version, which contains errors).
5 | """
6 |
7 | from __future__ import absolute_import, division, print_function
8 |
9 | import math
10 |
11 | import numpy
12 | import numpy.testing.utils as ntest
13 | import matplotlib.pyplot as pylab
14 |
15 | import cosmolopy.distance as cd
16 | import cosmolopy.constants as cc
17 | import cosmolopy.density as cden
18 | import cosmolopy.reionization as cr
19 |
20 |
21 | def test_GBL_tau_star():
22 | """Test tau_* against GB&L astro-ph/9812125v3.
23 |
24 | tau_* is a quantity used in optical_depth_instant.
25 | """
26 | z = 1.0
27 |
28 | # Fully ionized H and He
29 | x_ionH = 1.0
30 | x_ionHe = 2.0
31 |
32 | cosmo = {}
33 | cosmo['omega_M_0'] = numpy.array([[0.3],[0.6],[1.0]])
34 | cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
35 | cosmo['h'] = 0.65
36 | cosmo['omega_b_0'] = 0.02 / cosmo['h']**2.
37 | cosmo['Y_He'] = 0.24
38 | cd.set_omega_k_0(cosmo)
39 |
40 | tau_inst, tau_star = cr.optical_depth_instant(z,
41 | x_ionH=x_ionH,
42 | x_ionHe=x_ionHe,
43 | return_tau_star=True,
44 | **cosmo)
45 | print("tau_star = %.7f" % (tau_star))
46 | print("tau_star/(h Omega_b) = %.7f =? 0.061" %
47 | (tau_star / (cosmo['h'] * cosmo['omega_b_0'])))
48 |
49 | ntest.assert_approx_equal(tau_star / (cosmo['h'] * cosmo['omega_b_0']),
50 | 0.061,
51 | 2)
52 |
53 | print("(1 - Y_He/2) = %.3f =? 0.88" % (1. - (cosmo['Y_He']/2.)))
54 | ntest.assert_approx_equal((1. - (cosmo['Y_He']/2.)),
55 | 0.88,
56 | 7)
57 |
58 | H_0 = cc.H100_s * cosmo['h']
59 |
60 | # s^-1 * Mpc s^-1 * Mpc^2 / Mpc^3 msun^-1 s^-2 / Msun ->
61 | tau_star_explicit = ((1. - (cosmo['Y_He']/2.)) *
62 | ((3. * H_0 * cosmo['omega_b_0'] * cc.c_light_Mpc_s *
63 | cc.sigma_T_Mpc) /
64 | (8. * math.pi * cc.G_const_Mpc_Msun_s *
65 | (cc.m_p_g/cc.M_sun_g))))
66 |
67 | print("tau_star_explicit = %.7f =? tau_star" % (tau_star_explicit))
68 | ntest.assert_approx_equal(tau_star, tau_star_explicit, 3)
69 |
70 | def test_GBL_tau_inst():
71 | """Test match between analytical and numerical tau with instant
72 | reionization.
73 |
74 | Also makes a plot reproducing figure 1 of arXiv:astro-ph/9812125v3.
75 | """
76 | dz = 0.05
77 | z = numpy.arange(0., 80. + 1.5*dz, dz)
78 |
79 | # Fully ionized H and He
80 | x_ionH = 1.0
81 | x_ionHe = 2.0
82 |
83 | cosmo = {}
84 | cosmo['omega_M_0'] = numpy.array([[0.3],[0.6],[1.0]])
85 | cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
86 | cosmo['h'] = 0.65
87 | cosmo['omega_b_0'] = 0.02 / cosmo['h']**2.
88 | cosmo['Y_He'] = 0.24
89 | cd.set_omega_k_0(cosmo)
90 |
91 | tau_inst = cr.optical_depth_instant(z, x_ionH=x_ionH, x_ionHe=x_ionHe,
92 | **cosmo)
93 | tau_int = cr.integrate_optical_depth(x_ionH, x_ionHe, z, **cosmo)
94 |
95 | linestyle = ['-', ':', '--']
96 |
97 | pylab.figure()
98 | pylab.subplot(2,1,1)
99 | pylab.title("Compare to GB&L fig. 1 (astro-ph/9812125v3.)")
100 | for i in range(len(linestyle)):
101 | pylab.plot(z, tau_inst[i], ls=linestyle[i], color='b')
102 | pylab.plot(z, tau_int[i], ls=linestyle[i], color='r')
103 |
104 | pylab.xlim(0,80)
105 | pylab.ylim(0,1)
106 | pylab.xlabel(r"$\mathrm{z_{ion}}$")
107 | pylab.ylabel(r"$\tau$")
108 |
109 | pylab.subplot(2,1,2)
110 | for i in range(len(linestyle)):
111 | pylab.plot(z,
112 | 1.e4 * (tau_int[i] - tau_inst[i])/tau_inst[i],
113 | ls=linestyle[i], color='k')
114 | diff = (tau_int[i] - tau_inst[i]) / tau_inst[i]
115 | diff[numpy.isnan(diff)] = 0.0
116 | print("max fractional error in num. int. = %.3g" %
117 | numpy.max(numpy.abs(diff))
118 | )
119 | ntest.assert_array_less(numpy.abs(diff),
120 | numpy.zeros(diff.shape) + 2.e-4)
121 |
122 | pylab.xlim(0,40)
123 | pylab.xlabel(r"$\mathrm{z_{ion}}$")
124 | pylab.ylabel(r"$\mathrm{10^4 \times (num.\tau - ana.\tau)/ana.\tau}$")
125 |
126 | if __name__ == "__main__":
127 | test_GBL_tau_star()
128 | test_GBL_tau_inst()
129 | pylab.show()
130 |
131 |
--------------------------------------------------------------------------------
/tests/test_plot_reionization.py:
--------------------------------------------------------------------------------
1 | """Plot IGM ionized fraction.
2 |
3 | Note that there are no actual quantitative tests here. Just checks
4 | that it runs without errors.
5 |
6 | """
7 |
8 | from __future__ import absolute_import, division, print_function
9 |
10 | import numpy
11 | import numpy.testing.utils as ntest
12 | import matplotlib.pyplot as pylab
13 |
14 | import cosmolopy.perturbation as cp
15 | import cosmolopy.distance as cd
16 | import cosmolopy.density as cden
17 | import cosmolopy.reionization as cr
18 | import cosmolopy.constants as cc
19 | import cosmolopy.parameters as cparam
20 |
21 | import testingutils as tu
22 |
23 | def test_plot_FZH():
24 | """Plot figure 3 from FZH (2004ApJ...613....1F) (no quantitative tests).
25 | """
26 |
27 | cosmo = {}
28 | cosmo['omega_M_0'] = 0.3
29 | cosmo['omega_k_0'] = 0.0
30 | cosmo['omega_lambda_0'] = 0.7
31 | cosmo['h'] = 0.7
32 | cosmo['n'] = 1.0
33 | cosmo['sigma_8'] = 0.9
34 |
35 | cosmo['omega_b_0'] = 0.0462 # not specified in paper
36 | cosmo['omega_n_0'] = 0.0 # not specified in paper
37 | cosmo['N_nu'] = 0 # not specified in paper
38 | cosmo['Y_He'] = 0.24 # not specified in paper
39 | cosmo['baryonic_effects'] = False
40 | dz = 0.1
41 | z = numpy.arange(25., 8. - 1.5 * dz, -1. * dz)
42 |
43 | T_min = 1e4 #K
44 | c_ion = numpy.array([[500.], [40.], [12.]])
45 |
46 | # calculate ionized fraction from collapse fraction
47 | x_fcol = cr.ionization_from_collapse(z,
48 | c_ion,
49 | T_min,
50 | **cosmo)
51 | #linestyle = ['-', ':', '--']
52 | color = ['r', 'g', 'b']
53 | pylab.figure()
54 | pylab.subplot(2,1,1)
55 | for i in range(len(color)):
56 | pylab.plot(z, x_fcol[i], ls='--', color=color[i])
57 | pylab.axhline(y=0.75)
58 | pylab.yscale('log')
59 | pylab.xlim(8,25)
60 | pylab.ylim(1e-4, 1)
61 | pylab.title("Compare to figure 3 from FZH (2004ApJ...613....1F)")
62 |
63 | pylab.subplot(2,1,2)
64 | for i in range(len(color)):
65 | pylab.plot(z, x_fcol[i], ls='--', color=color[i])
66 | pylab.axhline(y=0.75)
67 | pylab.xlim(8,25)
68 | pylab.ylim(0, 1)
69 |
70 | def test_plot_integrate_ion_recomb_collapse():
71 | """Plot results of integrate_ion_recomb_collapse (no quantitative tests).
72 | """
73 |
74 | cosmo = cparam.WMAP5_mean(flat=True)
75 |
76 | dz = 0.5
77 | z = numpy.arange(25., 8. - 1.5 * dz, -1. * dz)
78 |
79 | T_min = 1e4 #K
80 | c_ion = numpy.array([[500.], [40.], [12.]])
81 |
82 | # calculate ionized fraction from collapse fraction
83 | x_fcol = cr.ionization_from_collapse(z,
84 | c_ion,
85 | T_min,
86 | **cosmo)
87 |
88 | x_rec = numpy.empty(x_fcol.shape)
89 | w_rec = numpy.empty(x_fcol.shape)
90 | for i in range(x_fcol.shape[0]):
91 | # calculate ionized fraction, including recombinations
92 | x_rec[i], w_rec[i], t = cr.integrate_ion_recomb_collapse(z, c_ion[i,0],
93 | temp_min = T_min,
94 | **cosmo)
95 |
96 | #linestyle = ['-', ':', '--']
97 | color = ['r', 'g', 'b']
98 | pylab.figure()
99 | pylab.subplot(2,1,1)
100 | for i in range(len(color)):
101 | pylab.plot(z, x_fcol[i], ls='--', color=color[i])
102 | pylab.plot(z, x_rec[i], ls='-', color=color[i])
103 | pylab.plot(z, w_rec[i], ls=':', color=color[i])
104 | pylab.axhline(y=0.75)
105 | pylab.yscale('log')
106 | pylab.xlim(8,25)
107 | pylab.ylim(1e-4, 1)
108 |
109 | pylab.subplot(2,1,2)
110 | for i in range(len(color)):
111 | pylab.plot(z, x_fcol[i], ls='--', color=color[i])
112 | pylab.plot(z, x_rec[i], ls='-', color=color[i])
113 | pylab.plot(z, w_rec[i], ls=':', color=color[i])
114 | pylab.axhline(y=0.75)
115 | pylab.xlim(8,25)
116 | pylab.ylim(0, 1)
117 |
118 | if __name__ == "__main__":
119 | test_plot_FZH()
120 | test_plot_integrate_ion_recomb_collapse()
121 | pylab.show()
122 |
123 |
--------------------------------------------------------------------------------
/tests/test_plot_reionization_BH.py:
--------------------------------------------------------------------------------
1 | """Reproduce some results from Bolton and Haehnelt (2007MNRAS.382..325B).
2 | """
3 |
4 | from __future__ import absolute_import, division, print_function
5 |
6 | import pylab
7 |
8 | import numpy
9 | import scipy.interpolate
10 |
11 | import cosmolopy.distance as cd
12 | import cosmolopy.reionization as cr
13 | import cosmolopy.perturbation as cp
14 |
15 | def nIonDotLowz(z):
16 | """Ionizations per second per Mpc^3 from BH2007 for z < 6
17 | """
18 | return 10.**(50.5 - 0.06 * (z - 6.0))
19 |
20 | def nIonDotBHmodel2(z):
21 | """Ionization model 2 from BH2007: constant above z=6.
22 | """
23 | return ((z < 6) * nIonDotLowz(z) +
24 | (z >= 6) * nIonDotLowz(6))
25 |
26 | def test_plot_nIonDotBH():
27 | """Compare with BH2007 figure 7."""
28 | z = numpy.linspace(1.75, 15., 100)
29 | n2 = nIonDotBHmodel2(z)
30 |
31 | pylab.figure()
32 | pylab.plot(z, numpy.log10(n2), label='Model 2')
33 | pylab.xlim(1.75, 15.)
34 | pylab.ylim(48.9, 51.8)
35 | pylab.legend(loc='best')
36 |
37 | def test_plot_integrate_ionization_recomb_BH(xHe=0.0):
38 |
39 | cosmo = {'omega_b_0' : 0.0463,
40 | 'omega_M_0' : 0.26,
41 | 'omega_lambda_0' : 1.-0.26,
42 | 'omega_k_0' : 0.0,
43 | 'h' : 0.72,
44 | 'n' : 0.95,
45 | 'sigma_8' : 0.85,
46 | #'tau' : 0.09,
47 | #'tau_err' : 0.03,
48 | 'omega_n_0' : 0.0,
49 | 'N_nu': 0,
50 | 'Y_He': 0.24,
51 | 'baryonic_effects' : False,
52 | }
53 |
54 | nIonDot2 = lambda z1: cr.ionization_from_luminosity(z1,
55 | nIonDotBHmodel2,
56 | xHe=xHe,
57 | **cosmo)
58 |
59 | zi = numpy.linspace(3.,15.,500.)
60 | w2i = nIonDot2(zi)
61 | ifunc2 = scipy.interpolate.interp1d(zi, w2i)
62 | ifunc2b = scipy.interpolate.interp1d(zi, w2i * 2.0)
63 |
64 | clump_fact_func = lambda z1: 2.0
65 |
66 | z = numpy.linspace(15,4,100.)
67 | fIon2, w2, t2 = cr.integrate_ion_recomb(z,
68 | ifunc2,
69 | clump_fact_func,
70 | xHe=xHe,
71 | **cosmo)
72 | fIon2b, w2b, t2b = cr.integrate_ion_recomb(z,
73 | ifunc2b,
74 | clump_fact_func,
75 | xHe=xHe,
76 | **cosmo)
77 |
78 | pylab.plot(z, fIon2, "--", label='Model 2')
79 | pylab.plot(z, fIon2b, "-", label='Model 2b')
80 | pylab.plot(z, w2, "0.75", label='M2 no rec.')
81 |
82 | pylab.xlim(4,15)
83 | pylab.ylim(0,1.0)
84 | pylab.legend(loc='best')
85 |
86 | if __name__ == '__main__':
87 | test_plot_nIonDotBH()
88 | pylab.figure()
89 | test_plot_integrate_ionization_recomb_BH()
90 | pylab.show()
91 |
92 |
--------------------------------------------------------------------------------
/tests/test_utils.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import absolute_import, division, print_function
3 |
4 | import numpy
5 |
6 | from cosmolopy.utils import *
7 | from cosmolopy.saveable import Saveable
8 |
9 |
10 | ######### Testing ############
11 |
12 | def test_integrate_piecewise(pieces=2, method='quad'):
13 | # Test modified from scipy test_quadrature.py.
14 | n = 2
15 | z = 1.8
16 | def func(x): # Bessel function integrand
17 | return numpy.cos(n*x-z*numpy.sin(x))/numpy.pi
18 | x = numpy.linspace(0, numpy.pi, pieces)
19 | val = integrate_piecewise(func,x, method=method)
20 | table_val = 0.30614353532540296487
21 | diff = val[-1] - table_val
22 | print("Error with %i %s pieces = %.3g" % (pieces, method, diff))
23 | numpy.testing.assert_almost_equal(val[-1], table_val, decimal=7)
24 |
25 | def test_PiecewisePowerlaw(n=4, plot=False):
26 |
27 | powers = 1.5 * (0.5 - numpy.random.rand(n))
28 | limits = 10. * numpy.cumsum(numpy.random.rand(n+1))
29 |
30 | pfunc = PiecewisePowerlaw(limits, powers, externalval=0)
31 | x = numpy.linspace(limits[0] - 0.1, limits[-1] + 0.1, 20.)
32 | #x = numpy.linspace(limits[0], limits[-1], 20.)
33 | y = pfunc(x)
34 |
35 | integral = pfunc.integrate(0, x)
36 | numintegral = integrate_piecewise(pfunc, x, method='quad')
37 |
38 | integral2 = pfunc.integrate(x, x[-1])
39 | numintegral2 = numintegral[-1] - numintegral
40 |
41 | # Weighted integral
42 | integral3 = pfunc.integrate(0, x, weight_power=1.5)
43 | weightedfunc = lambda x: (x**1.5) * pfunc(x)
44 | numintegral3 = integrate_piecewise(weightedfunc, x, method='quad')
45 |
46 | if plot:
47 | import pylab
48 |
49 | pylab.subplot(221)
50 | pylab.title('x vs. y')
51 | pylab.plot(x,y)
52 | pylab.xlim(min(x), max(x))
53 | for xlim in pfunc._limits.flat:
54 | pylab.axvline(x=xlim)
55 |
56 | pylab.subplot(223)
57 | pylab.title('x vs. forward/reverse integral')
58 | pylab.plot(x, integral)
59 | pylab.plot(x, numintegral)
60 | pylab.plot(x, integral2)
61 | pylab.plot(x, numintegral2)
62 | pylab.plot(pfunc._limits.flat[1:], numpy.cumsum(pfunc._integrals), '.')
63 | pylab.xlim(min(x), max(x))
64 |
65 | pylab.subplot(222)
66 | pylab.title('frac. diffs (num - ana)/ana')
67 | pylab.plot(x, (integral - numintegral)/integral)
68 | pylab.plot(x, (integral2 - numintegral2)/integral2)
69 | pylab.plot(x, (integral3 - numintegral3)/integral3)
70 |
71 | pylab.subplot(224)
72 | pylab.title('weighted integrals')
73 | pylab.plot(x, integral3)
74 | pylab.plot(x, numintegral3)
75 |
76 | pylab.show()
77 | assert numpy.all(numpy.abs(integral - numintegral) < 1e-4)
78 | assert numpy.all(numpy.abs(integral2 - numintegral2) < 1e-4)
79 | assert numpy.all(numpy.abs(integral3[integral3>0] -
80 | numintegral3[integral3>0]) /
81 | integral3[integral3>0] < 1e-3)
82 | assert numpy.abs(integral[-1] - 1.) < 1e-4
83 | assert numpy.abs(integral2[0] - 1.) < 1e-4
84 |
85 |
86 | def test_Extrapolate1d():
87 |
88 | slope = 2. * (0.5 - numpy.random.rand(1))
89 | intercept = 20. * (0.5 - numpy.random.rand(1))
90 | x = numpy.array([3., 4.,
91 | 5., 6., 7.,
92 | 8., 9.])
93 | y = slope * x + intercept
94 |
95 | # Random deviations in the midde.
96 | y[2:5] = y[2:5] + (5. * (0.5 - numpy.random.rand(3)))
97 | x1 = numpy.linspace(0., 15., 100.)
98 |
99 | extrap = Extrapolate1d(x,y)
100 | print(extrap.extrap_string())
101 | y1 = extrap(x1)
102 | ytrue = slope * x1 + intercept
103 |
104 | # Test extrapolation with a fixed slope.
105 | newslopes = [3.0, 2.0]
106 | extrap2 = Extrapolate1d(x, y, slopes=newslopes)
107 | print(extrap2.extrap_string())
108 | y2 = extrap2(x1)
109 |
110 | mask = numpy.logical_or(x1 >= x[5],
111 | x1 <= x[1])
112 |
113 | assert numpy.all(numpy.abs((y1 - ytrue)[mask]) < 1e-10)
114 |
115 | import pylab
116 | pylab.plot(x, y, 'o')
117 | pylab.plot(x1, y1, '-')
118 | pylab.plot(x1, ytrue, ':')
119 | pylab.plot(x1, y2, '--')
120 |
121 | if __name__ == '__main__':
122 |
123 | import pylab
124 | pylab.figure()
125 | for i in range(4):
126 | test_Extrapolate1d()
127 | pylab.show()
128 |
129 |
130 | test_PiecewisePowerlaw(plot=True)
131 |
132 | import numpy.testing
133 | for method in ['quad', 'romberg']:
134 | for pieces in range(2,1000,300):
135 | test_integrate_piecewise(pieces, method)
136 |
--------------------------------------------------------------------------------
/tests/test_wmap.py:
--------------------------------------------------------------------------------
1 | """Optical depth and cosmic age consistency check against WMAP parameters.
2 |
3 | Take various sets of WMAP parameters and see if I derive values for
4 | instant reionization optical depth and age of universe that agree with
5 | them.
6 |
7 | """
8 |
9 | from __future__ import absolute_import, division, print_function
10 |
11 | import numpy
12 | import numpy.testing.utils as ntest
13 | import matplotlib.pyplot as pylab
14 |
15 | import cosmolopy.perturbation as cp
16 | import cosmolopy.distance as cd
17 | import cosmolopy.density as cden
18 | import cosmolopy.reionization as cr
19 | #import reionization as cr
20 | import cosmolopy.constants as cc
21 | import cosmolopy.parameters as cparam
22 | #import parameters as cparam
23 |
24 | import testingutils as tu
25 |
26 | def test_tau_instant():
27 | """Check the optical depth we get using the WMAP z_reion.
28 | """
29 | dz = 0.1
30 | z = numpy.arange(80., 0. - 1.5 * dz, -1. * dz)
31 |
32 | # Can't match WMAP7 optical depths exactly. Need to look into new
33 | # treatment in CAMB as mentioned in the WMAP7 paper (see
34 | # parameters.py).
35 | cosmos = [cparam.WMAP7_BAO_H0_mean(flat=True),
36 | cparam.WMAP7_ML(flat=True),
37 | cparam.WMAP5_BAO_SN_mean(flat=True),
38 | cparam.WMAP5_ML(flat=True),
39 | cparam.WMAP5_mean(flat=True)]
40 |
41 | # The WMAP5 numbers apparently assume He is neutral, while WMAP7
42 | # includes simultaneous singly ionized He plus Helium (double)
43 | # reionization at z=3.5.
44 | x_ionHe_list = [1.0, 1.0, 0, 0, 0]
45 | z_rHe_list = [3.5, 3.5, None, None, None] #[3.5, None, None, None]
46 | for cosmo in cosmos:
47 | # Fully ionized H
48 | x_ionH = 1.0
49 |
50 | # He ionization with H?
51 | x_ionHe = x_ionHe_list.pop(0)
52 |
53 | # Redshift for Helium double reionization?
54 | z_rHe = z_rHe_list.pop(0)
55 |
56 | zr = cosmo['z_reion']
57 | tau_zr = cosmo['tau']
58 | tau_calc = cr.optical_depth_instant(zr,
59 | x_ionH=x_ionH,
60 | x_ionHe=x_ionHe,
61 | z_rHe=z_rHe,
62 | verbose = 1,
63 | **cosmo)
64 |
65 | print("z_r = %f, testing tau:" % (zr))
66 | print(tu.fractional_diff_string(tau_zr, tau_calc, 3))
67 |
68 | ntest.assert_approx_equal(tau_calc, tau_zr, significant=2,
69 | err_msg="Optical depth doesn't match WMAP")
70 |
71 |
72 | def test_t_0():
73 | """Check the age of the universe we get using WMAP cosmologies.
74 |
75 | We only find agreement to 3 sig figs, not the 4 specified in the
76 | WMAP paper.
77 |
78 | The results of test_age.py show that we're doing the integral
79 | correctly, so I think the problem is that we're not taking into
80 | account some of the higher-order effects included in the WMAP
81 | numbers.
82 |
83 | """
84 |
85 | dz = 0.1
86 | z = numpy.arange(80., 0. - 1.5 * dz, -1. * dz)
87 |
88 | flat = True
89 | cosmos = [cparam.WMAP7_BAO_H0_mean(flat=True),
90 | cparam.WMAP7_ML(flat=True),
91 | cparam.WMAP5_BAO_SN_mean(flat=True),
92 | cparam.WMAP5_ML(flat=True),
93 | cparam.WMAP5_mean(flat=True)]
94 |
95 | for cosmo in cosmos:
96 | age = cd.age(0.0, **cosmo)
97 | age_flat = cd.age_flat(0.0, **cosmo)
98 | gyr = 1e9 * cc.yr_s
99 | age /= gyr
100 | age_flat /= gyr
101 |
102 | print("integrated age: ")
103 | print(tu.fractional_diff_string(age, cosmo['t_0'], 4))
104 | ntest.assert_approx_equal(age, cosmo['t_0'], significant=3,
105 | err_msg="Integrated age doesn't match WMAP")
106 |
107 | print("analytical age: ")
108 | print(tu.fractional_diff_string(age_flat, cosmo['t_0'], 4))
109 | ntest.assert_approx_equal(age_flat, cosmo['t_0'], significant=3,
110 | err_msg="Analytical age doesn't match WMAP")
111 |
112 | if __name__ == "__main__":
113 | test_tau_instant()
114 | test_t_0()
115 |
--------------------------------------------------------------------------------
/tests/testingutils.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, division, print_function
2 |
3 | import numpy
4 |
5 | def fractional_diff_string(actual, desired, places=3):
6 | formats = "% ." + ("%i" % places) + "g"
7 | template = "frac. diff. of "+formats+" and "+formats+" = "+formats
8 | return template % (actual, desired, (desired - actual)/desired)
9 |
10 |
11 |
--------------------------------------------------------------------------------
/www/astrobetter.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sample blurb about me, feel free to modify or delete: This is
4 | a guest post by Roban
5 | Hultman Kramer, who is currently an astronomy grad student at
6 | Columbia University, but will be starting as a Zwicky Fellow at ETH
7 | Zurich in January.
8 |
9 |
CosmoloPy is a
10 | package of basic cosmology routines for Python, designed for use with
11 | NumPy and SciPy. Features currently
12 | include: calculation of cosmological distance measures,
13 | perturbation-theory-based calculation of the matter power spectrum and
14 | halo collapse fraction (courtesy of Eisenstein & Hu's transfer
15 | function code), and integration of simple reionization models and the
16 | resulting electron scattering optical depth due to reionization. I
17 | hope it will prove useful to the increasing number of astronomers
18 | turning to Python.
19 |
20 | Using CosmoloPy is as simple as setting up a dictionary of
21 | cosmological parameters (some WMAP5 parameters are provided for
22 | convenience in cosmolopy.parameters) and passing it to
23 | the functions you want to use. For instance, we could quickly calculate the comoving distance to redshift 6 like this:
24 |
25 | >>> import cosmolopy.distance as cd
26 | >>> cosmo = {'omega_M_0' : 0.3,
27 | ... 'omega_lambda_0' : 0.7,
28 | ... 'h' : 0.72}
29 | >>> d_co, err = cd.comoving_distance(z=6., **cosmo)
30 | >>> print "Comoving distance to z=6 is %.1f Mpc" % (d_co)
31 | Comoving distance to z=6 is 8017.8 Mpc
32 |
33 | A few more lines
34 | of code,
35 | and you can produce a plot like the one shown above.
36 |
37 |
CosmoloPy is released under
38 | the MIT
39 | software license, which allows it to be freely used and
40 | modified. So
41 | please download
42 | it, use it, and request or add features you'd like to see included
43 | (and point out bugs we need to fix). Anyone can
44 | access the git
45 | repository, so please edit the code and send in useful changes and
46 | additions. All questions about use or development can be posted to
47 | the developer
48 | discussion group.
7 | CosmoloPy is a package of cosmology routines for Python, designed for
8 | use with NumPy and SciPy. Reionization is a particular focus. See
9 | below for a longer list of capabilities.
10 |
11 |
12 |
Functions take cosmological parameters (which can be numpy arrays)
13 | as keywords, and ignore any extra keywords. This means you can make a
14 | dictionary of all of your cosmological parameters and pass it to any
15 | function.
16 |
17 |
Example
18 |
19 |
20 | Calculate the comoving distance to redshift 6.
21 |
22 | >>> import cosmolopy.distance as cd
23 | >>> cosmo = {'omega_M_0':0.3, 'omega_lambda_0':0.7, 'omega_k_0':0.0, 'h':0.72}
24 | >>> d_co, err = cd.comoving_distance(6., **cosmo)
25 | >>> print "Comoving distance to z=6 is %.1f Mpc" % (d_co)
26 | Comoving distance to z=6 is 8017.8 Mpc
27 |
28 |
29 |
30 | Look
31 | in tests/
32 | and examples/
33 | for more examples.
34 |
35 |
power (or cosmolopy.EH.power), which is a python wrapper of power.c
60 |
from Eisenstein & Hu (1999 ApJ 511 5)
61 |
62 |
63 |
64 |
65 |
tf_fit (or cosmolopy.EH.tf_fit), which is a python wrapper of
66 |
tf_fit.c from Eisenstein & Hu (1998 ApJ 496 605)
67 |
68 |
69 |
70 |
71 |
The first module contains no baryonic features in the transfer function, but
72 | applies to wider range of CDM variants (e.g. including neutrinos). The second
73 | module applies more narrowly but possesses effects including the baryonic
74 | acoustic osciallations.
power.c is redistributed under the MIT License with the permission of
77 | Wayne Hu, and is described in Eisenstein, D. J., & Hu, W. "Power
78 | Spectra for Cold Dark Matter and Its Variants," 1999, ApJ, 511, 5
79 | [astro-ph/9710252]. Please cite this paper to acknowledge use of power
80 | spectrum calculations.
53 | 1"""See `cosmolopy.perturbation.transfer_function_EH`
54 | 2
55 | 3Eisenstein & Hu power spectrum transfer function used in
56 | 4`cosmolopy.perturbation.transfer_function_EH`.
57 | 5
58 | 6This package contains two modules:
59 | 7
60 | 8i. `power` (or `cosmolopy.EH.power`), which is a python wrapper of power.c
61 | 9 from Eisenstein & Hu (1999 ApJ 511 5)
62 | 10
63 | 11ii. `tf_fit` (or `cosmolopy.EH.tf_fit`), which is a python wrapper of
64 | 12 tf_fit.c from Eisenstein & Hu (1998 ApJ 496 605)
65 | 13
66 | 14The first module contains no baryonic features in the transfer function, but
67 | 15applies to wider range of CDM variants (e.g. including neutrinos). The second
68 | 16module applies more narrowly but possesses effects including the baryonic
69 | 17acoustic osciallations.
70 | 18
71 | 19See also: http://background.uchicago.edu/~whu/transfer/transferpage.html
72 | 20
73 | 21power.c is redistributed under the MIT License with the permission of
74 | 22Wayne Hu, and is described in Eisenstein, D. J., & Hu, W. "Power
75 | 23Spectra for Cold Dark Matter and Its Variants," 1999, ApJ, 511, 5
76 | 24[astro-ph/9710252]. Please cite this paper to acknowledge use of power
77 | 25spectrum calculations.
78 | 26
79 | 27See LISCENSE for additional information.
80 | 28
81 | 29"""
82 | 30
87 |
When javascript is enabled, this page will redirect URLs of
22 | the form redirect.html#dotted.name to the
23 | documentation for the object with the given fully-qualified
24 | dotted name.