redback.multimessenger.MultiMessengerTransient

class redback.multimessenger.MultiMessengerTransient(optical_transient: Transient | None = None, xray_transient: Transient | None = None, radio_transient: Transient | None = None, uv_transient: Transient | None = None, infrared_transient: Transient | None = None, gw_likelihood: bilby.Likelihood | None = None, neutrino_likelihood: bilby.Likelihood | None = None, custom_likelihoods: Dict[str, bilby.Likelihood] | None = None, name: str = 'multimessenger_transient')[source]

Bases: object

Joint analysis of multiple messengers for transient events.

This class enables multi-messenger analysis by combining data from different observational channels (electromagnetic, gravitational wave, neutrino) and performing joint parameter estimation with shared physical parameters.

Examples

Basic usage for a kilonova + GRB afterglow analysis:

>>> import redback
>>> mm_transient = MultiMessengerTransient(
...     optical_transient=kilonova_transient,
...     xray_transient=xray_transient,
...     radio_transient=radio_transient
... )
>>> result = mm_transient.fit_joint(
...     models={'optical': 'two_component_kilonova_model',
...             'xray': 'tophat',
...             'radio': 'tophat'},
...     shared_params=['viewing_angle', 'luminosity_distance'],
...     model_kwargs={'optical': {'output_format': 'magnitude'},
...                   'xray': {'output_format': 'flux_density'},
...                   'radio': {'output_format': 'flux_density'}},
...     priors=priors
... )

Advanced usage with custom likelihoods and GW data:

>>> mm_transient = MultiMessengerTransient(
...     optical_transient=optical_lc,
...     gw_likelihood=gw_likelihood  # Pre-constructed bilby GW likelihood
... )
>>> result = mm_transient.fit_joint(
...     models={'optical': 'two_component_kilonova_model'},
...     shared_params=['viewing_angle', 'luminosity_distance'],
...     priors=priors
... )
__init__(optical_transient: Transient | None = None, xray_transient: Transient | None = None, radio_transient: Transient | None = None, uv_transient: Transient | None = None, infrared_transient: Transient | None = None, gw_likelihood: bilby.Likelihood | None = None, neutrino_likelihood: bilby.Likelihood | None = None, custom_likelihoods: Dict[str, bilby.Likelihood] | None = None, name: str = 'multimessenger_transient')[source]

Initialize a MultiMessengerTransient object.

Parameters:
  • optical_transient (redback.transient.Transient, optional) – Optical/NIR data as a Redback transient object

  • xray_transient (redback.transient.Transient, optional) – X-ray data as a Redback transient object

  • radio_transient (redback.transient.Transient, optional) – Radio data as a Redback transient object

  • uv_transient (redback.transient.Transient, optional) – UV data as a Redback transient object

  • infrared_transient (redback.transient.Transient, optional) – Infrared data as a Redback transient object

  • gw_likelihood (bilby.Likelihood, optional) – Pre-constructed gravitational wave likelihood (e.g., from bilby.gw)

  • neutrino_likelihood (bilby.Likelihood, optional) – Pre-constructed neutrino likelihood

  • custom_likelihoods (dict, optional) – Dictionary of custom likelihood objects with messenger names as keys

  • name (str, optional) – Name for this multi-messenger transient (default: ‘multimessenger_transient’)

__call__(**kwargs)

Call self as a function.

Methods

__init__([optical_transient, ...])

Initialize a MultiMessengerTransient object.

add_messenger(messenger_name[, transient, ...])

Add a new messenger to the analysis.

fit_individual(models, priors[, ...])

Fit each messenger independently (for comparison with joint analysis).

fit_joint(models, priors[, shared_params, ...])

Perform joint multi-messenger analysis.

remove_messenger(messenger_name)

Remove a messenger from the analysis.

add_messenger(messenger_name: str, transient: Transient | None = None, likelihood: bilby.Likelihood | None = None)[source]

Add a new messenger to the analysis.

Parameters:
  • messenger_name (str) – Name for the messenger

  • transient (redback.transient.Transient, optional) – Transient data object

  • likelihood (bilby.Likelihood, optional) – Pre-constructed likelihood object

Notes

Either transient or likelihood must be provided, but not both.

fit_individual(models: Dict[str, str | callable], priors: Dict[str, bilby.core.prior.PriorDict | dict], model_kwargs: Dict[str, Dict] | None = None, parameter_mappings: Dict[str, Dict[str, str]] | None = None, sampler: str = 'dynesty', nlive: int = 2000, walks: int = 200, outdir: str | None = None, resume: bool = True, plot: bool = True, **kwargs) Dict[str, RedbackResult][source]

Fit each messenger independently (for comparison with joint analysis).

