def duet_fluence_to_abmag(fluence, duet_no, duet=None, bandpass=None): """ Convert AB magnitude for a source into the number of source counts. Parameters ---------- fluence: float fluence in the bandpass that you're using in units (ph / cm2 / sec) duet_no: int, 1 or 2 DUET channel Other parameters ---------------- duet : `astroduet.config.Telescope` object if None, allocate a new Telescope object bandpass: array DUET bandpass you're using Returns ------- AB magnitude in the band (ABmag) Example ------- >>> funit = u.ph / u.cm**2/u.s >>> abmag = duet_fluence_to_abmag(0.01*funit, 1) >>> np.isclose(abmag.value, 18.54584301) True """ from astroduet.config import Telescope if duet is None: duet = Telescope() band = getattr(duet, f'band{duet_no}') spec = [1] * u.ph / (u.s * u.cm**2 * u.AA) wave = [band['eff_wave'].to(u.AA).value] * u.AA if bandpass is None: bandpass = band['eff_width'].to(u.AA) scale = (duet.apply_filters(wave, spec, duet_no)).value[0] fluence_corr = fluence / scale ABmag = (fluence_corr / bandpass).to(u.ABmag, equivalencies=u.spectral_density( band['eff_wave'].to(u.AA))) return ABmag
def duet_abmag_to_fluence(ABmag, duet_no, duet=None, bandpass=None): """ Convert AB magnitude for a source into the number of source counts. Parameters ---------- ABmag: float AB magnitude in the bandpass that you're using duet_no: int, 1 or 2 DUET channel Other parameters ---------------- duet : `astroduet.config.Telescope` object if None, allocate a new Telescope object bandpass: array DUET bandpass you're using Returns ------- Fluence in the band (ph / cm2 / sec) Example ------- >>> fluence = duet_abmag_to_fluence(20*u.ABmag, 1) >>> np.isclose(fluence.value, 0.00262022) True """ import numpy as np from astroduet.config import Telescope if duet is None: duet = Telescope() band = getattr(duet, f'band{duet_no}') spec = [1] * u.ph / (u.s * u.cm**2 * u.AA) wave = [band['eff_wave'].to(u.AA).value] * u.AA if bandpass is None: bandpass = band['eff_width'].to(u.AA) scale = (duet.apply_filters(wave, spec, duet_no)).value[0] funit = u.ph / u.cm**2 / u.s / u.AA # Spectral radiances per Hz or per angstrom fluence = bandpass * ABmag.to( funit, equivalencies=u.spectral_density(band['eff_wave'].to(u.AA))) return fluence * scale
def bb_abmag_fluence(val=False, duet=None, **kwargs): """ Take a blackbody with a certain temperature and convert to photon rate in a band. Other Parameters ---------------- val : boolean Retrurns AB mags without units (False, default) or with Astropy units duet: ``astroduet.conifg.Telescope() object`` If you've already instanced a duet telecope object, feed it in here. Currently allows the use of the default bandpasses. umag : float Must have astropy AB units Apparent U-band AB mag. Only used if other values not provided? siwftmag : float Must have astropy AB units. Apparent Swift magnitude (default is 22*u.ABmag) ref : string Band to use for reference magnitude; options are 'u', 'swift' ('swift') bbtemp : float Blackbody temperature to use (20000*ur.K) dist : float Distance of the source. swiftmags are assumed to be given at a reference distance of 10 pc (I think?) bolflux : float Bolometric flux; if not 1, refmag and distance are ignored. Should have units like (1*ur.erg/ur.cm**2/ur.s) diag : boolean SHow diagnostic inforamtion Returns ------- ABmag1, ABmag2 """ import astropy.units as ur import astropy.constants as cr from astropy.modeling import models from astropy.modeling.blackbody import FLAM import numpy as np from astroduet.config import Telescope if duet is None: duet = Telescope() bbtemp = kwargs.pop('bbtemp', 20000. * ur.K) umag = kwargs.pop('umag', 22 * ur.ABmag) swiftmag = kwargs.pop('swiftmag', 22 * ur.ABmag) dist = kwargs.pop('dist', 10 * ur.pc) ref = kwargs.pop('ref', 'swift') diag = kwargs.pop('diag', False) dist0 = 10 * ur.pc bolflux = kwargs.pop('bolflux', 1. * ur.erg / (ur.cm**2 * ur.s)) bandu = [340, 380] * ur.nm # For comparison purposes bandsw = [ 172.53, 233.57 ] * ur.nm # Swift UVW2 effective band (lambda_eff +/- 0.5 width_eff) wav = np.arange(1000, 9000) * ur.AA # Wavelength scale in 1 Angstrom steps bb = models.BlackBody1D( temperature=bbtemp, bolometric_flux=bolflux) # Load the blackbody model flux = bb(wav).to(FLAM, ur.spectral_density(wav)) # Get Swift reference AB mag fluxden_sw = np.mean(flux[(wav >= bandsw[0].to(ur.AA)) & (wav <= bandsw[1].to(ur.AA))]) magsw = fluxden_sw.to(ur.ABmag, equivalencies=ur.spectral_density(np.mean(bandsw))) # Conver to flux AB mags across the band. flux_ab = flux.to(ur.ABmag, equivalencies=ur.spectral_density(wav)) # Distance modulus distmod = (5 * np.log10(dist / dist0)).value * ur.mag # Set up input: magoff = swiftmag - magsw # Apply the distance modulus and the Swift reference offset if (bolflux == 1. * ur.erg / (ur.cm**2 * ur.s)): flux_mag = flux_ab + magoff + distmod else: flux_mag = flux_ab # Convert back to flux flux_conv = flux_mag.to(FLAM, equivalencies=ur.spectral_density(wav)) dw = 1 * ur.AA ph_energy = (cr.h.cgs * cr.c.cgs / wav.cgs) / ur.ph # Convert to photon flux. ph_flux = flux_conv * dw / ph_energy # Apply filters, QE, etc. band1_fluence = duet.apply_filters(wav, ph_flux, diag=diag, **kwargs).sum() band2_fluence = duet.apply_filters(wav, ph_flux, band=2, diag=diag, **kwargs).sum() if diag: print() print('Compute ABmags in TD bands for blackbody') print('Blackbody temperature: {}'.format(bbtemp)) print('Reference UVW2-band magnitude: {}'.format(swiftmag)) print('Distance: {} (Reference distance is 10 pc)'.format(dist)) print() print('Flux density Swift: {}'.format(fluxden_sw)) print('Distance modulus: {}'.format(distmod)) print('Raw ABmag Swift: {}'.format(magsw)) print('Offset from Swift band: {}'.format(magoff)) print('Fluence band one: {}'.format(band1_fluence)) print('Fluence band two: {}'.format(band2_fluence)) print('') if val: return band1_fluence.value, band2_fluence.value else: return band1_fluence, band2_fluence
def filter_parameters(duet=None, *args, **kwargs): """ Construct the effective central wavelength and the effective bandpass for the filters. Parameters ---------- Other parameters ---------------- vega : conditional, default False Use the Vega spetrum (9.8e3 K blackbody) to compute values. Otherwise computed "flat" values if quoting AB mags. diag : conditional, default False Show the diagnostic info on the parameters. Examples -------- >>> band1, band2 = filter_parameters() >>> allclose(band1['eff_wave'].value, 198.63858525) True """ from astroduet.config import Telescope if duet is None: duet = Telescope() from astropy.modeling import models from astropy.modeling.blackbody import FNU, FLAM from astropy import units as u import numpy as np vega = kwargs.pop('vega', False) diag = kwargs.pop('diag', False) wave = np.arange(1000, 10000) * u.AA if vega: temp = 9.8e3 * u.K bb = models.BlackBody1D(temperature=temp) flux = bb(wave).to(FLAM, u.spectral_density(wave)) else: flat_model = np.zeros_like(wave.value) flat_model += 1 flat_model *= FNU flux = flat_model.to(FLAM, u.spectral_density(wave)) band1 = duet.apply_filters(wave, flux, band=1, **kwargs) band2 = duet.apply_filters(wave, flux, band=2, **kwargs) λ_eff1 = ((band1 * wave).sum() / (band1.sum())).to(u.nm) λ_eff2 = ((band2 * wave).sum() / (band2.sum())).to(u.nm) dλ = wave[1] - wave[0] t1 = band1 / flux t2 = band2 / flux w1 = (dλ * t1.sum() / t1.max()).to(u.nm) w2 = (dλ * t2.sum() / t2.max()).to(u.nm) band1 = {'eff_wave': λ_eff1, 'eff_width': w1} band2 = {'eff_wave': λ_eff2, 'eff_width': w2} if diag: print('Band1: {0:0.2f} λ_eff, {1:0.2f} W_eff'.format(λ_eff1, w1)) print('Band2: {0:0.2f} λ_eff, {1:0.2f} W_eff'.format(λ_eff2, w2)) return band1, band2