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.
Pointing flux is defined as
→S=→E×→H.For a plane wave we find
S≡|→S|=√ε0μ0|→E|2=E2R0with
R0≡√ε0μ0=376.73 Ω.S is also known as the power flux density, and it is
S=GtxPtx4πd2=∫dνSν,the power per unit area from a transmitter with power Ptx and gain, Gtx, at distance, d. Sν is the flux density, which is often expressed in units of Jansky in radio astronomy. If a field strength, Erx, is observed originating from this transmitter we can thus calculate Ptx via
Ptx(Erx,d,Gtx)=4πd2GtxE2rxR0.Here, free-space propagation is assumed! Likewise, we can calculate Erx for a given transmitter power, Ptx,
Erx(Ptx,d,Gtx)=√PtxGtx4πR01d.Example:
Eunitrx≡Erx(1 W,1 km,1)=5.475⋅10−3 VmOne often uses logarithmic units for convenience (logx≡log10x):
dBm(P)=dBmW(P)≡dB[P[mW]]=10log(P[W])+30dBμV/m(E)≡dB[(E[μV/m])2]=20log(E[μV/m])dBW/m2(S)≡dB[S[W/m2]]=10log(S[W/m2])Example:
Eunitrx[dBμV/m]=74.768If a receiving station detects a certain field strengths (or power), the equivalent isotropically radiated power (EIRP) is the necessary transmitted power, Ptx if the transmitter gain, Gtx, was 0 dBi. The true transmitted power could have been much lower (higher), if the transmitter had positive (negative) gain (in dBi) towards the receiver.
Ptx[dBm]=dBm[4πd2GE2rxR0]=dB[(E[μV/m])2]+dB[(d[m])2]+dB[G]+dB[R0[mW/μV2]]=20log(E[μV/m])+20log(d[m])+10log(G)−74.8=20log(E[μV/m])+20log(d[km])+10log(G)−44.8Up to now, we only converted (transmitted) power to (received) field strength at a certain distance. However, usually an antenna is used to measure (the power of) the field strength. This is where things get frequency-dependent, as we will see now. The observed power flux density, S, from the transmitter creates a power, Prx, depending on the effective area of the receiver
Prx=S⋅Arxeff.One can show that independent of the antenna type
G(θ,ϕ)Aeff(θ,ϕ)=4πλ2.Hence,
Prx=S⋅Arxeff=S⋅Grxλ24π,i.e., the received power is dependent on frequency. From this, it also follows that
Prx=E2R0Grxλ24π.This seemingly counterintuitive behavior can also be understood with the following argument. Assume, both antenna gains are one, G=1=0 dBi (w.l.o.g). To receive a certain power with the given antenna area, i.e., receive power flux density, S, and as such have G=1, an antenna needs to get larger with larger wavelength, because
Aeff=Gλ24πCombining
Prx=S⋅Grxλ24π=S⋅Grxc24π1f2,and
S=GtxPtx4πd2,it directly follows that
PrxPtx=GtxGrx(λ4πd)2The last term is called free-space propagation loss
FSPL≡Prx[dBm]−Ptx[dBm]−Gtx[dB]−Grx[dB]=20log(λ4πd)=20log(14πdcf)=−dB[(d[km])2]−dB[(f[GHz])2]−92.4=−20log(d[km])−20log(f[GHz])−92.4Note, often one only quotes the absolute value of this as FSPL (as the name 'loss' is unambiguous).
Example:
FSPL(1 km,1 GHz)=−92.4 dBThe above equations can be combined in various ways (for convenience, we repeat some of the above). Superscript 'iso' is used if Grx=1 or Gtx=1, respectively
Prx[dBm]=Ptx[dBm]+Gtx[dB]+Grx[dB]+FSPLFSPL=−20log(d[km])−20log(f[GHz])−92.4Aperture efficiency, εa, is defined as εa≡AeffAgeom
Therefore, G≡G(0,0)=4πλ2εaAgeom.
The antenna temperature, TA is the temperature of a hypothetical resistor at the input of an ideal noise-free receiver that would generate the same output noise power per unit bandwidth as that at the antenna output at a specified frequency (from Wikipedia). Thus TA=Prx2kBΔν=Prx,ν2kB
Often, especially in radio astronomy, the "sensitivity", Γ, of an antenna is introduced as Γ=Aeff2kB.
Note, for "1-D" antennas, Ageom is not defined. However, one can assign an Aeff using the power-gain figure. From Wikipedia:
Wire antenna | Power gain | Effective area |
---|---|---|
Short dipole | 1.50 (1.76 dB) | 0.1194 λ2 |
Dipole antenna/Half-wave dipole | 1.64 (2.15 dB) | 0.1305 λ2 |
Monopole antenna/Quarter-wave monopole | 1.28 (1.07 dB) | 0.1025 λ2 |
From the HPBW, θ, of an antenna, one can estimate the gain
ΩBeam=4πGmax,withΩBeam=πθ2[rad]4ln2The power flux density (or received power) will increase the antenna temperature by
TA=Prx2kBΔf=AeffSν2kBwith Δf the bandwidth of the signal (assuming constant intensity within the bandwidth).
We can identify the sensitivity, Γ, (the Kelvins-per-Jansky): Γ≡TASν=Aeff2kB
This is another way to characterize an antenna, which allows easy conversion between E-field strength at the antenna, Eant≡Erx and induced voltage in the receiver, Urx:
KA=ErxUrxKA[dB1/m]=Erx[dBμV/m]−Urx[dBμV]The antenna factor can be related to the antenna gain via
KA=√4πGrxλ2R0Zibecause Prx=U2rxZi=E2R0Grxλ24π
with Zi being the Antenna impedance (at footpoint). Note, that receiver input impedance and antenna impedance at footpoint are not necessarily equal. One may have to apply a correction factor (especially for high Voltage Standing Wave Ratio, VSWR).
The pycraf package contains functions that implement the above equation. Making use of the astropy.units module, one can avoid many pitfalls related to the conversion between linear and logarithmic scales, etc.
%matplotlib inline
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 dBμV/m scale operates on amplitude-squares, so for astropy we need to take this into account.
Conversion between linear and logscale is easy (usually, only necessary for printing):
print('1 dBm = {0.value:.3f} {0.unit} = {1.value:.3f} {1.unit}'.format(
(1 * cnv.dBm).to(cnv.dB_W), (1 * cnv.dBm).to(u.W)
))
1 dBm = -29.000 dB(W) = 0.001 W
A_eff = 10 * u.m ** 2 # effective area
A_geom = 20 * u.m ** 2 # geometric area
eta_a = 50 * u.percent # antenna efficiency
print('A_eff = {0.value:.1f} {0.unit}'.format(cnv.eff_from_geom_area(A_geom, eta_a)))
print('A_geom = {0.value:.1f} {0.unit}'.format(cnv.geom_from_eff_area(A_eff, eta_a)))
A_eff = 10.0 m2 A_geom = 20.0 m2
frequency = 10 * u.GHz
gain = 60 * cnv.dBi
print('G = {0.value:.1f} {0.unit}'.format(cnv.gain_from_eff_area(A_eff, frequency)))
print('Aeff = {0.value:.1f} {0.unit}'.format(cnv.eff_area_from_gain(gain, frequency)))
G = 51.5 dB Aeff = 71.5 m2
S = 10 * u.Jy * u.MHz
E_rx = -30 * cnv.dB_uV_m
distance = 10 * u.km
G_tx = 20 * cnv.dBi
G_rx = 10 * cnv.dBi
P_rx = -10 * cnv.dBm
P_tx = 20 * cnv.dBm
print('E_rx = {0.value:.1f} {0.unit}'.format(cnv.efield_from_powerflux(S).to(cnv.dB_uV_m)))
print('S = {0.value:.1f} {0.unit}'.format(cnv.powerflux_from_efield(E_rx).to(cnv.dB_W_m2)))
E_rx = -44.2 dB(uV2 / m2) S = -175.8 dB(W / m2)
print('P_tx = {0.value:.1f} {0.unit}'.format(cnv.ptx_from_efield(E_rx, distance, G_tx).to(cnv.dB_W)))
print('E_rx = {0.value:.1f} {0.unit}'.format(cnv.efield_from_ptx(P_tx, distance, G_tx).to(cnv.dB_uV_m)))
P_tx = -104.8 dB(W) E_rx = 64.8 dB(uV2 / m2)
print('P_tx = {0.value:.1f} {0.unit}'.format(cnv.ptx_from_powerflux(S, distance, G_tx).to(cnv.dB_W)))
print('S = {0.value:.1f} {0.unit}'.format(cnv.powerflux_from_ptx(P_tx, distance, G_tx).to(cnv.dB_W_m2)))
P_tx = -119.0 dB(W) S = -81.0 dB(W / m2)
print('P_rx = {0.value:.1f} {0.unit}'.format(cnv.prx_from_powerflux(S, frequency, G_rx).to(cnv.dB_W)))
print('S = {0.value:.1f} {0.unit}'.format(cnv.powerflux_from_prx(P_rx, frequency, G_rx).to(cnv.dB_W_m2)))
P_rx = -221.5 dB(W) S = -8.5 dB(W / m2)
fspl = cnv.free_space_loss(distance, frequency)
print('FSPL = {0.value:.1f} {0.unit}'.format(fspl))
FSPL = -132.4 dB
print('P_rx = {0.value:.1f} {0.unit}'.format(
cnv.prx_from_ptx(P_tx, G_tx, G_rx, distance, frequency).to(cnv.dB_W)
))
print('P_tx = {0.value:.1f} {0.unit}'.format(
cnv.ptx_from_prx(P_rx, G_tx, G_rx, distance, frequency).to(cnv.dB_W)
))
P_rx = -112.4 dB(W) P_tx = 62.4 dB(W)
flux_0dbm_1km_iso = cnv.powerflux_from_ptx(0 * cnv.dBm, 1 * u.km, 0 * cnv.dBi)
print(
'Flux at 1 km distance for Ptx = 0 dBm, isotropic:\n'
'{0.value:.1f} {0.unit} = {1.value:.1f} {1.unit}\n'.format(
flux_0dbm_1km_iso.to(cnv.dB_W_m2),
flux_0dbm_1km_iso.to(cnv.dB_Jy_Hz)
)
)
prx_1W_m2_at1GHz_iso = cnv.prx_from_powerflux(1 * u.Watt / u.m ** 2, 1 * u.GHz, 0 * cnv.dBi)
print(
'Received power for a power flux density of 1 W / m^2 at 1 GHz, isotropic:\n'
'{0.value:.1f} {0.unit}\n'.format(
prx_1W_m2_at1GHz_iso.to(cnv.dBm)
)
)
prx_1JyHz_at1GHz_iso = cnv.prx_from_powerflux(1 * u.Jy * u.Hz, 1 * u.GHz, 0 * cnv.dBi)
print(
'Received power for a power flux density of 1 Jy.Hz at 1 GHz, isotropic:\n'
'{0.value:.1f} {0.unit}\n'.format(
prx_1JyHz_at1GHz_iso.to(cnv.dBm)
)
)
prx_0dbm_at1km1GHz_iso = cnv.prx_from_powerflux(
cnv.powerflux_from_ptx(0 * cnv.dBm, 1 * u.km, 0 * cnv.dBi),
1 * u.GHz, 0 * cnv.dBi
)
print(
'Power received from a 0 dBm transmitter at 1 km distance, at 1 GHz:\n'
'(both antennas isotropic)\n'
'{0.value:.1f} {0.unit}\n'.format(
prx_0dbm_at1km1GHz_iso.to(cnv.dBm)
)
)
Flux at 1 km distance for Ptx = 0 dBm, isotropic: -101.0 dB(W / m2) = 159.0 dB(Hz Jy) Received power for a power flux density of 1 W / m^2 at 1 GHz, isotropic: 8.5 dB(mW) Received power for a power flux density of 1 Jy.Hz at 1 GHz, isotropic: -251.5 dB(mW) Power received from a 0 dBm transmitter at 1 km distance, at 1 GHz: (both antennas isotropic) -92.4 dB(mW)
We can also check, if the convenience equations above are correct:
freq = 1 * u.GHz
dist = 1 * u.km
loss_1ghz_1km = cnv.free_space_loss(dist, freq)
print(
'Free-space loss at 1 km, 1 GHz: '
'{0.value:.1f} {0.unit}'.format(
loss_1ghz_1km
))
print(
'PFD from 1 dbm at 1 km distance: '
'{0.value:.1f} {0.unit} = {1.value:.1f} {1.unit}\n'.format(
cnv.powerflux_from_ptx(0 * cnv.dBm, 1 * u.km, 1. * cnv.dimless).to(cnv.dB_W_m2),
cnv.powerflux_from_ptx(0 * cnv.dBm, 1 * u.km, 1. * cnv.dimless).to(cnv.dB_Jy_Hz)
))
print(
'Prx from 1 W/m**2 at 1 GHz: {0.value:.1f} {0.unit}\n'.format(
cnv.prx_from_powerflux(0 * cnv.dB_W_m2, 1 * u.GHz, 1. * cnv.dimless).to(cnv.dBm)
))
print(
'Prx from 1 Jy*Hz at 1 GHz: {0.value:.1f} {0.unit}\n'.format(
cnv.prx_from_powerflux(0 * cnv.dB_Jy_Hz, 1 * u.GHz, 1. * cnv.dimless).to(cnv.dBm)
))
print('EIRP from 1 uV/m at 1 km distance: {0.value:.3f} {0.unit}\n'.format(
cnv.ptx_from_efield(0. * cnv.dB_uV_m, 1 * u.km, 1. * cnv.dimless).to(cnv.dBm)
))
print('Prx from 1 uV/m at 1 GHz: {0.value:.1f} {0.unit}\n'.format(
cnv.prx_from_ptx(
cnv.ptx_from_efield(0. * cnv.dB_uV_m, 1 * u.km, 0. * cnv.dBi),
0. * cnv.dBi, 0. * cnv.dBi, 1 * u.km, 1 * u.GHz
).to(cnv.dBm)))
Free-space loss at 1 km, 1 GHz: -92.4 dB PFD from 1 dbm at 1 km distance: -101.0 dB(W / m2) = 159.0 dB(Hz Jy) Prx from 1 W/m**2 at 1 GHz: 8.5 dB(mW) Prx from 1 Jy*Hz at 1 GHz: -251.5 dB(mW) EIRP from 1 uV/m at 1 km distance: -44.768 dB(mW) Prx from 1 uV/m at 1 GHz: -137.2 dB(mW)