Parameters:
  • models (dict) – Dictionary mapping messenger names to model names/functions

  • priors (dict) – Dictionary mapping messenger names to their prior distributions

  • model_kwargs (dict of dict, optional) – Dictionary mapping messenger names to their model keyword arguments

  • parameter_mappings (dict of dict, optional) – Dictionary mapping messenger names to parameter maps. Each map should map sampled parameter names to that messenger model’s native parameter names, matching fit_joint().

  • sampler (str, optional) – Sampler to use (default: ‘dynesty’)

  • nlive (int, optional) – Number of live points (default: 2000)

  • walks (int, optional) – Number of random walks (default: 200)

  • outdir (str, optional) – Output directory (default: ‘./outdir_individual’)

  • resume (bool, optional) – Whether to resume from checkpoint (default: True)

  • plot (bool, optional) – Whether to create plots (default: True)

  • **kwargs – Additional arguments for bilby.run_sampler

Returns:

Dictionary mapping messenger names to their individual fit results

Return type:

dict

Examples

>>> individual_results = mm_transient.fit_individual(
...     models={'optical': 'two_component_kilonova_model', 'xray': 'tophat'},
...     priors={'optical': optical_priors, 'xray': xray_priors}
... )
>>> optical_result = individual_results['optical']
fit_joint(models: Dict[str, str | callable], priors: bilby.core.prior.PriorDict | dict, shared_params: List[str] | None = None, model_kwargs: Dict[str, Dict] | None = None, likelihood_types: Dict[str, str] | None = None, parameter_mappings: Dict[str, Dict[str, str]] | None = None, sampler: str = 'dynesty', nlive: int = 2000, walks: int = 200, outdir: str | None = None, label: str | None = None, resume: bool = True, plot: bool = True, save_format: str = 'json', **kwargs) bilby.core.result.Result[source]

Perform joint multi-messenger analysis.

This method builds individual likelihoods for each messenger, combines them into a joint likelihood, and runs parameter estimation with the specified sampler.

Parameters:
  • models (dict) – Dictionary mapping messenger names to model names/functions. Example: {‘optical’: ‘two_component_kilonova_model’, ‘xray’: ‘tophat’}

  • priors (bilby.core.prior.PriorDict or dict) – Prior distributions for all parameters. For shared parameters, the same prior will be used across all messengers.

  • shared_params (list of str, optional) – List of parameter names that are shared across messengers. Example: [‘viewing_angle’, ‘luminosity_distance’, ‘time_of_merger’] If None, parameters are assumed independent unless they have the same name.

  • model_kwargs (dict of dict, optional) –

    Dictionary mapping messenger names to their model keyword arguments. Example: {‘optical’: {‘output_format’: ‘magnitude’},

    ’xray’: {‘output_format’: ‘flux_density’, ‘frequency’: freq_array}}

  • likelihood_types (dict of str, optional) – Dictionary mapping messenger names to likelihood types. Example: {‘optical’: ‘GaussianLikelihood’, ‘xray’: ‘GaussianLikelihoodQuadratureNoise’} Default: ‘GaussianLikelihood’ for all messengers

  • parameter_mappings (dict of dict, optional) – Dictionary mapping messenger names to parameter maps. Each map should map joint sampled parameter names to that messenger model’s native parameter names. Example: {‘xray’: {‘viewing_angle’: ‘thv’}}.

  • sampler (str, optional) – Sampler to use (default: ‘dynesty’). See bilby documentation for options.

  • nlive (int, optional) – Number of live points for nested sampling (default: 2000)

  • walks (int, optional) – Number of random walks for dynesty (default: 200)

  • outdir (str, optional) – Output directory for results (default: ‘./outdir_multimessenger’)

  • label (str, optional) – Label for output files (default: self.name)

  • resume (bool, optional) – Whether to resume from checkpoint if available (default: True)

  • plot (bool, optional) – Whether to create corner plots (default: True)

  • save_format (str, optional) – Format for saving results (default: ‘json’)

  • **kwargs – Additional keyword arguments passed to bilby.run_sampler

Returns:

Result object containing posterior samples and evidence

Return type:

bilby.core.result.Result

Notes

The joint likelihood is constructed as the product of individual messenger likelihoods: L_joint = L_optical × L_xray × L_radio × …

For shared parameters, the same parameter value is used across all relevant models, allowing the data from different messengers to jointly constrain these parameters.

Examples

>>> result = mm_transient.fit_joint(
...     models={'optical': 'two_component_kilonova_model',
...             'xray': 'tophat',
...             'radio': 'tophat'},
...     shared_params=['viewing_angle', 'luminosity_distance'],
...     priors=my_priors,
...     nlive=2000
... )
remove_messenger(messenger_name: str)[source]

Remove a messenger from the analysis.

Parameters:

messenger_name (str) – Name of the messenger to remove