-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor remaining functions from Issue #11 #31
Open
annalea-albright
wants to merge
22
commits into
eurec4a:master
Choose a base branch
from
annalea-albright:define_vertical_structure
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 19 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a755119
adding a messy code for iteration
annalea-albright edc6ebc
add messy file, BL height
annalea-albright 9bb5db2
minor change
annalea-albright eec0c98
minor edit
annalea-albright 0e63e1f
calculate density
annalea-albright 3322c86
Update calculate_density.py
annalea-albright 686adf1
test for calc_density function
annalea-albright f2312e6
fixed coordinates
annalea-albright 22ba43e
minor edit
annalea-albright 364a2c4
add test file
annalea-albright f7e1075
updating files
annalea-albright 675a4b2
remove redundant code
annalea-albright 3a198e8
Merge branch 'master' of https://github.com/eurec4a/eurec4a-environme…
annalea-albright 1436af2
Update eurec4a_environment/variables/calc_density.py
annalea-albright 5924a80
Delete mixed_layer_height_from_gradient.py
annalea-albright 13c4d4f
refactor remaining functions
annalea-albright c0bbb7c
minor changes
annalea-albright fdb0668
Merge branch 'master' into define_vertical_structure
leifdenby d836e54
Merge branch 'master' into define_vertical_structure
leifdenby 6795d30
Merge branch 'master' into define_vertical_structure
leifdenby b619ec1
apply black and fix flake8 errors
leifdenby cbd6bb3
start refactoring mixed-layer peak RH linfit calculation
leifdenby File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
import xarray as xr | ||
|
||
|
||
def calc_static_stability(ds, pres="p", temp="T", theta="theta", altitude="height"): | ||
|
||
""" Equation from: https://www.ncl.ucar.edu/Document/Functions/Contributed/static_stability.shtml | ||
S = -(T/theta)*d(theta)/dp. From Bluestein (1992), pg 197, eqn 4.3.8 | ||
|
||
Static stability measures the gravitational resistance of an atmosphere to vertical displacements. | ||
It results from fundamental buoyant adjustments, and so it is determined by the vertical stratification | ||
of density or potential temperature. | ||
""" | ||
|
||
# !! edit these lines based on units function !! | ||
# Celsius to Kelvin | ||
if ds[temp].max().values < 100: | ||
temp_K = ds[temp] + 273.15 | ||
else: | ||
temp_K = ds[temp] | ||
|
||
# convert Pa to hPa | ||
if ds[pres].max().values > 1400: | ||
ds[pres] = ds[pres] / 100 | ||
|
||
static_stability = -(temp_K / ds[theta]) * ( | ||
ds[theta].diff(dim=altitude) / ds[pres].diff(dim=altitude) | ||
) | ||
static_stability = static_stability.transpose( | ||
transpose_coords=True | ||
) # same dimension order as original dataset | ||
|
||
dims = list(static_stability.dims) | ||
da = xr.DataArray( | ||
static_stability, dims=dims, coords={d: static_stability[d] for d in dims} | ||
) | ||
da.attrs["long_name"] = "static stability" | ||
da.attrs["units"] = "K/hPa" | ||
|
||
return da |
91 changes: 91 additions & 0 deletions
91
eurec4a_environment/variables/inversion_layers/inversion_layer_height.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
import numpy as np | ||
import xarray as xr | ||
|
||
|
||
def calc_inversion_static_stability( | ||
ds, time="sounding", altitude="height", z_min=1000, z_max=3000 | ||
): | ||
|
||
""" | ||
Returns inversion height defined as the height where static stability profiles | ||
first exceed 0.1 K/hPa between given heights | ||
Adapted from Bony and Stevens 2018, Measuring Area-Averaged Vertical Motions with Dropsondes, p 772 | ||
To do: combine static stability criterion with one for moisture (i.e. hydrolapse) | ||
""" | ||
|
||
from eurec4a_environment.variables.calc_static_stability import ( | ||
calc_static_stability, | ||
) | ||
|
||
ds_inversion = ds.sel({altitude: slice(z_min, z_max)}) | ||
da_static_stability = calc_static_stability(ds_inversion) | ||
|
||
inversion_height_stability = np.zeros(len(da_static_stability[time])) | ||
for i in range(len(da_static_stability[time])): | ||
stability_sounding = da_static_stability.isel({time: i}).values | ||
idx_stability = np.argmax(stability_sounding > 0.1) | ||
inversion_height_stability[i] = da_static_stability[altitude][idx_stability] | ||
|
||
dims = list(da_static_stability.dims) | ||
# drop the height coord | ||
del dims[dims.index(altitude)] | ||
|
||
da = xr.DataArray( | ||
inversion_height_stability, | ||
dims=dims, | ||
coords={d: da_static_stability[d] for d in dims}, | ||
) | ||
da.attrs["long_name"] = "inversion base height, static stability > 0.1 K/hPa" | ||
da.attrs["units"] = "m" | ||
|
||
return da | ||
|
||
|
||
def calc_inversion_grad_RH_T( | ||
ds, | ||
time="sounding", | ||
altitude="height", | ||
temperature="T", | ||
rh="rh", | ||
z_min=1000, | ||
z_max=2500, | ||
): | ||
|
||
""" | ||
Inversion base following Grindinger et al, 1992; Cao et al 2007 | ||
dT/dz > 0 and dRH/dz < 0 | ||
To do: find all inversion bases and heights, not just first inversion base | ||
""" | ||
|
||
ds_inversion = ds.sel({altitude: slice(z_min, z_max)}) | ||
gradient_RH = ds_inversion[rh].differentiate(coord=altitude) | ||
gradient_T = ds_inversion[temperature].differentiate(coord=altitude) | ||
inversion_levels = gradient_T[altitude].where( | ||
(gradient_RH <= 0) & (gradient_T >= 0) | ||
) | ||
|
||
num_iters = len(inversion_levels[time]) | ||
inv_base_height_gradients = np.zeros(num_iters) | ||
for i in range(num_iters): | ||
alt_inv_da = inversion_levels.isel({time: i}) | ||
inversion_alts = alt_inv_da[~np.isnan(alt_inv_da)] | ||
if inversion_alts[altitude].size == 0: | ||
print(f"sounding {i} has no inversion below {z_max} m") | ||
continue | ||
inv_base_height_gradients[i] = inversion_alts[0] # find first inversion base | ||
inv_base_height_gradients[inv_base_height_gradients == 0] = np.nan | ||
|
||
dims = list(ds.dims.keys()) | ||
# drop the height coord | ||
del dims[dims.index(altitude)] | ||
da = xr.DataArray( | ||
inv_base_height_gradients, dims=dims, coords={d: ds[d] for d in dims} | ||
) | ||
da.attrs["long_name"] = "inversion base height from RH and T gradient" | ||
da.attrs["units"] = "m" | ||
return da | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
import numpy as np | ||
from eurec4a_environment.variables.inversion_layers import inversion_layer_height | ||
import eurec4a_environment.source_data | ||
|
||
|
||
def test_inversion_static_stability(): | ||
ds = eurec4a_environment.source_data.open_joanne_dataset() | ||
ds = ds.isel(sounding=slice(0, 10)) | ||
da_ss = inversion_layer_height.calc_inversion_static_stability(ds) | ||
assert len(da_ss) == 10 | ||
assert np.all(da_ss < 5000.0) | ||
assert da_ss.units == "m" | ||
|
||
|
||
def test_inversion_gradient_RH_T(): | ||
ds = eurec4a_environment.source_data.open_joanne_dataset() | ||
ds = ds.isel(sounding=slice(0, 10)) | ||
# adjust threshold based on units 0.4 g/kg/10m or 0.0004 kg/kg/10m | ||
da_gradRH_T = inversion_layer_height.calc_inversion_grad_RH_T(ds) | ||
assert len(da_gradRH_T) == 10 | ||
assert np.all(da_gradRH_T < 5000.0) | ||
assert da_gradRH_T.units == "m" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
#!/usr/bin/env python3 | ||
# -*- coding: utf-8 -*- | ||
|
||
|
||
from eurec4a_environment.variables.calc_static_stability import calc_static_stability | ||
import eurec4a_environment.source_data | ||
|
||
|
||
def test_static_stability_calculation(): | ||
ds = eurec4a_environment.source_data.open_joanne_dataset() | ||
da_static_stability = calc_static_stability(ds) | ||
# check that we get some sensible numbers | ||
assert da_static_stability.units == "K/hPa" | ||
assert da_static_stability.max() < 3 | ||
assert da_static_stability.min() > -3 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be better to define this outside of the function in case it could be used elsewhere? If you don't want it as a generally visible function you can rename it with an underscore in front (i.e. _calculateHmix_var)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raising an issue for higher precision tests sounds great -- thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And yes that sounds good with _calculateHmix_var, will do. Thanks for the tip