"With four parameters I can fit an elephant, and with five I can make him wiggle his trunk."
- Attributed to John von Neumann
BayeSED3 is a general and sophisticated tool for the full Bayesian interpretation of spectral energy distributions (SEDs) of galaxies and AGNs. It performs Bayesian parameter estimation using posteriori probability distributions (PDFs) and Bayesian SED model comparison using Bayesian evidence. BayeSED3 supports various built-in SED models and can emulate other SED models using machine learning techniques.
- Explore the BayeSED3-AI Assistant 🚀 or
for interactive help and guidance!
- Multi-component SED synthesis and analysis of galaxies and AGNs
- Flexible stellar population synthesis modeling
- Flexible dust attenuation and emission modeling
- Flexible stellar and gas kinematics modeling
- Non-parametric and parametric star formation history options
- Comprehensive AGN component modeling (Accretion disk, BLR, NLR, Torus)
- Intergalactic medium (IGM) absorption modeling
- Handling of both photometric and spectroscopic data
- Bayesian parameter estimation and model comparison
- Machine learning techniques for SED model emulation
- Parallel processing support for improved performance
- User-friendly CLI, Python script and GUI interfaces
Platform support:
- Linux x86_64
- macOS (x86_64 and ARM64 via Rosetta 2)
- Windows (via WSL - uses Linux binaries)
1. Clone the repository:
git clone https://github.com/hanyk/BayeSED3.git
cd BayeSED32. Install OpenMPI 4.1.6 (required for all installation methods):
Via conda (recommended):
conda install -c conda-forge openmpi=4.1.6Via system package manager:
- Ubuntu/Debian:
sudo apt-get install openmpi-bin openmpi-common libopenmpi-dev - Fedora:
sudo dnf install openmpi openmpi-devel - macOS (Homebrew):
brew install openmpi
Or compile from source:
wget https://download.open-mpi.org/release/open-mpi/v4.1/openmpi-4.1.6.tar.gz
tar xzvf openmpi-4.1.6.tar.gz
cd openmpi-4.1.6
./configure --prefix=$PWD/../openmpi
make
make installNote: BayeSED3 automatically detects OpenMPI from conda, system, or local installation. If none is found, it will auto-compile OpenMPI 4.1.6.
System-level installation using pip - allows you to use BayeSED3 from any directory.
Prerequisites: Complete the Prerequisites section above.
Installation:
# Install BayeSED3 (run from repository root)
pip install . # Regular install (for production use)
pip install -e . # Editable install (for development - changes immediately visible)Uninstall:
pip uninstall bayesed3
# Dependencies (OpenMPI, matplotlib, etc.) stay installedNote:
- Regular install (
pip install .): Copies files to site-packages. Use for production. - Editable install (
pip install -e .): Links to source directory. Changes are immediately visible without reinstalling. Ideal for development.
System-level installation using conda - automatically handles all dependencies including OpenMPI. Note: BayeSED3 is not yet available on conda-forge. You must build it locally.
Prerequisites: Clone the repository (step 1 from Prerequisites). OpenMPI will be handled automatically by conda.
Installation:
# Build conda package from source (run from repository root)
conda build conda/
# Install the locally built package
conda install --use-local bayesed3Uninstall:
# Remove BayeSED3 (also removes dependencies like OpenMPI, matplotlib, etc.)
conda remove bayesed3
# Optional: Clean package cache
conda clean --packages -y
# Optional: Clean build cache (if you built it locally)
conda build purgeNote: BayeSED3 will be available on conda-forge in the future for easier installation.
HDF5 utilities (optional):
- Ubuntu/Debian:
sudo apt-get install h5utils - Fedora:
sudo dnf install hdf5-tools - macOS (with Homebrew):
brew install h5utils
tkinter (required for GUI):
- Ubuntu/Debian:
sudo apt-get install python3-tk - Fedora:
sudo dnf install python3-tkinter - macOS (with Homebrew):
brew install python-tk
- SDSS spectroscopic SED analysis
python tests/run_test.py gal plot python tests/run_test.py qso plot
- photometric SED analysis
python tests/run_test.py test1 plot python tests/run_test.py test2 plot
- mock CSST photometric and/or spectroscopic SED analysis
python tests/run_test.py test3 phot plot python tests/run_test.py test3 spec plot python tests/run_test.py test3 both plot
jupyter-notebook observation/agn_host_decomp/demo.ipynb
BayeSED3 provides a high-level Python interface for programmatic SED analysis. The interface simplifies configuration, data preparation, and result access while maintaining full access to all BayeSED3 capabilities.
Quick Start Examples:
from bayesed import BayeSEDInterface, BayeSEDParams, BayeSEDResults
# Initialize interface
bayesed = BayeSEDInterface(mpi_mode='auto')
# Simple galaxy fitting
params = BayeSEDParams.galaxy(
input_file='observation/test/gal.txt',
outdir='tests/output_quick_start',
ssp_model='bc2003_hr_stelib_chab_neb_2000r',
sfh_type='exponential',
dal_law='calzetti'
)
# Run analysis
result = bayesed.run(params)
# Load and analyze results
results = BayeSEDResults('tests/output_quick_start',catalog_name='gal')
results.print_summary()
# Access parameters and objects
free_params = results.get_free_parameters()
available_objects = results.list_objects()
# Load all parameters as astropy Table from HDF5 file
hdf5_table = results.load_hdf5_results()
# Built-in SNR filtering
high_snr_table = results.load_hdf5_results(filter_snr=True, min_snr=5.0)
# Access all statistical estimates for specific parameters
age_table = results.get_parameter_values('log(age/yr)[0,1]')
mass_table = results.get_parameter_values('log(Mstar)[0,1]')
custom_labels = {
# Free parameters
'log(age/yr)[0,1]': r'\log(age/\mathrm{yr})',
'log(tau/yr)[0,1]': r'\log(\tau/\mathrm{yr})',
'log(Z/Zsun)[0,1]': r'\log(Z/Z_\odot)',
'Av_2[0,1]': r'A_V',
# Derived parameters
'log(Mstar)[0,1]': r'\log(M_\star/M_\odot)',
'log(SFR_{100Myr}/[M_{sun}/yr])[0,1]': r'\log(\mathrm{SFR}/M_\odot\,\mathrm{yr}^{-1})'
}
results.set_parameter_labels(custom_labels)
results.plot_bestfit()
results.plot_posterior_free()
results.plot_posterior_derived(max_params=5)
results.plot_posterior(params=['log(age/yr)[0,1]', 'log(Z/Zsun)[0,1]', 'log(Mstar)[0,1]', 'log(SFR_{100Myr}/[M_{sun}/yr])[0,1]']) # Mixed free+derived parameters
# Object-level analysis
if available_objects:
object_id = available_objects[0]
object_results = BayeSEDResults('tests/output_quick_start', object_id=object_id,catalog_name='gal')
object_results.plot_bestfit()
object_results.set_parameter_labels(custom_labels)
object_results.plot_posterior_free()
object_results.plot_posterior_derived(max_params=5)
object_results.plot_posterior(params=['log(age/yr)[0,1]', 'log(Z/Zsun)[0,1]', 'log(Mstar)[0,1]', 'log(SFR_{100Myr}/[M_{sun}/yr])[0,1]']) # Mixed free+derived parametersAGN Fitting:
from bayesed import BayeSEDInterface, BayeSEDParams
# Initialize interface with Ntest for quick testing (optional)
bayesed = BayeSEDInterface(mpi_mode='auto', Ntest=2) # Process only first 2 objects
# AGN with all components (includes galaxy host)
params = BayeSEDParams.agn(
input_file='observation/test/qso.txt',
outdir='tests/output_agn_fitting',
ssp_model='bc2003_hr_stelib_chab_neb_2000r',
sfh_type='exponential',
dal_law='calzetti',
agn_components=['dsk', 'blr', 'nlr', 'feii'] # Disk, BLR, NLR, FeII
)
bayesed.run(params)BayeSED3 provides a powerful API for managing parameter priors programmatically without manually editing .iprior files.
Basic Usage:
from bayesed import SEDInference, BayeSEDParams
# Initialize and load priors
params = BayeSEDParams.galaxy(input_file='observation/test/gal.txt', outdir='tests/output_prior_management')
inference = SEDInference()
inference.priors_init(params)
# View and modify priors
inference.print_priors()
inference.set_prior('log(age/yr)', min_val=8.5, max_val=9.8, nbin=60)
# List all available prior types
inference.list_prior_types() # Shows: Uniform, Gaussian, Gamma, Beta, Student's t, Weibull, etc.
# Use different prior types (Uniform, Gaussian, Gamma, Beta, etc.)
inference.set_prior('log(age/yr)', prior_type='Gaussian',
min_val=8.0, max_val=12.0, hyperparameters=[10.0, 1.0])
# Regex patterns (with confirmation)
inference.set_prior('^Av_.*', prior_type='Gaussian', hyperparameters=[1.0, 0.3])
# Partial matching
inference.set_prior('age', min_val=8.0, max_val=10.0) # Matches 'log(age/yr)', etc.
# Query without modifying
inference.set_prior('age') # Shows all parameters containing 'age'
# Reset a single parameter to its default prior
inference.set_prior('log(age/yr)', reset_to_default=True)
# Reset multiple parameters using patterns
inference.set_prior('Av_.*', reset_to_default=True) # Reset all Av parametersimport numpy as np
import os
from bayesed import BayeSEDInterface, BayeSEDParams
from bayesed.data import SEDObservation
# Create observations from arrays (synthetic data for demonstration)
obs = SEDObservation(
ids=['galaxy_001', 'galaxy_002'],
z_min=[0.1, 0.2],
z_max=[0.15, 0.25],
phot_filters=['SLOAN/SDSS.g', 'SLOAN/SDSS.r', 'SLOAN/SDSS.i'],
phot_fluxes=np.array([[12.5, 25.1, 18.3], [15.2, 28.9, 22.1]]),
phot_errors=np.array([[1.2, 2.5, 1.8], [1.5, 2.9, 2.2]]),
input_type=0 # Flux in μJy
)
# Convert to BayeSED input format
os.makedirs('observation/demo_analysis', exist_ok=True)
input_file = obs.to_bayesed_input('observation/demo_analysis', 'demo_catalog')
# Download filters from SVO
bayesed = BayeSEDInterface()
filter_files = bayesed.prepare_filters_from_svo(
svo_filter_ids=['SLOAN/SDSS.g', 'SLOAN/SDSS.r', 'SLOAN/SDSS.i'],
output_dir='observation/demo_analysis/filters'
)
# Create and run analysis
params = BayeSEDParams.galaxy(
input_file=input_file,
outdir='tests/output_data_arrays',
filters=filter_files['filters_file'],
filters_selected=filter_files['filters_selected_file']
)
bayesed.run(params)from bayesed import BayeSEDInterface, BayeSEDParams
from bayesed.model import SEDModel
bayesed = BayeSEDInterface(mpi_mode='auto')
# Create galaxy instance with dust emission (using real data from observation/test2/)
galaxy = SEDModel.create_galaxy(
ssp_model='bc2003_lr_BaSeL_chab',
sfh_type='exponential',
dal_law='smc'
)
galaxy.add_dust_emission() # Add dust emission component
# Create AGN instance with torus
agn = SEDModel.create_agn(agn_components=['tor'])
# Assemble configuration using real data files
params = BayeSEDParams(
input_type=0, # Flux in μJy
input_file='observation/test2/test.txt',
outdir='tests/output_custom_model',
filters='observation/test2/filters.txt',
filters_selected='observation/test2/filters_selected.txt',
save_sample_par=True # Enable posterior sample generation
)
params.add_galaxy(galaxy)
params.add_agn(agn)
bayesed.run(params)from bayesed import BayeSEDInterface, BayeSEDParams, BayeSEDResults
from bayesed.results import standardize_parameter_names, plot_posterior_comparison
from bayesed.model import SEDModel
bayesed = BayeSEDInterface(mpi_mode='auto')
# Same input data, different models
input_file = 'observation/test/gal.txt'
# Model 1: Exponential SFH with Calzetti dust law
params1 = BayeSEDParams.galaxy(
input_file=input_file,
outdir='tests/output_model1_exp_calzetti',
ssp_model='bc2003_hr_stelib_chab_neb_2000r',
sfh_type='exponential',
dal_law='calzetti',
save_sample_par=True
)
bayesed.run(params1)
# Model 2: Delayed SFH with SMC dust law
params2 = BayeSEDParams.galaxy(
input_file=input_file,
outdir='tests/output_model2_delayed_smc',
ssp_model='bc2003_hr_stelib_chab_neb_2000r',
sfh_type='delayed',
dal_law='smc',
save_sample_par=True
)
bayesed.run(params2)
# Compare results for the same object with different models
results1 = BayeSEDResults('tests/output_model1_exp_calzetti')
results2 = BayeSEDResults('tests/output_model2_delayed_smc')
# Standardize parameter names across models for comparison
results_list = [results1, results2]
standardize_parameter_names(results_list)
# Create comparison plots showing how model choice affects parameter inference
plot_posterior_comparison(
results_list,
labels=['Exp+Calzetti', 'Delayed+SMC'],
output_file='model_comparison.png'
)
# Compare Bayesian evidence to determine which model is preferred
evidence1 = results1.get_evidence()
evidence2 = results2.get_evidence()
delta_logZ = evidence1['INSlogZ'] - evidence2['INSlogZ']
delta_logZ_err = (evidence1['INSlogZerr']**2 + evidence2['INSlogZerr']**2)**0.5Compute parameter correlations, statistics, and integrate with GetDist for advanced posterior analysis:
from bayesed import BayeSEDResults
# Load results with intelligent configuration detection
# Note: If multiple catalogs exist, specify catalog_name explicitly
results = BayeSEDResults('tests/output_quick_start',catalog_name='gal')
# Get available parameter names (with component IDs like [0,1])
free_params = results.get_free_parameters()
derived_params = results.get_derived_parameters()
# Example: ['z', 'log(age/yr)[0,1]', 'log(tau/yr)[0,1]', 'log(Z/Zsun)[0,1]', 'Av_2[0,1]', ...]
# Load HDF5 data with SNR filtering
hdf5_table = results.load_hdf5_results(filter_snr=True, min_snr=3.0)
# Compute parameter correlations (use actual parameter names with component IDs)
correlations = results.compute_parameter_correlations(['log(age/yr)[0,1]', 'log(Z/Zsun)[0,1]', 'Av_2[0,1]'])
# Get parameter statistics
stats = results.get_parameter_statistics(['log(age/yr)[0,1]', 'log(Z/Zsun)[0,1]', 'Av_2[0,1]'])
# Object-level analysis
objects = results.list_objects()
object_id = objects[0] # e.g., 'spec-0285-51930-0184_GALAXY_STARFORMING'
# GetDist integration with intelligent caching for custom posterior analysis
samples = results.get_getdist_samples(object_id=object_id)
samples.label = 'Galaxy Model'
# Use GetDist for advanced visualization and analysis
from getdist import plots
import matplotlib.pyplot as plt
g = plots.get_subplot_plotter()
g.triangle_plot([samples], ['log(age/yr)[0,1]', 'log(Z/Zsun)[0,1]', 'Av_2[0,1]'], filled=True)
plt.show()For more detailed documentation and advanced usage, see docs/BayeSED3.md.
Launch the GUI:
python bayesed_gui.py
The GUI provides an intuitive way to set up complex SED analysis scenarios with meaningful defaults.
bayesed/: Python package providing high-level interface to BayeSED3core.py: Main interface classes (BayeSEDInterface,BayeSEDParams,BayeSEDExecution)results/: Enhanced BayeSEDResults with intelligent scope management, 2-5x performance improvements, advanced plotting (plot_posterior_free,plot_posterior_derived,plot_bestfit), analytics (compute_parameter_correlations,get_parameter_statistics), and comprehensive error handlingmodel.py: Model configuration classes (SEDModel)data.py: Data handling classes (SEDObservation,PhotometryObservation,SpectrumObservation)params.py: Parameter configuration classesinference.py: Inference configuration (SEDInference)prior.py: Prior definitions (Prior)prior_manager.py: Prior management (PriorManager)utils.py: Utility functions for data preparation and filter managementplotting.py: Plotting functions for visualization
bayesed_gui.py: Graphical User Interface for BayeSED3pyproject.toml: Modern Python packaging configuration (dependencies and metadata)setup.py: Minimal setup for data files (pyproject.toml doesn't support data_files)tests/: Python interface examples and test scriptsrun_test.py: Examples using low-level Python interface (direct parameter construction)quick_start.py: Basic usage examples for high-level Python interfacetest_agn_fitting.py: Examples for AGN component fitting and analysistest_data_arrays.py: Working with data arrays and creating observations programmaticallytest_custom_model.py: Custom model configuration and advanced setuptest_multi_model_comparison.py: Comparing multiple models using Bayesian evidencetest_advanced_analytics.py: Advanced posterior analysis and GetDist integrationtest_bayesed_bagpipes_comparison.py: Comparison between BayeSED3 and BAGPIPES results
observation/test/: Contains test data and configuration filesbin/: Contains BayeSED3 executables for different platformsnets/: Contains Fast Artificial Neural Network (FANN) and Approximate K-Nearest Neighbors (AKNN) models for SED emulationmodels/: Template SED models (galaxy types, AGN components)filters/: Filter transmission curves (cigale, eazy-photoz)data/: Other data files used by BayeSED3 (extinction curves, emission line templates)docs/: Detailed documentationpapers/: Related publications in markdown formatconda/: Conda packaging scripts and configuration
- Linux: x86_64 architecture
- macOS: x86_64 architecture (ARM supported via Rosetta 2)
- Windows: Supported through Windows Subsystem for Linux (WSL)
This project is licensed under the MIT License. See the LICENSE file for details.
Issues and pull requests are welcome. Please make sure to update tests before submitting a pull request.
The further development of BayeSED needs your support. If BayeSED has been of benefit to you, either directly or indirectly, please consider citing our papers:
- Han, Y., & Han, Z. 2012, ApJ, 749, 123 — "Decoding Spectral Energy Distributions of Dust-obscured Starburst-Active Galactic Nucleus"
- Han, Y., & Han, Z. 2014, ApJS, 215, 2 — "BayeSED: A General Approach to Fitting the Spectral Energy Distribution of Galaxies"
- Han, Y., & Han, Z. 2019, ApJS, 240, 3 — "A Comprehensive Bayesian Discrimination of the Simple Stellar Population Model, Star Formation History, and Dust Attenuation Law in the Spectral Energy Distribution Modeling of Galaxies"
- Han, Y., Fan, L., Zheng, X. Z., Bai, J.-M., & Han, Z. 2023, ApJS, 269, 39 — "BayeSED-GALAXIES. I. Performance Test for Simultaneous Photometric Redshift and Stellar Population Parameter Estimation of Galaxies in the CSST Wide-field Multiband Imaging Survey"
- Han, Y., Zheng, X. Z., Yang, X., Wen, R., Liu, F. S., Zou, H., Bai, J.-M., Zhao, Y., Fan, L., Zhang, F., Kang, X., Li, X., Guo, H., Zhang, P., Zhan, H., Zhao, G.-B., Li, C., Gong, Y., Gu, Y., Shi, F., Zhou, X., Sui, J., Jing, Y., & Han, Z. 2026, ApJS, 283, 66 — "BayeSED-GALAXIES. II. Bayesian Full Spectrum Analysis of Galaxies and Application in the CSST Wide-field Slitless Spectroscopy Survey"
For more information about MultiNest, please refer to the README_multinest.txt file.








