Skip to content
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

Implement convective condensation level (CCL) #2550

Merged
merged 16 commits into from
Sep 30, 2022
Merged

Conversation

Z-Richard
Copy link
Contributor

@Z-Richard Z-Richard commented Jun 24, 2022

Description Of Changes

This PR implemented the convective condensation level (CCL), with options to use either the surface mixing ratio or the average mixing ratio over a shallow layer near the surface, according to the definition of CCL by AMS.

I also wrote a bunch of tests to make sure that what I implemented is correct using UWYO sounding. I can't find any existing software to compare my CCL calculations to, so I just eyeballed the desired values from the Skew-T diagrams.

Sorry for creating a new PR -- it turns out that I messed up with git for the last PR, and opening a new one seems the best option.

Checklist

@Z-Richard Z-Richard requested a review from a team as a code owner June 24, 2022 02:58
@Z-Richard Z-Richard requested review from dcamron and removed request for a team June 24, 2022 02:58
Fix docstring for ccl function

Fix inline comment for ccl
@Z-Richard
Copy link
Contributor Author

@dopplershift @dcamron Hi MetPy developers -- I would really appreciate it if I could get some feedback on this PR. The math here is pretty straightforward:

  • We can plug in the mixing ratio equation to the saturation vapor pressure equation and obtain a T(p) relationship in an atmosphere with a constant r. Although we can't directly solve for T, we can express the relationship in a form of A(P)=B(T) and obtain the temperature in two steps (a_p and rt_profile in the function). Both the mixing ratio equation and the saturation vapor pressure equation are consistent with what MetPy currently has.
  • Then find_intersections would come in handy, as we have both an ambient temperature profile and a temperature profile with constant r. The users may choose which CCL level to return, and I have set the default to top (lowest pressure, which is consistent with LFC).

The tests provide decent coverage for the function, although there are a few caveats. I basically grabbed some sounding data from siphon and used the arrays directly in the tests. I think it's better to leave it at that than to import siphon for testing because the additional dependency can be tricky to deal with. I'm also a little lazy to not write a test to validate the correctness of the height parameter, which is directly passed onto the mixed_layer function and thus should not have any issues if mixed_layer is implemented correctly. I can write an additional test if this is necessary.

Please let me know if there is anything else I can do to improve my code. Thanks for reviewing this PR!

@dcamron
Copy link
Member

dcamron commented Jul 7, 2022

Thanks for the PR and the explanation! Grabbing arrays from siphon is perfect for the tests. I'll comment on explicitly testing height once I review, but you're right that it likely doesn't need it. I do plan on reviewing this and we can include it in for our feature release scheduled for the end of this month.

Copy link
Member

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the terribly delayed response and review.

The code looks to be in great shape. I only have a question about a reference for the calculation so that I can validate the implementation against that. Otherwise, just a few minor doc formatting items.

src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
@dopplershift dopplershift added this to the September 2022 milestone Sep 15, 2022
@dopplershift dopplershift added Type: Feature New functionality Area: Calc Pertains to calculations labels Sep 15, 2022
Z-Richard and others added 3 commits September 15, 2022 20:04
Co-authored-by: Ryan May <rmay31@gmail.com>
Co-authored-by: Ryan May <rmay31@gmail.com>
Co-authored-by: Ryan May <rmay31@gmail.com>
@Z-Richard
Copy link
Contributor Author

Z-Richard commented Sep 16, 2022

The derivation for CCL. The T in the last step is the temperature profile with a constant mixing ratio.

image

Copy link
Member

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed derivation, which I went through and checked as well.

Then I realized we were doing this in SkewT already, so you can make use of those functions instead. Do that and consider updating the docs like suggested, and this can go on in!

src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
@dopplershift
Copy link
Member

Oh, there's one more consideration: I'm not sold on the need to build in the mixed layer approach. We don't do it in much else (like lcl), with the lone exception being mixed_layer_cape_cin. I think I'd prefer to keep the implementation simpler.

Is the need for this that mixed_layer operates properly on mixing ratio, and we ask users to pass in dewpoint?

