Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • john-veitch/bilby
  • duncanmmacleod/bilby
  • colm.talbot/bilby
  • lscsoft/bilby
  • matthew-pitkin/bilby
  • salvatore-vitale/tupak
  • charlie.hoy/bilby
  • bfarr/bilby
  • virginia.demilio/bilby
  • vivien/bilby
  • eric-howell/bilby
  • sebastian-khan/bilby
  • rhys.green/bilby
  • moritz.huebner/bilby
  • joseph.mills/bilby
  • scott.coughlin/bilby
  • matthew.carney/bilby
  • hyungwon.lee/bilby
  • monica.rizzo/bilby
  • christopher-berry/bilby
  • lindsay.demarchi/bilby
  • kaushik.rao/bilby
  • charles.kimball/bilby
  • andrew.matas/bilby
  • juan.calderonbustillo/bilby
  • patrick-meyers/bilby
  • hannah.middleton/bilby
  • eve.chase/bilby
  • grant.meadors/bilby
  • khun.phukon/bilby
  • sumeet.kulkarni/bilby
  • daniel.reardon/bilby
  • cjhaster/bilby
  • sylvia.biscoveanu/bilby
  • james-clark/bilby
  • meg.millhouse/bilby
  • joshua.willis/bilby
  • nikhil.sarin/bilby
  • paul.easter/bilby
  • youngmin/bilby
  • daniel-williams/bilby
  • shanika.galaudage/bilby
  • bruce.edelman/bilby
  • avi.vajpeyi/bilby
  • isobel.romero-shaw/bilby
  • andrew.kim/bilby
  • dominika.zieba/bilby
  • jonathan.davies/bilby
  • marc.arene/bilby
  • srishti.tiwari/bilby-tidal-heating-eccentric
  • aditya.vijaykumar/bilby
  • michael.williams/bilby
  • cecilio.garcia-quiros/bilby
  • rory-smith/bilby
  • maite.mateu-lucena/bilby
  • wushichao/bilby
  • kaylee.desoto/bilby
  • brandon.piotrzkowski/bilby
  • rossella.gamba/bilby
  • hunter.gabbard/bilby
  • deep.chatterjee/bilby
  • tathagata.ghosh/bilby
  • arunava.mukherjee/bilby
  • philip.relton/bilby
  • reed.essick/bilby
  • pawan.gupta/bilby
  • francisco.hernandez/bilby
  • rhiannon.udall/bilby
  • leo.tsukada/bilby
  • will-farr/bilby
  • vijay.varma/bilby
  • jeremy.baier/bilby
  • joshua.brandt/bilby
  • ethan.payne/bilby
  • ka-lok.lo/bilby
  • antoni.ramos-buades/bilby
  • oliviastephany.wilk/bilby
  • jack.heinzel/bilby
  • samson.leong/bilby-psi4
  • viviana.caceres/bilby
  • nadia.qutob/bilby
  • michael-coughlin/bilby
  • hemantakumar.phurailatpam/bilby
  • boris.goncharov/bilby
  • sama.al-shammari/bilby
  • siqi.zhong/bilby
  • jocelyn-read/bilby
  • marc.penuliar/bilby
  • stephanie.letourneau/bilby
  • alexandresebastien.goettel/bilby
  • alec.gunny/bilby
  • serguei.ossokine/bilby
  • pratyusava.baral/bilby
  • sophie.hourihane/bilby
  • eunsub/bilby
  • james.hart/bilby
  • pratyusava.baral/bilby-tg
  • zhaozc/bilby
  • pratyusava.baral/bilby_SoG
  • tomasz.baka/bilby
  • nicogerardo.bers/bilby
  • soumen.roy/bilby
  • isaac.mcmahon/healpix-redundancy
  • asamakai.baker/bilby-frequency-dependent-antenna-pattern-functions
  • anna.puecher/bilby
  • pratyusava.baral/bilby-x-g
  • thibeau.wouters/bilby
  • christian.adamcewicz/bilby
  • raffi.enficiaud/bilby
