-
Notifications
You must be signed in to change notification settings - Fork 1
Home
GRB Afterglow Lightcurve Calculator (GALC) is some code using the method outlined in Rossi et al. 2004. It calculates the afterglow lightcurve of GRB's of various initial conditions:
- A simple homogenous fireball with constant isotropic energy and initial lorentz factor across its face
- The so-called "gaussian" and "structured" fireballs outlined in Rossi.
- Fireballs of arbitrary energy and Lorentz distributions as functions of theta, which are read in from CSV files.
Every lightcurve is calculated in an instance of a galc.Lightcurve()
object. This object has a function, time_evolve
, which iterates through each timestep in the observer's frame, and calculates the following quantities (using Lightcurve.update_EATS_arr()
):
- The coordinates of the equal arrival time surface (EATS)
- The Lorentz factors, magnetic field, and frequencies across that surface
- The intensities and resulting luminosities of those frequencies.
In addition, there are several time-independent quantities which are calculated before the main time evolution (in Lightcurve.make_time_independent_arr()
). These are calculated on a grid of the radius and theta coordinates and include:
- The radius and theta coordinates of the fireball in its own center-of-mass frame.
- The distributions of energy and Lorentz factor as functions of theta.
- The Lorentz factor of the shock, the fraction of mass swept up at a given radius, and the laboratory time of each (r, th) bin.
The code then outputs luminosity data in units of erg/s for a given frequency in one column, and time in seconds in the other. Outside the Lightcurve object are functions to convert the data to flux/day, and to plot the data with matplotlib
.
A Lightcurve
object is initialized with the following parameters:
n_theta: int
the number of theta bins.
n_phi: int
the number of phi bins.
dt: float, default: 0.1
the log timestep. The observer time steps are determined by doing 10**(np.arange(start, end, dt)).
radius_range: tuple, default: (5.0, 20.0)
the log of the start and end radii of the fireball in cm. The radius is determined like above with 10**(np.arange(start, end, dr))
dr: float, default: 0.1
the log step between radii.
nu_obs: float
the observed frequency, in Hz
E_iso, G_0: float, str, numpy.ndarray
E_iso
and G_0
can be either:
-
A float specifying the isotropic equivalent energy and initial lorentz factor of the fireball for a homogenous, gaussian or structured case,
-
A string specifying the path to a data file containing the energy- or lorentz-factor-vs-theta data.
-
A numpy array with the energy- or lorentz-factor-vs-theta data.
The data in these files or arrays must be in two columns, the first specifying theta (in radians) and the second specifying energy or Lorentz distribution. If you specify an arbitrary energy and Lorentz distribution, you MUST also specify jet_type = 'numerical'
below.
It does not matter if n_theta
specified above matches the number of rows in these distributions. The distributions are just used to generate interpolation functions, so the code always generates n_theta
theta bins.
jet_type: str, default: homogenous
Type of jet to be simulated. Options include:
-
homogenous
: a spherically symmetric jet with simple, constant E_iso andG_0
-
gaussian
andstructured
: analytical energy and lorentz distributions, specified in Rossi. -
numerical
: If you specify an arbitrary energy distribution file, you MUST also set thejet_type
tonumerical
.
theta_j: float, default: 90
the jet opening angle, in degrees.
theta_obs: float, default:0
the observer angle, in degrees.
n_ism: float, default: 0.1
the interstellar medium number density, in cm^-3.
ee: float, default: 0.001
the electric field equipartition number
eB: float, default: 0.005
the magnetic field equipartition number
pel: float, default: 2.5
The electron acceleration slope
a_e, b_e, a_G, b_G, theta_c: floats, defaults: 2, 1, 1, 1, 90
parameters required to calculate the structured and gaussian jets as specified in Rossi. Ignored if jet_type
isn't structured or gaussian.
Note: there exist set_parameter
functions to dynamically change any of the above parameters. For example, say you define the following lightcurve object:
grblc = galc.Lightcurve(n_theta = 500,
n_phi = 500,
E_iso = 1e52,
G_0 = 1e4,
theta_obs = 0.)
and do some analysis before deciding you want to look at the same object from another angle. Then you would just do
grblc.set_theta_obs(45.)
and rerun the analysis. Similarly for set_E_iso
, set_nu_obs
, set_G_0
, set_n_ism
, etc...
There is an example of this in galc_examples.ipynb
in this GitHub repository.
To time evolve the object, you call the Lightcurve.time_evolve()
function. This takes two parameters, start_time and end_time, which are the log of the start and end of the integration, in days. time_evolve()
outputs the actual lightcurve luminosity data
When you have your data, there are two functions for converting the data to other units.
This function converts the luminosity output into Jy flux. It takes the parameters:
data: arr
This is just the second column of the output from time_evolve
.
z: float
This is the redshift of the GRB.
jy_data: arr
This is the output of get_Jy_flux()
This function will convert the data itself and return a matplotlib
plot of the lightcurve, in either Jy or AB units.
data: arr
This is the full 2-column output array from time_evolve
.
units: str
Either 'Jy' or 'AB'. Leaving this argument blank will plot it in erg/s/Hz.
z: float
The redshift of the GRB.
ax: matplotlib object
If left blank, the function will make its own plotting axis. Otherwise, you can pass it your own axis on which you plot other things.
**kwargs:
Any matplotlib
aesthetic parameters you want (linewidth, color, marker, etc...).