function [obs] = parse_metar(metar_str) % [obs] = parse_metar(metar_str) % % Last modified: Time-stamp: <2003-09-30 09:14:04 haines> % % Abstract: Function that loads, parses metar obs, appends new data, and saves with all data % % Usage: [obs] = parse_metar(metar_str) % metar_str = string of coded metar data % [obs] = vector array of decoded data % % % Author: Sara Haines, Sept 18, 2003 % Processing: % (1) break into words % (2) parse each word into categories % (3) further extract each category and convert as necessary % % # Major parts and general idea of this subroutine courtesy of: % # wmk % # www.ii.pw.edu.pl/~wkowalsk/metar2.cgi % # Thu May 20 21:34:39 CET 1999 % anything other than alph numeric or whitespace should be removed metar_str = regexprep(metar_str, '[^A-Z|a-z|0-9|\-|\/|\s]', ''); % cell array of coded metar words words = strread(metar_str, '%s', 'delimiter', ' '); words(1) = []; % for each word establish category for i = 1:length(words) word = char(words(i)); % if regexp(word, 'RMK|TEMPO|BECMG|NOSIG') % break; % break out of this loop % else if regexp(word, 'COR|AUTO') if ~exist('obstype') obstype = word; continue; end elseif regexp(word, '^(\d{6})Z|^(\d{6})') if ~exist('rtime') rtime = word; continue; end elseif regexp(word, '(..)MPS|(..)KT') if ~exist('wind1') wind1 = word; continue; end elseif regexp(word, '^(\d{4})|(..)SM|CAVOK') if ~exist('visib') visib = word; continue; end elseif regexp(word, 'BR|DZ|DS|DU|RA|SN|SG|SA|SS|SQ|IC|PE|PY|GR|GS|FG|FC|FU|HZ') if ~exist('phenom') phenom{1} = word; else phenom{length(phenom)+1} = word; end continue; elseif regexp(word, 'FEW|SCT|BKN|OVC') if ~exist('clouds') clouds{1} = word; else clouds{length(clouds)+1} = word; end continue; elseif regexp(word, '^(\d{3})V(\d{3})') if ~exist('wind2') wind2 = word; continue; end elseif regexp(word, '^(M?\d{2})\/(M?\d{2})') if ~exist('tempr') tempr = word; continue; end elseif regexp(word, 'Q(\d{4})|A(\d{4})') if ~exist('press') press = word; continue; end elseif regexp(word, '^SLP') if ~exist('slpress') slpress = word; continue; end end end % for % process wind1, wind2, tempr, and press to get started % to tease out wspd, wdir, peak_gusts, atemp, dewp, baro, slp % % eventually want to tease out higher precision temp and press % measurements from stations that have that (usually follows RMK, % for example, RMK AO2 SLP133 T03110178) % % (still will need to handle visib, phenom, and clouds later) % calm 00000KT % variable VRBdd(d)KT or VRBdd(d)Gdd(d)KT % wdir and wspd dddddKT % wdir and wspd with gust factor ddddd(d)Gdd(d)KT % (not worrying about direction variablility 350V040 assigned to wind2 word) if exist('wind1') % split string between dir and speed wind1_dir = wind1(1:3); wind1_spd = wind1(4:end); if regexp(wind1, 'VRB') wdir = 999; else try wdir = strread(wind1_dir, '%d'); catch wdir = -9999; end end if regexp(wind1_spd, 'G') try [wspd, maxwspd] = strread(wind1_spd, '%dG%d%*s'); catch wspd = -9999; maxwspd = -9999; end else try [wspd] = strread(wind1_spd, '%d%*s'); maxwspd = wspd; catch wspd = -9999; maxwspd = -9999; end end if regexp(wind1_spd, 'KT') wspd = wspd*0.5141; % from knots to mps (m/sec) maxwspd = maxwspd*0.5141; elseif regexp(wind1_spd, 'MPS') % already in m/sec, don't do anything end else wspd = -9999; wdir = -9999; maxwspd = -9999; end if exist('tempr') if length(tempr)>5 tempr = tempr(1:5); end tempr = regexprep(tempr, 'M', '-'); try [atemp,dewp] = strread(tempr, '%f/%f'); % deg C catch atemp = -9999; dewp = -9999; end else atemp = -9999; dewp = -9999; end if exist('press') if length(press)>5 press = press(1:5); end if regexp(press, '^Q') try baro = strread(press, 'Q%f'); % mbar catch baro = -9999; end elseif regexp(press, '^A') try baro = strread(press, 'A%f'); baro = baro*0.33868; % from inHg*100 to mbar catch baro = -9999; end else baro = -9999; end else baro = -9999; end if exist('slpress') if regexp(slpress, 'NO') slp = -9999; elseif length(slpress<4) slp = -9999; else try slp = strread(slpress, 'SLP%f'); slp = slp/10; if slp >= 50 slp = 900+slp; else slp = 1000+slp; end catch slp = -9999; end end else slp = -9999; end obs.wspd = wspd; obs.wdir = wdir; obs.maxwspd = maxwspd; obs.atemp = atemp; obs.dewp = dewp; obs.baro = baro; obs.slp = slp; % return;