109 results
Show changes
Commits on Source (54)
Showing
with 572 additions and 246 deletions
......@@ -35,13 +35,16 @@ authors:
# Test containers scripts are up to date
containers:
stage: initial
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
script:
- cd containers
- python write_dockerfiles.py #HACK
# Fail if differences exist. If this fails, you may need to run
# write_dockerfiles.py and commit the changes.
- git diff --exit-code
- cp env-template.yml env.yml
- echo " - python=3.11" >> env.yml
- mamba env create -f env.yml -n test --dry-run
.test-python: &test-python
stage: initial
......@@ -67,10 +70,6 @@ containers:
${script} --help;
done
basic-3.9:
<<: *test-python
image: python:3.9
basic-3.10:
<<: *test-python
image: python:3.10
......@@ -79,16 +78,16 @@ basic-3.11:
<<: *test-python
image: python:3.11
basic-3.12:
<<: *test-python
image: python:3.12
.test-samplers-import: &test-samplers-import
stage: initial
script:
- python -m pip install .
- *list-env
- python test/test_samplers_import.py
# import-samplers-3.9:
# <<: *test-samplers-import
# image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
- pytest test/test_samplers_import.py -v
import-samplers-3.10:
<<: *test-samplers-import
......@@ -98,6 +97,10 @@ import-samplers-3.11:
<<: *test-samplers-import
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
import-samplers-3.12:
<<: *test-samplers-import
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
.precommits: &precommits
stage: initial
script:
......@@ -109,26 +112,19 @@ import-samplers-3.11:
# Run precommits (flake8, spellcheck, isort, no merge conflicts, etc)
- pre-commit run --all-files --verbose --show-diff-on-failure
# precommits-py3.9:
# <<: *precommits
# image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
# variables:
# CACHE_DIR: ".pip39"
# PYVERSION: "python39"
precommits-py3.10:
precommits-py3.11:
<<: *precommits
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
variables:
CACHE_DIR: ".pip310"
PYVERSION: "python310"
CACHE_DIR: ".pip311"
PYVERSION: "python311"
install:
stage: initial
parallel:
matrix:
- EXTRA: [gw, mcmc, all]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
script:
- pip install .[$EXTRA]
......@@ -142,15 +138,15 @@ install:
- pytest --cov=bilby --durations 10
# python-3.9:
# <<: *unit-test
# needs: ["basic-3.9", "precommits-py3.9"]
# image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
python-3.10:
<<: *unit-test
needs: ["basic-3.10", "precommits-py3.10"]
needs: ["basic-3.10"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
python-3.11:
<<: *unit-test
needs: ["basic-3.11", "precommits-py3.11"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
after_script:
- coverage html
- coverage xml
......@@ -164,10 +160,10 @@ python-3.10:
- htmlcov/
expire_in: 30 days
python-3.11:
python-3.12:
<<: *unit-test
needs: ["basic-3.11"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
needs: ["basic-3.12"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
.test-sampler: &test-sampler
stage: test
......@@ -176,25 +172,25 @@ python-3.11:
- *list-env
- pytest test/integration/sampler_run_test.py --durations 10 -v
# python-3.9-samplers:
# <<: *test-sampler
# needs: ["basic-3.9", "precommits-py3.9"]
# image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
python-3.10-samplers:
<<: *test-sampler
needs: ["basic-3.10", "precommits-py3.10"]
needs: ["basic-3.10"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
python-3.11-samplers:
<<: *test-sampler
needs: ["basic-3.11"]
needs: ["basic-3.11", "precommits-py3.11"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
integration-tests-python-3.10:
python-3.12-samplers:
<<: *test-sampler
needs: ["basic-3.12"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
integration-tests-python-3.11:
stage: test
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
needs: ["basic-3.10", "precommits-py3.10"]
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
needs: ["basic-3.11", "precommits-py3.11"]
only:
- schedules
script:
......@@ -212,31 +208,32 @@ integration-tests-python-3.10:
- *list-env
- pytest test/gw/plot_test.py
# plotting-python-3.9:
# <<: *plotting
# image: containers.ligo.org/lscsoft/bilby/v2-bilby-python39
# needs: ["basic-3.9", "precommits-py3.9"]
plotting-python-3.10:
<<: *plotting
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
needs: ["basic-3.10", "precommits-py3.10"]
needs: ["basic-3.10"]
plotting-python-3.11:
<<: *plotting
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
needs: ["basic-3.11"]
needs: ["basic-3.11", "precommits-py3.11"]
plotting-python-3.12:
<<: *plotting
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python312
needs: ["basic-3.12"]
# ------------------- Docs stage -------------------------------------------
docs:
stage: docs
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python311
before_script:
- python -m ipykernel install
script:
# Make the documentation
- python -m pip install .
- python -m pip install myst_parser # only for testing purposes - remove once test image is generating correctly
- cd examples/tutorials
- jupyter nbconvert --to notebook --execute *.ipynb --output-dir ../../docs
- cd ../../docs
......@@ -251,7 +248,7 @@ docs:
pages:
stage: deploy
needs: ["docs", "python-3.10"]
needs: ["docs", "python-3.11"]
script:
- mkdir public/
- mv htmlcov/ public/
......@@ -283,12 +280,6 @@ pages:
- docker image tag v3-bilby-$PYVERSION containers.ligo.org/lscsoft/bilby/v2-bilby-$PYVERSION:latest
- docker image push containers.ligo.org/lscsoft/bilby/v2-bilby-$PYVERSION:latest
# disable building python39 container due to dependency issues
# build-python39-container:
# <<: *build-container
# variables:
# PYVERSION: "python39"
build-python310-container:
<<: *build-container
variables:
......@@ -299,6 +290,11 @@ build-python311-container:
variables:
PYVERSION: "python311"
build-python312-container:
<<: *build-container
variables:
PYVERSION: "python312"
pypi-release:
stage: deploy
image: containers.ligo.org/lscsoft/bilby/v2-bilby-python310
......
......@@ -11,10 +11,12 @@ Andrew Miller
Antoni Ramos-Buades
Apratim Ganguly
Avi Vajpeyi
Ben Patterson
Bruce Edelman
Carl-Johan Haster
Cecilio Garcia-Quiros
Charlie Hoy
Chentao Yang
Christopher Philip Luke Berry
Christos Karathanasis
Colm Talbot
......@@ -28,6 +30,7 @@ Gregory Ashton
Hank Hua
Hector Estelles
Ignacio Magaña Hernandez
Isaac McMahon
Isobel Marguarethe Romero-Shaw
Jack Heinzel
Jacob Golomb
......@@ -73,6 +76,7 @@ Roberto Cotesta
Rory Smith
S. H. Oh
Sacha Husa
Sama Al-Shammari
Samson Leong
Scott Coughlin
Serguei Ossokine
......@@ -97,3 +101,5 @@ Marc Penuliar
Andrew Fowlie
Martin White
Peter Tsun-Ho Pang
Alexandre Sebastien Goettel
Ann-Kristin Malz
# All notable changes will be documented in this file
## [2.2.3] 2024-02-24
## [Unreleased]
## [2.3.0] - 2024-05-30
### Added
- Add support for sampler plugins via entry points (!1340, !1355)
- Add `bilby.core.sampler.get_implemented_samplers` and `bilby.core.get_sampler_class` (!1340)
- Add `bilby.core.utils.entry_points.get_entry_points` (!1340)
- Add support for reading results from PathLike objects (!1342)
- Add `snrs_as_sample` property to `bilby.gw.likelihood.base.GravitationalWaveTransient` (!1344)
- Add `get_expected_outputs` method to the sampler classes (!1336)
### Changed
- Change `bilby_mcmc` to use `glasflow` instead of `nflows` (!1332)
- Sampler classes in are no longer imported in `bilby.core.sampler` (!1340)
- Sampler classes in `bilby.core.sampler.IMPLEMENTED_SAMPLERS` must now be loaded before use (!1340)
- `bilby.core.sampler.IMPLEMENTED_SAMPLERS` is now an instance of `bilby.core.sampler.ImplementedSampler` instead of a dictionary (!1355)
- Updates to support numpy v2 (!1362)
### Fixed
- Include final frequency point in relative binning integration (!1310)
- Address various deprecation warnings and deprecated keyword arguments (!1316, !1326, !1343)
- Fix typo in logging statement in `bilby.gw.source` (!1325)
- Fix missing import in `bilby.gw.detector.load_data_from_cache_file` (!1327)
- Fix bug where `linestyle` was ignored in `bilby.core.result.plot_multiple` (!1238)
- Fix `soft_init` sampler keyword argument with `dynesty` (!1335)
- Fix ZeroDivisionError when using the `dynesty` with `act-walk` and large values of `nact` (!1346)
- Fix custom prior loading from result file (!1360)
## [2.2.3] - 2024-02-24
Version 2.2.3 release of Bilby
This is a bugfix release
......@@ -13,7 +47,7 @@ There are also a number of testing/infrastructure updates.
- Add the ability to change the pool size when resuming a `dynesty` job (!1315)
- Fix how the random seed is passed to `dynesty` (!1319)
## [2.2.2] 2023-11-29
## [2.2.2] - 2023-11-29
Version 2.2.2 release of Bilby
This is a bugfix release reverting a change from 2.2.1
......@@ -21,7 +55,7 @@ This is a bugfix release reverting a change from 2.2.1
### Changes
- Revert !1284 (!1306)
## [2.2.1] 2023-1111
## [2.2.1] - 2023-1111
Version 2.2.1 release of Bilby
This release is a bugfix release.
......@@ -36,7 +70,7 @@ This release is a bugfix release.
- A bug with saving lists that contain None (!1301)
- Preparatory fix an upcoming change in dynesty (!1302)
## [2.2.0] 2023-07-24
## [2.2.0] - 2023-07-24
Version 2.2.0 release of Bilby
This release contains one new feature and drops support for Python 3.8.
......@@ -56,7 +90,7 @@ This release contains one new feature and drops support for Python 3.8.
### Deprecated
- Drop support for py38 (!1277)
## [2.1.2] 2023-07-17
## [2.1.2] - 2023-07-17
Version 2.1.2 release of Bilby
This is a bugfix release.
......@@ -70,7 +104,7 @@ Where users have previously used `np.random.seed` they should now call
- Enable cosmological priors to be written/read in our plain text format (!1258)
- Allow posterior reweighting to be performed when changing the likelihood and the prior (!1260)
## [2.1.1] 2023-04-28
## [2.1.1] - 2023-04-28
Version 2.1.1 release of Bilby
Bugfix release
......@@ -80,7 +114,7 @@ Bugfix release
- Bugfix for Fisher matrix proposals in `bilby_mcmc` (!1251)
- Make the changes to the spline calibration backward compatible, 2.0.2 resume files can't be read with 2.1.0 (!1250)
## [2.1.0] 2023-04-12
## [2.1.0] - 2023-04-12
Version 2.1.0 release of Bilby
Minor feature improvements and bug fixes
......@@ -103,7 +137,7 @@ Minor feature improvements and bug fixes
### Deprecated
- Reading/writing ROQ weights to json (!1232)
## [2.0.2] 2023-03-21
## [2.0.2] - 2023-03-21
Version 2.0.2 release of Bilby
This is a bugfix release after the last major update.
......@@ -113,7 +147,7 @@ This is a bugfix release after the last major update.
- Fix to time calibration (!1234)
- Fix nessai sampling time (!1236)
## [2.0.1] 2023-03-13
## [2.0.1] - 2023-03-13
Version 2.0.1 release of Bilby
This is a bugfix release after the last major update.
......@@ -126,7 +160,7 @@ Users may notice changes in inferred binary neutron star masses after updating t
- Update value for the solar mass (!1229).
- Make `scikit-learn` an explicit dependence of `bilby[GW]` (!1230).
## [2.0.0] 2023-02-29
## [2.0.0] - 2023-02-29
Version 2.0.0 release of Bilby
This major version release has a significant change to the behaviour of the `dynesty` wrapper.
......@@ -152,7 +186,7 @@ There are also a number of bugfixes and some new features in sampling and GW uti
- Optimize ROQ waveform and calibration calls (!1216)
- Add different proposal distribution and MCMC length for `dynesty` (!1187, !1222)
## [1.4.1] 2022-12-07
## [1.4.1] - 2022-12-07
Version 1.4.1 release of Bilby
This is a bugfix release to address some minor issues identified after v1.4.0.
......@@ -166,7 +200,7 @@ This is a bugfix release to address some minor issues identified after v1.4.0.
- Make sure that all dumping pickle files is done safely (!1189)
- Make error catching for `dynesty` checkpointing more robust (!1190)
## [1.4.0] 2022-11-18
## [1.4.0] - 2022-11-18
Version 1.4.0 release of Bilby
The main changes in this release are support for more recent versions of `dynesty` (!1138)
......@@ -188,7 +222,7 @@ and `nessai` (!1161) and adding the
- Allow prior arguments read from a string to be functions (!1144)
- Support `dynesty>=1.1.0` (!1138)
## [1.3.0] 2022-10-23
## [1.3.0] - 2022-10-23
Version 1.3.0 release of Bilby
This release has a major change to a sampler interface, `pymc3` is no longer supported, users should switch to `pymc>=4`.
......@@ -212,7 +246,7 @@ This release also contains various documentation improvements.
- Fix issue when specifying distance and redshfit independently (!1154)
- Fix a bug in the storage of likelihood/prior samples for `bilby_mcmc` (!1156)
## [1.2.1] 2022-09-05
## [1.2.1] - 2022-09-05
Version 1.2.1 release of Bilby
This release contains a few bug fixes following 1.2.0.
......@@ -230,7 +264,7 @@ This release contains a few bug fixes following 1.2.0.
- Extend mass conversions to include source-frame parameters (!1131)
- Fix prior ranges for GW150914 example (!1129)
## [1.2.0] 2022-08-15
## [1.2.0] - 2022-08-15
Version 1.2.0 release of Bilby
This is the first release that drops support for `Python<3.8`.
......@@ -261,7 +295,7 @@ with multiprocessing.
- `bilby.core.utils.progress`
- Deepdish IO for `Result`, `Interferometer`, and `InterferometerList`
## [1.1.5] 2022-01-14
## [1.1.5] - 2022-01-14
Version 1.1.5 release of Bilby
### Added
......@@ -279,7 +313,7 @@ Version 1.1.5 release of Bilby
- Improvements to the multi-banded GWT likelihood (!1026)
- Improve meta data comparison (!1035)
## [1.1.4] 2021-10-08
## [1.1.4] - 2021-10-08
Version 1.1.4 release of bilby
### Added
......@@ -299,7 +333,7 @@ Version 1.1.4 release of bilby
- Typo fix in eart light crossing (!1003)
- Fix zero spin conversion (!1002)
## [1.1.3] 2021-07-02
## [1.1.3] - 2021-07-02
Version 1.1.3 release of bilby
### Added
......@@ -329,7 +363,7 @@ Version 1.1.3 release of bilby
- Restructured utils module into several submodules. API remains backwards compatible (!873)
- Changed number of default walks in `dynesty` from `10*self.ndim` to `100` (!961)
## [1.1.2] 2021-05-05
## [1.1.2] - 2021-05-05
Version 1.1.2 release of bilby
### Added
......@@ -359,13 +393,13 @@ Version 1.1.2 release of bilby
- Fixed issues with pickle saving and loading (!932)
- Fixed an issue with the `_base_roq_waveform` (!959)
## [1.1.1] 2021-03-16
## [1.1.1] - 2021-03-16
Version 1.1.1 release of bilby
### Changes
- Added `include requirements.txt` in `MANIFEST.in` to stop the pip installation from breaking
## [1.1.0] 2021-03-15
## [1.1.0] - 2021-03-15
Version 1.1.0 release of bilby
### Added
......@@ -404,7 +438,7 @@ Version 1.1.0 release of bilby
- Fixed the likelihood count in `dynesty` (!853)
- Changed the ordering of keyword arguments for the `Sine` and `Cosine` constructors (!892)
## [1.0.4] 2020-11-23
## [1.0.4] - 2020-11-23
Version 1.0.4 release of bilby
### Added
......@@ -413,7 +447,7 @@ Version 1.0.4 release of bilby
### Changes
- Fixed issue in the CI
## [1.0.3] 2020-10-23
## [1.0.3] - 2020-10-23
Version 1.0.3 release of bilby
......@@ -432,7 +466,7 @@ Version 1.0.3 release of bilby
- Typo fixes (!878, !887, !879)
- Minor bug fixes (!888)
## [1.0.2] 2020-09-14
## [1.0.2] - 2020-09-14
Version 1.0.2 release of bilby
......@@ -454,7 +488,7 @@ Version 1.0.2 release of bilby
- Clean up of code (!854)
- Various minor bug, test and plotting fixes (!859, !874, !872, !865)
## [1.0.1] 2020-08-29
## [1.0.1] - 2020-08-29
Version 1.0.1 release of bilby
......@@ -479,7 +513,7 @@ Version 1.0.1 release of bilby
- Various minor bug fixes and improvements to the documentation (!820)(!823)(!837)
- Various testing improvements (!833)(!847)(!855)(!852)
## [1.0.0] 2020-07-06
## [1.0.0] - 2020-07-06
Version 1.0 release of bilby
......@@ -1030,3 +1064,33 @@ First `pip` installable version https://pypi.org/project/BILBY/ .
### Removed
- All chainconsumer dependency as this was causing issues.
[Unreleased]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.3.0...master
[2.3.0]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.2.3...v2.3.0
[2.2.3]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.2.2...v2.2.3
[2.2.2]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.2.1...v2.2.2
[2.2.1]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.2.0...v2.2.1
[2.2.0]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.1.2...v2.2.0
[2.1.2]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.1.1...v2.1.2
[2.1.1]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.1.0...v2.1.1
[2.1.0]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.0.2...v2.1.0
[2.0.2]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.0.1...v2.0.2
[2.0.1]: https://git.ligo.org/lscsoft/bilby/-/compare/v2.0.0...v2.0.1
[2.0.0]: https://git.ligo.org/lscsoft/bilby/-/compare/v1.4.1...v2.0.0
[1.4.1]: https://git.ligo.org/lscsoft/bilby/-/compare/v1.4.0...v1.4.1
[1.4.0]: https://git.ligo.org/lscsoft/bilby/-/compare/1.3.0...v1.4.0
[1.3.0]: https://git.ligo.org/lscsoft/bilby/-/compare/1.2.1...1.3.0
[1.2.1]: https://git.ligo.org/lscsoft/bilby/-/compare/1.2.0...1.2.1
[1.2.0]: https://git.ligo.org/lscsoft/bilby/-/compare/1.1.5...1.2.0
[1.1.5]: https://git.ligo.org/lscsoft/bilby/-/compare/1.1.4...1.1.5
[1.1.4]: https://git.ligo.org/lscsoft/bilby/-/compare/1.1.2...1.1.4
[1.1.3]: https://git.ligo.org/lscsoft/bilby/-/compare/1.1.2...1.1.3
[1.1.2]: https://git.ligo.org/lscsoft/bilby/-/compare/1.1.1...1.1.2
[1.1.1]: https://git.ligo.org/lscsoft/bilby/-/compare/1.1.0...1.1.1
[1.1.0]: https://git.ligo.org/lscsoft/bilby/-/compare/1.0.4...1.1.0
[1.0.4]: https://git.ligo.org/lscsoft/bilby/-/compare/1.0.3...1.0.4
[1.0.3]: https://git.ligo.org/lscsoft/bilby/-/compare/1.0.2...1.0.3
[1.0.2]: https://git.ligo.org/lscsoft/bilby/-/compare/1.0.1...1.0.2
[1.0.1]: https://git.ligo.org/lscsoft/bilby/-/compare/1.0.0...1.0.1
[1.0.0]: https://git.ligo.org/lscsoft/bilby/-/compare/0.6.9...1.0.0
# Contributing to bilby
This is a short guide to contributing to bilby aimed at general LVC members who
This is a short guide to contributing to bilby aimed at general LVK members who
have some familiarity with python and git.
1. [Code of conduct](#code-of-conduct)
2. [Code style](#code-style)
3. [Code relevance](#code-relevance)
4. [Merge requests](#merge-requests)
5. [Typical workflow](#typical-workflow)
6. [Hints and tips](#hints-and-tips)
7. [Code overview](#code-overview)
3. [Automated Code Checking](#automated-code-checking)
4. [Unit Testing](#unit-testing)
5. [Code relevance](#code-relevance)
6. [Merge requests](#merge-requests)
7. [Typical workflow](#typical-workflow)
8. [Hints and tips](#hints-and-tips)
9. [Code overview](#code-overview)
## Code of Conduct
......@@ -17,7 +19,7 @@ have some familiarity with python and git.
Everyone participating in the bilby community, and in particular in our issue
tracker, merge requests, and chat channels, is expected to treat other people
with respect and follow the guidelines articulated in the [Python Community
Code of Conduct](https://www.python.org/psf/codeofconduct/).
Code of Conduct](https://www.python.org/psf/codeofconduct/). Furthermore, members of the LVK collaboration must follow the [LVK Code of Conduct](https://dcc.ligo.org/LIGO-M1900037/public).
## Code style
......@@ -46,8 +48,8 @@ def my_new_function(x, y, print=False):
```
3. Avoid inline comments unless necessary. Ideally, the code should make it obvious what is going on, if not the docstring, only in subtle cases use comments
4. Name variables sensibly. Avoid using single-letter variables, it is better to name something `power_spectral_density_array` than `psda`.
5. Don't repeat yourself. If code is repeated in multiple places, wrap it up into a function.
6. Add tests. The C.I. is there to do the work of "checking" the code, both now and into the future. Use it.
5. Don't repeat yourself. If code is repeated in multiple places, wrap it up into a function. This also helps with the writing of robust unit tests (see below).
## Automated code checking
......@@ -76,6 +78,50 @@ If you experience any issues with pre-commit, please ask for support on the
usual help channels.
## Unit Testing
Unit tests are an important part of code development, helping to minimize the number of undetected bugs which may be present in a merge request. They also greatly expedite the review of code, and can even help during the initial development if used properly. Accordingly, bilby requires unit testing for any changes with machine readable inputs and outputs (i.e. pretty much everything except plotting).
Unit testing is integrated into the CI/CD pipeline, and uses the builtin unittest package. Tests should be written into the `test/` directory which corresponds to their location within the package, such that, for example, a change to `bilby/gw/conversion.py` should go into `test/gw/conversion_test.py`. To run a single test locally, one may simply do `pytest /path/to/test TestClass.test_name`, whereas to run all the tests in a given test file one may omit the class and function.
For an example of what a test looks like, consider this test for the fft utils in bilby:
```
class TestFFT(unittest.TestCase):
def setUp(self):
self.sampling_frequency = 10
def tearDown(self):
del self.sampling_frequency
def test_nfft_sine_function(self):
injected_frequency = 2.7324
duration = 100
times = utils.create_time_series(self.sampling_frequency, duration)
time_domain_strain = np.sin(2 * np.pi * times * injected_frequency + 0.4)
frequency_domain_strain, frequencies = bilby.core.utils.nfft(
time_domain_strain, self.sampling_frequency
)
frequency_at_peak = frequencies[np.argmax(np.abs(frequency_domain_strain))]
self.assertAlmostEqual(injected_frequency, frequency_at_peak, places=1)
def test_nfft_infft(self):
time_domain_strain = np.random.normal(0, 1, 10)
frequency_domain_strain, _ = bilby.core.utils.nfft(
time_domain_strain, self.sampling_frequency
)
new_time_domain_strain = bilby.core.utils.infft(
frequency_domain_strain, self.sampling_frequency
)
self.assertTrue(np.allclose(time_domain_strain, new_time_domain_strain))
```
`setUp` and `tearDown` handle construction and deconstruction of the test, such that each of the other test functions may be run independently, in any order. The other two functions each make an intuitive test of the functionality of and fft/ifft function: that the fft of a sine wave should be a delta function, and that an ifft should be an inverse of an fft.
For more information on how to write effective tests, see [this guide](https://docs.python-guide.org/writing/tests/), and many others.
## Code relevance
The bilby code base is intended to be highly modular and flexible. We encourage
......@@ -153,7 +199,19 @@ $ git clone git@git.ligo.org:albert.einstein/bilby.git
```
replacing the SSH url to that of your fork. This will create a directory
`/bilby` containing a local copy of the code. From this directory, you can run
`/bilby` containing a local copy of the code.
It is strongly advised to perform development with a dedicated conda environment.
In depth instructions for creating a conda environment may be found at the relevant
[conda docs](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#activating-an-environment),
but for most purposes the commands
```bash
$ conda create -n my-environment-name python=3.X
$ conda activate my-environment-name
```
will produce the desired results. Once this is completed, one may proceed to the `/bilby` directory and run
```bash
$ pip install -e .
......@@ -202,8 +260,25 @@ $ git checkout -b my-new-feature lscsoft/master
### Step d) Hack away
1. Develop the changes you would like to introduce, using `git add` to add files with changes. Ideally commit small units of change often, rather than creating one large commit at the end, this will simplify review and make modifying any changes easier.
2. Commit the changes using `git commit`. This will prompt you for a commit message. Commit messages should be clear, identifying which code was changed, and why. Common practice (see e.g. [this blog](https://chris.beams.io/posts/git-commit/)) is to use a short summary line (<50 characters), followed by a blank line, then more information in longer lines.
3. Push your changes to the remote copy of your fork on git.ligo.org
2. Commit the changes using `git commit`. This will prompt you for a commit message. Commit messages should be clear, identifying which code was changed, and why. Bilby is adopting the use of scipy commit format, specified [here](https://docs.scipy.org/doc/scipy/dev/contributor/development_workflow.html#writing-the-commit-message). Commit messages take a standard format of `ACRONYM: Summary message` followed by a more detailed description. For example, an enhancement would look like:
```
ENH: Add my awesome new feature
This is a very cool change that makes parameter estimation run 10x faster by changing a single line.
```
Similarly a bugfix:
```
BUG: Fix type error in my_awesome_feature.py
Correct a typo at L1 of /bilby/my_awesome_feature.py which returned a dictionary instead of a string.
```
For more discussion of best practices, see e.g. [this blog](https://chris.beams.io/posts/git-commit/).
4. Push your changes to the remote copy of your fork on git.ligo.org
```bash
git push origin my-new-feature
......
|pipeline status| |coverage report| |pypi| |conda| |version|
=====
Bilby
Bilby development has moved to `GitHub <https://github.com/bilby-dev/bilby>`__!
=====
Please open any new issues or pull requests there. A full migration guide will be provided soon. Links below here may no longer be active.
====
A user-friendly Bayesian inference library.
Fulfilling all your Bayesian dreams.
......@@ -30,47 +32,7 @@ us directly. For advice on contributing, see `the contributing guide <https://gi
Citation guide
--------------
If you use :code:`bilby` in a scientific publication, please cite
* `Bilby: A user-friendly Bayesian inference library for gravitational-wave
astronomy
<https://ui.adsabs.harvard.edu/#abs/2018arXiv181102042A/abstract>`__
* `Bayesian inference for compact binary coalescences with BILBY: validation and application to the first LIGO-Virgo gravitational-wave transient catalogue <https://ui.adsabs.harvard.edu/abs/2020MNRAS.499.3295R/abstract>`__
The first of these papers introduces the software, while the second introduces advances in the sampling approaches and validation of the software.
If you use the :code:`bilby_mcmc` sampler, please additionally cite
* `BILBY-MCMC: an MCMC sampler for gravitational-wave inference <https://ui.adsabs.harvard.edu/abs/2021MNRAS.507.2037A/abstract>`__
Additionally, :code:`bilby` builds on a number of open-source packages. If you
make use of this functionality in your publications, we recommend you cite them
as requested in their associated documentation.
**Samplers**
* `dynesty <https://github.com/joshspeagle/dynesty>`__
* `nestle <https://github.com/kbarbary/nestle>`__
* `pymultinest <https://github.com/JohannesBuchner/PyMultiNest>`__
* `cpnest <https://github.com/johnveitch/cpnest>`__
* `emcee <https://github.com/dfm/emcee>`__
* `nessai <https://github.com/mj-will/nessai>`_
* `ptemcee <https://github.com/willvousden/ptemcee>`__
* `ptmcmcsampler <https://github.com/jellis18/PTMCMCSampler>`__
* `pypolychord <https://github.com/PolyChord/PolyChordLite>`__
* `PyMC3 <https://github.com/pymc-devs/pymc3>`_
**Gravitational-wave tools**
* `gwpy <https://github.com/gwpy/gwpy>`__
* `lalsuite <https://git.ligo.org/lscsoft/lalsuite>`__
* `astropy <https://github.com/astropy/astropy>`__
**Plotting**
* `corner <https://github.com/dfm/corner.py>`__ for generating corner plot
* `matplotlib <https://github.com/matplotlib/matplotlib>`__ for general plotting routines
Please refer to the `Acknowledging/citing bilby guide <https://lscsoft.docs.ligo.org/bilby/citing-bilby.html>`__.
.. |pipeline status| image:: https://git.ligo.org/lscsoft/bilby/badges/master/pipeline.svg
:target: https://git.ligo.org/lscsoft/bilby/commits/master
......
import torch
from nflows.distributions.normal import StandardNormal
from nflows.flows.base import Flow
from nflows.nn import nets as nets
from nflows.transforms import (
from glasflow.nflows.distributions.normal import StandardNormal
from glasflow.nflows.flows.base import Flow
from glasflow.nflows.nn import nets as nets
from glasflow.nflows.transforms import (
CompositeTransform,
MaskedAffineAutoregressiveTransform,
RandomPermutation,
)
from nflows.transforms.coupling import (
from glasflow.nflows.transforms.coupling import (
AdditiveCouplingTransform,
AffineCouplingTransform,
)
from nflows.transforms.normalization import BatchNorm
from glasflow.nflows.transforms.normalization import BatchNorm
from torch.nn import functional as F
# Turn off parallelism
......
......@@ -754,10 +754,10 @@ class NormalizingFlowProposal(DensityEstimateProposal):
@staticmethod
def check_dependencies(warn=True):
if importlib.util.find_spec("nflows") is None:
if importlib.util.find_spec("glasflow") is None:
if warn:
logger.warning(
"Unable to utilise NormalizingFlowProposal as nflows is not installed"
"Unable to utilise NormalizingFlowProposal as glasflow is not installed"
)
return False
else:
......
......@@ -127,6 +127,9 @@ class Bilby_MCMC(MCMCSampler):
initial_sample_dict: dict
A dictionary of the initial sample value. If incomplete, will overwrite
the initial_sample drawn using initial_sample_method.
normalize_prior: bool
When False, disables calculation of constraint normalization factor
during prior probability computation. Default value is True.
verbose: bool
Whether to print diagnostic output during the run.
......@@ -175,6 +178,7 @@ class Bilby_MCMC(MCMCSampler):
resume=True,
exit_code=130,
verbose=True,
normalize_prior=True,
**kwargs,
):
......@@ -194,6 +198,7 @@ class Bilby_MCMC(MCMCSampler):
self.kwargs["target_nsamples"] = self.kwargs["nsamples"]
self.L1steps = self.kwargs["L1steps"]
self.L2steps = self.kwargs["L2steps"]
self.normalize_prior = normalize_prior
self.pt_inputs = ParallelTemperingInputs(
**{key: self.kwargs[key] for key in ParallelTemperingInputs._fields}
)
......@@ -309,6 +314,7 @@ class Bilby_MCMC(MCMCSampler):
evidence_method=self.evidence_method,
initial_sample_method=self.initial_sample_method,
initial_sample_dict=self.initial_sample_dict,
normalize_prior=self.normalize_prior,
)
def get_setup_string(self):
......@@ -382,7 +388,9 @@ class Bilby_MCMC(MCMCSampler):
If true, resume file was successfully loaded, otherwise false
"""
if os.path.isfile(self.resume_file) is False:
if os.path.isfile(self.resume_file) is False or not os.path.getsize(
self.resume_file
):
return False
import dill
......@@ -547,6 +555,29 @@ class Bilby_MCMC(MCMCSampler):
all_samples=ptsampler.samples,
)
@classmethod
def get_expected_outputs(cls, outdir=None, label=None):
"""Get lists of the expected outputs directories and files.
These are used by :code:`bilby_pipe` when transferring files via HTCondor.
Parameters
----------
outdir : str
The output directory.
label : str
The label for the run.
Returns
-------
list
List of file names.
list
List of directory names. Will always be empty for bilby_mcmc.
"""
filenames = [os.path.join(outdir, f"{label}_resume.pickle")]
return filenames, []
class BilbyPTMCMCSampler(object):
def __init__(
......@@ -560,11 +591,13 @@ class BilbyPTMCMCSampler(object):
evidence_method,
initial_sample_method,
initial_sample_dict,
normalize_prior=True,
):
self.set_pt_inputs(pt_inputs)
self.use_ratio = use_ratio
self.initial_sample_method = initial_sample_method
self.initial_sample_dict = initial_sample_dict
self.normalize_prior = normalize_prior
self.setup_sampler_dictionary(convergence_inputs, proposal_cycle)
self.set_convergence_inputs(convergence_inputs)
self.pt_rejection_sample = pt_rejection_sample
......@@ -635,6 +668,7 @@ class BilbyPTMCMCSampler(object):
use_ratio=self.use_ratio,
initial_sample_method=self.initial_sample_method,
initial_sample_dict=self.initial_sample_dict,
normalize_prior=self.normalize_prior,
)
for Eindex in range(n)
]
......@@ -1129,12 +1163,13 @@ class BilbyMCMCSampler(object):
use_ratio=False,
initial_sample_method="prior",
initial_sample_dict=None,
normalize_prior=True,
):
self.beta = beta
self.Tindex = Tindex
self.Eindex = Eindex
self.use_ratio = use_ratio
self.normalize_prior = normalize_prior
self.parameters = _sampling_convenience_dump.priors.non_fixed_keys
self.ndim = len(self.parameters)
......@@ -1209,7 +1244,10 @@ class BilbyMCMCSampler(object):
return logl
def log_prior(self, sample):
return _sampling_convenience_dump.priors.ln_prob(sample.parameter_only_dict)
return _sampling_convenience_dump.priors.ln_prob(
sample.parameter_only_dict,
normalized=self.normalize_prior,
)
def accept_proposal(self, prop, proposal):
self.chain.append(prop)
......
......@@ -168,14 +168,14 @@ class Prior(object):
def cdf(self, val):
""" Generic method to calculate CDF, can be overwritten in subclass """
from scipy.integrate import cumtrapz
from scipy.integrate import cumulative_trapezoid
if np.any(np.isinf([self.minimum, self.maximum])):
raise ValueError(
"Unable to use the generic CDF calculation for priors with"
"infinite support")
x = np.linspace(self.minimum, self.maximum, 1000)
pdf = self.prob(x)
cdf = cumtrapz(pdf, x, initial=0)
cdf = cumulative_trapezoid(pdf, x, initial=0)
interp = interp1d(x, cdf, assume_sorted=True, bounds_error=False,
fill_value=(0, 1))
return interp(val)
......
......@@ -510,14 +510,14 @@ class PriorDict(dict):
sample: dict
Dictionary of the samples of which we want to have the probability of
kwargs:
The keyword arguments are passed directly to `np.product`
The keyword arguments are passed directly to `np.prod`
Returns
=======
float: Joint probability of all individual sample probabilities
"""
prob = np.product([self[key].prob(sample[key]) for key in sample], **kwargs)
prob = np.prod([self[key].prob(sample[key]) for key in sample], **kwargs)
return self.check_prob(sample, prob)
......@@ -537,7 +537,7 @@ class PriorDict(dict):
constrained_prob[keep] = prob[keep] * ratio
return constrained_prob
def ln_prob(self, sample, axis=None):
def ln_prob(self, sample, axis=None, normalized=True):
"""
Parameters
......@@ -546,6 +546,9 @@ class PriorDict(dict):
Dictionary of the samples of which to calculate the log probability
axis: None or int
Axis along which the summation is performed
normalized: bool
When False, disables calculation of constraint normalization factor
during prior probability computation. Default value is True.
Returns
=======
......@@ -554,10 +557,14 @@ class PriorDict(dict):
"""
ln_prob = np.sum([self[key].ln_prob(sample[key]) for key in sample], axis=axis)
return self.check_ln_prob(sample, ln_prob)
return self.check_ln_prob(sample, ln_prob,
normalized=normalized)
def check_ln_prob(self, sample, ln_prob):
ratio = self.normalize_constraint_factor(tuple(sample.keys()))
def check_ln_prob(self, sample, ln_prob, normalized=True):
if normalized:
ratio = self.normalize_constraint_factor(tuple(sample.keys()))
else:
ratio = 1
if np.all(np.isinf(ln_prob)):
return ln_prob
else:
......@@ -770,7 +777,7 @@ class ConditionalPriorDict(PriorDict):
sample: dict
Dictionary of the samples of which we want to have the probability of
kwargs:
The keyword arguments are passed directly to `np.product`
The keyword arguments are passed directly to `np.prod`
Returns
=======
......@@ -782,10 +789,10 @@ class ConditionalPriorDict(PriorDict):
self[key].prob(sample[key], **self.get_required_variables(key))
for key in sample
]
prob = np.product(res, **kwargs)
prob = np.prod(res, **kwargs)
return self.check_prob(sample, prob)
def ln_prob(self, sample, axis=None):
def ln_prob(self, sample, axis=None, normalized=True):
"""
Parameters
......@@ -794,6 +801,9 @@ class ConditionalPriorDict(PriorDict):
Dictionary of the samples of which we want to have the log probability of
axis: Union[None, int]
Axis along which the summation is performed
normalized: bool
When False, disables calculation of constraint normalization factor
during prior probability computation. Default value is True.
Returns
=======
......@@ -806,7 +816,8 @@ class ConditionalPriorDict(PriorDict):
for key in sample
]
ln_prob = np.sum(res, axis=axis)
return self.check_ln_prob(sample, ln_prob)
return self.check_ln_prob(sample, ln_prob,
normalized=normalized)
def cdf(self, sample):
self._prepare_evaluation(*zip(*sample.items()))
......
......@@ -162,11 +162,11 @@ class Interped(Prior):
self._initialize_attributes()
def _initialize_attributes(self):
from scipy.integrate import cumtrapz
from scipy.integrate import cumulative_trapezoid
if np.trapz(self._yy, self.xx) != 1:
logger.debug('Supplied PDF for {} is not normalised, normalising.'.format(self.name))
self._yy /= np.trapz(self._yy, self.xx)
self.YY = cumtrapz(self._yy, self.xx, initial=0)
self.YY = cumulative_trapezoid(self._yy, self.xx, initial=0)
# Need last element of cumulative distribution to be exactly one.
self.YY[-1] = 1
self.probability_density = interp1d(x=self.xx, y=self._yy, bounds_error=False, fill_value=0)
......
......@@ -69,7 +69,11 @@ def result_file_name(outdir, label, extension='json', gzip=False):
def _determine_file_name(filename, outdir, label, extension, gzip):
""" Helper method to determine the filename """
if filename is not None:
return filename
if isinstance(filename, os.PathLike):
# convert PathLike object to string
return str(filename)
else:
return filename
else:
if (outdir is None) and (label is None):
raise ValueError("No information given to load file")
......@@ -1795,7 +1799,7 @@ class ResultList(list):
if isinstance(result, Result):
super(ResultList, self).append(result)
elif isinstance(result, str):
elif isinstance(result, (str, os.PathLike)):
super(ResultList, self).append(read_in_result(result))
else:
raise TypeError("Could not append a non-Result type")
......@@ -2057,7 +2061,7 @@ def plot_multiple(results, filename=None, labels=None, colours=None,
hist_kwargs['color'] = c
hist_kwargs["linestyle"] = linestyle
kwargs["hist_kwargs"] = hist_kwargs
fig = result.plot_corner(fig=fig, save=False, color=c, contour_kwargs={"linestyle": linestyle}, **kwargs)
fig = result.plot_corner(fig=fig, save=False, color=c, contour_kwargs={"linestyles": linestyle}, **kwargs)
default_filename += '_{}'.format(result.label)
lines.append(mpllines.Line2D([0], [0], color=c, linestyle=linestyle))
default_labels.append(result.label)
......
......@@ -2,54 +2,129 @@ import datetime
import inspect
import sys
import bilby
from bilby.bilby_mcmc import Bilby_MCMC
from ..prior import DeltaFunction, PriorDict
from ..utils import command_line_args, env_package_list, loaded_modules_dict, logger
from ..utils import (
command_line_args,
env_package_list,
get_entry_points,
loaded_modules_dict,
logger,
)
from . import proposal
from .base_sampler import Sampler, SamplingMarginalisedParameterError
from .cpnest import Cpnest
from .dnest4 import DNest4
from .dynamic_dynesty import DynamicDynesty
from .dynesty import Dynesty
from .emcee import Emcee
from .fake_sampler import FakeSampler
from .kombine import Kombine
from .nessai import Nessai
from .nestle import Nestle
from .polychord import PyPolyChord
from .ptemcee import Ptemcee
from .ptmcmc import PTMCMCSampler
from .pymc import Pymc
from .pymultinest import Pymultinest
from .ultranest import Ultranest
from .zeus import Zeus
IMPLEMENTED_SAMPLERS = {
"bilby_mcmc": Bilby_MCMC,
"cpnest": Cpnest,
"dnest4": DNest4,
"dynamic_dynesty": DynamicDynesty,
"dynesty": Dynesty,
"emcee": Emcee,
"kombine": Kombine,
"nessai": Nessai,
"nestle": Nestle,
"ptemcee": Ptemcee,
"ptmcmcsampler": PTMCMCSampler,
"pymc": Pymc,
"pymultinest": Pymultinest,
"pypolychord": PyPolyChord,
"ultranest": Ultranest,
"zeus": Zeus,
"fake_sampler": FakeSampler,
}
class ImplementedSamplers:
"""Dictionary-like object that contains implemented samplers.
This class is singleton and only one instance can exist.
"""
_instance = None
_samplers = get_entry_points("bilby.samplers")
def keys(self):
"""Iterator of available samplers by name.
Reduces the list to its simplest. This includes removing the 'bilby.'
prefix from native samplers if a corresponding plugin is not available.
"""
keys = []
for key in self._samplers.keys():
name = key.replace("bilby.", "")
if name in self._samplers.keys():
keys.append(key)
else:
keys.append(name)
return iter(keys)
def values(self):
"""Iterator of sampler classes.
Note: the classes need to loaded using :code:`.load()` before being
called.
"""
return iter(self._samplers.values())
def items(self):
"""Iterator of tuples containing keys (sampler names) and classes.
Note: the classes need to loaded using :code:`.load()` before being
called.
"""
return iter(((k, v) for k, v in zip(self.keys(), self.values())))
def valid_keys(self):
"""All valid keys including bilby.<sampler name>."""
keys = set(self._samplers.keys())
return iter(keys.union({k.replace("bilby.", "") for k in keys}))
def __getitem__(self, key):
if key in self._samplers:
return self._samplers[key]
elif f"bilby.{key}" in self._samplers:
return self._samplers[f"bilby.{key}"]
else:
raise ValueError(
f"Sampler {key} is not implemented! "
f"Available samplers are: {list(self.keys())}"
)
def __contains__(self, value):
return value in self.valid_keys()
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
IMPLEMENTED_SAMPLERS = ImplementedSamplers()
def get_implemented_samplers():
"""Get a list of the names of the implemented samplers.
This includes natively supported samplers (e.g. dynesty) and any additional
samplers that are supported through the sampler plugins.
Returns
-------
list
The list of implemented samplers.
"""
return list(IMPLEMENTED_SAMPLERS.keys())
def get_sampler_class(sampler):
"""Get the class for a sampler from its name.
This includes natively supported samplers (e.g. dynesty) and any additional
samplers that are supported through the sampler plugins.
Parameters
----------
sampler : str
The name of the sampler.
Returns
-------
Sampler
The sampler class.
Raises
------
ValueError
Raised if the sampler is not implemented.
"""
return IMPLEMENTED_SAMPLERS[sampler.lower()].load()
if command_line_args.sampler_help:
sampler = command_line_args.sampler_help
if sampler in IMPLEMENTED_SAMPLERS:
sampler_class = IMPLEMENTED_SAMPLERS[sampler]
sampler_class = IMPLEMENTED_SAMPLERS[sampler].load()
print(f'Help for sampler "{sampler}":')
print(sampler_class.__doc__)
else:
......@@ -60,7 +135,7 @@ if command_line_args.sampler_help:
)
else:
print(f"Requested sampler {sampler} not implemented")
print(f"Available samplers = {IMPLEMENTED_SAMPLERS}")
print(f"Available samplers = {get_implemented_samplers()}")
sys.exit()
......@@ -185,24 +260,20 @@ def run_sampler(
if isinstance(sampler, Sampler):
pass
elif isinstance(sampler, str):
if sampler.lower() in IMPLEMENTED_SAMPLERS:
sampler_class = IMPLEMENTED_SAMPLERS[sampler.lower()]
sampler = sampler_class(
likelihood,
priors=priors,
outdir=outdir,
label=label,
injection_parameters=injection_parameters,
meta_data=meta_data,
use_ratio=use_ratio,
plot=plot,
result_class=result_class,
npool=npool,
**kwargs,
)
else:
print(IMPLEMENTED_SAMPLERS)
raise ValueError(f"Sampler {sampler} not yet implemented")
sampler_class = get_sampler_class(sampler)
sampler = sampler_class(
likelihood,
priors=priors,
outdir=outdir,
label=label,
injection_parameters=injection_parameters,
meta_data=meta_data,
use_ratio=use_ratio,
plot=plot,
result_class=result_class,
npool=npool,
**kwargs,
)
elif inspect.isclass(sampler):
sampler = sampler.__init__(
likelihood,
......@@ -219,7 +290,7 @@ def run_sampler(
else:
raise ValueError(
"Provided sampler should be a Sampler object or name of a known "
f"sampler: {', '.join(IMPLEMENTED_SAMPLERS.keys())}."
f"sampler: {get_implemented_samplers()}."
)
if sampler.cached_result:
......
......@@ -173,6 +173,13 @@ class Sampler(object):
Whether the implemented sampler exits hard (:code:`os._exit` rather
than :code:`sys.exit`). The latter can be escaped as :code:`SystemExit`.
The former cannot.
sampler_name : str
Name of the sampler. This is used when creating the output directory for
the sampler.
abbreviation : str
Abbreviated name of the sampler. Does not have to be specified in child
classes. If set to a value other than :code:`None`, this will be used
instead of :code:`sampler_name` when creating the output directory.
Raises
======
......@@ -187,6 +194,8 @@ class Sampler(object):
"""
sampler_name = "sampler"
abbreviation = None
default_kwargs = dict()
npool_equiv_kwargs = [
"npool",
......@@ -248,9 +257,10 @@ class Sampler(object):
self.exit_code = exit_code
self._log_likelihood_eval_time = np.nan
if not soft_init:
self._verify_parameters()
self._time_likelihood()
self._log_likelihood_eval_time = self._time_likelihood()
self._verify_use_ratio()
self.kwargs = kwargs
......@@ -433,6 +443,10 @@ class Sampler(object):
n_evaluations: int
The number of evaluations to estimate the evaluation time from
Returns
=======
log_likelihood_eval_time: float
The time (in s) it took for one likelihood evaluation
"""
t1 = datetime.datetime.now()
......@@ -442,15 +456,16 @@ class Sampler(object):
)[:, 0]
self.log_likelihood(theta)
total_time = (datetime.datetime.now() - t1).total_seconds()
self._log_likelihood_eval_time = total_time / n_evaluations
log_likelihood_eval_time = total_time / n_evaluations
if self._log_likelihood_eval_time == 0:
self._log_likelihood_eval_time = np.nan
if log_likelihood_eval_time == 0:
log_likelihood_eval_time = np.nan
logger.info("Unable to measure single likelihood time")
else:
logger.info(
f"Single likelihood evaluation took {self._log_likelihood_eval_time:.3e} s"
f"Single likelihood evaluation took {log_likelihood_eval_time:.3e} s"
)
return log_likelihood_eval_time
def _verify_use_ratio(self):
"""
......@@ -773,8 +788,37 @@ class Sampler(object):
def write_current_state(self):
raise NotImplementedError()
@classmethod
def get_expected_outputs(cls, outdir=None, label=None):
"""Get lists of the expected outputs directories and files.
These are used by :code:`bilby_pipe` when transferring files via HTCondor.
Both can be empty. Defaults to a single directory:
:code:`"{outdir}/{name}_{label}/"`, where :code:`name`
is :code:`abbreviation` if it is defined for the sampler class, otherwise
it defaults to :code:`sampler_name`.
Parameters
----------
outdir : str
The output directory.
label : str
The label for the run.
Returns
-------
list
List of file names.
list
List of directory names.
"""
name = cls.abbreviation or cls.sampler_name
dirname = os.path.join(outdir, f"{name}_{label}", "")
return [], [dirname]
class NestedSampler(Sampler):
sampler_name = "nested_sampler"
npoints_equiv_kwargs = [
"nlive",
"nlives",
......@@ -848,6 +892,7 @@ class NestedSampler(Sampler):
class MCMCSampler(Sampler):
sampler_name = "mcmc_sampler"
nwalkers_equiv_kwargs = ["nwalker", "nwalkers", "draws", "Niter"]
nburn_equiv_kwargs = ["burn", "nburn"]
......
......@@ -40,6 +40,7 @@ class Cpnest(NestedSampler):
"""
sampler_name = "cpnest"
default_kwargs = dict(
verbose=3,
nthreads=1,
......
......@@ -99,6 +99,7 @@ class DNest4(_TemporaryFileSamplerMixin, NestedSampler):
If True, prints information during run
"""
sampler_name = "d4nest"
default_kwargs = dict(
max_num_levels=20,
num_steps=500,
......
......@@ -14,6 +14,7 @@ class DynamicDynesty(Dynesty):
"""
external_sampler_name = "dynesty"
sampler_name = "dynamic_dynesty"
@property
def nlive(self):
......
......@@ -3,6 +3,7 @@ import inspect
import os
import sys
import time
import warnings
import numpy as np
from pandas import DataFrame
......@@ -151,6 +152,7 @@ class Dynesty(NestedSampler):
specified.
"""
sampler_name = "dynesty"
sampling_seed_key = "seed"
@property
......@@ -239,8 +241,12 @@ class Dynesty(NestedSampler):
self.nestcheck = nestcheck
if self.n_check_point is None:
self.n_check_point = max(
int(check_point_delta_t / self._log_likelihood_eval_time / 10), 10
self.n_check_point = (
10
if np.isnan(self._log_likelihood_eval_time)
else max(
int(check_point_delta_t / self._log_likelihood_eval_time / 10), 10
)
)
self.check_point_delta_t = check_point_delta_t
logger.info(f"Checkpoint every check_point_delta_t = {check_point_delta_t}s")
......@@ -295,6 +301,32 @@ class Dynesty(NestedSampler):
)
Sampler._verify_kwargs_against_default_kwargs(self)
@classmethod
def get_expected_outputs(cls, outdir=None, label=None):
"""Get lists of the expected outputs directories and files.
These are used by :code:`bilby_pipe` when transferring files via HTCondor.
Parameters
----------
outdir : str
The output directory.
label : str
The label for the run.
Returns
-------
list
List of file names.
list
List of directory names. Will always be empty for dynesty.
"""
filenames = []
for kind in ["resume", "dynesty"]:
filename = os.path.join(outdir, f"{label}_{kind}.pickle")
filenames.append(filename)
return filenames, []
def _print_func(
self,
results,
......@@ -646,12 +678,21 @@ class Dynesty(NestedSampler):
chain of nested samples within dynesty and have to be removed before
restarting the sampler.
"""
logger.debug("Running sampler with checkpointing")
old_ncall = self.sampler.ncall
sampler_kwargs = self.sampler_function_kwargs.copy()
warnings.filterwarnings(
"ignore",
message="The sampling was stopped short due to maxiter/maxcall limit*",
category=UserWarning,
module="dynesty.sampler",
)
while True:
self.finalize_sampler_kwargs(sampler_kwargs)
if getattr(self.sampler, "added_live", False):
self.sampler._remove_live_points()
self.sampler.run_nested(**sampler_kwargs)
if self.sampler.ncall == old_ncall:
break
......@@ -666,8 +707,8 @@ class Dynesty(NestedSampler):
if last_checkpoint_s > self.check_point_delta_t:
self.write_current_state()
self.plot_current_state()
if getattr(self.sampler, "added_live", False):
self.sampler._remove_live_points()
if getattr(self.sampler, "added_live", False):
self.sampler._remove_live_points()
self.sampler.run_nested(**sampler_kwargs)
self.write_current_state()
......@@ -705,7 +746,10 @@ class Dynesty(NestedSampler):
if os.path.isfile(self.resume_file):
logger.info(f"Reading resume file {self.resume_file}")
with open(self.resume_file, "rb") as file:
sampler = dill.load(file)
try:
sampler = dill.load(file)
except EOFError:
sampler = None
if not hasattr(sampler, "versions"):
logger.warning(
......
......@@ -300,6 +300,8 @@ class ACTTrackingRWalk:
)
reject += nfail
blob = {"accept": accept, "reject": reject, "scale": args.scale}
iact = int(np.ceil(self.act))
thin = self.thin * iact
if accept == 0:
logger.debug(
......@@ -314,11 +316,9 @@ class ACTTrackingRWalk:
"Unable to find a new point using walk: try increasing maxmcmc"
)
self._cache.append((current_u, current_v, logl, ncall, blob))
elif self.thin == -1:
elif (self.thin == -1) or (len(u_list) <= thin):
self._cache.append((current_u, current_v, logl, ncall, blob))
else:
iact = int(np.ceil(self.act))
thin = self.thin * iact
u_list = u_list[thin::thin]
v_list = v_list[thin::thin]
logl_list = logl_list[thin::thin]
......
import os
import shutil
from collections import namedtuple
from shutil import copyfile
import numpy as np
from packaging import version
......@@ -45,6 +44,7 @@ class Emcee(MCMCSampler):
"""
sampler_name = "emcee"
default_kwargs = dict(
nwalkers=500,
a=2,
......@@ -310,7 +310,11 @@ class Emcee(MCMCSampler):
"""
if hasattr(self, "_sampler"):
pass
elif self.resume and os.path.isfile(self.checkpoint_info.sampler_file):
elif (
self.resume
and os.path.isfile(self.checkpoint_info.sampler_file)
and os.path.getsize(self.checkpoint_info.sampler_file)
):
import dill
logger.info(
......@@ -328,16 +332,19 @@ class Emcee(MCMCSampler):
def write_chains_to_file(self, sample):
chain_file = self.checkpoint_info.chain_file
temp_chain_file = chain_file + ".temp"
if os.path.isfile(chain_file):
copyfile(chain_file, temp_chain_file)
if self.prerelease:
points = np.hstack([sample.coords, sample.blobs])
else:
points = np.hstack([sample[0], np.array(sample[3])])
with open(temp_chain_file, "a") as ff:
for ii, point in enumerate(points):
ff.write(self.checkpoint_info.chain_template.format(ii, *point))
shutil.move(temp_chain_file, chain_file)
data_to_write = "\n".join(
self.checkpoint_info.chain_template.format(ii, *point)
for ii, point in enumerate(points)
)
with open(temp_chain_file, "w") as ff:
ff.write(data_to_write)
with open(temp_chain_file, "rb") as ftemp, open(chain_file, "ab") as fchain:
shutil.copyfileobj(ftemp, fchain)
os.remove(temp_chain_file)
@property
def _previous_iterations(self):
......