This document describes a C++ program called CRadtran that calculates microwave radiance from the atmosphere. It presents the radiative transfer equation that models how intensity changes as light travels through atmospheric layers. The atmosphere is divided into thin slices where temperature, pressure, and attenuation are constant. The change in intensity is calculated for each slice using the radiative transfer equation, accounting for emission and absorption. Integrating the intensity changes across all slices allows determining the upwelling microwave radiance from the top of the atmosphere. This program improves on an older FORTRAN model by being more readable and usable.
International Journal of Computational Engineering Research (IJCER) is dedicated to protecting personal information and will make every reasonable effort to handle collected information appropriately. All information collected, as well as related requests, will be handled as carefully and efficiently as possible in accordance with IJCER standards for integrity and objectivity
P-Wave Onset Point Detection for Seismic Signal Using Bhattacharyya DistanceCSCJournals
In seismology Primary p-wave arrival identification is a fundamental problem for the geologist worldwide. Several numbers of algorithms that deal with p-wave onset detection and identification have already been proposed. Accurate p- wave picking is required for earthquake early warning system and determination of epicenter location etc. In this paper we have proposed a novel algorithm for p-wave detection using Bhattacharyya distance for seismic signals. In our study we have taken 50 numbers of real seismic signals (generated by earthquake) recorded by K-NET (Kyoshin network), Japan. Our results show maximum standard deviation of 1.76 sample from true picks which gives better accuracy with respect to ratio test method.
International Journal of Computational Engineering Research (IJCER) is dedicated to protecting personal information and will make every reasonable effort to handle collected information appropriately. All information collected, as well as related requests, will be handled as carefully and efficiently as possible in accordance with IJCER standards for integrity and objectivity
P-Wave Onset Point Detection for Seismic Signal Using Bhattacharyya DistanceCSCJournals
In seismology Primary p-wave arrival identification is a fundamental problem for the geologist worldwide. Several numbers of algorithms that deal with p-wave onset detection and identification have already been proposed. Accurate p- wave picking is required for earthquake early warning system and determination of epicenter location etc. In this paper we have proposed a novel algorithm for p-wave detection using Bhattacharyya distance for seismic signals. In our study we have taken 50 numbers of real seismic signals (generated by earthquake) recorded by K-NET (Kyoshin network), Japan. Our results show maximum standard deviation of 1.76 sample from true picks which gives better accuracy with respect to ratio test method.
Tomography is important for network design and routing optimization. Prior approaches require either
precise time synchronization or complex cooperation. Furthermore, active tomography consumes explicit
probing resulting in limited scalability. To address the first issue we propose a novel Delay Correlation
Estimation methodology named DCE with no need of synchronization and special cooperation. For the
second issue we develop a passive realization mechanism merely using regular data flow without explicit
bandwidth consumption. Extensive simulations in OMNeT++ are made to evaluate its accuracy where we
show that DCE measurement is highly identical with the true value. Also from test result we find that
mechanism of passive realization is able to achieve both regular data transmission and purpose of
tomography with excellent robustness versus different background traffic and package size.
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxySérgio Sacani
Pesquisa feita com dados do Hubble mostram ondas de choque em colisão dentro dos chamados jatos extragalácticos emitidos pelos buracos negros supermassivos.
PRML 9.1-9.2: K-means Clustering & Mixtures of GaussiansShinichi Tamura
The presentation material for the reading club of Pattern Recognition and Machine Learning by Bishop.
The contents of the sections cover
- K-Means Clustering and its application for Image Compression
- Introduction of Latent Variables
- Mixtures of Gaussians and its update using EM-algorithm
-------------------------------------------------------------------------
研究室でのBishop著『パターン認識と機械学習』(PRML)の輪講用発表資料(ぜんぶ英語)です。
担当範囲は
・K-meansクラスタリングとその画像圧縮への応用
・隠れ変数の導入
・混合ガウス分布とEMアルゴリズムによる更新
In this day and age of connected living, it is critical for people to interface the wellbeing factors and health conditions into trends so as to picturize the state of health of an individual. In addition, it is essential to include the wearables and therapeutic gears to viably speedup up the treatment cycle. It is equally important to pull health records and scanned images from various systems which follow different standards and ensure that they interact appropriately. These interactions could either be driven from the clinics and hospitals, or performed as a part of awareness by the end users (patients and health conscious individuals). To understand these interactions, we have taken Diabetes management as our use case. Diabetes is turning into a lifestyle disease and hence is an ideal candidate since we need to monitor the health conditions of the patient continuously. The vital parameters of the body could either be monitored through medical devices and equipment, body sensors, mobile applications, or wearables.This paper analyses the solutions proposed so far for effective diabetes management using cloud technology. The paper also touches upon IoT-based solutions which could be used to treat chronic ailments from remote locations.
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...Journal For Research
Against a backdrop of our world’s changing climate solar thermal power generation shows great potential to move global energy production away from fossil fuels to non-polluting sources. A parameter study was conducted based on the previous analysis to improve specific aspects of the initial design using a value of benefit analysis to evaluate the different design. This project focused on the design, analysis and verification of a high temperature solar receiver. Computational Fluid Dynamic (CFD) analysis of Radiation model is carried out with new geometry design of receiver. Discrete Transfer Radiation Model (DTRM) model is used for numerical simulation.
Tomography is important for network design and routing optimization. Prior approaches require either
precise time synchronization or complex cooperation. Furthermore, active tomography consumes explicit
probing resulting in limited scalability. To address the first issue we propose a novel Delay Correlation
Estimation methodology named DCE with no need of synchronization and special cooperation. For the
second issue we develop a passive realization mechanism merely using regular data flow without explicit
bandwidth consumption. Extensive simulations in OMNeT++ are made to evaluate its accuracy where we
show that DCE measurement is highly identical with the true value. Also from test result we find that
mechanism of passive realization is able to achieve both regular data transmission and purpose of
tomography with excellent robustness versus different background traffic and package size.
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxySérgio Sacani
Pesquisa feita com dados do Hubble mostram ondas de choque em colisão dentro dos chamados jatos extragalácticos emitidos pelos buracos negros supermassivos.
PRML 9.1-9.2: K-means Clustering & Mixtures of GaussiansShinichi Tamura
The presentation material for the reading club of Pattern Recognition and Machine Learning by Bishop.
The contents of the sections cover
- K-Means Clustering and its application for Image Compression
- Introduction of Latent Variables
- Mixtures of Gaussians and its update using EM-algorithm
-------------------------------------------------------------------------
研究室でのBishop著『パターン認識と機械学習』(PRML)の輪講用発表資料(ぜんぶ英語)です。
担当範囲は
・K-meansクラスタリングとその画像圧縮への応用
・隠れ変数の導入
・混合ガウス分布とEMアルゴリズムによる更新
In this day and age of connected living, it is critical for people to interface the wellbeing factors and health conditions into trends so as to picturize the state of health of an individual. In addition, it is essential to include the wearables and therapeutic gears to viably speedup up the treatment cycle. It is equally important to pull health records and scanned images from various systems which follow different standards and ensure that they interact appropriately. These interactions could either be driven from the clinics and hospitals, or performed as a part of awareness by the end users (patients and health conscious individuals). To understand these interactions, we have taken Diabetes management as our use case. Diabetes is turning into a lifestyle disease and hence is an ideal candidate since we need to monitor the health conditions of the patient continuously. The vital parameters of the body could either be monitored through medical devices and equipment, body sensors, mobile applications, or wearables.This paper analyses the solutions proposed so far for effective diabetes management using cloud technology. The paper also touches upon IoT-based solutions which could be used to treat chronic ailments from remote locations.
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...Journal For Research
Against a backdrop of our world’s changing climate solar thermal power generation shows great potential to move global energy production away from fossil fuels to non-polluting sources. A parameter study was conducted based on the previous analysis to improve specific aspects of the initial design using a value of benefit analysis to evaluate the different design. This project focused on the design, analysis and verification of a high temperature solar receiver. Computational Fluid Dynamic (CFD) analysis of Radiation model is carried out with new geometry design of receiver. Discrete Transfer Radiation Model (DTRM) model is used for numerical simulation.
1. CRADTRAN: A C++ RADIATIVE TRANSFER CODE
by
Alexander J. Marvin
A senior thesis submitted to the faculty of
Brigham Young University-Idaho
in partial fulfillment of the requirements for the degree of
Bachelor of Science
Department of Physics
Brigham Young University-Idaho
July 2016
5. BRIGHAM YOUNG UNIVERSITY-IDAHO
DEPARTMENT APPROVAL
of a senior thesis submitted by
Alexander J. Marvin
This thesis has been reviewed by the research advisor, research coordinator,
and department chair and has been found to be satisfactory.
Date Todd Lines, Advisor
Date Kevin Kelley, Committee Member
Date Stephen Turcotte, Committee Member
Date Evan Hansen, Research Coordinator
Date Steven McNeil, Department Chair
6.
7. ABSTRACT
CRADTRAN: A C++ RADIATIVE TRANSFER CODE
Alexander J. Marvin
Department of Physics
Bachelor of Science
In Earth observing satellites, it is often necessary to calculate the brightness
of microwaves coming out of the atmosphere. We have written a program,
CRadtran in C++ to complete this calculation. CRadtran replaces an older
program, RADTRAN, to be more readable and usable to modern users. The
atmosphere is divided into slices, where pressure, temperature, and attenua-
tion were kept constant. For each layer, microwave attenuation from oxygen
is calculated, based on the properties of the oxygen molecules. Microwave
attenuation of contributions from each slice are then summed using numerical
integration. Our results were consistent with that of RADTRAN, for similar
atmospheric conditions. The algorithm for oxygen attenuation produced at-
tenuation constants that are also consistent with a published paper by Meeks
and Lilley [1].
8.
9. ACKNOWLEDGMENTS
I would like to thank my research advisor, Todd Lines for all the help he has
given me in this project. I would also like to thank my committee, including
Kevin Kelley for assisting my in the writing of this thesis. Lastly, I would like
to thank Evan Hansen for all the suggestions of things I should add to make
it more complete.
15. Chapter 1
Introduction
The launch of Sputnik, the first satellite, initiated an age of artificial satellites. Since
then, our lives have been improved by satellites orbiting the Earth. One important
application is Earth observing satellites, which tell us what is going on the surface
and atmosphere of the planet. Understanding of what is happening on our planet is
important to helping prevent natural disasters, maximizing yields for farmers, and
other benefits.
In addition to visible cameras, observations are made in other parts of the electro-
magnetic spectrum, such as infra-red, UV, and the microwave spectrum. The Earth
glows in the microwave spectrum, much like a piece of metal glows at high temper-
atures. This is known as blackbody radiation. Atmospheric scientists are interested
in microwaves because it allows us to see the atmosphere like a CAT scan. Our
observations involve passive microwaves, rather then active microwaves from a radar.
The microwave radiometers spectrally averages over a bandwidth. To complete
the calculations, we need to do spectral averaging for our microwave radiometer,
which doesn’t have the same response to different frequencies of microwaves across
its operational range. Before spectral averaging can be completed, one must do
1
16. 2 Chapter 1 Introduction
calculations to determine the radiance or the brightness of microwaves coming out
of the top of atmosphere for different conditions. This is best done with a computer
model, which is the purpose of this project.
This project is written to replace older code dating back to the 1960’s [2]. There
are a number of things that make this older model harder to use. For one, this
model is written in FORTRAN, which limited variable names, making readability
bad. Another problem was the program required FORTRAN formatted input, which
is unnecessarily difficult for the user.(The original input was input on punch cards.)
The new code, written in C++, will be more readable to the user, be less stringent
with input, and be easier to extend. The code will help scientists better analyze
satellite data, and improve our understanding of the atmosphere.
17. Chapter 2
Background and Theory
2.1 General radiative transfer equation
Microwave radiative transfer refers to microwaves traveling through the atmosphere.
The Earth emits microwaves as a black body emitter. In a microwave remote sensing
application, we want to know how much radiative power is absorbed by a detector.
This measured radiative power is used to find out what is happening in the atmosphere
or on the surface of the Earth. This is similar to what our eyes do, but at a different
wavelength. In designing the remote sensor, a range of radiative power is needed.
Power is expressed in introductory physics texts as
P =
∆E
∆t
(2.1)
as the time rate of change of energy. In remote sensing, the symbol Q is used,
representing a group of photons so that
P =
∆Q
∆t
(2.2)
3
18. 4 Chapter 2 Background and Theory
The power in this case is delivered by a flux a moving photons, so we change to the
letter Φ, and call it radiant flux.
Φ =
∆Q
∆t
(2.3)
From this, the intensity of the microwaves is calculated
I =
Φ
A
(2.4)
as power delivered over an area. We, of course, want to know how light travels
through the atmosphere. In our model, we assume that the Earth is flat, and that
the atmosphere is split into many horizontal slices of air, with light going in and out of
each slice, as well as emitting light. We define a new variable, k, the mass extinction
coefficient, defined as
k =
κ
ρ
(2.5)
where κ is the attenuation constant. We define the intensity of light that leaves each
slice (Figure 2.1) as:
Iout = Iine− s
0 ρ k ds
(2.6)
where Iin is the light going in, ρ is the density, k is the mass extinction coefficient, and
s is the length our slice. This equation is derived in Lines’ white paper [3, 4, 5]. Values
like temperature, pressure and so on are assumed constant. This is done to each slice
Figure 2.1 A slice of air
19. 2.1 General radiative transfer equation 5
in succession, until we get to the top of the atmosphere. The output of equation 2.6
is in Watts per meter squared and k is in Nepers per meter. By rearranging the above
equation we have
Iout
Iin
= e− s
0 ρ k ds
(2.7)
which is the fraction of intensity still in the beam, or the transmissivity T . Thus
transmissivity is equal to
T = e− s
0 ρ k ds
(2.8)
We now define the differential equation that governs radiative transfer:
1
kρ
dI
ds
= J − I (2.9)
The derivation of this equation can be found in Lines’ [3]. We need to solve this
equation so that we have our final general equation. We first ignore scattering. With
this simplification,
J = B (T) (2.10)
The term B (T) is our Plank function as a function of temperature (in Kelvins):
B (T) =
2hν3
c2
1
e
hν
kT − 1
(2.11)
Our differential equation than becomes
1
kαρ
dI
ds
= B (T) − I (2.12)
We then define absorption along the path s1 to s2 as
τ (s2,s1) =
s2
s1
kαρds (2.13)
The absorption coefficient kα and density will change as we go up or down in the
atmosphere. To get around this, we make the slices sufficiently small so those values
are constant, so now our equation is
dτ = kαρds (2.14)
20. 6 Chapter 2 Background and Theory
This quantity is known as the optical thickness, τ(s1, s2) or just τ, and tells us how
hard it is to get light through our slice [3]. Using Equation 2.14, our expression for
Equation 2.13 is now
dI
dτ
= B (T) − I (2.15)
or more explicitly
dI (s)
dτ (s,s1)
= B (T) − I (s) (2.16)
To solve this equation, we first multiply by e−τ(s,s1)
, which becomes
dI (s)
dτ (s,s1)
e−τ(s,s1)
= B (T) e−τ(s,s1)
− I (s) e−τ(s,s1)
(2.17)
and multiply by dτ(s, s1)
dI (s) e−τ(s,s1)
= B (T) e−τ(s,s1)
dτ (s,s1) − I (s) e−τ(s,s1)
dτ (s,s1) (2.18)
We then combine the I terms
dI (s) e−τ(s,s1)
+ I (s) e−τ(s,s1)
dτ (s,s1) = B (T) e−τ(s,s1)
dτ (s,s1) (2.19)
at which point we integrate and obtain
s1
0
d I (s) e−τ(s,s1)
=
s1
0
B (T) e−τ(s,s1)
dτ (s,s1) (2.20)
We perform the integral on the left side and we have
I (s1) e−τ(s1,s1)
− I (0) e
−τ(0,s1)
0 =
s1
0
B (T) e−τ(s,s1)
kαρds (2.21)
Recalling Equation 2.14
τ (s2,s1) =
s2
s1
kαρds
we see τ(s1, s1) equals zero, so
I (s1) e0
− I (0) e
−τ(0,s1)
0 =
s1
0
B (T) e−τ(s,s1)
kαρds (2.22)
21. 2.1 General radiative transfer equation 7
or
I (s1) = I (0) e
−τ(0,s1)
0 +
s1
0
B (T) e−τ(s,s1)
kαρds (2.23)
This expression is known as the Equation of Radiative Transfer for Absorption. It
models the intensity leaving each layer of atmosphere, except the surface.
Figure 2.2 Our Euclidean system
As mentioned earlier, we use a plane parallel atmosphere, which greatly simplifies
our integration. Assuming a Euclidean system with z pointing up, as seen in Figure
2.2 above, we measure an angle θ from the z axis. As we go up, distances are measured
by (see Figure 2.3)
cos θ =
z
s
(2.24)
22. 8 Chapter 2 Background and Theory
and we can write altitude as
z = s cos θ (2.25)
and a differential equation as
dz = ds cos θ (2.26)
The path ds is written like this
ds =
dz
cos θ
(2.27)
Figure 2.3 Distance s of the light
We than insert than into our differential equation
1
kρ
dI
dz
cos θ
= J − I (2.28)
or
cos θ
1
kρ
dI
dz
= J − I (2.29)
23. 2.1 General radiative transfer equation 9
The dependence on the coordinate variables is then shown
cos θ
1
kρ
dI (z, θ, φ)
dz
= J (z, θ, φ) − I (z, θ, φ) (2.30)
Similar to Equation 2.14
τ (z) =
∞
z
kαρdz (2.31)
but now as a function of altitude. Skipping some steps, found in Lines [3], we have
I (τ1, µ, φ) = I (τ2, µ, φ) e−(τ2−τ1)/µ
+
τ2
τ1
J (τ , µ, φ) e−(τ −τ)/µ dτ
µ
(2.32)
Where
µ = cos θ (2.33)
Looking at Figure 2.4, upward radiation would be positive µ and downward radia-
tion is −µ. Our notation then becomes I(0, µ, φ) for microwaves coming out of the
atmosphere and I(0, −µ, φ) for downward radiance at the top of the atmosphere. At
slices in between, the expressions are I(τ, µ, φ) for upward radiance and I(τ, −µ, φ)
for downward radiance. At the surface the expressions are I(τb, −µ, φ) for downward
intensity, and I(τb, µ, φ) for glow from the surface.
Two different instances are analyzed: first the light leaving the top of the atmo-
sphere and the radiance coming down to the surface. Recalling that τ is optical depth
and letting τ1 = 0, and integrating down,
I (0, µ, φ) = I (τb, µ, φ) e−τb/µ
+
τb
0
J (τ , µ, φ) e−τ /µ dτ
µ
(2.34)
For the other case we have
I (τ1, −µ, φ) = I (τ2, −µ, φ) e−(τ2−τ1)/(−µ)
+
τ2
τ1
J (τ , −µ, φ) e−(τ −τ)/(−µ) dτ
−µ
(2.35)
Integrating that equation from bottom to top, τb to τ = 0 it becomes
I (τb, −µ, φ) = I (0, −µ, φ) e−(0−τb)/(−µ)
+
0
τb
J (τ , −µ, φ) e−(τb−τ )/µ dτ
−µ
(2.36)
24. 10 Chapter 2 Background and Theory
Figure 2.4 The whole atmosphere
25. 2.1 General radiative transfer equation 11
and rearranging it:
I (τb, −µ, φ) = I (0, −µ, φ) e−τb/µ
+
τb
0
J (τ , −µ, φ) e−(τb−τ )/µ dτ
µ
(2.37)
The custom is to write our equations in terms of wavenumber ν which is
ν =
1
λ
(2.38)
To be tidy, we just write ν as a subscript:
Iν (0, µ, φ) = Iν (τb, µ, φ) e−τb/µ
+
τb
0
Jν (τ , µ, φ) e−τ /µ dτ
µ
(2.39)
Iν (τb, −µ, φ) = Iν (0, −µ, φ) e−τb/µ
+
τb
0
Jν (τ , −µ, φ) e−(τb−τ )/µ dτ
µ
(2.40)
Like discussed before, there is no scattering right now. So
Jν = Bν (τ) (2.41)
One other simplification is that we are only looking up or down, so µ = 1 at the top
and µ = −1 at the bottom looking up. And our equations become
Iν (0, φ) = Iν (τb, φ) e−τb
+
τb
0
Bν (τ ) e−τ
dτ (2.42)
Iν (τb, φ) = Iν (0, φ) e−τb
+
τb
0
Bν (τ ) e−(τb−τ )
dτ (2.43)
No matter the value of φ, our value will be the same, so we drop it:
Iν (0) = Iν (τb) e−τb
+
τb
0
Bν (τ ) e−τ
dτ (2.44)
Iν (τb) = Iν (0) e−τb
+
τb
0
Bν (τ ) e−(τb−τ )
dτ (2.45)
With wavenumber notation, we write the transmittance as
Tν (τ) = e−τ
(2.46)
Rewriting it as a differential equation, we have
∂Tν
∂τ
= −e−τ
(2.47)
26. 12 Chapter 2 Background and Theory
Multiplying each side by dτ
∂Tν
∂τ
dτ = −e−τ
dτ (2.48)
and substituting into our special cases
Iν (0) = Iν (τb) Tν (τb) −
τb
0
Bν (τ )
∂Tν (τ )
∂τ
dτ (2.49)
Iν (τb) = Iν (0) Tν (τb) −
τb
0
Bν (τ )
∂Tν (τb − τ )
∂τ
dτ (2.50)
Weather scientists are used to optical depth, so we will do a change of variables
to pressure levels. We introduce the hydrostatic equation
dP = −ρ g dz (2.51)
Which we use to make a change of variables. Recalling that
τ =
∞
z
kν (z ) ρa (z ) dz (2.52)
where kν is the absorption coefficient at ν and ρa is the density of our gases, we
rearrange the hydrostatic equation and insert, we have
τ =
∞
z
kν (z ) −
1
g
dP
dz
dz (2.53)
which becomes
τ = −
1
g
∞
Ps
kν (P ) dP (2.54)
with PS as the surface pressure. We then change variables τ to P and then Tν (τb) is
Tν (Ps) = Tν (Ps, 0) = exp
1
g
0
Ps
kν (P ) dP (2.55)
and top of atmosphere is
Iν (0) = Iν (Ps) Tν (Ps, 0) −
Ps
0
Bν (T (P ))
∂Tν (P , 0)
∂P
dP (2.56)
27. 2.1 General radiative transfer equation 13
The intensity leaving the surface could be modeled by
Iν (φ) = εB (Ts) (2.57)
with Ts as the temperature of the surface and ε is the surface emissivity. Then
Iν (0) = εB (Ts) Tν (Ps, 0) −
Ps
0
Bν (T (P ))
∂Tν (P , 0)
∂P
dP (2.58)
No instrument can detect just one wavelength or wavenumber. Hence the to need
to do spectral averaging for our instrument in question. Light is detected best by
the instrument by some wavenumber νo, with ν1 and ν2 being the limits of what
can be detected by the sensor. The curve (Figure 2.5) that describes this is known
Figure 2.5 The responsivity of a theoretical instrument
as the responsivity of the instrument and is represented by the symbol L (ν). To
calculate what the instrument will actually give us, we integrate the intensity Iν (0, φ),
multiplied by the responsivity
I¯ν =
ν2
ν1
Iν (0, φ) L (ν) dν (2.59)
To normalize our function we divide Equation 2.59 by the responsivity
I¯ν =
ν2
ν1
Iν (0, φ) L (ν) dν
ν2
ν1
L (ν) dν
(2.60)
28. 14 Chapter 2 Background and Theory
The spectral transmittance is defined as
T¯ν =
ν2
ν1
exp −1
g
P
0
(kν (P ) q (P ) dP ) L (ν) dν
ν2
ν1
L (ν) dν
(2.61)
where
q =
ρa
ρ
(2.62)
is the gas density of the absorbing gas per total gas density. The upward light that
a satellite sees becomes
I¯ν (0) = εB¯ν (Ts) T¯ν (Ps, 0) −
Ps
0
B¯ν (T (P ))
∂T¯ν (P , 0)
∂P
dP (2.63)
Now we come back to some derivation. The surface needs to be accounted for. It
will reflect light, so we need to take that into account as well. The amount of light
that will hit the surface will of course be
Iν (Ps) =
Ps
0
Bν (T (P ))
∂Tν (Ps,P )
∂P
dP (2.64)
This is multiplied by the reflectivity or the percentage of light that is reflected
Ireflected = RνIν (Ps) = Rν
Ps
0
Bν (T (P ))
∂Tν (Ps,P )
∂P
dP (2.65)
We need to integrate over ν, but let’s do it one wavenumber at a time. Now absorp-
tivity, transmissivity, and reflectivity sum to 1
Aν + Tν + Rν = 1 (2.66)
For the surface of the Earth, we can safely ignore transmission. So now our equation
is
Aν + Rν = 1 (2.67)
and rearranging things
Rλ = 1 − Aν (2.68)
29. 2.1 General radiative transfer equation 15
It so happens that emissivity is the same thing as absorptivity, so that
Rλ = 1 − εν (2.69)
And now
Ireflected = RνIν (Ps) = (1 − εν)
Ps
0
Bν (T (P ))
∂Tν (Ps,P )
∂P
dP (2.70)
and we write the emission from the surface as
Bν (Ts) Tν (Ps, 0) (2.71)
Our equation for top of atmosphere (for one wavelength)
Iν (0) = ενBν (Ts) Tν (Ps, 0)
+ (1 − εν ) Tν (Ps)
Ps
0
Bν (T (P ))
∂Tν (Ps,P )
∂P
dP (2.72)
−
Ps
0
Bν (T (P ))
∂Tν (P , 0)
∂P
dP
We introduce the Rayleigh-Jeans approximation to the Planck curve
Iν ≈
2kB(ν)2
c2
T (2.73)
This works just as well in the range of frequencies we are using. The temperature
T in this equation is known as the brightness temperature TB. Solving for this
temperature, we get
TB =
c2
2kBν2
Iν (2.74)
which we can use as the intensity variable. Substituting into our equation for Iν, the
equation for the top of the atmosphere is
2k2
ν
c2
TB (ν) = ε
2k2
ν
c2
TsTν (Ps)
+ (1 − εν) Tν (Ps)
Ps
0
2k2
ν
c2
T (P )
∂Tν (Ps,P )
∂P
dP (2.75)
−
Ps
0
2k2
ν
c2
T (P )
∂Tν (P )
∂P
dP
30. 16 Chapter 2 Background and Theory
and the factor of 2kBν2
c2 T divides out
TB (ν) = εTsTν (Ps, 0)
+ (1 − εν) Tν (Ps, 0)
Ps
0
T (P )
∂Tν (Ps,P )
∂P
dP (2.76)
−
Ps
0
T (P )
∂Tν (P , 0)
∂P
dP
Skipping a number of steps(which could be an exercise for the reader), we end up
with the equation
TB (ν)TOA = εTsTν (Ps,0) +
0
Ps
T (P )
∂Tν (P , 0)
∂P
dP (2.77)
+
0
Ps
(1 − εν) T (P )
(Tν (Ps,0))2
(Tν (P, 0))2
∂Tν (P , 0)
∂P
dP
Our three terms are basically look like this:
TB (ν) = (TB (ν))surface + (TB (ν))atmosphere + (TB (ν))reflected (2.78)
Last term could also be written as
(TB (ν))reflected = (1 − εν) TB (ν)BOA (2.79)
Converting our integrations to summations, our equation becomes
TB (ν) = εTsTν (Ps,0) +
i
T (Pi) (Tν (Pi+1) − Tν (Pi−1)) (2.80)
+ (1 − εν)
i
T (Pi) (Tν (Pb, Pi+1) − Tν (Pb, Pi−1))
We than find the transmission term T (Pi) for each layer of atmosphere. Recall that
Tν (Ps,P) = exp
1
g
P
Ps
kν (P ) dP (2.81)
with kν (P ) being the absorption coefficient at a wavenumber ν, for the gases that are
absorbing. The total absorption coefficient is a sum of all coefficient from all different
types of absorption
kν (P) = kν (P)air + kν (P)cloud + kν (P)fog + kν (P) + · · · (2.82)
31. 2.1 General radiative transfer equation 17
If the change in the height is known for the pressure levels in the atmosphere, ∆hi,
then transmission in terms of altitude is
τi =
zi
zs
kν (z ) ρa (z ) dz (2.83)
The total absorption coefficient is then defined as
aν (z) = kν (z) ρa (z) (2.84)
thus
τi ≈
j<i
aν (zj) ∆zj (2.85)
and the transmission at slice i is
Tν (Ps,Pi) = exp
z
zs
kν (z ) ρa (z ) dz (2.86)
= e−τi
= exp
M
j<i
aν (zj) ∆zj
= Tν (0, zi)
and at the top of the atmosphere
Tν (Ps,0) = exp
1
g
0
Ps
kν (P ) dP (2.87)
= exp
0
zs
kν (z ) ρa (z ) dz
= e−τT OA
= exp
M
j
aν (zj) ∆zj
= Tν (0, zM )
with all slices contributions are summed up. Just like above
Tν (Pi) = Tν (Pi, 0) = exp
1
g
0
Pi
kν (P ) dP (2.88)
32. 18 Chapter 2 Background and Theory
which in this case is the transmission down to a pressure level P. The optical depth
we calculate in terms of height is
τ =
∞
z
kν (z ) ρa (z ) dz (2.89)
or
τi =
∞
zi
aν (z ) dz (2.90)
We could do what we did with the previous terms, but Tν (Pi, 0) is already calculated
for each i, so we will use it to calculate downward transmission
Tν (+Pi, 0) =
Tν (Ps,PM )
Tν (Ps,Pi)
(2.91)
=
e−τT OA
e−τi
= exp (− (τTOA − τi))
= Tν (zi, zM )
which is what is wanted for T (Pi, 0). Now we substitute into
TB (ν) = εTsTν (Ps,0) +
i
T (Pi) (Tν (Pi+1, 0) − Tν (Pi−1, 0)) (2.92)
+ (1 − εν)
i
T (Pi) (Tν (Ps, Pi+1) − Tν (Ps, Pi−1))
to get our general radiative transfer equation
TB (ν) = εTsTν (0, zM ) +
i
T (zi) (Tν (zi+1, zM ) − Tν (zi−1, zM )) (2.93)
+ (1 − εν)
i
T (zi) (Tν (0, zi+1) − Tν (0, zi−1))
Of note to the reader is that aν(zi) or aν(p) is the same as the attenuation constant
κ. The attenuation constant κ is calculated in two separate parts, oxygen and water
vapor. Oxygen attenuation is covered in the next section. Water vapor is not currently
implemented in the code.
33. 2.2 Oxygen attenuation 19
2.2 Oxygen attenuation
First we will go through the mechanics and theory of oxygen attenuation. The general
equation given by Meeks and Lilley [1] is
γ (ν, P, T) =
C1Pν2
T3
N
SN e
−
EN
kT
(2.94)
Some parts of the equation are obvious like, pressure and temperature, while ν is
frequency. C1 is a constant that is 2.6742 for γ in decibels per kilometer and 0.61576
for γ in nepers per kilometer [1]. The sum is familiar with those who studied thermal
and statistical physics as the Boltzmann distribution. Much of this section will go over
the calculation of the Boltzmann distribution for oxygen. The factor SN is defined as
SN = FN+µ2
N+ + FN−µ2
N− + Foµ2
No (2.95)
where Fo is defined as
Fo =
∆v
ν2 + ∆ν2
(2.96)
and FN+ and FN− are defined as
FN+ =
∆ν
(νN+ − ν)2
+ ∆ν2
+
∆ν
(νN+ + ν)2
+ ∆ν2
(2.97)
FN− =
∆ν
(νN− − ν)2
+ ∆ν2
+
∆ν
(νN− + ν)2
+ ∆ν2
(2.98)
respectively. The term ∆ν in the last three expressions is known as the line width
parameter. The terms νN+ and νN− are resonant frequencies corresponding to the
quantum number N for oxygen molecules. The µ terms µ2
N+, µ2
N−, and µ2
No are
defined as
µ2
N+ =
N (2N + 3)
N + 1
(2.99)
µ2
N− =
(N + 1) (2N + 1)
N
(2.100)
34. 20 Chapter 2 Background and Theory
µ2
No =
2 (N2
+ N + 1) (2N + 1)
N (N + 1)
(2.101)
respectively. N is of course the quantum number. For the part of the expression
e−
EN
kT
EN is an energy level of our molecule. The exponent is approximated by
EN
kT
= 2.06844
N (N + 1)
T
(2.102)
The line width parameter is a line fit of a number of different line broadening
phenomena. It depends on pressure and temperature:
∆v (P, T) = αP (0.21 + 0.78β)
300
T
0.85
(2.103)
with α and β are constants. α is defined as 1.95 MHz per mm Hg [1]. This repre-
sents line broadening that varies with pressure [1]. The other constant, β, is more
complicated, and varies according to altitude.
β =
0.25 if h < H1
0.25 + 0.50 h−H1
H2−H1
if H1 ≤ h ≤ H2
0.75 if h > H2
(2.104)
where h is the altitude, H1 is the height where transitions begin between lines, and
H2 is where the transitions ends. They are defined as H1 = 8km and H2 = 25km.
Our oxygen transition frequencies are in a table from Meeks and Lilley. Some
of them are measured, while others are calculated. Due to certain rules in quantum
mechanics, the quantum number N only has odd values. We also only go up to
N = 45 because higher quantum numbers do not have significant populations [1].
35. Chapter 3
Methods
To simplify implementation, code was separated into functions, and later classes. The
classes simplify using values such as pressure and temperature across the code. The
code has evolved over time to try to follow the object oriented model as much as
possible. We now go into detail about how the code works.
The first part of the code, in the file CRadtran.cpp contains main(). It reads
in the command line parameters. If it detects no command line parameters, it will
print an error message and exit from the program. The program will take either one
or else two parameters, with the first being the input file, and the second being the
output file. If the second parameter is not specified, it will set a default value. In
emphmain(), it will then read in the file using the function readFile(), which reads
in settings into the settings class. The code then loops through all the frequencies
that are specified in the input file, and calls the function upwardRadiance() for each
frequency. Lastly, it calls the function writeFile(), which writes the results, intensity
in Watts per Meter squared, into the output file. Details about the input file are in
the README file.
The file calculate.cpp, in the function upwardRadiance(), implements a numerical
21
36. 22 Chapter 3 Methods
integration from the bottom to the top of the atmosphere. In the loop, atmosphere
is split into slices, and the attenuation and optical length of each is calculated as if
the pressure, temperature, etc are constant for that slice. Before that, the size of
dz is calculated by dividing the maximum height of the atmosphere by the number
of slices. The attenuation constant κ, for the given slice, is calculated in the class
oxygenAtten and returned. It is stored in a variable temporaly. The optical lengths
are also calculated in that loop, by calling the function sliceTrans(). The function
sliceTrans() multiplies κ by 0.23025 to convert the attenuation constant to nepers/km
from decibels/km and multiplies that by dz. Lastly, in the loop, the blackbody radi-
ation for each layer is calculated in the function plankv(). After looping through the
slices, each of the three terms of the general radiative transfer equation is calculated,
added together and returned.
For the first term of the general radiative equation, the values of the variable tau
are summed up in sum(). The value of the temperature of the surface is used to
calculate the blackbody radiation of the surface using the function plankv(). This
is multiplied by the natural number e raised to the negative sum of tau times the
emissivity constant ε and is placed into the variable firstTerm. The second term
of the general radiative equation is calculated in the function atmosphereTerm, and
placed in the variable secondTerm. The last term of the general radiative equation is
partly calculated in reflectedTerm(). The value of reflectedTerm() is multiplied times
one minus the emissivity constant and placed in thirdTerm.
The functions reflectedTerm and atmosphereTerm in calculate.cpp are a little more
complicated. The function atmosphereTerm first sets the first sum to 0 and the other
to the top most slice. It then raises e to negative sum of both, and takes the difference.
This is multiplied by the blackbody radiation stored in brightness and added to the
total value. This is done for each layer and returned, with exception of the boundary
37. 23
layers. The function reflectedTerm() does the same thing, but starts from the bottom
instead of the top.
For the calculation of κ, the values from oxygen attenuation were calculated sep-
arately in a class called oxygenAtten. Variables for pressure, frequency and temper-
ature were stored locally, after being copied from the datafile class, by a function,
getValues(). This is done by passing a datafile pointer through the constructor. This
pointer is copied to a pointer variable. There is another function, resetValues(), that
can call getValues() after the constructor is initially called. When one wants to get
the attenuation constant at the given frequency and altitude, getValue() is called.
The function getValue() returns the value of the equation
γ (ν, P, T) =
C1Pν2
T3
N
SN e
−
EN
kT
where C1 is defined in the atten.h header file. The sum
N
SN e
−
EN
kT
is calculated in a separate function, rotationalStateSum(). The function loops through
the odd rotational states, 1 to 45. Each rotational state SN is calculated in a separate
function, rotationalState(). The e
−
EN
kT
term is approximated, for oxygen as
e
EN
kT = e2.06844(N(N+1)
T )
as discussed in the theory section.
In the function rotationalState() of the oxygenAtten class, the terms µ2
N+, µ2
N−,
and µ2
N0 are calculated in single lines and put in the variables muNPlusSq, muNMi-
nusSqr, and muNOSqr respectively. The variable deltaV or ∆V , known as the line
width parameter, is calculated in a separate function linewidth(), and divided by 1000
to convert to gigacycles. The next two lines of code get the resonant frequencies
νN+ and νN− from the functions getTransitionPlus() and getTransitionMinus() for
38. 24 Chapter 3 Methods
the given N. The terms FN+, FN−, and FO are calculated from previously stored
values. The last line calculates SN from the previous terms and returns it.
The oxygenAtten class, the lineWidth() function calculates equation 2 from Meeks
and Lilley in one line, with the β constant calculated in yet another function, get-
Beta(). The function returns 0.25 for altitudes less than 8km and 0.75 for a height
greater than 25km. For values from 8km to 25km, the constant is some function
β = 0.25 + 0.50(h − H1)/(H2 − H1)
where H1 = 8km and H2 = 25km. Lastly, the functions getTransitionPlus() and get-
TransitionMinus() are simply switch statements that return the values in gigahertz.
In the datafile class, three standard template library (STL) map classes are used
to store data in a table. The three values stored for various altitudes are temperature,
pressure, and relative humidity. If given an altitude that is not in the table, it calls
the interpolate() function. The interpolate() function takes the two closest values to
our altitude and uses them to linearly interpolate the value needed. For edge cases,
it interpolates between the closest value and zero.
To test the code, different components were tested with test drivers, which are
pieces of code that have a main() and tests a particular component. To see the test
code, please see the Appendices.
Results were also tested against known graphs at given values. For the bright-
ness temp.cpp file, we tested the function plank() against a calculator on usgs.gov [6]
and in the book Fundamentals of Infrared Detector Operation & Testing [7], as well
as Mathematica. For oxygen attenuation code, in the oxygenAtten class, it was tested
against the graph in Meeks and Lilley [1].
39. Chapter 4
Results and Discussion
With CRadtran, we were able to get results consistent with those of RADTRAN at
multiple frequencies for the Planck function and the oxygen attenuation. Also, the
CRadtran oxygen attenuation routine produces attenuation constants consistent with
Meeks and Lilley, for sea level and for other altitudes.
The results of the oxygen attenuation code are overlayed in blue in Figure 4.1
with the original graph from the Meek and Lilley paper at sea level. The highest
point is about 17 decibels/km, and to the far right and left, the constants drop to
nearly zero. For an altitude of 8km, the Meeks and Lilley peaks reflect the vibrational
modes of oxygen. The highest attenuation at 30km is about 14 decibels/km. The
highest altitude has sharp peaks, which correspond to the oxygen absorption lines.
CRadtran has not been tested with high resolution for altitudes 8 or 30km.
Our most important results, which are the brightness temperature at the top of
the atmosphere, are in Figure 4.1. For the CRadtran vs. RADTRAN comparison,
the results in brightness temperature are in excellent agreement. RADTRAN is in
grey, and CRadtran is in red. With all the factors involved, we managed to still get
good results. There is a dip in the graph, in and around 60GHz, corresponding with
25
40. 26 Chapter 4 Results and Discussion
the peak of the oxygen attenuation in Figure 4.1.
Figure 4.1 Oxygen attenuation constants
For the results of all the code, I initially got results that were eight orders of
magnitude off from RADTRAN [2]. After talking to Todd Lines, I discovered that
the equation from Meeks and Lilley [1], Equation 2.94, already accounted for mass
density/pressure. We next found out there was an unit problem, using the book by
Liou [4]. This was fixed, among other things, by converting GHz to Hz, and replacing
the plankw() function with plankv(). After that, the results were consistent at 37 GHz.
Then we tested at multiple frequencies in with both CRadtran and RADTRAN. To
do this, I had to convert intensity into brightness temperature (using equation 2.74)
and then compare the results from CRadtran and RADTRAN.
Unfortunately, at that point, it was not consistent at 70 GHz; it was four times
bigger compared to RADTRAN! We searched and searched for the problem. First, we
41. 27
Figure 4.2 Comparison of RADTRAN and CRadtran
tested against multiple terms, and found that the second term had problems. After
some time, I found that I was calculating wrong, and changed it. Now, for some
reason, it was as much as two times off from RADTRAN in places. We could not
find out was wrong. Todd Lines modified the code. I put those changes into my
code. I put the results in my sheet, and the results didn’t change! I then realized
it was the Mathematica sheet. I realized that I was using the same frequency, for
all the calculations, when the results were at multiple frequencies. I had Todd Lines
calculate and place it on the same graph, and they were consistent.
43. Chapter 5
Conclusion
In order to design a microwave radiometer for an earth observing satellite, we needed
to calculate the intensity of microwaves at the top of the atmosphere. We have
used C++ code to produce a model of microwaves traveling through the atmosphere,
called CRadtran. The model used in this code included the general radiative transfer
equation, oxygen attenuation and the Planck equation. This code takes into account
atmospheric pressure and temperature, as a function of altitude. Water vapor atten-
uation was not included. We compared CRadtran to the legacy code, RADTRAN.
Oxygen attenuation matches the results in Meeks and Lilley at sea level. Oxygen
attenuation should be tested at multiple altitudes, and at high enough resolution to
see expected spectral content. The brightness temperature at the top of atmosphere
calculated by CRadtran matches that of RADTRAN with the humidity set to zero.
All my results from CRadtran agree well with RADTRAN. No substantial issues have
been found to date.
29
44. 30 Chapter 5 Conclusion
5.1 Future work
Future work will include adding water vapor attenuation, scattering, and surfaces
models into CRadtran. Other future work include using more sophisticated algo-
rithms, like using Simpson’s rule to integrate across layers of the atmosphere. Paral-
lel processing needs to added for problems involving multiple atmospheric conditions.
The linear fit to pressure, temperature, and relative humidity, as a function of alti-
tude, may be replaced by a more accurate fit, like spline fitting, to provide better
inputs for calculations.
One reason why we left out water vapor is it is more complicated than oxygen.
For one, we have variation of the concentration of water vapor according t altitude,
climate, weather patterns, and type of cloud. Another difficulty, is that from an
atomic physics point of view, water molecules have complicated absorption spectra
and vibrational modes.
45. Bibliography
[1] M. L. Meeks and A. E. Lilley, Journal of Geophysical Research 68, 1683 (1963).
[2] V. J. Falcone, L. W. Abreu, and E. P. Shettle, “Atmospheric attenuation of
millimeter and submillimeter waves: Models and computer code,” Enviromental
Research Papers No. 679 (Air Force Geophysics Laboratory, 1979).
[3] T. Lines, “Microwave radiative transfer,” (2016).
[4] K. N. Liou, An Introduction to Atmospheric Radiation, 2nd ed., International
Geophysics, Vol. 84 (Academic Press, 2002, 1980).
[5] F. T. Ulaby, R. K. Moore, and A. K. Fung, Microwave Remote Sensing, Active
and Passive, 1st ed., Vol. 1 (Addison-Wesley Publishing Company, 1981).
[6] R. G. Vaughan, “Radiance calculator,” http://astrogeology.usgs.gov/tools/
thermal-radiance-calculator/ (2009), accessed: 2016-07-19.
[7] J. D. Vincent, Fundamentals of Infrared Detector Operation & Testing, 1st ed.,
Wiley Series in Pure and Applied Optics (Wiley-Interscience, 1990).
31
47. Appendix A
Source Code
A.1 makefile
#
→ ########################################################################
→
# Program :
# CRadtran
# Author :
# Alexander Marvin
# Summary :
# These f i l e s are f or CRadtran . Short f o r C++ Radative
→ Transfer Code
#
→ ########################################################################
→
#
33
48. 34 Chapter A Source Code
→ ########################################################################
→
# Building executable of CRadtran
#
→ ########################################################################
→
CRadtran : c a l c u l a t e . o CRadtran . o brightness temp . o d a t a f i l e . o
→ oxygenAtten . o
g++ −o CRadtran c a l c u l a t e . o CRadtran . o brightness temp . o
→ d a t a f i l e . o oxygenAtten . o
#
→ ########################################################################
→
# Build s t a t i c l i b r a r y
#
→ ########################################################################
→
s t a t i c : c a l c u l a t e . o CRadtran . o brightness temp . o d a t a f i l e . o
→ oxygenAtten . o
ar rcs libCRadtran . a c a l c u l a t e . o CRadtran . o
→ brightness temp . o d a t a f i l e . o oxygenAtten . o
#
→ ########################################################################
→
# Build testDataFile
49. A.1 makefile 35
#
→ ########################################################################
→
testDataFile : testDataFile . o d a t a f i l e . o
g++ −o testDataFile testDataFile . o d a t a f i l e . o
#
→ ########################################################################
→
# Build testAtmTemp
#
→ ########################################################################
→
testAtmTemp : us atm temp . o testAtmTemp . o f i l e . o
g++ −o testAtmTemp testAtmTemp . o us atm temp . o f i l e . o
#
→ ########################################################################
→
# Build t e s t testOxyAtten
#
→ ########################################################################
→
testOxyAtten : testOxyAtten . o oxygenAtten . o d a t a f i l e . o
g++ −o testOxyAtten testOxyAtten . o oxygenAtten . o d a t a f i l e
→ . o
50. 36 Chapter A Source Code
#
→ ########################################################################
→
# Individual f i l e s
#
→ ########################################################################
→
c a l c u l a t e . o : c a l c u l a t e . cpp c a l c u l a t e . h brightness temp . h
g++ −c c a l c u l a t e . cpp
CRadtran . o : CRadtran . cpp c a l c u l a t e . h
g++ −c CRadtran . cpp
brightness temp . o : brightness temp . cpp brightness temp . h
g++ −c brightness temp . cpp
d a t a f i l e . o : d a t a f i l e . cpp d a t a f i l e . h
g++ −c d a t a f i l e . cpp
testDataFile . o : testDataFile . cpp d a t a f i l e . h
g++ −c testDataFile . cpp
testAtmTemp . o : testAtmTemp . cpp us atm temp . h
g++ −c testAtmTemp . cpp
testOxyAtten . o : testOxyAtten . cpp atten . h
g++ −c testOxyAtten . cpp
51. A.1 makefile 37
oxygenAtten . o : oxygenAtten . cpp atten . h
g++ −c oxygenAtten . cpp
us atm temp . o : us atm temp . cpp us atm temp . h
g++ −c us atm temp . cpp
#
→ ########################################################################
→
# General r u l e s
#
→ ########################################################################
→
a l l : CRadtran
clean :
rm −f ∗˜ ∗. o ∗. a CRadtran testDataFile testOxyAtten
→ testAtmTemp
l i b r a r y s t a t i c : s t a t i c
package :
tar −cf CRadtran . tar makefile ∗. cpp ∗. h TIGR0001 input3 .
→ txt
52. 38 Chapter A Source Code
archive :
make clean
rm −f ∗. tar
tar −cf Crandtran$ ( s h e l l date ”+%m−%d−%y” ) . tar ∗
A.2 README.txt
∗Author : Alex Marvin
∗Copyright 2016
∗You are allowed to distribute , as long as you give c r e d i t to the
→ author
∗ Version : CRadtran 0.1 (Not currently f i n i s h e d yet )
∗For more information on how the code works , r e f e r to the senior
→ t h e s i s
”CRadtran : A C++ Radiative Transfer Code , by Alexander J . Marvin”
∗∗How to compile and run the make f i l e ∗∗
∗Simple compilation
make
∗To clean up :
make clean
∗Package i t :
make package
−name i s CRadtran . tar
∗ s t a t i c l i b r a r y :
53. A.2 README.txt 39
make l i b r a r y s t a t i c
∗∗ or ∗∗
make s t a t i c
∗ archive the f o l d e r while developing
make archive
−note that i t w i l l stamp i t with the name CRadtran [ date stamp ] .
→ tar
∗∗Run CRadtran∗∗
Currently , CRadtran runs from command l i n e only . To run i t you
must supply the input f i l e at minimum .
The command i s as f o l l o w s :
CRadtran i n p u t f i l e [ o u t p u t f i l e ]
I f CRadtran i s not in the execution path :
./ CRadtran i n p u t f i l e [ o u t p u t f i l e ]
For the input f i l e , i t might be formatted l i k e t h i s :
Range 37 70
Step 5
S l i c e s 40
Emissivity 1
Surface temperature 300
Print Attenuation TRUE
Max Altitude 81000
54. 40 Chapter A Source Code
The key words can be e i t h e r c a p i t a l i z e d or not , followed by the
→ value , or
values in the case of the f i r s t l i n e .
The f i r s t l i n e s p e c i f i e s the range of f r e q u e n c i e s in GHz, using
→ the key word
”Range” , and the second i s the step size , using the key ”Step ”.
Alternatively , you can j u s t do one frequency , using the ”
→ frequency ” word :
frequency 37
−note : currently , i t w i l l not loop through multiple s i n g l e
→ s p e c i f i e d
f r e q u e n c i e s
The third l i n e s p e c i f i e s the number of s l i c e s of atmosphere that
→ you want
i t s p l i t into using the keyword ” s l i c e s ”. The fourth l i n e
→ s p e c i f i e s the
e mi ss iv it y of our surface , using the keyword ” Emissivity ”. The
→ f i f t h i s the
surface temperature , using the keywords ” Surface temperature ”.
→ The sixth l i n e
s p e c i f i e s i f you want to print the attenuations f or each
→ frequencies , with the
keywords ” Print Attenuation ” , and the p o s s i b l e values TRUE or
→ FALSE.
−−Note−do FALSE f or now , because the code that prints the
55. A.3 CRadtran.cpp 41
→ attenuation constants
currently does not work .
The l a s t l i n e i s optional , and s p e c i f i e s the maximum a l t i t u d e of
→ our atmosphere ,
in meters , using the keywords ”Max a l t i t u d e ”. I f i t i s not set ,
→ the default
i s 100 ,000 meters .
∗∗ Notes on the TIGR0001 f i l e ∗∗
Contains default atmosphere p r o f i l e .
I f you want to make your own , I would suggest backing up the
→ o r i g i n a l :
mv TIGR0001 TIGR0001 . backup
To set the p r o f i l e , the values need to be in tab delimited
→ columns ,
with the columns being pressure ( in milibar ) , height ( in meters ) ,
temperature ( Kelvins ) , and r e l a t i v e humidity , from l e f t to right .
A.3 CRadtran.cpp
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Source code :
∗ main driver
∗ Author :
56. 42 Chapter A Source Code
∗ Alexander Marvin
∗ Summary :
∗ Main part of code . Reads in command l i n e parameters , reads
→ in
∗ input f i l e , c a l c u l a t e s microwave i n t e n s i t y at top of
→ atmosphere
∗ and outputs r e s u l t s to output f i l e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#include <iostream>
#include <string >
#include <fstream>
#include ” c a l c u l a t e . h”
using namespace std ;
// function prototypes
bool readFile ( s t r i n g filename , setup & s e t t i n g s ) ;
bool w r i t e F i l e ( s t r i n g filename , double data [ ] [ 2 ] , int length [ ] ,
→ double ∗∗ppK) ;
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ MAIN
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
int main ( int argc , char ∗∗ argv )
57. A.3 CRadtran.cpp 43
{
// i n i t i a l i z e s t u f f
double radiance = 0;
double frequency = 0;
s t r i n g i n p u t f i l e ;
s t r i n g o u t p u t f i l e ;
setup s e t t i n g s ;
bool ok = true ;
char ans ;
// check the number of command l i n e parameters
// f i r s t thing in argc i s always the name of the executable ,
→ CRadtran
i f ( argc < 2)
{ // i f only one parameter , output error message and e x i t
cout << ”∗∗ Invalid number of parameters ∗∗n” ;
cout << ”Usage : CRadtran INPUT [OUTPUT FILE NAME] n” ;
return −1;
}
e l s e i f ( argc == 2)
{ // i f one parameter , set default f o r output f i l e
i n p u t f i l e = argv [ 1 ] ;
o u t p u t f i l e = ” r e s u l t s . txt ” ;
}
e l s e
{ // otherwise , set input f i l e and output f i l e to user defined
i n p u t f i l e = argv [ 1 ] ;
o u t p u t f i l e = argv [ 2 ] ;
58. 44 Chapter A Source Code
}
// read in input f i l e
ok = readFile ( i n p u t f i l e , s e t t i n g s ) ;
i f ( ! ok ) // i f f a i l e d , e x i t
return −1;
// setup array to hold s t u f f
int length [ 2 ] ;
length [ 0 ] = ( s e t t i n g s .max − s e t t i n g s . min) / s e t t i n g s . step +1;
length [ 1 ] = 0;
double r e s u l t s [ length [ 0 ] ] [ 2 ] ;
double ∗ ppK[ length [ 0 ] ] ;
i f ( s e t t i n g s . printK )
length [ 1 ] = s e t t i n g s .M; // set length
// loop array
f or ( int i = 0; i < length [ 0 ] ; i++)
{
frequency = i ∗ s e t t i n g s . step+s e t t i n g s . min ; // frequency i s in
→ GHz
// wavelength comes back in meters , convert to Hz f i r s t
radiance = upwardRadiance ( frequency , s e t t i n g s ) ;
// place in array
r e s u l t s [ i ] [ 0 ] = frequency ;
r e s u l t s [ i ] [ 1 ] = radiance ;
59. A.3 CRadtran.cpp 45
}
//now write r e s u l t s to f i l e
ok = w r i t e F i l e ( o u t p u t f i l e , re sult s , length , ppK) ;
// i f not defined , compile t h i s part
// otherwise don ’ t
#i f n d e f RUNTIME LIB
while ( ! ok )
{ // give user multiple chances to attempt to write output
cout << ”Would you l i k e to attempt to write again (y/n) ? ” ;
cin >> ans ;
// i f no , e x i t
i f ( ans == ’n ’ | | ans == ’N’ )
return −1;
// otherwise continue
cout << ”Do you want to change the output f i l e (y/n) ? ” ;
cin >> ans ;
i f ( ans == ’y ’ | | ans == ’Y’ )
{
cout << ” Please enter the name of the new f i l e : ” ;
cin >> o u t p u t f i l e ;
}
e l s e
{
cout << ”Attempting to write to f i l e . . . n” ;
}
ok = w r i t e F i l e ( o u t p u t f i l e , re sult s , length , ppK) ;
60. 46 Chapter A Source Code
}
cout << ”Write to output f i l e s u c c e s s f u l ! n” ;
#e l s e
i f ( ! ok )
return −2; // return error
#endif
return 0;
};
bool readFile ( s t r i n g filename , setup & s e t t i n g s )
{
// i n i t i a l i z a t i o n
ifstream f i n ;
s t r i n g temp ;
s t r i n g temp2 ;
//open f i l e
f i n . open ( filename . c s t r () ) ;
// check to i f opened
i f ( ! f i n . is open () )
{
// Print error
cerr << ”∗∗Unable to open ” << filename << ” !∗∗n” ;
return f a l s e ;
}
61. A.3 CRadtran.cpp 47
// read from f i l e
f i n >> temp ;
// check fo r type of run
i f (temp == ”Range” )
{ // get range
f i n >> s e t t i n g s . min ;
f i n >> s e t t i n g s .max;
// get s t e p s i z e
f i n >> temp ;
i f (temp == ”Step” )
{
f i n >> s e t t i n g s . step ;
}
e l s e // e l s e set to default s t e p s i z e of 1
s e t t i n g s . step = 1;
}
e l s e i f (temp == ”Frequency” | | temp == ” frequency ” )
{ // e l s e j u s t put in one frequency
f i n >> s e t t i n g s . min ;
s e t t i n g s .max = s e t t i n g s . min ;
s e t t i n g s . step = 1;
}
e l s e
{
cerr << ”∗∗ Invalid f i l e !∗∗n” ;
62. 48 Chapter A Source Code
f i n . c l o s e () ;
return f a l s e ;
}
// read in number of s l i c e s
f i n >> temp ;
i f (temp == ” s l i c e s ” | | temp == ” S l i c e s ” )
{
f i n >> s e t t i n g s .M;
}
e l s e
{
cerr << ”∗∗ Invalid f i l e !∗∗n” ;
f i n . c l o s e () ;
return f a l s e ;
}
// read in surface em is si vi ty
f i n >> temp ;
i f (temp == ” Emissivity ” | | temp == ” e mi ss iv it y ” )
{
f i n >> s e t t i n g s . epsilon ;
}
e l s e
{
cerr << ”∗∗ Invalid f i l e !∗∗n” ;
f i n . c l o s e () ;
63. A.3 CRadtran.cpp 49
return f a l s e ;
}
// read in surface temperature
f i n >> temp ;
f i n >> temp2 ;
i f (( temp==” Surface ” | | temp==” surface ” )&&(temp2==”Temperature” | |
→ temp2==” temperature ” ) )
{
f i n >> s e t t i n g s . surfaceTemperature ;
}
e l s e
{
cerr << ”∗∗ Invalid f i l e !∗∗n” ;
f i n . c l o s e () ;
return f a l s e ;
}
// read in option : Print K?
f i n >> temp ;
f i n >> temp2 ;
i f (( temp==” Print ” | | temp==” print ” )&&(temp2==” attenuation ” | |
→ temp2==” Attenuation ” ) )
{
f i n >> temp ;
i f (temp == ” true ” | | temp == ”TRUE” | | temp == ”True” )
s e t t i n g s . printK = true ;
64. 50 Chapter A Source Code
e l s e
s e t t i n g s . printK = f a l s e ;
}
// read optional max a l t i t u d e
f i n >> temp ;
f i n >> temp2 ;
i f (( temp==”Max” | | temp==”max” )&&(temp2==” Altitude ” | | temp2==”
→ a l t i t u d e ” ) )
{
f i n >> s e t t i n g s . max altitude ;
}
e l s e i f ( f i n . eof () )
{
s e t t i n g s . max altitude = A0;
}
e l s e
{
cerr << ”∗∗ Invalid f i l e ∗∗n” ;
}
i f ( f i n . f a i l () && ! f i n . eof () | | f i n . bad () )
{
cerr << ”∗∗ File read f a i l e d !∗∗n” ;
}
// c l o s e f i l e
65. A.3 CRadtran.cpp 51
f i n . c l o s e () ;
// return
return true ;
}
bool w r i t e F i l e ( s t r i n g filename , double data [ ] [ 2 ] , int length [ ] ,
→ double ∗∗ ppK)
{
// i n i t i a l i z e
ofstream fout ;
//open f i l e
fout . open ( filename . c s t r () ) ;
// fout . open (” example . txt ”) ;
// check that i t opens
i f ( ! fout . is open () )
{
cerr << ”∗∗Unable to open f i l e !∗∗n” ;
return f a l s e ;
}
// write r e s u l t s to output f i l e
fout << ”Freq (GHz) , Radiance” << endl ;
f or ( int i = 0; i < length [ 0 ] ; i++)
{
fout << data [ i ] [ 0 ] << ” , ” << data [ i ] [ 1 ] << endl ;
66. 52 Chapter A Source Code
}
// check again
i f ( fout . f a i l () )
{ // i f f a i l e d , notify user
cerr << ”∗∗Write to f i l e f a i l e d !∗∗n” ;
return f a l s e ;
}
// c l o s e f i l e
fout . c l o s e () ;
// true meaning s u c c e s s f u l
return true ;
}
A.4 calculate.h
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Header File :
∗ Header f i l e fo r c a l c u l a t e . cpp
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Contains function headers
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
67. A.4 calculate.h 53
→ ∗/
#i f n d e f CALCULATE H
#define CALCULATE H
// declare setup c l a s s
c l a s s setup
{
public :
setup ()
{
pKappa = NULL;
printK = f a l s e ;
};
double min ;
double max;
double step ;
int M;
double epsilon ;
double surfaceTemperature ;
double max altitude ;
bool printK ;
double ∗ pKappa ;
˜ setup ()
{
pKappa = NULL;
}
};
68. 54 Chapter A Source Code
double sliceTrans ( double k , double deltaZ ) ;
// double calcDensity ( double temperature , double pressure ) ;
double sum( double ∗pArray , int length ) ;
double atmosphereTerm ( double tau [ ] , double brightTemp [ ] , int
→ length ) ;
double reflectedTerm ( double tau [ ] , double brightness [ ] , int
→ length ) ;
double freqToWavelength ( double freq ) ;
double upwardRadiance ( double frequency , setup & s e t t i n g s ) ;
double calcPressure ( double a l t i t u d e ) ;
double wavelengthToFreq ( double wavelength ) ;
// constants
#define GRAV 9.81 // meters per second squared
#define A0 100000 // meters , Karman l i n e
#define IDEAL GAS CONST 0.286 // kJ/ kg/k
#define LAP RATE 0.0065 // K/m ( temperature lapse rate )
#define P0 101.325 //kPa ( sea l e v e l atm pressure )
#define T0 288.15 //K ( sea l e v e l standard temperature )
#endif // CALCULATE H
A.5 calculate.cpp
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
69. A.5 calculate.cpp 55
∗ c a l c u l a t e . cpp :
∗ Source code f o r c a l c u l a t i o n s
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ This c a l c u l a t e s and does i n t e g r a t i o n
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#include <iostream>
#include <cmath>
#include <cassert >
#include ” c a l c u l a t e . h”
#include ” brightness temp . h”
#include ” d a t a f i l e . h”
#include ” atten . h”
using namespace std ;
double upwardRadiance ( double frequency , setup & s e t t i n g s )
{
// i n t i a l i z a t i o n
int M = s e t t i n g s .M; //M i s the number of s l i c e s
// create an array
double tau [M] ;
double brightTemp [M] ;
double k [M] ;
70. 56 Chapter A Source Code
s e t t i n g s . pKappa = k ;
// i n t i a l i z e everything e l s e
double deltaZ = s e t t i n g s . max altitude /(( double )M) ; // length of
→ s l i c e
double epsilon = s e t t i n g s . epsilon ; // e mi ss iv it y constant
// surface temperature in Kelvin
double surfaceTemp = s e t t i n g s . surfaceTemperature ;
double bright Temp Surface , firstTerm , secondTerm , thirdTerm ,
→ pressure ,
temperature , totalTrans ;
// set up d a t a f i l e object
d a t a f i l e data ( ”TIGR0001” ) ;
// read our data in
data . readFile ( true ) ;
// setup oxgenAtten object
oxygenAtten kappa(&data ) ;
// c a l c u l a t i o n s
// c a l c u l a t e transmission f or each s l i c e
f or ( int i = 0; i < M; i++)
{
// set our a l t i t u d e
data . setAltitude ( i ∗ deltaZ ) ;
71. A.5 calculate.cpp 57
// set frequency
data . setFreq ( frequency ) ;
// r e s e t kappa
kappa . resetValues () ;
// c a l c u l a t e attenuation constant
k [ i ] = kappa . getValue () ;
// get pressure fo r s l i c e
pressure = data . getPressure () ;
a s s e r t ( pressure >= 0) ;
// get temperature f or s l i c e
temperature = data . getTemperature () ;
// c a l c u l a t e o p t i c a l length f or s l i c e
tau [ i ] = sliceTrans (k [ i ] , deltaZ ) ;
a s s e r t ( tau [ i ] >= 0) ;
// c a l c u l a t e Brightness temp fo r s l i c e
brightTemp [ i ] = planckv ( frequency ∗1e9 , temperature ) ;
}
// c a l c u l a t e blackbody radiation of surface
bright Temp Surface = planckv ( frequency ∗1e9 , surfaceTemp ) ;
//sum a l l the values up
72. 58 Chapter A Source Code
totalTrans = sum( tau ,M) ;
//now c a l c u l a t e f i r s t term
firstTerm = epsilon ∗ bright Temp Surface ∗exp(−totalTrans ) ;
// c a l c u l a t e second term
secondTerm = atmosphereTerm ( tau , brightTemp , M) ;
// c a l c u l a t e third and l a s t term
thirdTerm = (1− epsilon ) ∗ reflectedTerm ( tau , brightTemp , M) ;
//add terms and return value
return firstTerm + secondTerm + thirdTerm ;
};
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Function : sliceTrans
∗ Parameters : double k , double deltaZ
∗ Returns : double tau
∗ Calculates the o p t i c a l depth of s l i c e of a i r
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double sliceTrans ( double k , double deltaZ )
{
// c a l c u l a t e o p t i c a l depth
return 0.23025∗k∗ deltaZ /1000;
73. A.5 calculate.cpp 59
};
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Function : sum
∗ Parameters : double array
∗ Returns : double t o t a l
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double sum( double ∗pArray , int length )
{
long double t o t a l = 0;
f or ( int i = 0; i < length ; i++)
{
t o t a l += pArray [ i ] ;
}
return t o t a l ;
};
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Function : atmosphereTerm
∗ Parameters : array tau , array brightness , integer length
∗ Returns : double r e s u l t
∗ Summary : c a l c u l a t e s value f o r second term in general r a d i a t i v e
74. 60 Chapter A Source Code
∗ t r a n s f e r equation
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double atmosphereTerm ( double tau [ ] , double brightness [ ] , int
→ length )
{
double value = 0;
double sum1 = 0;
double sum2 = tau [ length − 1 ] ;
f or ( int i = length − 2; i > 0; i −−)
{ //sum up
sum1 += tau [ i +1];
sum2 += tau [ i ] ;
// c a l c u l a t e t o t a l value
value += brightness [ i ] ∗ ( exp(−sum1) − exp(−sum2) ) ;
}
return value ;
};
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Function : reflectedTerm
∗ Parameters : array tau , array brightness , integer length
∗ Returns : double r e s u l t
∗ Summary : c a l c u l a t e s value f o r third term in general r a d i a t i v e
∗ t r a n s f e r equation
75. A.5 calculate.cpp 61
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double reflectedTerm ( double tau [ ] , double brightness [ ] , int
→ length )
{
double value = 0;
double sum1 = tau [ 0 ] ;
double sum2 = 0;
f or ( int i = 1; i < length −1; i++)
{
sum1 += tau [ i ] ;
sum2 += tau [ i −1];
value += brightness [ i ] ∗ ( exp(−sum1) − exp(−sum2) ) ;
}
return value ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Function : frequency to wavelength
∗ Parameters : double frequency
∗ Returns : wavelength
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double freqToWavelength ( double freq )
{
76. 62 Chapter A Source Code
return SPEED OF LIGHT/ freq ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Function : wavelength to frequency
∗ Parameters : double wavelength
∗ Returns : frequency
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double wavelengthToFreq ( double wavelength )
{
return SPEED OF LIGHT/wavelength ;
}
A.6 brightness temp.h
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Header File :
∗ brightness temp . h
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Header f i l e fo r planck functions
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
77. A.7 brightness temp.cpp 63
→ ∗/
#i f n d e f BRIGHTNESS TEMP H
#define BRIGHTNESS TEMP H
//now define some s t u f f
#define PLANCK CONST 6.62606957 // ∗10ˆ−34 Joule−Seconds
#define SPEED OF LIGHT 299792458 // meters per second
#define BOLTZMAN CONST 1.3806488 //∗10ˆ−23 Joule per Kelvin
long double planckv ( double freq , double temp) ;
long double planckw ( double wavelength , double temp) ;
#endif // BRIGHTNESS TEMP H
A.7 brightness temp.cpp
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Source Code :
∗ brightness temp . cpp
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Calculates blackbody radiation , using Planck ’ s equation
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#include <iostream>
78. 64 Chapter A Source Code
#include <cstdlib >
#include <cmath>
#include ” brightness temp . h”
using namespace std ;
long double planckv ( double freq , double temp)
{ // c a l c u l a t e s blackbody radiation using frequency in Hz
long double B;
long double c = SPEED OF LIGHT;
long double h = PLANCK CONST∗pow(10 , −34) ;
long double kB = BOLTZMAN CONST∗pow(10 , −23) ;
B = 2∗h∗pow( freq , 3) /pow( c , 2) ∗1/( exp (h∗ freq /(kB∗temp) ) − 1) ;
return B;
};
long double planckw ( double wave , double temp)
{ // c a l c u l a t e s blackbody radiation using wavelength in meters
long double B;
long double c = SPEED OF LIGHT;
long double h = PLANCK CONST∗pow(10 , −34) ;
long double kB = BOLTZMAN CONST∗pow(10 , −23) ;
B = 2∗h∗pow( c , 2 ) /pow(wave , 5 ) ∗1/( exp (h∗c /(wave∗kB∗temp) ) − 1) ;
return B;
};
A.8 datafile.h
79. A.8 datafile.h 65
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Header File :
∗ d a t a f i l e . h
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Header f o r d a t a f i l e . cpp
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#i f n d e f DATA FILE H
#define DATA FILE H
#include <map>
#include <string >
// typedef
typedef std : : map<double , double >:: i t e r a t o r mIter ;
c l a s s d a t a f i l e
{
public :
// constructors
d a t a f i l e () ;
d a t a f i l e ( std : : s t r i n g s ) ;
d a t a f i l e ( double a l t ) ;
80. 66 Chapter A Source Code
d a t a f i l e ( std : : s t r i n g s , double a l t ) ;
d a t a f i l e ( std : : s t r i n g s , std : : s t r i n g t ) ;
d a t a f i l e ( std : : s t r i n g s , std : : s t r i n g t , double a l t ) ;
// g e t t e r s
std : : s t r i n g getDirectory () { return directory ; };
std : : s t r i n g getFilename () ;
std : : s t r i n g getFullPath () ;
double getAltitude () { return a l t i t u d e ; }; // a l t i t u d e in meters
double getFreq () { return frequency ; }; // frequency in GHz
// s e t t e r s
void setDirectory ( std : : s t r i n g d) ;
void setFilename ( std : : s t r i n g f ) ;
void setAltitude ( double a l t ) { a l t i t u d e = a l t ; }; // a l t i t u d e in
→ meters
void setFreq ( double freq ) { frequency = freq ; }; // frequency in
→ GHz
// u s e f u l functions
bool hasFileName () { return ! filename . empty () ; };
bool readFile ( bool hasHead ) ;
bool readCsvFile ( bool hasHead ) ;
bool convertFile ( const char filename [ ] ) ;
double getTemperature () ; // in Kelvin
double getPressure () ; // in milibars
double getHumidity () ;
void displayData () ;
private :
bool endWord( char presChar , char prevChar , char futChar ) ;
81. A.9 datafile.cpp 67
void convertFileOutName ( char s t r [ ] ) ;
double i n t e r p o l a t e ( int type ) ;
std : : s t r i n g directory ; // working directory of our object
std : : s t r i n g filename ; // filename
std : : map<double , double> temperature ;
std : : map<double , double> pressure ;
std : : map<double , double> humidity ;
double a l t i t u d e ; // a l t i t u d e in meters ?
double frequency ; // frequency in GHz
};
#endif // DATA FILE H
A.9 datafile.cpp
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Source Code :
∗ Source code f o r d a t a f i l e . cpp
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Reads f i l e in , using filename from user , and s t o r e s data in
→ l o c a l
∗ memory . Stores temperature , pressure , and r e l a t i v e humidity
→ .
∗ Linearly i n t e r p o l a t e s values not in table .
82. 68 Chapter A Source Code
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#include <iostream>
#include <unistd . h>
#include <iomanip>
#include <fstream>
#include <vector>
#include <string >
#include <cstring >
#include ” d a t a f i l e . h”
using namespace std ;
// typedef
typedef map<double , double >:: i t e r a t o r mIter ;
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Default Constructor
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
d a t a f i l e : : d a t a f i l e ()
{
char cwd [ 2 5 5 ] ;
getcwd (cwd , 255) ; // get current working directory
directory = cwd ; // place char array in s t r i n g directory
a l t i t u d e = 0;
83. A.9 datafile.cpp 69
frequency = 0.00001;
// cout << ” I ’ ve been i n i t i a l i z e d , yay” << endl ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Constructor that takes s t r i n g f o r filename
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
d a t a f i l e : : d a t a f i l e ( s t r i n g s ) : filename ( s )
{
char cwd [ 2 5 5 ] ;
getcwd (cwd , 255) ;
directory = cwd ;
a l t i t u d e = 0;
frequency = 0.00001; // j u s t to eliminate divide by zero error
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Constructor that takes a l t i t u d e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
d a t a f i l e : : d a t a f i l e ( double a l t )
{
char cwd [ 2 5 5 ] ;
84. 70 Chapter A Source Code
getcwd (cwd , 255) ;
directory = cwd ;
a l t i t u d e = a l t ;
frequency = 0.00001;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Constructor takes filename and a l t i t u d e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
d a t a f i l e : : d a t a f i l e ( s t r i n g s , double a l t ) : filename ( s )
{
char cwd [ 2 5 5 ] ;
getcwd (cwd , 255) ;
directory = cwd ;
a l t i t u d e = a l t ;
frequency = 0.00001;
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ Constructor takes filename and directory
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
d a t a f i l e : : d a t a f i l e ( s t r i n g s , s t r i n g t ) : filename ( s ) , directory ( t
→ )
85. A.9 datafile.cpp 71
{
a l t i t u d e = 0;
frequency = 0.00001;
};
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Constructor takes a l l of the above
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
d a t a f i l e : : d a t a f i l e ( s t r i n g s , s t r i n g t , double a l t ) : filename ( s ) ,
→ directory ( t )
{
a l t i t u d e = a l t ;
frequency = 0.00001;
};
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ Function : getFilename ()
∗ Parameters : none
∗ Returns : s t r i n g
∗ Summary : Returns the filename being loaded from
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
s t r i n g d a t a f i l e : : getFilename ()
{
i f ( filename . empty () )
86. 72 Chapter A Source Code
{
cerr << ”No filename yet . ” ;
return filename ;
}
e l s e
return filename ;
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET FULL PATH: gets the current directory of object
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
s t r i n g d a t a f i l e : : getFullPath ()
{
i f ( filename . empty () )
throw ( ”There i s no filename ” ) ;
return directory + ”/” + filename ;
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ DISPLAY DATA: display data in table
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
void d a t a f i l e : : displayData ()
{
map<double , double >:: i t e r a t o r i t ;
// display header
cout << setw (8) << ” Altitude ” ;
cout << setw (8) << ”Temperature ” ;
87. A.9 datafile.cpp 73
i f ( ! pressure . empty () )
cout << setw (8) << ” Pressure ” ;
i f ( ! humidity . empty () )
cout << setw (8) << ”Humidity” ;
cout << endl ;
// loop through values
f or ( i t = temperature . begin () ; i t != temperature . end () ; i t++)
{
double temp = it −>f i r s t ;
cout << setw (8) << it −>f i r s t << ” ” ; // print a l t i t u d e
cout << setw (8) << it −>second << ” ” ; // print temperature
i f ( ! pressure . empty () )
cout << ” ” << setw (8) << pressure [ temp ] ; // print
→ pressure
i f ( ! humidity . empty () )
cout << ” ” << setw (8) << humidity [ temp ] ; // print
→ humidity
cout << endl ; // print l i n e carriage
}
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ SET DIRECTORY: set working directory
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
void d a t a f i l e : : setDirectory ( s t r i n g d)
{
88. 74 Chapter A Source Code
directory = d ;
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ SET FILENAME: set filename
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
void d a t a f i l e : : setFilename ( s t r i n g f )
{
filename = f ;
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ READ FILE : Read in data into maps
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
bool d a t a f i l e : : readFile ( bool hasHead )
{
// check to see i f has filename
i f ( filename . empty () )
{
cerr << ”There i s no filename ” ;
throw ( ”No filename ” ) ;
}
// i n i t i a l i z e
s t r i n g f i l e p a t h ;
double temp ;
double temp2 ;
ifstream f i n ;
89. A.9 datafile.cpp 75
//open f i l e
f i l e p a t h = getFullPath () ;
f i n . open ( f i l e p a t h . c s t r () ) ;
// check to see i f i t opened
i f ( f i n . f a i l () )
{
cout << ” File opening has f a i l e d n” ;
return f a l s e ;
}
// read f i l e
// ignore f i r s t l i n e i f has header
i f ( hasHead )
{
f i n . ignore (256 , ’ n ’ ) ;
}
// read in data
while ( ! f i n . eof () )
{
f i n >> temp ; // read in pressure
f i n >> temp2 ; // read in a l t i t u d e
pressure . i n s e r t ( std : : pair<double , double >(temp2 , temp) ) ;
f i n >> temp ; // read in temperature
temperature . i n s e r t ( std : : pair<double , double >(temp2 , temp) ) ;
f i n >> temp ; // read in humidity
humidity . i n s e r t ( std : : pair<double , double >(temp2 , temp) ) ;
90. 76 Chapter A Source Code
}
// c l o s e f i l e
f i n . c l o s e () ;
return true ;
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ READ CSV FILE : read in two column data
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
bool d a t a f i l e : : readCsvFile ( bool hasHead )
{
// check to see i f has filename
i f ( filename . empty () )
{
cerr << ”There i s no filename ” ;
throw ( ”No filename ” ) ;
}
// i n i t i a l i z e
double temp ;
double temp2 ;
s t r i n g f i l e p a t h ;
ifstream f i n ;
//open f i l e
f i l e p a t h = getFullPath () ;
f i n . open ( f i l e p a t h . c s t r () ) ;
// check to see i f i t opened
91. A.9 datafile.cpp 77
i f ( f i n . f a i l () )
{
cout << ” File opening has f a i l e d ” << endl ;
return f a l s e ;
}
// read f i l e
// ignore f i r s t l i n e i f has header
i f ( hasHead )
{
f i n . ignore (256 , ’ n ’ ) ; // ignore f i r s t l i n e
}
// read in data
do
{
// read f i r s t item on l i n e
f i n >> temp ;
f i n . ignore (1 , ’ n ’ ) ; // ignore newline character
// read second item on l i n e
f i n >> temp2 ;
// place in map
temperature . i n s e r t ( std : : pair<double , double >(temp , temp2 ) ) ;
f i n . ignore (1 , ’ n ’ ) ; // ignore comma
}
while ( ! f i n . eof () ) ;
// c l o s e f i l e
f i n . c l o s e () ;
return true ;
92. 78 Chapter A Source Code
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET TEMPERATURE: Gets temperature at set a l t i t u d e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double d a t a f i l e : : getTemperature ()
{// get value from map
i f ( temperature . empty () )
{
cerr << ” File i s not read in ! n” ;
return −1;
}
// f i r s t create map i t e r a t o r
map<double , double >:: i t e r a t o r i t ;
// get temperature
i t = temperature . find ( a l t i t u d e ) ;
i f ( i t == temperature . end () ) // i f point not found , return −1
{
return i n t e r p o l a t e (1) ;
}
e l s e
{
return temperature [ a l t i t u d e ] ; // i f found return value
}
}
93. A.9 datafile.cpp 79
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET PRESSURE: Get pressure at set a l t i t u d e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double d a t a f i l e : : getPressure ()
{ // r e t r i e v e value from map
i f ( pressure . empty () )
{
cerr << ” File i s not read in ! n” ;
return −1;
}
// a l l o c a t e i t e r a t o r
map<double , double >:: i t e r a t o r i t ;
// get pressure
// cout << ” getPressure running ! n ”;
i t = pressure . find ( a l t i t u d e ) ;
i f ( i t == pressure . end () ) // i f point not found , return −1
return i n t e r p o l a t e (2) ;
e l s e
{
return pressure [ a l t i t u d e ] ; // i f found return value
}
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET HUMIDITY: Get humidity at set a l t i t u d e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
94. 80 Chapter A Source Code
double d a t a f i l e : : getHumidity ()
{ // r e t r i e v e value from map
i f ( humidity . empty () )
{
cerr << ” File i s not read in ! n” ;
return −1;
}
// a l l o c a t e i t e r a t o r
map<double , double >:: i t e r a t o r i t ;
// get humidity
i t = humidity . find ( a l t i t u d e ) ;
i f ( i t == humidity . end () ) // i f point not found , return −1
return i n t e r p o l a t e (3) ;
e l s e
{
return humidity [ a l t i t u d e ] ;
}
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ INTERPOLATE: Linearly i n t e r p o l a t e s between two values
∗ in our table
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double d a t a f i l e : : i n t e r p o l a t e ( int type )
{ // l i n e a r i n t e r p o l a t i o n between two points
// cout << ” Interpolate running ! n ”;
map<double , double> ∗ mptr ;
95. A.9 datafile.cpp 81
// set mptr to right map
switch ( type )
{
case 1: // temperature
mptr = &temperature ;
break ;
case 2: // pressure
mptr = &pressure ;
break ;
case 3: // humidity
mptr = &humidity ;
break ;
}
//do boundary check
//need to be changed to deal with proper
// i n t e r p o l a t i o n at boundaries .
map<double , double >:: i t e r a t o r i t ;
// check to see i f a l t i t u d e i s p o s i t i v e
i f ( a l t i t u d e < 0)
{
cerr << ” Altitude out of range ! n” << endl ;
i t = mptr−>begin () ;
return it −>second ;
}
i t = mptr−>end () ;
it −−;
96. 82 Chapter A Source Code
i f ( a l t i t u d e > it −>f i r s t )
{
return it −>second ;
}
// find upper and lower points to i n t e r p o l a t e
mIter upper = mptr−>upper bound ( a l t i t u d e ) ;
mIter lower = mptr−>upper bound ( a l t i t u d e ) ;
lower −−;
// c a l c u l a t e point
double xa = lower−>f i r s t ; //x of f i r s t point
double ya = lower−>second ; //y of f i r s t point
double xb = upper−>f i r s t ; //x of second point
double yb = upper−>second ; //y of second point
// l i n e a r i n t e r p o l a t i o n formula from
// https :// en . wikipedia . org / wiki / L i n e a r i n t e r p o l a t i o n
return ya + (yb − ya ) ∗( a l t i t u d e − xa ) /(xb − xa ) ;
}
A.10 atten.h
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Header File :
∗ atten . h attenuation c l a s s
∗ Author :
97. A.10 atten.h 83
∗ Alexander Marvin
∗ Summary :
∗ Calculates attenuation constant kappa f or d i f f e r e n t s l i c e s
→ of atmosphere .
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#i f n d e f ATTEN H
#define ATTEN H
#include ” d a t a f i l e . h”
c l a s s atten
{
public :
atten () ;
double getValue ( double a l t i t u d e ) ;
private :
// f r i e n d oxygenAtten ;
};
#define C1 2.6742 // d e c i b e l s per kilometer
c l a s s oxygenAtten
{
public :
oxygenAtten ( d a t a f i l e ∗ d) ; // r e c e i v e pointer f o r d a t a f i l e
double getValue () ;
98. 84 Chapter A Source Code
void resetValues () ;
private :
// v a r i a b l e s
double P; // pressure
double v ; // frequency
double T; // temperature
d a t a f i l e ∗ data ; // pointer to data
// functions
void setValues () ;
double rotationalStateSum () ;
double r o t a t i o n a l S t a t e ( int N) ;
double lineWidth () ;
double getBeta () ;
double getTransitionPlus ( int N) ;
double getTransitionMinus ( int N) ;
};
c l a s s waterVaporAtten
{
waterVaporAtten ( d a t a f i l e & d) ;
};
#endif // ATTEN H
A.11 oxygenAtten.cpp
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
99. A.11 oxygenAtten.cpp 85
→
∗ oxygenAtten . cpp :
∗ Source code f o r oxygenAtten . cpp
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Calculate the attenuation constant kappa fo r oxygen at the
→ given
∗ a l t i t u d e and frequency
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#include <iostream>
#include <cmath>
#include <cassert >
#include ” atten . h”
using namespace std ;
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Non−default constructor
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
oxygenAtten : : oxygenAtten ( d a t a f i l e ∗ d)
{
data = NULL; //make sure we have no bad pointer
data = d ;
100. 86 Chapter A Source Code
// set the values ( copy from d a t a f i l e c l a s s )
setValues () ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Reset values : copy over a l l the values again
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
void oxygenAtten : : resetValues ()
{
setValues () ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ Set values : helper function , copy from d a t a f i l e
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
void oxygenAtten : : setValues ()
{
v = data−>getFreq () ; //GHz
P = ( data−>getPressure () ) ∗0.750; // Expecting milibar , convert
→ to mmHg
101. A.11 oxygenAtten.cpp 87
T = data−>getTemperature () ; //K
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ GET VALUE: Return the calculated value of kappa
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double oxygenAtten : : getValue ()
{
return C1∗P∗pow(v , 2 ) /pow(T, 3) ∗ rotationalStateSum () ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ rotationalStateSum :
∗ Sum a l l the odd r o t a t i o n a l s t a t e s of oxygen from 1 to 45
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double oxygenAtten : : rotationalStateSum ()
{
// i n i t i a l i z e sum
double sum = 0;
// loop through a l l odd s t a t e s
f or ( int N = 1; N <= 45; N += 2)
102. 88 Chapter A Source Code
{
sum += r o t a t i o n a l S t a t e (N) ∗exp ( −2.06844∗N∗(N+1)/T) ;
}
return sum ;
}
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ r o t a t i o n a l S t a t e :
∗ c a l c u l a t e r o t a t i o n a l state of oxygen . The r o t a t i o n a l state i s
→ known
∗ as f a c t o r FN with N subscripted in the Meeks and L i l l e y paper .
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
double oxygenAtten : : r o t a t i o n a l S t a t e ( int N)
{
// underscore denotes subscript in these comments
// c a l c u l a t e term muˆ2 N+
long double muNPlusSqr = N∗(2∗N+3)/(N+1) ;
// c a l c u l a t e term muˆ2 N−
long double muNMinusSqr = (N+1)∗(2∗N+1)/N;
// c a l c u l a t e term muˆ2 NO
long double muNOSqr = 2∗(N∗N+N+1)∗(2∗N+1)/(N∗(N+1)) ;
// c a l c u l a t e delta V or l i n e broadening
long double deltaV = lineWidth () /1000; // convert to Gigacyles
// get resonant frequency v N+
103. A.11 oxygenAtten.cpp 89
long double VnPlus = getTransitionPlus (N) ;
a s s e r t ( VnPlus != −1) ;
// get resonant frequency v N−
long double VnMinus = getTransitionMinus (N) ;
a s s e r t (VnMinus != −1) ;
// c a l c u l a t e term F O
long double FO = deltaV /(pow(v , 2 )+pow( deltaV , 2 ) ) ;
// c a l c u l a t e F N+
long double FNPlus = deltaV /(pow( VnPlus−v , 2 )+pow( deltaV , 2 ) ) ;
FNPlus += deltaV /(pow( VnPlus+v , 2 )+pow( deltaV , 2 ) ) ;
// c a l c u l a t e F N−
long double FNMinus = deltaV /(pow(VnMinus−v , 2 )+pow( deltaV , 2 ) ) ;
FNMinus += deltaV /(pow(VnMinus+v , 2 )+pow( deltaV , 2 ) ) ;
// f i n a l c a l c u l a t i o n s
return FNPlus∗muNPlusSqr+FNMinus∗muNMinusSqr+FO∗muNOSqr; //
→ Gigacyles
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ LINE WIDTH: Calculate the l i n e width Delta nu
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double oxygenAtten : : lineWidth ()
{
return 1.95∗P∗(0.21+0.78∗ getBeta () ) ∗pow(300/T, 0 . 8 5 ) ; //
→ Megacycles
}
104. 90 Chapter A Source Code
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET BETA: Calculate beta according to a piecewise function
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double oxygenAtten : : getBeta ()
{
// set H1 and H2
int H1 = 12; //km
int H2 = 25; //km
// get a l t i t u d e
double h = ( data−>getAltitude () ) /1000; // convert to km
// cout << ” Altitude i s ” << h << endl ;
i f (h < H1)
return 0 . 2 5 ; // u n i t l e s s
e l s e i f (H1 <= h && h <= H2)
return 0.25+0.5∗(h − H1) /(H2 − H1) ; // u n i t l e s s
e l s e i f (h > H2)
return 0 . 7 5 ; // u n i t l e s s
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET TRANSITION +: Return oxygen t r a n s i t i o n frequency from
∗ Meeks and L i l l e y table , according to the energy l e v e l or
→ quantum
∗ number N
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double oxygenAtten : : getTransitionPlus ( int N)
{
105. A.11 oxygenAtten.cpp 91
switch (N)
{
case 1: return 56.2648;
case 3: return 58.4466;
case 5: return 59.5910;
case 7: return 60.4348;
case 9: return 61.1506;
case 11: return 61.8002;
case 13: return 62.4112;
case 15: return 62.9980;
case 17: return 63.5685;
case 19: return 64.1272;
case 21: return 64.6779;
case 23: return 65.2240;
case 25: return 65.7626;
case 27: return 66.2978;
case 29: return 66.8313;
case 31: return 67.3627;
case 33: return 67.8923;
case 35: return 68.4205;
case 37: return 68.9478;
case 39: return 69.4741;
case 41: return 70.0000;
case 43: return 70.5249;
case 45: return 71.0497;
default : return −1;
}
106. 92 Chapter A Source Code
}
/∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
∗ GET TRANSITION −: Return oxygen t r a n s i t i o n frequency from
∗ Meeks and L i l l e y table , according to the energy l e v e l or
→ quantum
∗ number N
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
double oxygenAtten : : getTransitionMinus ( int N)
{
switch (N)
{
case 1: return 118.7505;
case 3: return 62.4863;
case 5: return 60.3061;
case 7: return 59.1642;
case 9: return 58.3239;
case 11: return 57.6125;
case 13: return 56.9682;
case 15: return 56.3634;
case 17: return 55.7839;
case 19: return 55.2214;
case 21: return 54.6728;
case 23: return 54.1294;
case 25: return 53.5960;
case 27: return 53.0695;
case 29: return 52.5458;
107. A.11 oxygenAtten.cpp 93
case 31: return 52.0259;
case 33: return 51.5091;
case 35: return 50.9949;
case 37: return 50.4830;
case 39: return 49.9730;
case 41: return 49.4648;
case 43: return 48.9582;
case 45: return 48.4530;
default : return −1;
}
}
109. Appendix B
Test Code
B.1 testDataFile.cpp
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
∗ source code :
∗ Source code f o r testDataFile . cpp
∗ Author :
∗ Alexander Marvin
∗ Summary :
∗ Tests to make sure readFile and w r i t e F i l e work
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→ ∗/
#include <iostream>
#include <string >
#include <vector>
#include <cassert >
95
110. 96 Chapter B Test Code
#include ” d a t a f i l e . h”
using namespace std ;
int main ()
{
// i n i t i a l i z e
bool success ;
double key ;
double value ;
cout << ” testDataFile here n” ;
s t r i n g directory = ”/home/amarvin/ bin / research / temperatures . csv
→ ” ;
s t r i n g filename = ” temperatures . csv ” ;
d a t a f i l e data ;
cout << ”Current working directory i s : ” << data . getDirectory ()
→ << endl ;
cout << ” Is filename empty? ” << ( ! data . hasFileName () ? ”Yes” :
→ ”No” ) << endl ;
i f ( data . hasFileName () )
cout << ” Full path i s ” << data . getFullPath () << endl ;
cout << ” Altitude i s ” << data . getAltitude () << endl ;
cout << ”Frequency i s ” << data . getFreq () << endl ;
d a t a f i l e data2 ( ” temperatures . csv ” ) ;
data2 . setAltitude (56) ;
data2 . setFreq (45) ;
cout << ”Filename i s : ” << data2 . getFilename () << endl ;
cout << ” Full path i s : ” << data2 . getFullPath () << endl ;