-
Notifications
You must be signed in to change notification settings - Fork 1
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
CBTCU v1.9 #15
CBTCU v1.9 #15
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,31 +10,39 @@ local MU = level(HPLevelType.kMaximumThetaE,0) | |
local HL = level(HPLevelType.kHeightLayer,500,0) | ||
local HG = level(HPLevelType.kHeight,0) | ||
|
||
EL500 = luatool:Fetch(current_time, HL, param("EL-LAST-HPA"), current_forecast_type) | ||
LCL500 = luatool:Fetch(current_time, HL, param("LCL-HPA"), current_forecast_type) | ||
LFC500 = luatool:Fetch(current_time, HL, param("LFC-HPA"), current_forecast_type) | ||
CAPE500 = luatool:Fetch(current_time, HL, param("CAPE-JKG"), current_forecast_type) | ||
CIN500 = luatool:Fetch(current_time, HL, param("CIN-JKG"), current_forecast_type) | ||
|
||
LCLmu = luatool:Fetch(current_time, MU, param("LCL-HPA"), current_forecast_type) | ||
LFCmu = luatool:Fetch(current_time, MU, param("LFC-HPA"), current_forecast_type) | ||
ELmu = luatool:Fetch(current_time, MU, param("EL-LAST-HPA"), current_forecast_type) | ||
CINmu = luatool:Fetch(current_time, MU, param("CIN-JKG"), current_forecast_type) | ||
CAPEmu = luatool:Fetch(current_time, MU, param("CAPE-JKG"), current_forecast_type) | ||
|
||
Ttop = luatool:Fetch(current_time, HL, param("EL-K"), current_forecast_type) | ||
Tbase = luatool:Fetch(current_time, HL, param("LCL-K"), current_forecast_type) | ||
TtopMU = luatool:Fetch(current_time, MU, param("EL-K"), current_forecast_type) | ||
--LFC probably better than LCL for elev conv. base | ||
TbaseMU = luatool:Fetch(current_time, MU, param("LFC-K"), current_forecast_type) | ||
|
||
if not EL500 or not LCLmu or not Ttop then | ||
local EL500 = luatool:Fetch(current_time, HL, param("EL-LAST-M"), current_forecast_type) | ||
local pEL500 = luatool:Fetch(current_time, HL, param("EL-LAST-HPA"), current_forecast_type) | ||
local LCL500 = luatool:Fetch(current_time, HL, param("LCL-M"), current_forecast_type) | ||
local CAPE500 = luatool:Fetch(current_time, HL, param("CAPE-JKG"), current_forecast_type) | ||
local CIN500 = luatool:Fetch(current_time, HL, param("CIN-JKG"), current_forecast_type) | ||
local LFCmu = luatool:Fetch(current_time, MU, param("LFC-M"), current_forecast_type) | ||
local pLFCmu = luatool:Fetch(current_time, MU, param("LFC-HPA"), current_forecast_type) | ||
local ELmu = luatool:Fetch(current_time, MU, param("EL-LAST-M"), current_forecast_type) | ||
local pELmu = luatool:Fetch(current_time, MU, param("EL-LAST-HPA"), current_forecast_type) | ||
local CINmu = luatool:Fetch(current_time, MU, param("CIN-JKG"), current_forecast_type) | ||
local CAPEmu = luatool:Fetch(current_time, MU, param("CAPE-JKG"), current_forecast_type) | ||
local Ttop = luatool:Fetch(current_time, HL, param("EL-K"), current_forecast_type) | ||
local TtopMU = luatool:Fetch(current_time, MU, param("EL-K"), current_forecast_type) | ||
|
||
if not EL500 or | ||
not pEL500 or | ||
not LCL500 or | ||
not CAPE500 or | ||
not CIN500 or | ||
not LFCmu or | ||
not pLFCmu or | ||
not ELmu or | ||
not pELmu or | ||
not CINmu or | ||
not CAPEmu or | ||
not Ttop or | ||
not TtopMU then | ||
logger:Error("Some data not found") | ||
return | ||
end | ||
|
||
NL = luatool:Fetch(current_time, HG, param("NL-PRCNT"), current_forecast_type) | ||
NM = luatool:Fetch(current_time, HG, param("NM-PRCNT"), current_forecast_type) | ||
local NL = luatool:Fetch(current_time, HG, param("NL-PRCNT"), current_forecast_type) | ||
local NM = luatool:Fetch(current_time, HG, param("NM-PRCNT"), current_forecast_type) | ||
|
||
if not NL then | ||
NL = luatool:Fetch(current_time, HG, param("NL-0TO1"), current_forecast_type) | ||
|
@@ -44,16 +52,19 @@ if not NM then | |
NM = luatool:Fetch(current_time, HG, param("NM-0TO1"), current_forecast_type) | ||
end | ||
|
||
RR = luatool:Fetch(current_time, HG, param("RRR-KGM2"), current_forecast_type) | ||
local RR = luatool:Fetch(current_time, HG, param("RRR-KGM2"), current_forecast_type) | ||
|
||
CBlimit = 12 --required vertical thickness [degrees C] to consider a CB (tweak this..!) | ||
TCUlimit = 9 --required vertical thickness [degrees C] to consider a TCU (tweak this..!) | ||
CBtopLim = 263.15 --required top T [K] to consider a CB (tweakable!) | ||
CINlimTCU = -1 --CIN limit for TCu | ||
RRlimit = 0.1 -- precipitation limit [mm/h] to consider a Cb | ||
if not NL or not NM or not RR then | ||
logger:Error("Some data not found") | ||
return | ||
end | ||
|
||
--Max height [FL] to check for top | ||
TopLim = 650 | ||
local CBlimit = 2000 --required vertical thickness [m] to consider a CB (tweak this..!) | ||
local TCUlimit = 1500 --required vertical thickness [m] to consider a TCU (tweak this..!) | ||
local CBtopLim = -10 --required top T [K] to consider a CB (tweakable!) | ||
local CINlimTCU = -1 --CIN limit for TCu | ||
local RRlimit = 0.1 -- precipitation limit [mm/h] to consider a Cb | ||
local CAPElimit = 2.71828 --euler constant | ||
|
||
local i = 0 | ||
local res = {} | ||
|
@@ -64,10 +75,11 @@ for i=1, #EL500 do | |
res[i] = Missing | ||
|
||
--TCU | ||
if ((Tbase[i]-Ttop[i]>TCUlimit) and (NL[i]>0) and (CIN500[i]>CINlimTCU)) then | ||
res[i] = FlightLevel_(EL500[i]*100) | ||
if ((EL500[i] - LCL500[i] > TCUlimit) and (NL[i] > 0) and (CIN500[i] > CINlimTCU) ) then | ||
--we don't use vertical search for flight level of EL500 but calculate directly from EL500 pressure | ||
res[i] = FlightLevel_(pEL500[i] * 100) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is clever 👍 In thing that caught my eye is that the smarttool function call is:
The search is capped to TopLim which is set to FL 650. Should this also be checked here, ie.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is just there because smarttool function requires some value and FL650 is so high that EL500 will always be below. At least in our latitudes. And if there is 20km tall convection I think it's better to put it as it is than to turn it into missing. |
||
--Limit top value | ||
if (CAPE500[i]>math.exp(1)) then | ||
if (CAPE500[i] > CAPElimit) then | ||
--Add for overshooting top based on CAPE | ||
res[i] = -(res[i] + CAPE500[i] / (math.log(CAPE500[i]) * 10)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In smarttool the last term (10) has a division operator, not multiplication. I tried to think if you are doing some kind of mathematical trick here but I couldn't get it :D I don't understand why Simo is using exp(1) here, it's just a constant number. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I put () around it which is the mathematical trick you missed. On a high nerd level I think multiplication is a cheaper operation than division. exp(1) is used to generate the constant e that LUA doesn't provide. This was needed because we had some problems where CAPE was small and then the logarithm function goes to 0 for ln(1) and division by 0 is bad as well as for values below 1 it gives negative numbers that potentially turns the sign of the result around. Which by the logic of this macro turns CB into TCU. Probably it's not wise to have two things in one parameter and we should output CB and TCU as two separate fields but that's what it is now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was just wondering why e(1), does it have some special significance. Why doesn't he just declare "const CAPElimit = 2.78". I agree it's a bit weird that this parameter has different interpretation depending on the sign of the data value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think I'll change it to that CAPElimit version then. |
||
else | ||
|
@@ -76,33 +88,33 @@ for i=1, #EL500 do | |
end | ||
|
||
--CB | ||
if ((Ttop[i]<CBtopLim) and (Tbase[i]-Ttop[i]>CBlimit) and (RR[i]>RRlimit)) then | ||
res[i] = FlightLevel_(EL500[i]*100) | ||
if ((Ttop[i] < CBtopLim) and (EL500[i] - LCL500[i] > Cblimit) and (RR[i] > RRlimit)) then | ||
res[i] = FlightLevel_(pEL500[i] * 100) | ||
--Limit top value | ||
if (CAPE500[i]>math.exp(1)) then | ||
if (CAPE500[i] > math.exp(1)) then | ||
--Add for overshooting top based on CAPE | ||
res[i] = res[i] + CAPE500[i] / (math.log(CAPE500[i]) * 10) | ||
end | ||
end | ||
|
||
--If no TOP from above, check also with MU values, for elev. conv. only from blw 3,5km | ||
if ( IsMissing(res[i]) and (TbaseMU[i]<Tbase[i]) and (LFCmu[i]>650)) then | ||
-- TCU | ||
if ((TbaseMU[i]-TtopMU[i]>TCUlimit) and ((NL[i]>0) or (NM[i]>0)) and (CINmu[i]>CINlimTCU)) then | ||
res[i] = FlightLevel_(ELmu[i]*100) | ||
if ( IsMissing(res[i]) and (LFCmu[i] > LCL500[i]) and (pLFCmu[i] > 650)) then | ||
-- TCU elevated | ||
if ((ELmu[i] - LFCmu[i] > TCUlimit) and ((NL[i] > 0) or (NM[i] > 0)) and (CINmu[i] > CINlimTCU)) then | ||
res[i] = FlightLevel_(pELmu[i] * 100) | ||
--Limit top value | ||
if (CAPEmu[i]>math.exp(1)) then | ||
if (CAPEmu[i] > CAPElimit) then | ||
--Add for overshooting top based on CAPE, +1000ft/350J/kg (tweak this!) | ||
res[i] = -(res[i] + CAPEmu[i] / (math.log(CAPEmu[i]) * 10)) | ||
else | ||
res[i] = -res[i] | ||
end | ||
end | ||
--CB | ||
if ((TtopMU[i]<CBtopLim) and (TbaseMU[i]-TtopMU[i]>CBlimit) and (RR[i]>RRlimit)) then | ||
res[i] = FlightLevel_(ELmu[i]*100) | ||
--CB elevated | ||
if ((TtopMU[i] < CBtopLim) and (ELmu[i] - LFCmu[i] > CBlimit) and (RR[i] > RRlimit)) then | ||
res[i] = FlightLevel_(pELmu[i] * 100) | ||
--Limit top value | ||
if (CAPEmu[i]>math.exp(1)) then | ||
if (CAPEmu[i] > CAPElimit) then | ||
--Add for overshooting top based on CAPE, +1000ft/350J/kg (tweak this!) | ||
res[i] = res[i] + CAPEmu[i] / (math.log(CAPEmu[i]) * 10) | ||
end | ||
|
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.
"local" could be used for these variables
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.
What does "local" actually do?
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.
Well it declares the variable as a local variable instead of global, as you may have guessed :D
Basically it is the way lua recommends to be done: always use "local" unless you have a reason not to. It also has some performance implications as fetching a variable from global scope is more expensive. I have not benchmarked this though and I guess it's rather small, unless running on a very tight loop.