astro-brutus 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. astro_brutus-1.1.0/AUTHORS.md +12 -0
  2. astro_brutus-1.1.0/CHANGELOG.md +149 -0
  3. astro_brutus-1.1.0/LICENSE +21 -0
  4. astro_brutus-1.1.0/MANIFEST.in +26 -0
  5. astro_brutus-1.1.0/PKG-INFO +126 -0
  6. astro_brutus-1.1.0/README.md +65 -0
  7. astro_brutus-1.1.0/pyproject.toml +186 -0
  8. astro_brutus-1.1.0/setup.cfg +4 -0
  9. astro_brutus-1.1.0/src/astro_brutus.egg-info/PKG-INFO +126 -0
  10. astro_brutus-1.1.0/src/astro_brutus.egg-info/SOURCES.txt +52 -0
  11. astro_brutus-1.1.0/src/astro_brutus.egg-info/dependency_links.txt +1 -0
  12. astro_brutus-1.1.0/src/astro_brutus.egg-info/not-zip-safe +1 -0
  13. astro_brutus-1.1.0/src/astro_brutus.egg-info/requires.txt +32 -0
  14. astro_brutus-1.1.0/src/astro_brutus.egg-info/tmp774xmyh4 +97 -0
  15. astro_brutus-1.1.0/src/astro_brutus.egg-info/tmpckz_m4kz +97 -0
  16. astro_brutus-1.1.0/src/astro_brutus.egg-info/top_level.txt +1 -0
  17. astro_brutus-1.1.0/src/astro_brutus.egg-info/touch-test +0 -0
  18. astro_brutus-1.1.0/src/brutus/__init__.py +110 -0
  19. astro_brutus-1.1.0/src/brutus/analysis/__init__.py +51 -0
  20. astro_brutus-1.1.0/src/brutus/analysis/individual.py +2430 -0
  21. astro_brutus-1.1.0/src/brutus/analysis/los_dust.py +610 -0
  22. astro_brutus-1.1.0/src/brutus/analysis/offsets.py +676 -0
  23. astro_brutus-1.1.0/src/brutus/analysis/populations.py +879 -0
  24. astro_brutus-1.1.0/src/brutus/core/__init__.py +31 -0
  25. astro_brutus-1.1.0/src/brutus/core/grid_generation.py +644 -0
  26. astro_brutus-1.1.0/src/brutus/core/individual.py +1975 -0
  27. astro_brutus-1.1.0/src/brutus/core/neural_nets.py +542 -0
  28. astro_brutus-1.1.0/src/brutus/core/populations.py +900 -0
  29. astro_brutus-1.1.0/src/brutus/core/sed_utils.py +195 -0
  30. astro_brutus-1.1.0/src/brutus/data/__init__.py +36 -0
  31. astro_brutus-1.1.0/src/brutus/data/download.py +389 -0
  32. astro_brutus-1.1.0/src/brutus/data/filters.py +56 -0
  33. astro_brutus-1.1.0/src/brutus/data/loader.py +382 -0
  34. astro_brutus-1.1.0/src/brutus/dust/__init__.py +29 -0
  35. astro_brutus-1.1.0/src/brutus/dust/extinction.py +102 -0
  36. astro_brutus-1.1.0/src/brutus/dust/maps.py +369 -0
  37. astro_brutus-1.1.0/src/brutus/plotting/__init__.py +32 -0
  38. astro_brutus-1.1.0/src/brutus/plotting/binning.py +324 -0
  39. astro_brutus-1.1.0/src/brutus/plotting/corner.py +574 -0
  40. astro_brutus-1.1.0/src/brutus/plotting/distance.py +250 -0
  41. astro_brutus-1.1.0/src/brutus/plotting/offsets.py +543 -0
  42. astro_brutus-1.1.0/src/brutus/plotting/sed.py +192 -0
  43. astro_brutus-1.1.0/src/brutus/plotting/summary.py +227 -0
  44. astro_brutus-1.1.0/src/brutus/plotting/utils.py +310 -0
  45. astro_brutus-1.1.0/src/brutus/priors/PSMrLF_lnprior.dat +435 -0
  46. astro_brutus-1.1.0/src/brutus/priors/__init__.py +47 -0
  47. astro_brutus-1.1.0/src/brutus/priors/astrometric.py +226 -0
  48. astro_brutus-1.1.0/src/brutus/priors/extinction.py +178 -0
  49. astro_brutus-1.1.0/src/brutus/priors/galactic.py +943 -0
  50. astro_brutus-1.1.0/src/brutus/priors/stellar.py +275 -0
  51. astro_brutus-1.1.0/src/brutus/utils/__init__.py +54 -0
  52. astro_brutus-1.1.0/src/brutus/utils/math.py +630 -0
  53. astro_brutus-1.1.0/src/brutus/utils/photometry.py +541 -0
  54. astro_brutus-1.1.0/src/brutus/utils/sampling.py +451 -0
