By Ingo Dahn, (Koblenz, Germany [email protected]) and Ambjörn Naeve (Stockholm, Sweden [email protected])
Weather balloons are a simple, but important mean to explore the atmosphere. They carry radiosondes high up in the air (how high?) These radiosondes measure several parameters of the atmosphere during their flight, for instance air temeperature and air pressure. Weather balloons collect many data. With a good understanding of athmospheric phenomena we should be able to predict these data to a certain extent. Can you do it?
This notebook lets you perform your own experiments with real weather balloons. We start with a simple method for calculating the air temperature in various height and check it against the measurements of a real weather balloon. And you can repeat this experiment yourself with many ballon risings! Can you come up with a better model?
This notebook is made of a sequence of cells:
Text cells, explaining what we do. The text cells analyze a specific default balloon flight. They do not change and, depending on your working environment, you may not be able to change the content of text cells.
Hovering the mouse over the SageMath icon will reveal some additional explanations on the code - try it
Don't worry, if you don't understand the content of the code cells! We start simple and so you don't need to know a lot of Math, Physics or Programming - just go and experiment! Whenever you run into trouble - have a look at our .
License: This document is made available under a Creative Commons Attribution Share Alike License 4.0.
Let's go to the weather station in Idar-Oberstein/Germany. It is located 105 km (ca 65 miles) southwest of Frankfur/Main at a height of 376 m.
Or fly high up with a weather balloon in this video from Overlook Horizon:
The German Weather Service (Deutscher Wetterdienst) provides data from it's radio sondes on the web. The following cell fetches these recent data from the Idar-Oberstein weather station for you to work with. "
If it has in line 2 `randomBalloon=False` (the default) it uses a specific sample balloon flight which is discussed in the comments. You may change it to `randomBalloon=True` in order to select data from a randomly selected balloon flight.
In the subsequent chapters we discuss some mathematical models of the atmosphere. In order to compare the predictions of these models with the data from the weather balloons, the following cell must be executed first.
# Change the value of randomBalloon to True in order to select a flight by chance randomBalloon=False load('https://raw.githubusercontent.com/ingodahn/sageutils/master/weather.py') station=station() if randomBalloon: flight=station.getFlight('random') else: flight=station.getFlight() temp=flight.dataPoints('height','temperature') press=flight.dataPoints('height','pressure')
Temperature is one of the basic properties of any gas. Air temperature is easy to determine with a thermometer.
There is a simple model describing the decrease of temperature when the balloon gets higher up. Usin this model requires some understanding of linear functions. Don't forget to answer the questions!
People climbing mountains early noted that the air gets colder as they climb up. Based on measurements with thermometers scientists carried uphill, scientist calculated that the air temperature $t(x)$ decreases by 6.5°C if height is increased by 1000 m (a so-called Lapse Rate) . $T(x+1000)=T(x)-6.5$
Source: Connolly & Connolly: Balloons in the Air: Understanding weather and climate.
Using such a lapse rate and a given temperature on the ground we can use this to calculate the temperature at any height.
Let's assume a temperature of 15°C on the ground (we may change that later): $T(0)= t_0 =15$. What would be the temperature at a height of 7500 m according to this model? You can calculate that using the standard lapse rate $l_s=\frac{-6.5}{1000}=-0.0065$ of change in °/m.
t_0=15 l_s=-6.5/1000 T(x)=l_s*x+t_0 T(7500)
The temperature at a height of 7500 m is, according to our model. -33.75°C.
Modify the cell above to calculate the temperature at 9200 m by replacing in line 4 7500
with 9200
! Depending upon the context where you read this, you need to select Run
from the Cell menu or press Shift+Return
or click the Execute button to evaluate the cell for the new height.
Play around and calculate the expected air temperature at various heights; vary also the ground temperature t_0
!
Let's plot this function - the temperature should decrease as we get higher up :
plot(T,0,20000,axes_labels=["Height (m)","Temperature (°C)"],gridlines=True)
It seems to get pretty cold up there. That diagram would be more intuitive if the Height axes goes upward (on the ordinates) and the Temperature values are written horizontally (on the abscissae). We can get that presentation when we interchange the role of height and temperature, i.e. we let the height depend upon the temperature (do you think that is weird?), i.e. we plot the inverse function $T_{inv}$ of our temperature function $T$.
Can you calculate the inverse of our function $T$?
Now let's plot $T_{inv}$. You can play with the lapse rate lr
and the ground temperature t_0
using your mouse or arrow keys to explore effects of their change.
@interact def _(lr=slider(4,8,step_size=0.1,default=6.5),t_0=slider(-30,30,step_size=1,default=15)): c=-lr/1000 T1_inv(x)=(x-t_0)/c show(plot(T1_inv,xmin=-100,xmax=30,ymin=0,ymax=15000,axes_labels=["Temperature (°C)","Height (m)"],gridlines=True))
That looks much more natural. Now we are ready for a reality test.
Let's see, what the balloon actually measured up in the air!
Let us plot the temperature that our balloon has measured at the various heights. As in the previous plots, we draw the inverse function to direct the height axis upwards.
temp_inv=invert(temp) balloonPlot=list_plot(temp_inv,axes_labels=['Temperature (°C)','Height (m)'],gridlines=True) balloonPlot
Oops, that doesn't look like what our model predicted.
We observe, that the development of air temperature with height on this day has three phases.
Let's call the upper region of oscillating temeperature - here above 12000 m - Tropopause and the region below it Troposphere.
Clearly, our simple linear model does not work in the Tropopause, but perhaps it works in the upper region of the Troposphere? Let's check!
This region is between 4000 m and 12000 m for the default flight, it may be different for other flights!
# Adapt these two values if you are not using the default flight linMin=4000 linMax=12000 print("Range of presumed linear temperature descent defined.")
As we don't have the real temperature at height 0, we have to redefine our model function $T(x)$ by using the temperature at a another height $h_t$.
Instead of defining the linear function such that $T(0)=t_0$ we define $T$ such that $T(h_t)=t_h$ for some data point $(h_t,t_h)$ from our flight. We chose this data point as the first measurement in the height region we are interested in, i. e. the first data point at a height above 4000 m.
i=0 while temp[i][0] < linMin: i+=1 h_t=temp[i][0]; t_h=temp[i][1]; i_h=i print("The first data point above %i m is at a height of %i m with an air temperature of %f°C."%(linMin,h_t,t_h))
When we know that $T(h_t)=l_s\cdot h_t+t_0=t_h$, where $t_0$ is the unknown temperature at sea level, then $t_0=t_h-l_s\cdot h_t$ and we have our new model $T(x)=l_s x+t_0$. We need to define $T(x)$ such that $T(4119)=-3.7$. Let's calculate $t_0$ as described above.
t_0 = t_h-l_s*h_t T(x)=l_s*x+t_0 print("T(x)=",T(x)) show(LatexExpr("t_0 = "),t_0) show(LatexExpr("T(x)="),T(x))
A side remark on accuracy in case you wonder why there are so many zeros:
Our computer calculates with a limited precision and the number of trailing zeros indicates the precision that is actually used. Real data, as those from the weather balloons, have a much lower accuracy and so many of the trailing decimals cannot be taken seriously. Nevertheless we use the calculated data with all their digits in order to avoid accumulating rounding errors and to keep the code simple.
Let's now compare the data from our model with the data from our balloon - recall that we have to compare the balloon data with the inverse function $T_{inv}$. We combine the previous plot of the balloon data with the plot of our model function inverse.
T_inv(x)=(x-t_0)/l_s show(balloonPlot+plot(T_inv,-70,20,color='red'),gridlines=True)
That's not a very good match! The simple linear model predicts a more strong decrease of temperature than shown by the measurement. Well, that may be due to particular conditions at this day at this place and we need to analyse more balloon reports. At least, the adequate laps rate may vary from day to day - but by how much?
In order to get an indication for a better model, we may try to find a linear function that provides the best fit to the data between 4000 m and 12000 m.
This can be achieved by a mathematical method called Linear Regression. We can use Linear Regression to find a better model and plot it against the balloon data.
dataLin0=[p for p in temp_inv if p[1] > linMin] dataLin=[p for p in dataLin0 if p[1]< linMax] var('a,b,x') f_lin(x)=a*x+b q=find_fit(dataLin, f_lin, solution_dict = True) aLin=q[a];bLin=q[b] show(f_lin(a=aLin,b=bLin)) show(balloonPlot+plot(f_lin(a=aLin,b=bLin),-70,20,color='red',gridlines=True)) print(f_lin(a=aLin,b=bLin))
That fits much better than the original model. To get the real temperature lapse rate in the upper troposphere, we have to convert the fitting function by taking its inverse.
show((1/aLin)*x-(bLin/aLin)) lapse=round((-1000/aLin),1) print((1/aLin)*x-(bLin/aLin)) print("The temperature decreases in the upper part of the troposphere by about",str(lapse)+"° each 1000 m.")
We see, that in fact the air temperature decreases by 7.9°C every 1000 m!
We have started with the hypothesis that the air temperature decreases by 6.5°C when the height increases by 1000 m. This has led us to establish a linear model for the development of air temperature.
Looking at the data from one radio balloon flight suggests that the development of air temperature follows different laws in the lower and in the upper part of the atmosphere travelled by the balloon, providing indications for at least three layers of the atmosphere. In the upper and in the lower layer, not even the linear form of our model is adequate, while in the middle layer a linear model fits well, but we have to adjust the cofficients of our model to make it fit to the data.
Criticism: Climate data can depend upon many factors, e.g. geographic location and season of the year. In order to evaluate our claims, they need to be checked against many weather balloon data. Only then may we have a chance to understand the various factors influencing and changing our climate.
ToDo: Look for answers to the following questions.
flight.dataPoints('height','pressure')
. This requires some adaptation of the code in this notebook.The following cell prints some basic status data from this notebook for re-use in other notebooks. Execute it and copy it's output into the input cell of another notebook, designated by a green border, or save it for later use in a text file.
print('temp =',temp) print('press =',press)
You may use the following cell for your own experiments.