Basic conversion formulas for Radioastronomy.
Copyright (C) 2012+ Axel Jessner (jessner@mpifr.de)
2015+ Benjamin Winkel (bwinkel@mpifr.de)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
%matplotlib inline
/home/bwinkel/local/anaconda3/lib/python3.5/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment. warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.') /home/bwinkel/local/anaconda3/lib/python3.5/site-packages/matplotlib/font_manager.py:273: UserWarning: Matplotlib is building the font cache using fc-list. This may take a moment. warnings.warn('Matplotlib is building the font cache using fc-list. This may take a moment.')
import matplotlib.pyplot as plt
import numpy as np
from astropy import units as u
from astropy import constants
from pycraf import conversions as cnv
For convenience, pycraf defines the often used log-scales and quantities
cnv.dimless # == u.Unit(1)
cnv.dB # == dBi = u.dB(dimless)
cnv.dB_W # == u.dB(u.W)
cnv.dB_W_Hz # == u.dB(u.W / u.Hz)
cnv.dB_W_m2 # == u.dB(u.W / u.m ** 2)
cnv.dB_W_m2_Hz # == u.dB(u.W / u.Hz / u.m ** 2)
cnv.dB_Jy_Hz # == u.dB(u.Jy * u.Hz)
cnv.dBm # == dB_mW = u.dB(u.mW)
cnv.dBm_MHz # == dB_mW_MHz = u.dB(u.mW / u.MHz)
cnv.dB_uV_m # == u.dB(u.uV ** 2 / u.m ** 2)
cnv.dB_1_m # == u.dB(1. / u.m) # for antenna factor
cnv.R0 # == 1. * (con.mu0 / con.eps0) ** 0.5
cnv.Erx_unit #= (1 * u.W / 4. / np.pi * R0) ** 0.5 / (1 * u.km)
print('R0 = {0.value:.3f} {0.unit}'.format(cnv.R0.to(u.ohm)))
print('Erx = {0.value:.3f} {0.unit}'.format(cnv.Erx_unit.to(cnv.dB_uV_m)))
R0 = 376.730 Ohm Erx = 74.768 dB(uV2 / m2)
Note, that mathematically, the $\mathrm{dB}_{\mathrm{\mu V / m}}$ scale operates on amplitude-squares, so for astropy we need to take this into account.
wavlen = 6 * u.cm
freq = constants.c / wavlen
print('f = {:.3f}'.format(freq.to(u.GHz)))
bandwidth = 500 * u.MHz
S_nu = 1 * u.Jy
Aeff = 3927 * u.m ** 2
S = S_nu * bandwidth
print('S = {:.3e} = {:.1f}'.format(
S.to(u.Watt / u.m ** 2), S.to(cnv.dB_W_m2)
))
Prx = S * Aeff
print('P_rx = {:.3e} = {:.1f}'.format(Prx.to(u.Watt), Prx.to(cnv.dBm)))
f = 4.997 GHz S = 5.000e-18 W / m2 = -173.0 dB(W / m2) P_rx = 1.964e-14 W = -107.1 dB(mW)
int_time = 1 * u.min
E = Prx * int_time
print('E = {:.3e} = {:.3e} = {:.3e}'.format(
E.to(u.Watt * u.h), E.to(u.picoWatt * u.h), E.to(u.Joule)
))
E = 3.273e-16 h W = 3.273e-04 h pW = 1.178e-12 J
int_time = 40 * u.year
S_nu = 40 * u.Jy
E = S_nu * bandwidth * Aeff * int_time
print('E = {:.3e}'.format(E.to(u.Joule)))
mass = 10 * u.g
print('E = {:.3e} = {:.3f}'.format(E.to(u.Watt * u.h), E.to(u.nanoWatt * u.h)))
def h_from_E(mass, E):
# E_pot = mass * height * g
return E / mass / constants.g0
print('h = {:.1f}'.format(h_from_E(mass, E).to(u.cm)))
E = 9.914e-04 J E = 2.754e-07 h W = 275.393 h nW h = 1.0 cm
dist = 384400 * u.km
Peirp = 2 * u.Watt
bandwidth = 200 * u.kHz
tdma_factor = 1 / 8
S = cnv.powerflux_from_ptx(tdma_factor * Peirp, dist, 0 * cnv.dBi)
S_nu = S / bandwidth
print('S_nu = {:.1f}'.format(S_nu.to(u.Jy)))
S_nu = 67.3 Jy
freq = 900 * u.MHz
wavelen = constants.c / freq
print('wave length = {:.1f}'.format(wavelen.to(u.cm)))
gain = 30 * cnv.dBi
Prx = cnv.prx_from_powerflux(S, freq, gain)
print('Prx = {:.3e} = {:.3f}'.format(Prx.to(u.W), Prx.to(cnv.dBm)))
wave length = 33.3 cm Prx = 1.189e-18 W = -149.249 dB(mW)
from pycraf import antenna
gain = antenna.ras_pattern(0 * u.deg, 1 * u.m, wavelen, eta_a=50 * u.percent)
print('Gmax = {:.1f}'.format(gain.to(cnv.dBi)))
Gmax = 16.5 dB
Prx = cnv.prx_from_powerflux(S, freq, gain)
print('Prx = {:.3e} = {:.3f}'.format(Prx.to(u.W), Prx.to(cnv.dBm)))
Prx = 5.287e-20 W = -162.768 dB(mW)
Tsys = 100 * u.K
chan_width = 5 * u.kHz
# calculate increase in antenna temperature (per spectral channel)
# induced by cell phone
Prx_nu = Prx / bandwidth
Tphone = cnv.t_a_from_prx_nu(Prx_nu)
print('T_A[phone] = {:.1f}'.format(Tphone.to(u.mK)))
T_A[phone] = 9.6 mK
# want a 5-sigma detection, i.e., need Tphone / Trms > 5
Trms = Tphone / 5
print('T_A[rms] = {:.1f}'.format(Trms.to(u.mK)))
T_A[rms] = 1.9 mK
# with the radiometer equation
# Trms = Tsys / sqrt(2 * tau * bandwidth) # factor 2 only if dual-polarization Rx
# we can calculate the necessary integration time:
tau = (Tsys / Trms) ** 2 / 2 / chan_width
print('Min. integration time, tau = {:.1f}'.format(tau.to(u.hour)))
Min. integration time, tau = 75.8 h
gain = antenna.ras_pattern(0 * u.deg, 100 * u.m, wavelen, eta_a=50 * u.percent)
print('Gmax = {:.1f}'.format(gain.to(cnv.dBi)))
Gmax = 56.5 dB
Let's use an alternative approach, just for fun.
A_eff = cnv.eff_area_from_gain(gain, freq)
print('A_eff = {:.1f}'.format(A_eff.to(u.m ** 2)))
A_eff = 3927.0 m2
Tphone = cnv.t_a_from_powerflux_nu(S_nu, A_eff)
Trms = Tphone / 5
print('T_A[phone] = {:.3f}'.format(Tphone.to(u.K)))
print('T_A[rms] = {:.3f}'.format(Trms.to(u.K)))
T_A[phone] = 95.737 K T_A[rms] = 19.147 K
tau = (Tsys / Trms) ** 2 / 2 / chan_width
print('Min. integration time, tau = {:.1f}'.format(tau.to(u.ms)))
Min. integration time, tau = 2.7 ms