Making changes to models and plotting using dependency injections
Several models and classes in redback
use dependency injections.
This enables users to easily swap some functionality with their own preferred method while keeping the rest of the infrastructure intact.
Modifying a model physics/Creating a new model
In models we discussed how to make changes to models with functions/classes already implemented in redback.
Here we show how to create your own modification to the physics and pass that into a redback model. We demonstrate this functionality with creating a new ejecta relation class, that provides a link from the intrinsic binary neutron star parameters to the properties of the ejecta.
from redback.ejecta_relations import calc_compactness_from_lambda
class I_made_this_relation_up(object):
"""
Relations to connect intrinsic GW parameters to extrinsic kilonova parameters
"""
def __init__(self, mass_1, mass_2, lambda_1, lambda_2):
self.mass_1 = mass_1
self.mass_2 = mass_2
self.lambda_1 = lambda_1
self.lambda_2 = lambda_2
self.reference = 'No, I really just made this up'
self.ejecta_mass = self.calculate_ejecta_mass
self.ejecta_velocity = self.calculate_ejecta_velocity
@property
def calculate_ejecta_velocity(self):
c1 = calc_compactness_from_lambda(self.lambda_1)
c2 = calc_compactness_from_lambda(self.lambda_2)
vej = 1000 * (self.mass_1 / self.mass_2) * (1 + 0.5) + 0.99 * (self.mass_2 / self.mass_1)
return vej
@property
def calculate_ejecta_mass(self):
c1 = calc_compactness_from_lambda(self.lambda_1)
c2 = calc_compactness_from_lambda(self.lambda_2)
log10_mej = self.mass_1 * (self.mass_2 / self.mass_1)**c1
mej = 10 ** log10_mej
return mej
We can now use the class above in the redback
one_component_ejecta_relation_model kilonova model
from redback.model_library import all_models_dict
import numpy as np
model = 'one_component_ejecta_relation_model'
function = all_models_dict(model)
time = np.logspace(2, 8, 100)/day_to_s
# create a kwargs dictionary for additional model parameters/ejecta relationship
kwargs = {}
# Pass in our class name, the class will be instantiated within the function.
kwargs['ejecta_relation'] = I_made_this_relation_up
kwargs['frequency'] = 2e14 # frequency to evaluate on
kwargs['temperature_floor'] = 4000 # minimum photosphere temperature
kwargs['output_format'] = flux_density # output format
flux_density = function(time, redshift=0.05, mass_1=1.4, mass_2=1.4,
lambda_1=400, lambda_2=400, kappa=3, **kwargs)
The above is just an example to create a new model by changing the relating the ejecta properties in a kilonova to the binary parameters. We can similarly create other functions/classes to change what cosmology is used, model engine, type of interaction process, photosphere, or SED.
Modifying plot_lightcurve
Similarly to how a user can modify a model, a user can also modify the plot_lightcurve and plot_multiband_lightcurve routines. We don’t really recommend this for aesthetic things as they can be simply passed to the existing function, but a user can do this if they want to.
Using your own cosmology
If a user works with a transient outside of the Hubble flow, redshift is not a useful measure of the distance. In such a case, the user could provide a known physical distance.
from astropy import units as u
from redback.util import user_cosmology
your_cosmology = user_cosmology()
your_cosmology.set_luminosity_distance(40*u.kpc)
# To use your cosmology in the fitting
model_kwargs = dict(cosmology = your_cosmology)