def integral_flux(self, emin=2.0, emax=8.0, t=None, erg=True): """Return the integral source flux at a generic time. This is achieved by taking a "slice" of the source spectrum at that time and integrating between a minimum and maximum energy. Arguments --------- emin : float The minimum integration energy (default 2 keV). emax : float The maximum integration energy (default 2 keV). t : float The time (default is the minimum source validity time). """ if t is None: t = self.min_validity_time _x = numpy.linspace(emin, emax, 100) _y = _x*self.energy_spectrum(_x, t) _flux = xInterpolatedUnivariateSplineLinear(_x, _y).integral(emin, emax) if erg: _flux = keV2erg(_flux) return _flux
def scale_flux(energy, flux, emin=2., emax=8.): ism_model = xpeInterstellarAbsorptionModel() ism_trans = ism_model.transmission_factor(GAL_NH) flux *= ism_trans(energy) norm = xInterpolatedUnivariateSplineLinear(energy,energy*flux).integral( emin, emax) norm = keV2erg(norm) scale_factor = FLUX/norm return flux*scale_factor
def mdp_table(self, column_density, index, exposure_time, eflux): """Return the MDP table for a point source with a power-law spectral shape with a given set of parameters and for a given observation time. There's a slight complication, here, due to the fact that the sensitivity calculator is rescaling the absorbed fluxes so that the input energy flux (in the web form) is that at the observer instead of that at the source. Therefore we need to do the same here. """ tsamples = numpy.linspace(0.0, exposure_time, 2) norm = int_eflux2pl_norm(eflux, self.emin, self.emax, index, erg=True) energy_spectrum = power_law(norm, index) ism_trans = self.ism_model.transmission_factor(column_density) _x = numpy.linspace(self.emin, self.emax, 1000) _y = _x * energy_spectrum(_x, 0.0) * ism_trans(_x) absorbed_energy_spectrum = xInterpolatedUnivariateSplineLinear(_x, _y) absorbed_eflux = keV2erg(absorbed_energy_spectrum.norm()) scale = eflux / absorbed_eflux count_spectrum = xCountSpectrum(energy_spectrum, self.aeff, tsamples, column_density, scale_factor=scale) mdp_table = count_spectrum.build_mdp_table(self.ebinning, self.modf) return mdp_table
Note that the normaliztion of the integral energy flux between 2 and 8 keV is provided into a separate file (see below) so that we need to integrate this to have the conversion factors. """ # Read in the file and create the spline. spectrum_file_path = _full_path("gk_per_spectrum_full.txt") _emin, _emax, _flux = numpy.loadtxt(spectrum_file_path, unpack=True) _e = numpy.sqrt(_emin * _emax) _fmt = dict(xname="Energy", xunits="keV", yname="Differential flux", yunits="cm$^{-2}$ s$^{-1}$ keV$^{-1}$") spectrum_spline = xInterpolatedUnivariateSplineLinear(_e, _flux, **_fmt) # And we need a spline for the energy flux as well, so that we can integrate it # and evaluate the average energy flux. This comes out around # 1.0214032297e-10 erg/s/cm2, so it's in the right ballpark---good. _fmt = dict(xname="Energy", xunits="keV", yname="Differential energy flux", yunits="cm$^{-2}$ s$^{-1}$") espectrum_spline = xInterpolatedUnivariateSplineLinear(_e, _e * _flux, **_fmt) average_eflux = keV2erg(espectrum_spline.integral(2.0, 8.0)) """Parse the phasogram file. This includes the integral energy flux between 2 and 8 keV, in erg cm^-2 s^-1 in 10 phase bins. Despite the fact that the input values are most likely the average fluxes within each phase bin, we just add 0.05 and consider them as the values at the bin center. In addition, in order not to have discontinuities at the boundaries, we set the values at 0 and 1 as the average values of the first and last point. We might want to be smarter in the long run, but this should be a sensible first step. """ phasogram_file_path = _full_path("gk_per_flux_2_8_keV_ph10.txt")