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
Fixing minor LFC bug #491
Fixing minor LFC bug #491
Conversation
Can you show an example of this? I'm not clear on why we should be ignoring the surface point. Seems like in the case of surface saturation and a completely unstable profile, the surface point should count. Is this another case where truncation (or whatnot) is causing problems? Also, if this goes in, I'd like a comment above the line indicating why |
So is the problem that the LFC should be at the surface? |
Nope, in this case there should be no LFC. I did figure out that it is a precision issue, however. The surface temperature in this particular case is 20.6 C going in to parcel profile, and the surface point of the parcel path is 20.600000000000023 C. |
It appears that the spurious digits get added on somewhere in parcel profile, or in converting parcel profile's output to Celsius. |
I have to think about this a bit it terms of both why no LFC is the correct result and the conversion issues, but sounds related (maybe) to what @tjwixtrom found. |
That's what we're thinking back here in Boulder. Just to clarify things, the sounding from Denver that I posted is the one that should have no LFC, and Ryan is correct in saying that for his hypothetical example where the sounding is absolutely unstable and saturated from the surface up the LFC should be at the surface. Also, that's a hilarious gif. |
So I think that @dopplershift and I can agree that dropping the surface point comparison isn't the desired behavior as the LFC could be at the surface. So we're back to a precision issue then. |
Yeah, that makes sense. I think part of this goes into the whole idea of where we want to define the LFC (at the base of the largest area of CAPE vs the first time the parcel path is warmer than the environment, etc.) What if we defined the LFC as the point where the parcel path crosses over the temperature trace in a positive direction nearest to the largest positive difference between the parcel temperature and the environment? Theoretically, that should do a decent job of placing the LFC at the base of the largest area of CAPE, and I think I might know how to code it up. |
But is it really at the base of the largest area or is it the first crossing? I've got a way to potentially handle precision, but if it's not needed that's fine. |
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.
I think the answer isn't to skip the first point, but maybe do a comparison with np.isclose()
. Does that make sense here?
Wouldn't the new |
Absolutely - some asynchronous comm here as that was added post that comment, but yes, it is the exact right tool for the job @mwilson14 |
Sounds good! |
Less_or_close has been implemented in LFC. |
metpy/calc/thermo.py
Outdated
@@ -232,7 +232,7 @@ def lfc(pressure, temperature, dewpt): | |||
direction='increasing') | |||
# Two possible cases here: LFC = LCL, or LFC doesn't exist | |||
if len(x) == 0: | |||
if np.any(ideal_profile > temperature): | |||
if np.any(_less_or_close(ideal_profile[1:], temperature[1:]) == False): |
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.
I think the idea was to use _less_or_close
instead of slicing off the first point.
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.
Yes because the first point could be the answer
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.
Oops. That was a typo.
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.
Also should be:
if not np.any(...)
rather than doing ==False
Don't merge this yet, I may have just found a bug. |
Now it should be ok. |
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.
Minor nit, otherwise we're good to go here.
metpy/calc/thermo.py
Outdated
if np.any(ideal_profile > temperature): | ||
if np.all(_less_or_close(ideal_profile, temperature)): | ||
return np.nan * pressure.units, np.nan * temperature.units | ||
# LFC doesn't exist |
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.
Can you put this on the same line as the else? It makes it clearer what block we're referring to.
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.
Fixed it!
Look good @jrleeman ? |
I think rebasing on master might help Travis succeed. |
Test failure due to broken link in docs, which is fixed on master. Merging... |
Adding a fix so that, in the case where the parcel path never intersects the profile, the surface data point is ignored in determining whether the parcel path is ever warmer than the environment (and thus, whether the LFC exists). Currently, in some cases the parcel is identified as warmer at the surface than the environment, resulting in a spurious LFC being identified at the same pressure as the LCL.