SlideShare a Scribd company logo
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
Copyright c 2016 Alexander J. Marvin
All Rights Reserved
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
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].
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.
Contents
Table of Contents xi
List of Figures xiii
1 Introduction 1
2 Background and Theory 3
2.1 General radiative transfer equation . . . . . . . . . . . . . . . . . . . 3
2.2 Oxygen attenuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3 Methods 21
4 Results and Discussion 25
5 Conclusion 29
5.1 Future work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Bibliography 31
A Source Code 33
A.1 makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
A.2 README.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
A.3 CRadtran.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
A.4 calculate.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
A.5 calculate.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
A.6 brightness temp.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
A.7 brightness temp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
A.8 datafile.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
A.9 datafile.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
A.10 atten.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
A.11 oxygenAtten.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
B Test Code 95
B.1 testDataFile.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
xi
xii CONTENTS
B.2 testOxyAtten.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
List of Figures
2.1 A slice of air . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Our Euclidean system . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Distance s of the light . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 The whole atmosphere . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 The responsivity of a theoretical instrument . . . . . . . . . . . . . . 13
4.1 Oxygen attenuation constants . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Comparison of RADTRAN and CRadtran . . . . . . . . . . . . . . . 27
xiii
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
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.
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
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
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)
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)
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)
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)
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)
10 Chapter 2 Background and Theory
Figure 2.4 The whole atmosphere
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)
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)
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)
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)
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
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)
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)
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.
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)
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].
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
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
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
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].
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
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
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.
28 Chapter 4 Results and Discussion
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
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.
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
32 BIBLIOGRAPHY
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
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
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
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
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
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 :
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
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
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 :
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 )
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 ] ;
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 ;
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) ;
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 ;
}
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” ;
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 () ;
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 ;
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
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 ;
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
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
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;
}
};
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
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
→
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] ;
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 ) ;
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
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;
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
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
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 )
{
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
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
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>
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
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 ) ;
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 ) ;
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 .
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;
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 ] ;
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
→ )
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 () )
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 ” ;
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)
{
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 ;
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) ) ;
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
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 ;
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
}
}
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
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
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 ;
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 −−;
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 :
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 () ;
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
/∗
→ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
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 ;
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
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)
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+
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
}
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)
{
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;
}
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;
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;
}
}
94 Chapter A Source Code
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
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 ;
Alex_MarvinS16
Alex_MarvinS16
Alex_MarvinS16
Alex_MarvinS16
Alex_MarvinS16

More Related Content

What's hot

Finite Volume Method For Predicting Radiant Heat Transfer
Finite Volume Method For Predicting Radiant Heat TransferFinite Volume Method For Predicting Radiant Heat Transfer
Finite Volume Method For Predicting Radiant Heat Transfer
Rajibul Alam
 
Dce a novel delay correlation
Dce a novel delay correlationDce a novel delay correlation
Dce a novel delay correlation
ijdpsjournal
 
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxy
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxyA kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxy
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxy
Sérgio Sacani
 
PRML 9.1-9.2: K-means Clustering & Mixtures of Gaussians
PRML 9.1-9.2: K-means Clustering & Mixtures of GaussiansPRML 9.1-9.2: K-means Clustering & Mixtures of Gaussians
PRML 9.1-9.2: K-means Clustering & Mixtures of Gaussians
Shinichi Tamura
 
Kalman filter for object tracking
Kalman filter for object trackingKalman filter for object tracking
Kalman filter for object trackingMohit Yadav
 
AY121 Lab4 (Jonathan Kao) Final
AY121 Lab4 (Jonathan Kao) FinalAY121 Lab4 (Jonathan Kao) Final
AY121 Lab4 (Jonathan Kao) FinalJonathan Kao
 

What's hot (8)

ProjectReport
ProjectReportProjectReport
ProjectReport
 
Finite Volume Method For Predicting Radiant Heat Transfer
Finite Volume Method For Predicting Radiant Heat TransferFinite Volume Method For Predicting Radiant Heat Transfer
Finite Volume Method For Predicting Radiant Heat Transfer
 
bakerca2Thesis2s
bakerca2Thesis2sbakerca2Thesis2s
bakerca2Thesis2s
 
Dce a novel delay correlation
Dce a novel delay correlationDce a novel delay correlation
Dce a novel delay correlation
 
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxy
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxyA kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxy
A kiloparsec scale_internal_shock_collision_in_the_jet_of_a_nearby_radio_galaxy
 