Z-Richard and others added 3 commits September 18, 2022 20:43
Co-authored-by: Ryan May <rmay31@gmail.com>
Co-authored-by: Ryan May <rmay31@gmail.com>
@Z-Richard
Copy link
Contributor Author

Z-Richard commented Sep 19, 2022

Thanks for the suggestion! I should have speculated that this was implemented somewhere in MetPy, but I would have never figured out what those globals() mean on my own.

I agree that we should simplify the function by not using the mixed layer approach, but I got this definition from AMS. There may be folks in AMS who want to adhere to their own definition of CCL, and I think the function should still be reasonably simple to use if we add an example to show what the default behavior looks like (i.e. use surface dewpoint instead of a mixed layer.) Again, I am good with going either direction, so it might be your call to decide which way is better for our users.

And as a last note, I will be adding some examples after we have settled down on whether we should use a mixed layer approach. These examples will make life much easier for our users.

@Z-Richard
Copy link
Contributor Author

And one last thing: I just realized that the unit handling in this function is terribly wrong but somehow escapes the test cases. It seems that assert_almost_equal in metpy.testing thinks that two values are equal to each other even if their units are different. This is rather bizarre, and at this point, I am not sure about what is the correct way to test units, so people might need to check that as well.

@Z-Richard
Copy link
Contributor Author

Quick ping @dopplershift

@dopplershift
Copy link
Member

@Z-Richard based on our discussion on today's MetPy dev call (which anyone is welcome to join), we can keep the direct implementation of the mixed layer support since it seems like it would be a really common use case for the tool. So feel free to add some examples demonstrating this.

I'll dig into the unit issue you encountered and see what's up there.

@Z-Richard
Copy link
Contributor Author

@dopplershift Never mind the unit issue. It turns out that I should also add assert input.units == output.units to explicitly test for unit, and I was just implicitly thinking that assert_almost_equal would throw an AssertionError when two values have different units. I will add the appropriate tests using the pattern above, and we should be good to go.

@dopplershift
Copy link
Member

I was just implicitly thinking that assert_almost_equal would throw an AssertionError when two values have different units.

Ah, yeah the converter is just smart enough to first make sure to convert things to a common unit and then check the values.

Copy link
Member

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code here looks great. If you could add the examples you mentioned in the gallery (and maybe one in the docstring) this will be great to include in the next release.

@Z-Richard
Copy link
Contributor Author

Z-Richard commented Sep 29, 2022

I think it would be worth the effort to bundle LCL, LFC and CCL into a single example gallery as a separate PR because it makes the most sense to introduce all three functionalities at once. For this PR, a docstring example might suffice.

@dopplershift
Copy link
Member

#2629 is adding a bunch of examples, including one with all the indices, might make sense to add this there (cc @kgoebber) since I sense this is getting merged shortly.

Adding a docstring example will be fine, you're right.

@Z-Richard
Copy link
Contributor Author

One last question: should the docstring description

This function is implemented directly based on the definition of the CCL,
as in [USAF1990]_, and finding where the ambient temperature profile
intersects the line of constant mixing ratio starting at the surface,
using the surface dewpoint.

also reflect the fact that users can use a mixed layer dewpoint to compute CCL? I haven't looked into the USAF manual myself and am not 100% sure that the mixed-layer approach is mentioned there.

@dopplershift
Copy link
Member

The manual (4.18 and 4.19) says

When there is much variation in moisture content in the layers near the surface, an average moisture value of the lower layer may be used in place of the surface-parcel moisture value in computing the CCL.

I think it's fine to mention the option to use a mixed layer and still be consistent with the reference.

@Z-Richard
Copy link
Contributor Author

This should be good to go in. Could you do a final check?

Co-authored-by: Ryan May <rmay31@gmail.com>
Copy link
Member

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, one last change to correct convective temperature.

src/metpy/calc/thermo.py Outdated Show resolved Hide resolved
Copy link
Member

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Thanks for working with us on this great contribution!

@dopplershift dopplershift merged commit 0f079df into Unidata:main Sep 30, 2022
@Z-Richard Z-Richard deleted the ccl branch June 26, 2023 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Calc Pertains to calculations Type: Feature New functionality
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Convective temperature calculation
3 participants