====== Making changes to models and plotting using dependency injections ====== Several models and classes in :code:`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. .. code:: python 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 :code:`redback` `one_component_ejecta_relation_model` kilonova model .. code:: python 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. Note that redback also allows you to use a different cosmology object from astropy as well. For example, if you wanted to simply use a different cosmology object, you could do the following: .. code:: python from astropy.cosmology import FlatLambdaCDM your_cosmology = FlatLambdaCDM(H0=73, Om0=0.3) # To use your cosmology in the fitting, where model kwargs is the standard redback model kwargs dictionary model_kwargs = dict(cosmology = your_cosmology) If you don't want to deal with the astropy cosmology object, you can also use the UserCosmology class available in :code:`redback.utils` to create a cosmology object which always outputs a specific distance. Note, this requires you are using a new version of :code:`bilby` (>=2.5.0). .. code:: python from redback.utils import UserCosmology import astropy.units as uu dl = 200*uu.Mpc your_cosmology = UserCosmology() your_cosmology.set_luminosity_distance(dl) # To use your cosmology in the fitting, where model kwargs is the standard redback model kwargs dictionary model_kwargs = dict(cosmology = your_cosmology) Now if you use the result file from the fitting directly (i.e., within the same python session/notebook), then the cosmology will be set to the one you provided. However, if you are reading the result file in a different session, you will need the distance again via .. code:: python import astropy.units as uu result = redback.result.read_in_result('replace_with_your_file_path') result.model_kwargs['cosmology'].set_luminosity_distance(200*uu.Mpc)