Model Sounding Data
Notebook The EDEX modelsounding plugin creates 64-level vertical profiles from GFS and ETA (NAM) BUFR products distirubted over NOAAport. Paramters which are requestable are pressure, temperature, specHum, uComp, vComp, omega, cldCvr.
from awips.dataaccess import DataAccessLayer
import matplotlib.tri as mtri
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from math import exp, log
import numpy as np
from metpy.calc import wind_components, lcl, dry_lapse, parcel_profile, dewpoint
from metpy.calc import wind_speed, wind_direction, thermo, vapor_pressure
from metpy.plots import SkewT, Hodograph
from metpy.units import units, concatenate
import warnings
warnings.filterwarnings("ignore",category =RuntimeWarning)
DataAccessLayer.changeEDEXHost("edex-cloud.unidata.ucar.edu")
request = DataAccessLayer.newDataRequest("modelsounding")
forecastModel = "GFS"
request.addIdentifier("reportType", forecastModel)
request.setParameters("pressure","temperature","specHum","uComp","vComp","omega","cldCvr")
Available Locations
locations = DataAccessLayer.getAvailableLocationNames(request)
locations.sort()
list(locations)
['',
'1V4',
'3J2',
'4BL',
'4BQ',
'4HV',
'4OM',
'5AF',
'5AG',
'5SZ',
'6RO',
'8V7',
'9B6',
'A#2',
'A#3',
'A#4',
'A#5',
'A#6',
'A#7',
'A#8',
'A#9',
'A#A',
'A#B',
'ABL',
'ADM',
'AFA',
'AGR',
'AHN',
'AIA',
'AIH',
'AJO',
'ANJ',
'APX',
'AQQ',
'ATH',
'ATL1',
'ATL2',
'ATL3',
'ATL4',
'ATLH',
'AWH',
'AWR',
'B#1',
'B#2',
'B#3',
'B#4',
'B#5',
'B#6',
'B#7',
'B#8',
'B#9',
'B#A',
'B#B',
'B#C',
'B#D',
'B#E',
'B#F',
'B#G',
'B#H',
'B#J',
'B#K',
'B#L',
'B#M',
'B#N',
'B#O',
'B#P',
'B#Q',
'B#S',
'BAB',
'BDG',
'BDP',
'BFL',
'BGTL',
'BH1',
'BH2',
'BH3',
'BH4',
'BH5',
'BHK',
'BID',
'BIR',
'BLS',
'BLU',
'BMX',
'BNA',
'BOD',
'BRA',
'BTL',
'BVR',
'C01',
'C02',
'C03',
'C04',
'C06',
'C07',
'C08',
'C09',
'C10',
'C11',
'C12',
'C13',
'C14',
'C17',
'C18',
'C19',
'C20',
'C21',
'C22',
'C23',
'C24',
'C25',
'C27',
'C28',
'C30',
'C31',
'C32',
'C33',
'C34',
'C35',
'C36',
'C7H',
'CAI',
'CAN',
'CBE',
'CBN',
'CHE',
'CKN',
'CLD',
'CLE',
'CLN',
'COL1',
'COL2',
'COL3',
'COL4',
'COT',
'CQV',
'CRL',
'CRR',
'CTY',
'CVM',
'CVS',
'CWEU',
'CWFN',
'CWKX',
'CWLB',
'CWLO',
'CWLT',
'CWLW',
'CWMW',
'CWOS',
'CWPH',
'CWQG',
'CWSA',
'CWSE',
'CWZB',
'CWZC',
'CWZV',
'CYAH',
'CYAW',
'CYBK',
'CYBU',
'CYCB',
'CYCG',
'CYCX',
'CYDA',
'CYEG',
'CYEV',
'CYFB',
'CYFO',
'CYFS',
'CYGQ',
'CYHM',
'CYHZ',
'CYJT',
'CYLH',
'CYLJ',
'CYMD',
'CYMO',
'CYMT',
'CYMX',
'CYOC',
'CYOW',
'CYPA',
'CYPE',
'CYPL',
'CYPQ',
'CYQA',
'CYQD',
'CYQG',
'CYQH',
'CYQI',
'CYQK',
'CYQQ',
'CYQR',
'CYQT',
'CYQX',
'CYQY',
'CYRB',
'CYSM',
'CYSY',
'CYTH',
'CYTL',
'CYTS',
'CYUL',
'CYUX',
'CYVO',
'CYVP',
'CYVQ',
'CYVR',
'CYVV',
'CYWA',
'CYWG',
'CYWO',
'CYXC',
'CYXE',
'CYXH',
'CYXS',
'CYXU',
'CYXX',
'CYXY',
'CYXZ',
'CYYB',
'CYYC',
'CYYE',
'CYYJ',
'CYYQ',
'CYYR',
'CYYT',
'CYYZ',
'CYZF',
'CYZS',
'CYZT',
'CYZV',
'DEN',
'DOV',
'DPG',
'DSC',
'DSD',
'DTX',
'DVN',
'DYS',
'E28',
'E74',
'EAT',
'EAX',
'EDW',
'EFL',
'EMP',
'END',
'ENL',
'ESTC',
'FCS',
'FDR',
'FFC',
'FHU',
'FLG',
'FLP',
'FPK',
'FRI',
'FSI',
'FTR',
'FWD',
'G#1',
'G#2',
'G#3',
'G#4',
'G#5',
'G#6',
'G#7',
'G#8',
'G#9',
'G#A',
'G#B',
'G#C',
'G#D',
'G#E',
'G#F',
'G#G',
'G001',
'G003',
'G004',
'G005',
'G007',
'G009',
'GDP',
'GDV',
'GLRY',
'GMX1',
'GNB',
'GNC',
'GRF',
'GTB',
'GTP',
'GVL',
'GVS',
'GYX',
'H02',
'HAY',
'HGR',
'HMN',
'HOM',
'HOO',
'HSI',
'HYR',
'HYS',
'ICC',
'IGM',
'ILN',
'ILS',
'ILX',
'IMT',
'INK',
'IPX',
'JACK',
'JDN',
'K40B',
'K9V9',
'KABE',
'KABI',
'KABQ',
'KABR',
'KABY',
'KACK',
'KACT',
'KACV',
'KACY',
'KAGC',
'KAGS',
'KAHN',
'KAK',
'KALB',
'KALI',
'KALO',
'KALS',
'KALW',
'KAMA',
'KAN',
'KANB',
'KAND',
'KAOO',
'KAPA',
'KAPN',
'KART',
'KASE',
'KAST',
'KATL',
'KATY',
'KAUG',
'KAUS',
'KAUW',
'KAVL',
'KAVP',
'KAXN',
'KAYS',
'KAZO',
'KBAF',
'KBCE',
'KBDE',
'KBDL',
'KBDR',
'KBED',
'KBFD',
'KBFF',
'KBFI',
'KBFL',
'KBGM',
'KBGR',
'KBHB',
'KBHM',
'KBIH',
'KBIL',
'KBIS',
'KBJC',
'KBJI',
'KBKE',
'KBKW',
'KBLF',
'KBLH',
'KBLI',
'KBML',
'KBNA',
'KBNO',
'KBNV',
'KBOI',
'KBOS',
'KBPT',
'KBQK',
'KBRD',
'KBRL',
'KBRO',
'KBTL',
'KBTM',
'KBTR',
'KBTV',
'KBUF',
'KBUR',
'KBVI',
'KBVX',
'KBVY',
'KBWG',
'KBWI',
'KBYI',
'KBZN',
'KCAE',
'KCAK',
'KCAR',
'KCDC',
'KCDR',
'KCDS',
'KCEC',
'KCEF',
'KCGI',
'KCGX',
'KCHA',
'KCHH',
'KCHO',
'KCHS',
'KCID',
'KCIU',
'KCKB',
'KCKL',
'KCLE',
'KCLL',
'KCLM',
'KCLT',
'KCMH',
'KCMI',
'KCMX',
'KCNM',
'KCNU',
'KCOD',
'KCOE',
'KCON',
'KCOS',
'KCOU',
'KCPR',
'KCRE',
'KCRP',
'KCRQ',
'KCRW',
'KCSG',
'KCSV',
'KCTB',
'KCVG',
'KCWA',
'KCYS',
'KDAB',
'KDAG',
'KDAL',
'KDAN',
'KDAY',
'KDBQ',
'KDCA',
'KDDC',
'KDEC',
'KDEN',
'KDET',
'KDFW',
'KDHN',
'KDHT',
'KDIK',
'KDLH',
'KDLS',
'KDMN',
'KDPA',
'KDRA',
'KDRO',
'KDRT',
'KDSM',
'KDTW',
'KDUG',
'KDUJ',
'KEAT',
'KEAU',
'KECG',
'KEED',
'KEGE',
'KEKN',
'KEKO',
'KEL',
'KELD',
'KELM',
'KELO',
'KELP',
'KELY',
'KENV',
'KEPH',
'KEPO',
'KEPZ',
'KERI',
'KESF',
'KEUG',
'KEVV',
'KEWB',
'KEWN',
'KEWR',
'KEYW',
'KFAM',
'KFAR',
'KFAT',
'KFAY',
'KFCA',
'KFDY',
'KFKL',
'KFLG',
'KFLL',
'KFLO',
'KFMN',
'KFMY',
'KFNT',
'KFOE',
'KFPR',
'KFRM',
'KFSD',
'KFSM',
'KFTW',
'KFTY',
'KFVE',
'KFVX',
'KFWA',
'KFXE',
'KFYV',
'KGAG',
'KGCC',
'KGCK',
'KGCN',
'KGEG',
'KGFK',
'KGFL',
'KGGG',
'KGGW',
'KGJT',
'KGLD',
'KGLH',
'KGLS',
'KGMU',
'KGNR',
'KGNV',
'KGON',
'KGPT',
'KGRB',
'KGRI',
'KGRR',
'KGSO',
'KGSP',
'KGTF',
'KGUC',
'KGUP',
'KGWO',
'KGYY',
'KGZH',
'KHAT',
'KHBR',
'KHDN',
'KHIB',
'KHIO',
'KHKY',
'KHLG',
'KHLN',
'KHOB',
'KHON',
'KHOT',
'KHOU',
'KHPN',
'KHQM',
'KHRL',
'KHRO',
'KHSV',
'KHTH',
'KHTS',
'KHUF',
'KHUL',
'KHUT',
'KHVN',
'KHVR',
'KHYA',
'KIAD',
'KIAG',
'KIAH',
'KICT',
'KIDA',
'KIL',
'KILG',
'KILM',
'KIND',
'KINK',
'KINL',
'KINT',
'KINW',
'KIPL',
'KIPT',
'KISN',
'KISP',
'KITH',
'KIWD',
'KJAC',
'KJAN',
'KJAX',
'KJBR',
'KJFK',
'KJHW',
'KJKL',
'KJLN',
'KJMS',
'KJST',
'KJXN',
'KKL',
'KLAF',
'KLAN',
'KLAR',
'KLAS',
'KLAX',
'KLBB',
'KLBE',
'KLBF',
'KLCB',
'KLCH',
'KLEB',
'KLEX',
'KLFK',
'KLFT',
'KLGA',
'KLGB',
'KLGU',
'KLIT',
'KLMT',
'KLND',
'KLNK',
'KLOL',
'KLOZ',
'KLRD',
'KLSE',
'KLUK',
'KLVS',
'KLWB',
'KLWM',
'KLWS',
'KLWT',
'KLYH',
'KLZK',
'KMAF',
'KMBS',
'KMCB',
'KMCE',
'KMCI',
'KMCN',
'KMCO',
'KMCW',
'KMDN',
'KMDT',
'KMDW',
'KMEI',
'KMEM',
'KMFD',
'KMFE',
'KMFR',
'KMGM',
'KMGW',
'KMHE',
'KMHK',
'KMHT',
'KMHX',
'KMIA',
'KMIV',
'KMKC',
'KMKE',
'KMKG',
'KMKL',
'KMLB',
'KMLC',
'KMLI',
'KMLS',
'KMLT',
'KMLU',
'KMMU',
'KMOB',
'KMOT',
'KMPV',
'KMQT',
'KMRB',
'KMRY',
'KMSL',
'KMSN',
'KMSO',
'KMSP',
'KMSS',
'KMSY',
'KMTJ',
'KMTN',
'KMWH',
'KMYR',
'KNA',
'KNEW',
'KNL',
'KNSI',
'KOAK',
'KOFK',
'KOGD',
'KOKC',
'KOLM',
'KOMA',
'KONT',
'KOPF',
'KOQU',
'KORD',
'KORF',
'KORH',
'KOSH',
'KOTH',
'KOTM',
'KP11',
'KP38',
'KPAE',
'KPAH',
'KPBF',
'KPBI',
'KPDK',
'KPDT',
'KPDX',
'KPFN',
'KPGA',
'KPHF',
'KPHL',
'KPHN',
'KPHX',
'KPIA',
'KPIB',
'KPIE',
'KPIH',
'KPIR',
'KPIT',
'KPKB',
'KPLN',
'KPMD',
'KPNC',
'KPNE',
'KPNS',
'KPOU',
'KPQI',
'KPRB',
'KPRC',
'KPSC',
'KPSM',
'KPSP',
'KPTK',
'KPUB',
'KPVD',
'KPVU',
'KPWM',
'KRAD',
'KRAP',
'KRBL',
'KRDD',
'KRDG',
'KRDM',
'KRDU',
'KRFD',
'KRIC',
'KRIW',
'KRKD',
'KRKS',
'KRNO',
'KRNT',
'KROA',
'KROC',
'KROW',
'KRSL',
'KRST',
'KRSW',
'KRUM',
'KRWF',
'KRWI',
'KRWL',
'KSAC',
'KSAF',
'KSAN',
'KSAT',
'KSAV',
'KSBA',
'KSBN',
'KSBP',
'KSBY',
'KSCH',
'KSCK',
'KSDF',
'KSDM',
'KSDY',
'KSEA',
'KSEP',
'KSFF',
'KSFO',
'KSGF',
'KSGU',
'KSHR',
'KSHV',
'KSJC',
'KSJT',
'KSLC',
'KSLE',
'KSLK',
'KSLN',
'KSMF',
'KSMX',
'KSNA',
'KSNS',
'KSPI',
'KSPS',
'KSRQ',
'KSSI',
'KSTJ',
'KSTL',
'KSTP',
'KSTS',
'KSUN',
'KSUS',
'KSUX',
'KSVE',
'KSWF',
'KSYR',
'KTCC',
'KTCL',
'KTCS',
'KTEB',
'KTIW',
'KTLH',
'KTMB',
'KTOL',
'KTOP',
'KTPA',
'KTPH',
'KTRI',
'KTRK',
'KTRM',
'KTTD',
'KTTN',
'KTUL',
'KTUP',
'KTUS',
'KTVC',
'KTVL',
'KTWF',
'KTXK',
'KTYR',
'KTYS',
'KUCA',
'KUIN',
'KUKI',
'KUNV',
'KVCT',
'KVEL',
'KVLD',
'KVNY',
'KVRB',
'KWJF',
'KWMC',
'KWRL',
'KWYS',
'KY22',
'KY26',
'KYKM',
'KYKN',
'KYNG',
'KYUM',
'KZZV',
'LAA',
'LAP',
'LBY',
'LDL',
'LHX',
'LIC',
'LOR',
'LRR',
'LSF',
'LUS',
'LVM',
'LW1',
'MAC',
'MAX',
'MAZ',
'MDPC',
'MDPP',
'MDSD',
'MDST',
'MGFL',
'MGGT',
'MGHT',
'MGPB',
'MGSJ',
'MHAM',
'MHCA',
'MHCH',
'MHLC',
'MHLE',
'MHLM',
'MHNJ',
'MHPL',
'MHRO',
'MHSR',
'MHTE',
'MHTG',
'MHYR',
'MIB',
'MIE',
'MKJP',
'MKJS',
'MLD',
'MMAA',
'MMAS',
'MMBT',
'MMCE',
'MMCL',
'MMCN',
'MMCS',
'MMCU',
'MMCV',
'MMCZ',
'MMDO',
'MMGL',
'MMGM',
'MMHO',
'MMLP',
'MMMA',
'MMMD',
'MMML',
'MMMM',
'MMMT',
'MMMX',
'MMMY',
'MMMZ',
'MMNL',
'MMPR',
'MMRX',
'MMSD',
'MMSP',
'MMTC',
'MMTJ',
'MMTM',
'MMTO',
'MMTP',
'MMUN',
'MMVR',
'MMZC',
'MMZH',
'MMZO',
'MNMG',
'MNPC',
'MOR',
'MPBO',
'MPCH',
'MPDA',
'MPMG',
'MPSA',
'MPTO',
'MPX',
'MRCH',
'MRF',
'MRLB',
'MRLM',
'MROC',
'MRPV',
'MRS',
'MSAC',
'MSLP',
'MSSS',
'MTCH',
'MTL',
'MTPP',
'MTV',
'MTY',
'MUBA',
'MUBY',
'MUCA',
'MUCL',
'MUCM',
'MUCU',
'MUGM',
'MUGT',
'MUHA',
'MUMO',
'MUMZ',
'MUNG',
'MUVR',
'MUVT',
'MWCR',
'MYBS',
'MYEG',
'MYGF',
'MYGW',
'MYL',
'MYNN',
'MZBZ',
'MZT',
'NCK',
'NGX',
'NHK',
'NID',
'NKX',
'NOA',
'NRU',
'NTD',
...]
request.setLocationNames("KFRM")
cycles = DataAccessLayer.getAvailableTimes(request, True)
times = DataAccessLayer.getAvailableTimes(request)
try:
fcstRun = DataAccessLayer.getForecastRun(cycles[-1], times)
list(fcstRun)
response = DataAccessLayer.getGeometryData(request,[fcstRun[0]])
except:
print('No times available')
exit
Model Sounding Parameters
Construct arrays for each parameter to plot (temperature, pressure, moisutre (spec. humidity), wind components, and cloud cover)
tmp,prs,sh = np.array([]),np.array([]),np.array([])
uc,vc,om,cld = np.array([]),np.array([]),np.array([]),np.array([])
for ob in response:
tmp = np.append(tmp,ob.getNumber("temperature"))
prs = np.append(prs,ob.getNumber("pressure"))
sh = np.append(sh,ob.getNumber("specHum"))
uc = np.append(uc,ob.getNumber("uComp"))
vc = np.append(vc,ob.getNumber("vComp"))
om = np.append(om,ob.getNumber("omega"))
cld = np.append(cld,ob.getNumber("cldCvr"))
print("parms = " + str(ob.getParameters()))
print("site = " + str(ob.getLocationName()))
print("geom = " + str(ob.getGeometry()))
print("datetime = " + str(ob.getDataTime()))
print("reftime = " + str(ob.getDataTime().getRefTime()))
print("fcstHour = " + str(ob.getDataTime().getFcstTime()))
print("period = " + str(ob.getDataTime().getValidPeriod()))
parms = ['temperature', 'pressure', 'vComp', 'uComp', 'cldCvr', 'specHum', 'omega']
site = KFRM
geom = POINT (-94.41999816894531 43.65000152587891)
datetime = 2020-09-04 12:00:00
reftime = Sep 04 20 12:00:00 GMT
fcstHour = 0
period = (Sep 04 20 12:00:00 , Sep 04 20 12:00:00 )
Calculating Dewpoint from Specific Humidity
Because the modelsounding plugin does not return dewpoint values, we must calculate the profile ourselves. Here are three examples of dewpoint calculated from specific humidity, including a manual calculation following NCEP AWIPS/NSHARP.
1) MetPy calculated mixing ratio and vapor pressure
t = (tmp-273.15) * units.degC
p = prs/100 * units.mbar
u,v = uc*1.94384,vc*1.94384 # m/s to knots
spd = wind_speed(u*units.knots, v*units.knots)
dir = wind_direction(u*units.knots, v*units.knots) * units.deg
rmix = (sh/(1-sh)) *1000 * units('g/kg')
e = vapor_pressure(p, rmix)
td = dewpoint(e)
2) metpy calculated assuming spec. humidity = mixing ratio
td2 = dewpoint(vapor_pressure(p, sh))
3) NCEP AWIPS soundingrequest plugin
based on GEMPAK/NSHARP, from https://github.com/Unidata/awips2-ncep/blob/unidata_16.2.2/edex/gov.noaa.nws.ncep.edex.plugin.soundingrequest/src/gov/noaa/nws/ncep/edex/plugin/soundingrequest/handler/MergeSounding.java#L1783
# new arrays
ntmp = tmp
# where p=pressure(pa), T=temp(C), T0=reference temp(273.16)
rh = 0.263*prs*sh / (np.exp(17.67*ntmp/(ntmp+273.15-29.65)))
vaps = 6.112 * np.exp((17.67 * ntmp) / (ntmp + 243.5))
vapr = rh * vaps / 100
dwpc = np.array(243.5 * (np.log(6.112) - np.log(vapr)) / (np.log(vapr) - np.log(6.112) - 17.67)) * units.degC
MetPy SkewT and Hodograph
%matplotlib inline
plt.rcParams['figure.figsize'] = (12, 14)
# Create a skewT plot
skew = SkewT()
# Plot the data
skew.plot(p, t, 'r', linewidth=2)
skew.plot(p, td, 'b', linewidth=2)
skew.plot(p, td2, 'y')
skew.plot(p, dwpc, 'g', linewidth=2)
skew.plot_barbs(p, u, v)
skew.ax.set_ylim(1000, 100)
skew.ax.set_xlim(-40, 60)
plt.title( forecastModel + " " \
+ ob.getLocationName() \
+ "("+ str(ob.getGeometry()) + ")" \
+ ", " + str(ob.getDataTime())
)
# An example of a slanted line at constant T -- in this case the 0 isotherm
l = skew.ax.axvline(0, color='c', linestyle='--', linewidth=2)
# Draw hodograph
ax_hod = inset_axes(skew.ax, '40%', '40%', loc=1)
h = Hodograph(ax_hod, component_range=spd.max()/units.knots)
h.add_grid(increment=20)
h.plot_colormapped(u, v, spd)
# Show the plot
plt.show()