PRML 9.1-9.2: K-means Clustering & Mixtures of Gaussians
PRML 9.1-9.2: K-means Clustering & Mixtures of GaussiansPRML 9.1-9.2: K-means Clustering & Mixtures of Gaussians
PRML 9.1-9.2: K-means Clustering & Mixtures of Gaussians
 
Kalman filter for object tracking
Kalman filter for object trackingKalman filter for object tracking
Kalman filter for object tracking
 
AY121 Lab4 (Jonathan Kao) Final
AY121 Lab4 (Jonathan Kao) FinalAY121 Lab4 (Jonathan Kao) Final
AY121 Lab4 (Jonathan Kao) Final
 

Similar to Alex_MarvinS16

M2 Internship report rare-earth nickelates
M2 Internship report rare-earth nickelatesM2 Internship report rare-earth nickelates
M2 Internship report rare-earth nickelatesYiteng Dang
 
Characterization Studies of a CdTe Pixelated Timepix Detector for Applicatio...
Characterization Studies of a  CdTe Pixelated Timepix Detector for Applicatio...Characterization Studies of a  CdTe Pixelated Timepix Detector for Applicatio...
Characterization Studies of a CdTe Pixelated Timepix Detector for Applicatio...Costa Papadatos
 
GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...
GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...
GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...Mario Javier Rincón Pérez
 
SURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONS
SURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONSSURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONS
SURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONS
Journal For Research
 
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...
Journal For Research
 
TunnelSpectroscopy v2
TunnelSpectroscopy v2TunnelSpectroscopy v2
TunnelSpectroscopy v2Arash Zeinali
 
Emission Line Objects in Integral Field Spectroscopic Datacubes
Emission Line Objects in Integral Field Spectroscopic DatacubesEmission Line Objects in Integral Field Spectroscopic Datacubes
Emission Line Objects in Integral Field Spectroscopic Datacubes
Edmund Christian Herenz
 
Optical Absoprtion of Thin Film Semiconductors
Optical Absoprtion of Thin Film SemiconductorsOptical Absoprtion of Thin Film Semiconductors
Optical Absoprtion of Thin Film Semiconductors
Enrico Castro
 
Dynamics of cold atoms in moving optical lattices (Version Dek8)
Dynamics of cold atoms in moving optical lattices (Version Dek8)Dynamics of cold atoms in moving optical lattices (Version Dek8)
Dynamics of cold atoms in moving optical lattices (Version Dek8)Nadal Sarkytbayev
 
Kinetic growth of binary compounds by reactive magnetron sputtering
Kinetic growth of binary compounds by reactive magnetron sputteringKinetic growth of binary compounds by reactive magnetron sputtering
Kinetic growth of binary compounds by reactive magnetron sputtering
Javier García Molleja
 
Photometry of the UWISH2 extended H2 source catalogue
Photometry of the UWISH2 extended H2 source cataloguePhotometry of the UWISH2 extended H2 source catalogue
Photometry of the UWISH2 extended H2 source catalogueJack Nicholas
 
Senior Research paper
Senior Research paperSenior Research paper
Senior Research paperEvan Foley
 
daniel_kok_4_maart_2021 (2).pdf
daniel_kok_4_maart_2021 (2).pdfdaniel_kok_4_maart_2021 (2).pdf
daniel_kok_4_maart_2021 (2).pdf
AnkitBiswas31
 
SeniorThesis_DempseyRogers
SeniorThesis_DempseyRogersSeniorThesis_DempseyRogers
SeniorThesis_DempseyRogersDempsey Rogers
 

Similar to Alex_MarvinS16 (20)

M2 Internship report rare-earth nickelates
M2 Internship report rare-earth nickelatesM2 Internship report rare-earth nickelates
M2 Internship report rare-earth nickelates
 
Characterization Studies of a CdTe Pixelated Timepix Detector for Applicatio...
Characterization Studies of a  CdTe Pixelated Timepix Detector for Applicatio...Characterization Studies of a  CdTe Pixelated Timepix Detector for Applicatio...
Characterization Studies of a CdTe Pixelated Timepix Detector for Applicatio...
 
GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...
GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...
GLOBAL TRAJECTORY OPTIMISATION OF A SPACE-BASED VERY-LONG-BASELINE INTERFEROM...
 