@@ -0,0 +1,12 @@
1
+ # Authors
2
+
3
+ - [Josh Speagle](https://github.com/joshspeagle)
4
+
5
+ Contributors:
6
+
7
+ - [Gus Beane](https://github.com/gusbeane)
8
+ - [Catherine Zucker](https://github.com/catherinezucker)
9
+ - [Phil Cargile](https://github.com/pacargile)
10
+ - [Greg Green](https://github.com/gregreen)
11
+ - [Ben Johnson](https://github.com/bd-j)
12
+ - [Eddie Schlafly](https://github.com/schlafly)
@@ -0,0 +1,149 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.1.0] - 2026-05-29
9
+
10
+ Maintenance and polish release: verified bug fixes (several affecting numerical
11
+ output on specific paths), documentation accuracy, test-suite hygiene, and
12
+ release-process improvements. All fixes ship with regression tests.
13
+
14
+ ### Fixed
15
+
16
+ - **`FastNN.encode` silent mis-scaling for 6-sample batches** *(affects output)*:
17
+ a 2-D input of shape `(6 params, 6 samples)` broadcast against the parameter
18
+ bounds without error and normalized along the wrong axis, producing silently
19
+ corrupted SEDs/bolometric corrections only when exactly 6 valid samples were
20
+ evaluated (reached via `StellarPop` synthesis). Now dispatches on input
21
+ dimensionality explicitly.
22
+ - **`los_dust` kernels collapsing per-object cloud means** *(affects output)*:
23
+ `kernel_gauss`/`kernel_lorentz`/`kernel_tophat` collapsed an array-valued mean
24
+ to a scalar, so line-of-sight fits using a reddening template (`template_reds`,
25
+ `additive_foreground`) evaluated every object against object 0's cloud mean.
26
+ Means are now kept broadcastable. The default uniform-cloud path is unchanged.
27
+ - **Binary companions no longer discard a valid primary SED** *(affects binary
28
+ grid generation)*: `StarEvolTrack.get_seds` returned an all-NaN combined SED
29
+ (dropping the valid primary) when the secondary's age could not be matched to
30
+ the unrealistically tight default tolerance. The default `tol` is relaxed
31
+ `1e-6 -> 1e-2` dex and a primary-only fallback is used when the companion does
32
+ not converge. *Regenerate binary (smf>0) grids to benefit; single-star fitting
33
+ and the shipped default grids are unaffected.*
34
+ - `load_offsets` no longer crashes on a single-filter offsets file.
35
+ - `logp_imf` no longer raises `ZeroDivisionError` for a power-law slope of
36
+ exactly 1.0 (flat-in-log); uses the logarithmic mass integral.
37
+ - `_fetch` (data download) removes a stale/broken symlink before re-linking and
38
+ falls back to a file copy on filesystems without symlink support.
39
+ - `BruteForce.logpost_grid` floors the Monte-Carlo sample count at 1 (a very
40
+ small `mem_lim` could drive it to 0 and crash).
41
+ - `BruteForce.loglike_grid` guards the dimensional-prior `log(Ndim)` term and
42
+ fails fast with a clear error on a fully-masked object (was an opaque
43
+ `ZeroDivisionError` deep in the optimizer).
44
+ - `cornerplot` no longer mutates a caller-supplied `labels` list in place.
45
+ - `dist_vs_red` uses `interpolation="none"` so binned PDF images show raw bins;
46
+ fixed a no-op smoothing guard in `hist2d`.
47
+ - Removed a dead `from scipy import polyfit` import (`scipy` has no top-level
48
+ `polyfit`; the code always used `numpy.polyfit`).
49
+
50
+ ### Changed
51
+
52
+ - **Python support**: dropped end-of-life Python 3.8 (`requires-python>=3.9`);
53
+ added 3.13 to the classifiers and tooling targets.
54
+ - **Dependencies**: raised the `numba` floor to `>=0.59.0` (the old 0.53 floor
55
+ predates `numpy>=1.22`/2.x support); `numpy` remains uncapped (the code is
56
+ numpy-2.0 clean, verified on 2.2).
57
+ - **Documentation engine**: standardized on a single NumPy-docstring processor
58
+ (`napoleon`); removed the redundant `numpydoc` extension. The docs now build
59
+ with zero warnings.
60
+ - **Tutorials**: standardized on the committed `Orion_l209.1_b-19.9` example
61
+ field; replaced chi2/Nbands quality cuts with goodness-of-fit p-values.
62
+
63
+ ### Documentation
64
+
65
+ - Corrected numerous stale code examples across the docs and docstrings to match
66
+ the real API (`StarGrid(models, labels)`, `get_seds` 3-tuple in magnitudes,
67
+ `magnitude(flux, err)`, `sample_multivariate_normal(size=)`, the prior call
68
+ signatures, `samps_dred`, the data cache path/env var, real filter names, and
69
+ the maggies flux convention).
70
+ - Added `summary_plot` to the API reference; documented `BruteForce.fit`'s
71
+ performance/accuracy parameters (`max_models`, `precision_shrinkage`,
72
+ `subsample_mode`, `R_solar`, `Z_solar`); reframed fit-quality guidance around
73
+ the p-value methodology.
74
+
75
+ ### Testing & packaging
76
+
77
+ - Added regression tests covering every fix above; reconciled the `conftest`
78
+ coverage guidance with what CI actually runs
79
+ (`NUMBA_DISABLE_JIT=1 pytest --cov`); the default `pytest` run no longer
80
+ enables coverage (which crashed on some WSL/DrvFs paths).
81
+ - Added a tag-triggered PyPI publish workflow (Trusted Publishing); fixed the
82
+ stale `MANIFEST.in` data-file path.
83
+
84
+ ## [1.0.0] - 2025-12-08
85
+
86
+ First stable release of brutus following code verification, testing, and documentation improvements.
87
+
88
+ ### Added
89
+
90
+ - **Documentation**: Scientific background pages, user guides, API documentation with examples, and ReadTheDocs hosting
91
+ - **Testing**: 92% code coverage, 606 tests, GitHub Actions CI/CD with Codecov integration
92
+ - **Code verification**: All functions verified for correctness; fixed IMF normalization bug, StarGrid distance reference, and other issues
93
+
94
+ ### Changed
95
+
96
+ - Development status updated to Production/Stable
97
+ - Added `tqdm` as formal dependency
98
+ - Enforced Black formatting across codebase
99
+
100
+ ## [0.9.0] - 2024-08-28
101
+
102
+ Major refactoring to improve usability and maintainability while preserving scientific functionality.
103
+
104
+ ### Added
105
+
106
+ - **Modern packaging**: Migrated to `pyproject.toml` with black, isort, flake8, mypy
107
+ - **Testing**: pytest framework with 100+ tests, coverage reporting, multi-platform CI
108
+ - **Modular architecture**: Split into `brutus.core`, `brutus.analysis`, `brutus.plotting`, `brutus.dust`, `brutus.utils`, `brutus.data`, `brutus.priors`
109
+ - **Performance**: Numba JIT compilation, vectorized operations, improved caching
110
+
111
+ ### Changed
112
+
113
+ - Minimum Python version: 3.8+ (dropped Python 2.7)
114
+ - Split large modules (`utils.py`, `plotting.py`) into focused submodules
115
+ - Updated all dependencies to modern versions
116
+
117
+ ### Fixed
118
+
119
+ - Windows/WSL compatibility documentation
120
+ - Circular imports and module loading issues
121
+ - Infinite loop bug in `hist2d` function
122
+
123
+ ### Migration
124
+
125
+ Update imports:
126
+
127
+ ```python
128
+ # Old
129
+ from brutus.seds import Isochrone
130
+ from brutus.fitting import BruteForce
131
+
132
+ # New
133
+ from brutus import Isochrone, BruteForce
134
+ # or
135
+ from brutus.core import Isochrone
136
+ from brutus.analysis import BruteForce
137
+ ```
138
+
139
+ All scientific algorithms, file formats, and core APIs remain unchanged.
140
+
141
+ ## [0.8.3] - Previous Release
142
+
143
+ Final release using old project structure and Python 2 compatibility.
144
+
145
+ Features: individual star fitting, cluster modeling, 3D dust mapping, MIST support, neural network SED prediction.
146
+
147
+ ---
148
+
149
+ For migration questions or bug reports, see the [issue tracker](https://github.com/joshspeagle/brutus/issues).
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2018 Josh Speagle
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,26 @@
1
+ # Include package metadata and documentation
2
+ include LICENSE
3
+ include README.md
4
+ include AUTHORS.md
5
+ include CHANGELOG.md
6
+ include pyproject.toml
7
+
8
+ # Include data files
9
+ include src/brutus/priors/PSMrLF_lnprior.dat
10
+
11
+ # Include package data recursively
12
+ recursive-include src/brutus *.dat *.txt *.h5
13
+
14
+ # Exclude development and build files
15
+ exclude setup.py.old
16
+ recursive-exclude * __pycache__
17
+ recursive-exclude * *.py[co]
18
+ recursive-exclude * *~
19
+ recursive-exclude * .git*
20
+ exclude .gitignore
21
+
22
+ # Exclude test files from distribution
23
+ recursive-exclude tests *
24
+ exclude tox.ini
25
+ exclude .travis.yml
26
+ exclude .github
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: astro-brutus
3
+ Version: 1.1.0
4
+ Summary: Brute-force Bayesian inference for photometric distances, reddenings, and stellar properties
5
+ Author-email: Joshua S Speagle <j.speagle@utoronto.ca>
6
+ Maintainer-email: Joshua S Speagle <j.speagle@utoronto.ca>
7
+ License: MIT
8
+ Project-URL: Homepage, https://github.com/joshspeagle/brutus
9
+ Project-URL: Repository, https://github.com/joshspeagle/brutus
10
+ Project-URL: Documentation, https://brutus.readthedocs.io
11
+ Project-URL: Bug Tracker, https://github.com/joshspeagle/brutus/issues
12
+ Keywords: brute force,photometry,bayesian,stellar,star,cluster,isochrone,dust,reddening,parallax,distance,template fitting
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Natural Language :: English
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Operating System :: POSIX :: Linux
23
+ Classifier: Operating System :: MacOS
24
+ Classifier: Operating System :: Microsoft :: Windows
25
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
26
+ Classifier: Intended Audience :: Science/Research
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ License-File: AUTHORS.md
31
+ Requires-Dist: numpy>=1.19
32
+ Requires-Dist: scipy>=1.6.0
33
+ Requires-Dist: matplotlib>=3.3.0
34
+ Requires-Dist: h5py>=3.0.0
35
+ Requires-Dist: healpy>=1.14.0
36
+ Requires-Dist: numba>=0.59.0
37
+ Requires-Dist: pooch>=1.4.0
38
+ Requires-Dist: tqdm>=4.50.0
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest>=6.0; extra == "dev"
41
+ Requires-Dist: pytest-cov>=2.10; extra == "dev"
42
+ Requires-Dist: black>=21.0; extra == "dev"
43
+ Requires-Dist: flake8>=3.8; extra == "dev"
44
+ Requires-Dist: isort>=5.0; extra == "dev"
45
+ Requires-Dist: mypy>=0.900; extra == "dev"
46
+ Provides-Extra: docs
47
+ Requires-Dist: sphinx>=6.0; extra == "docs"
48
+ Requires-Dist: sphinx-book-theme>=1.0.0; extra == "docs"
49
+ Requires-Dist: sphinx-design>=0.5.0; extra == "docs"
50
+ Requires-Dist: sphinx-copybutton>=0.5.0; extra == "docs"
51
+ Requires-Dist: numpydoc>=1.1; extra == "docs"
52
+ Requires-Dist: jupyter>=1.0; extra == "docs"
53
+ Requires-Dist: myst-nb>=1.0; extra == "docs"
54
+ Provides-Extra: test
55
+ Requires-Dist: pytest>=6.0; extra == "test"
56
+ Requires-Dist: pytest-cov>=2.10; extra == "test"
57
+ Requires-Dist: numpy; extra == "test"
58
+ Requires-Dist: scipy; extra == "test"
59
+ Requires-Dist: matplotlib; extra == "test"
60
+ Dynamic: license-file
61
+
62
+ # brutus
63
+
64
+ *Et tu, Brute?*
65
+
66
+ ![brutus logo](https://github.com/joshspeagle/brutus/blob/master/brutus_logo.png?raw=true)
67
+
68
+ [![Tests](https://github.com/joshspeagle/brutus/workflows/Tests/badge.svg)](https://github.com/joshspeagle/brutus/actions)
69
+ [![Coverage](https://codecov.io/gh/joshspeagle/brutus/branch/master/graph/badge.svg)](https://codecov.io/gh/joshspeagle/brutus)
70
+ [![Documentation Status](https://readthedocs.org/projects/brutus/badge/?version=latest)](https://brutus.readthedocs.io/en/latest/?badge=latest)
71
+ [![PyPI](https://img.shields.io/pypi/v/astro-brutus.svg)](https://pypi.org/project/astro-brutus/)
72
+ [![arXiv](https://img.shields.io/badge/arXiv-2503.02227-b31b1b.svg)](https://arxiv.org/abs/2503.02227)
73
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
74
+
75
+ `brutus` is a Python package for Bayesian inference of stellar properties, distances, and extinctions from photometry. It supports individual star fitting, cluster analysis, and 3D dust mapping.
76
+
77
+ **Documentation**: [brutus.readthedocs.io](https://brutus.readthedocs.io)
78
+
79
+ ## Installation
80
+
81
+ ```bash
82
+ pip install astro-brutus
83
+ ```
84
+
85
+ Requires Python 3.9+ on Linux, macOS, or Windows with WSL.
86
+
87
+ **Windows users**: Due to the `healpy` dependency, brutus requires WSL (Windows Subsystem for Linux) on Windows.
88
+
89
+ ### Development Install
90
+
91
+ ```bash
92
+ git clone https://github.com/joshspeagle/brutus.git
93
+ cd brutus
94
+ pip install -e ".[dev]"
95
+ ```
96
+
97
+ ## Data Files
98
+
99
+ Download required stellar models and dust maps:
100
+
101
+ ```python
102
+ from brutus import fetch_grids, fetch_isos, fetch_dustmaps
103
+
104
+ fetch_grids() # MIST stellar grids
105
+ fetch_isos() # MIST isochrones
106
+ fetch_dustmaps() # 3D dust maps
107
+ ```
108
+
109
+ Data files are also available from the [Harvard Dataverse](https://dataverse.harvard.edu/dataverse/astro-brutus).
110
+
111
+ ## Citation
112
+
113
+ If you use `brutus`, please cite [Speagle et al. (2025)](https://arxiv.org/abs/2503.02227).
114
+
115
+ ## License
116
+
117
+ MIT License. See [LICENSE](LICENSE) for details.
118
+
119
+ ## Contact
120
+
121
+ - Author: Joshua S. Speagle (<j.speagle@utoronto.ca>)
122
+ - Issues: [GitHub Issues](https://github.com/joshspeagle/brutus/issues)
123
+
124
+ ## Acknowledgments
125
+
126
+ `brutus` uses [MIST](http://waps.cfa.harvard.edu/MIST/) stellar evolution models and [Bayestar](https://argonaut.skymaps.info/) dust maps. We thank the developers for making their data publicly available.
@@ -0,0 +1,65 @@
1
+ # brutus
2
+
3
+ *Et tu, Brute?*
4
+
5
+ ![brutus logo](https://github.com/joshspeagle/brutus/blob/master/brutus_logo.png?raw=true)
6
+
7
+ [![Tests](https://github.com/joshspeagle/brutus/workflows/Tests/badge.svg)](https://github.com/joshspeagle/brutus/actions)
8
+ [![Coverage](https://codecov.io/gh/joshspeagle/brutus/branch/master/graph/badge.svg)](https://codecov.io/gh/joshspeagle/brutus)
9
+ [![Documentation Status](https://readthedocs.org/projects/brutus/badge/?version=latest)](https://brutus.readthedocs.io/en/latest/?badge=latest)
10
+ [![PyPI](https://img.shields.io/pypi/v/astro-brutus.svg)](https://pypi.org/project/astro-brutus/)
11
+ [![arXiv](https://img.shields.io/badge/arXiv-2503.02227-b31b1b.svg)](https://arxiv.org/abs/2503.02227)
12
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
13
+
14
+ `brutus` is a Python package for Bayesian inference of stellar properties, distances, and extinctions from photometry. It supports individual star fitting, cluster analysis, and 3D dust mapping.
15
+
16
+ **Documentation**: [brutus.readthedocs.io](https://brutus.readthedocs.io)
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install astro-brutus
22
+ ```
23
+
24
+ Requires Python 3.9+ on Linux, macOS, or Windows with WSL.
25
+
26
+ **Windows users**: Due to the `healpy` dependency, brutus requires WSL (Windows Subsystem for Linux) on Windows.
27
+
28
+ ### Development Install
29
+
30
+ ```bash
31
+ git clone https://github.com/joshspeagle/brutus.git
32
+ cd brutus
33
+ pip install -e ".[dev]"
34
+ ```
35
+
36
+ ## Data Files
37
+
38
+ Download required stellar models and dust maps:
39
+
40
+ ```python
41
+ from brutus import fetch_grids, fetch_isos, fetch_dustmaps
42
+
43
+ fetch_grids() # MIST stellar grids
44
+ fetch_isos() # MIST isochrones
45
+ fetch_dustmaps() # 3D dust maps
46
+ ```
47
+
48
+ Data files are also available from the [Harvard Dataverse](https://dataverse.harvard.edu/dataverse/astro-brutus).
49
+
50
+ ## Citation
51
+
52
+ If you use `brutus`, please cite [Speagle et al. (2025)](https://arxiv.org/abs/2503.02227).
53
+
54
+ ## License
55
+
56
+ MIT License. See [LICENSE](LICENSE) for details.
57
+
58
+ ## Contact
59
+
60
+ - Author: Joshua S. Speagle (<j.speagle@utoronto.ca>)
61
+ - Issues: [GitHub Issues](https://github.com/joshspeagle/brutus/issues)
62
+
63
+ ## Acknowledgments
64
+
65
+ `brutus` uses [MIST](http://waps.cfa.harvard.edu/MIST/) stellar evolution models and [Bayestar](https://argonaut.skymaps.info/) dust maps. We thank the developers for making their data publicly available.
@@ -0,0 +1,186 @@
1
+ [build-system]
2
+ requires = ["setuptools>=64", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "astro-brutus"
7
+ version = "1.1.0"
8
+ description = "Brute-force Bayesian inference for photometric distances, reddenings, and stellar properties"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ authors = [
12
+ {name = "Joshua S Speagle", email = "j.speagle@utoronto.ca"}
13
+ ]
14
+ maintainers = [
15
+ {name = "Joshua S Speagle", email = "j.speagle@utoronto.ca"}
16
+ ]
17
+ classifiers = [
18
+ "Development Status :: 5 - Production/Stable",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Natural Language :: English",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Operating System :: POSIX :: Linux",
28
+ "Operating System :: MacOS",
29
+ "Operating System :: Microsoft :: Windows",
30
+ "Topic :: Scientific/Engineering :: Astronomy",
31
+ "Intended Audience :: Science/Research",
32
+ ]
33
+ keywords = [
34
+ "brute force", "photometry", "bayesian", "stellar", "star",
35
+ "cluster", "isochrone", "dust", "reddening",
36
+ "parallax", "distance", "template fitting"
37
+ ]
38
+ requires-python = ">=3.9"
39
+ dependencies = [
40
+ "numpy>=1.19",
41
+ "scipy>=1.6.0",
42
+ "matplotlib>=3.3.0",
43
+ "h5py>=3.0.0",
44
+ "healpy>=1.14.0",
45
+ "numba>=0.59.0",
46
+ "pooch>=1.4.0",
47
+ "tqdm>=4.50.0",
48
+ ]
49
+ # dynamic = ["version"] # removed to avoid conflict with static 'version' field
50
+
51
+ [project.optional-dependencies]
52
+ dev = [
53
+ "pytest>=6.0",
54
+ "pytest-cov>=2.10",
55
+ "black>=21.0",
56
+ "flake8>=3.8",
57
+ "isort>=5.0",
58
+ "mypy>=0.900",
59
+ ]
60
+ docs = [
61
+ "sphinx>=6.0",
62
+ "sphinx-book-theme>=1.0.0",
63
+ "sphinx-design>=0.5.0",
64
+ "sphinx-copybutton>=0.5.0",
65
+ "numpydoc>=1.1",
66
+ "jupyter>=1.0",
67
+ "myst-nb>=1.0",
68
+ ]
69
+ test = [
70
+ "pytest>=6.0",
71
+ "pytest-cov>=2.10",
72
+ "numpy",
73
+ "scipy",
74
+ "matplotlib",
75
+ ]
76
+
77
+ [project.urls]
78
+ Homepage = "https://github.com/joshspeagle/brutus"
79
+ Repository = "https://github.com/joshspeagle/brutus"
80
+ Documentation = "https://brutus.readthedocs.io"
81
+ "Bug Tracker" = "https://github.com/joshspeagle/brutus/issues"
82
+
83
+ [tool.setuptools]
84
+ zip-safe = false
85
+ include-package-data = true
86
+
87
+ [tool.setuptools.packages.find]
88
+ where = ["src"]
89
+
90
+ [tool.setuptools.package-data]
91
+ "*" = ["*.dat", "*.txt", "*.md"]
92
+
93
+ # Development tools configuration
94
+ [tool.black]
95
+ line-length = 88
96
+ target-version = ['py39', 'py310', 'py311', 'py312', 'py313']
97
+ include = '\.pyi?$'
98
+ extend-exclude = '''
99
+ /(
100
+ # directories
101
+ \.eggs
102
+ | \.git
103
+ | \.hg
104
+ | \.mypy_cache
105
+ | \.tox
106
+ | \.venv
107
+ | build
108
+ | dist
109
+ )/
110
+ '''
111
+
112
+ [tool.isort]
113
+ profile = "black"
114
+ line_length = 88
115
+ multi_line_output = 3
116
+ include_trailing_comma = true
117
+ force_grid_wrap = 0
118
+ use_parentheses = true
119
+ ensure_newline_before_comments = true
120
+
121
+ [tool.pytest.ini_options]
122
+ minversion = "6.0"
123
+ # Coverage flags are intentionally NOT enabled by default. Writing the HTML
124
+ # coverage report fails on some filesystems (notably WSL/DrvFs, with
125
+ # "OSError: [Errno 22] Invalid argument" on htmlcov/*), which aborts every
126
+ # pytest invocation including --collect-only. Default runs therefore omit
127
+ # coverage; CI measures it explicitly (see .github/workflows/tests.yml):
128
+ # NUMBA_DISABLE_JIT=1 pytest tests/ --cov=brutus --cov-report=xml
129
+ # For a local coverage report, run that command yourself.
130
+ addopts = [
131
+ "--strict-markers",
132
+ "--strict-config",
133
+ ]
134
+ testpaths = ["tests"]
135
+ python_files = ["test_*.py"]
136
+ python_classes = ["Test*"]
137
+ python_functions = ["test_*"]
138
+ markers = [
139
+ "slow: marks tests as slow-running (deselect with '-m \"not slow\"')",
140
+ "requires_data: marks tests that need downloaded model data (they skip if absent)",
141
+ ]
142
+ filterwarnings = [
143
+ "error",
144
+ "ignore::UserWarning",
145
+ "ignore::DeprecationWarning",
146
+ ]
147
+ # Note: Set NUMBA_DISABLE_JIT=1 environment variable for accurate coverage
148
+ # of @jit/@njit decorated functions. Without this, numba-compiled functions
149
+ # will show 0% coverage even if executed by tests.
150
+
151
+ [tool.coverage.run]
152
+ source = ["src/brutus"]
153
+ omit = [
154
+ "*/tests/*",
155
+ "*/test_*",
156
+ "setup.py",
157
+ ]
158
+
159
+ [tool.coverage.report]
160
+ exclude_lines = [
161
+ "pragma: no cover",
162
+ "def __repr__",
163
+ "if self.debug:",
164
+ "if settings.DEBUG",
165
+ "raise AssertionError",
166
+ "raise NotImplementedError",
167
+ "if 0:",
168
+ 'if __name__ == "__main__":',
169
+ 'class .*\bProtocol\):',
170
+ '@(abc\.)?abstractmethod',
171
+ ]
172
+
173
+ [tool.mypy]
174
+ python_version = "3.9"
175
+ warn_return_any = true
176
+ warn_unused_configs = true
177
+ disallow_untyped_defs = false # Start lenient, tighten later
178
+ disallow_incomplete_defs = false
179
+ check_untyped_defs = true
180
+ disallow_untyped_decorators = false
181
+ no_implicit_optional = true
182
+ warn_redundant_casts = true
183
+ warn_unused_ignores = true
184
+ warn_no_return = true
185
+ warn_unreachable = true
186
+ strict_equality = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+