I’ve always been fairly sensitive to air pressure, and experiencing the winters here out West has really exacerbated the effects beyond what I’m used to.

I set out to find out why that is, and used the subsequent discovery as the basis of a little Python project.

Low pressure blues

Central to the issue is the high altitude of Calgary: a happy little side effect of being so close to the Rockies. I knew going in that the altitude would affect things like cooking, and I was warned in advance about the weather—​chinooks in particular. What I wasn’t prepared for was even the slightest hint of overcast weather and the subsequent low pressure dropping my energy levels to the point where even caffeine and ADHD medication can’t (fully) overcome it.

I wasn’t having this issue nearly as much back in Halifax: overcast weather would decline my mood, sure, but almost never to the point of actively sapping my energy. To top it off, the chinooks that rolled in and spiked the air pressure provided me an almost immediate relief to these issues; I could really feel my energy coming back when they hit.

There had to be a reason for this, so I set out to research exactly what the cause might be.

Turns out that the altitude affected the apparent barometric pressure, as well.

Some pressure is more equal than others

When I became suspicious of the pressure changes, I started to track air pressure changes to map out when the good and bad days were happening. But this became confusing for me on account of my weather sources reporting wildly different values: Environment Canada’s values differed from Open-Meteo’s values by 10-20 kPa!

Upon interrogating Open-Meteo to see what was going on, I discovered that they were using two different values of barometric pressure: sea level, and surface level. To Open-Meteo’s credit, their data graph was very useful for highlighting the differences between the two.

Their values for sea level pressure largely matched Environment Canada’s data for pressure, which begged the question of how exactly they came up with this "surface level" pressure. This led me down the path of discovering a little thing called the barometric formula:

Barometric Formula

In short, given a different altitude and temperature, the air pressure can feel dramatically different than at sea level. Plugging the numbers into the formula—​and feeding it the sea level pressures—​gave me the "surface level" pressures that Open-Meteo was providing!

Mystery solved. And boy, were those pressures low: small wonder I kept feeling so lethargic!

No pressure, right?

Now, me being me, I wanted a way to calculate these values without requiring an Internet connection, such that I could figure out the values from whatever offline source of pressure I obtain in the future. (Pending testing, of course!)

And since I’ve been dipping my toes into Python as of late—​better late than never—​I thought it would be a nice little starter project to get a feel for how it all works!

Python code:
#!/usr/bin/env python3
# Calculate air pressure at higher altitudes
# Formula: P = (P0)*e^(((-g)*M*(h-h0))/(R*T))
# Where:   P  =  Current pressure being solved for (usually pascals)
#          h  =  Current altitude (in metres)
#          T  =  Current temperature (in Kelvin)
#          P0 =  Reference pressure (usually sea level -- 101325Pa or 101.325kPa nominal)
#          h0 =  Reference altitude (usually sea level -- 0m)
# Consts:  e  =  2.718281828 (natural log base, used for exponential function)
#          g  =  9.80665 (m/s)^2 (gravity acceleration)
#          M  =  0.0289644 kg/mol (molar mass of air)
#          R  =  8.31432 N.m/(mol/K) (universal gas constant)

### Setup
import argparse

parser = argparse.ArgumentParser(prog='AirPressure', description='Calculates the equivalent sea level air pressure from the given surface air pressure, altitude, and temperature.')
parser.add_argument('pressure', type=float, help='Current air pressure (any unit)')
parser.add_argument('altitude', type=float, help='Current altitude (in metres)')
parser.add_argument('temperature', type=float, help='Current temperature (in celsius)')
parser.add_argument('-r', '--reverse', action='store_true', help='Calculate equivalent surface air pressure from given sea pressure instead')

### Declarations
const_e = 2.718281828
const_g = -9.80665
const_M = 0.0289644
const_R = 8.31432
const_TK = 273.15           # Can +/- any *C temperature to this to get equivalent Kelvin value
args = parser.parse_args()
var_P = args.pressure
var_h = args.altitude
var_T = const_TK + args.temperature

### Code
if args.reverse == True:
    # Get sea level pressure from surface pressure
    out_P = var_P / const_e ** ((const_g * const_M * var_h) / (const_R * var_T))
    print(out_P)
else:
    # Get surface pressure from sea level pressure
    out_P = var_P * const_e ** ((const_g * const_M * var_h) / (const_R * var_T))
    print(out_P)

The code is fairly self-explanatory, but I’ll summarize it anyways:

  • It converts sea level to surface level pressure, given:

    • The provided pressure (in any unit—​it’s completely agnostic)

    • The provided altitude (in metres—​here in Calgary, that’s 1025m)

    • The provided temperature (in celsius—​it has a small but noticeable effect on the pressure change!)

  • Optionally, it can calculate the reverse instead; deriving sea level pressure from the surface pressure.

    • This was mostly added to check my work, and because the formula was really easy to rearrange for the other value.

Conclusion

The barometric pressure is just one component of my issues with the effects the weather has on me, but it’s proven to be a pretty substantial component. It’s been good, figuring that component of the equation out. Now I just have to tackle the rest of the equation!

With regards to the program, I could have gone full bore and automatically pulled from Open-Meteo—​it does provide Python example code, after all. But I wanted something quick, simple, and offline. For what it does, I’m fairly happy with the result.