thermal_physics
thermal_physicsthermal_physics
thermal_physics
 
SURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONS
SURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONSSURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONS
SURVEY ON CLOUD-BASED HEALTH MANAGEMENT SOLUTIONS
 
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...
DESIGN, OPTIMIZATION AND DEVELOPMENT OF SOLAR THERMAL HEAT RECEIVER SYSTEM WI...
 
lm201-Project
lm201-Projectlm201-Project
lm201-Project
 
TunnelSpectroscopy v2
TunnelSpectroscopy v2TunnelSpectroscopy v2
TunnelSpectroscopy v2
 
dissertation
dissertationdissertation
dissertation
 
EVM_TFM_printed
EVM_TFM_printedEVM_TFM_printed
EVM_TFM_printed
 
Emission Line Objects in Integral Field Spectroscopic Datacubes
Emission Line Objects in Integral Field Spectroscopic DatacubesEmission Line Objects in Integral Field Spectroscopic Datacubes
Emission Line Objects in Integral Field Spectroscopic Datacubes
 
Optical Absoprtion of Thin Film Semiconductors
Optical Absoprtion of Thin Film SemiconductorsOptical Absoprtion of Thin Film Semiconductors
Optical Absoprtion of Thin Film Semiconductors
 
Dynamics of cold atoms in moving optical lattices (Version Dek8)
Dynamics of cold atoms in moving optical lattices (Version Dek8)Dynamics of cold atoms in moving optical lattices (Version Dek8)
Dynamics of cold atoms in moving optical lattices (Version Dek8)
 
Kinetic growth of binary compounds by reactive magnetron sputtering
Kinetic growth of binary compounds by reactive magnetron sputteringKinetic growth of binary compounds by reactive magnetron sputtering
Kinetic growth of binary compounds by reactive magnetron sputtering
 
Photometry of the UWISH2 extended H2 source catalogue
Photometry of the UWISH2 extended H2 source cataloguePhotometry of the UWISH2 extended H2 source catalogue
Photometry of the UWISH2 extended H2 source catalogue
 
FinalThesis
FinalThesisFinalThesis
FinalThesis
 
Senior Research paper
Senior Research paperSenior Research paper
Senior Research paper
 
TF_thesis
TF_thesisTF_thesis
TF_thesis
 
daniel_kok_4_maart_2021 (2).pdf
daniel_kok_4_maart_2021 (2).pdfdaniel_kok_4_maart_2021 (2).pdf
daniel_kok_4_maart_2021 (2).pdf
 
SeniorThesis_DempseyRogers
SeniorThesis_DempseyRogersSeniorThesis_DempseyRogers
SeniorThesis_DempseyRogers
 

Alex_MarvinS16

  • 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
  • 2.
  • 3. Copyright c 2016 Alexander J. Marvin All Rights Reserved
  • 4.
  • 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.
  • 10.
  • 11. Contents Table of Contents xi List of Figures xiii 1 Introduction 1 2 Background and Theory 3 2.1 General radiative transfer equation . . . . . . . . . . . . . . . . . . . 3 2.2 Oxygen attenuation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3 Methods 21 4 Results and Discussion 25 5 Conclusion 29 5.1 Future work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 Bibliography 31 A Source Code 33 A.1 makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 A.2 README.txt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 A.3 CRadtran.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 A.4 calculate.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 A.5 calculate.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 A.6 brightness temp.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 A.7 brightness temp.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 A.8 datafile.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 A.9 datafile.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 A.10 atten.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 A.11 oxygenAtten.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 B Test Code 95 B.1 testDataFile.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 xi
  • 12. xii CONTENTS B.2 testOxyAtten.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
  • 13. List of Figures 2.1 A slice of air . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 2.2 Our Euclidean system . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.3 Distance s of the light . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.4 The whole atmosphere . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.5 The responsivity of a theoretical instrument . . . . . . . . . . . . . . 13 4.1 Oxygen attenuation constants . . . . . . . . . . . . . . . . . . . . . . 26 4.2 Comparison of RADTRAN and CRadtran . . . . . . . . . . . . . . . 27 xiii
  • 14.
  • 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.
  • 42. 28 Chapter 4 Results and Discussion
  • 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; } }
  • 108. 94 Chapter A Source Code
  • 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 ;