# python script to transform DCAO's snd data to netCDF # L. Fita, CIMA. Sept. 2018 ## e.g. # snd_DCAO_netcdf.py -f pedidoLluis200212.dat ### ASCII files from DCAO can have more than one sounding per file ### Script spect to find # ESTACION: 87155 RESISTENCIA AERO 27.30S 59.00W ( 52 M) # 1-12-2002 6 UTC # ::: NIVELES SIGNIFICATIVOS ::: # NIVEL PP(MB) TT(C) TD(C) TP(K) TPE(K) HR Z(MGP) GRAD. # 1 996 26.2 23.9 300 354 87 52 # 2 951 24.6 22.3 302 354 87 461 NORMAL # 3 930 26.4 21.4 306 357 74 658 INVERS. # 4 793 16.6 16.1 310 353 97 2047 NORMAL # 5 701 11.6 8.6 315 346 82 3092 NORMAL # 6 644 6.6 4.6 317 343 87 3797 NORMAL # 7 621 7.6 -4.4 322 336 43 4097 INVERS. # 8 610 6.2 -5.8 322 335 42 4244 ADIABAT # 9 607 6.4 -5.6 322 336 42 4284 ADIABAT # 10 567 2.8 -10.2 325 335 38 4840 NORMAL # 11 565 2.6 -10.4 325 335 38 4869 ADIABAT # 12 472 -9.1 -22.1 327 332 34 6292 NORMAL # 13 432 -12.3 -29.3 332 335 23 6973 NORMAL # 14 350 -25.9 -47.9 334 334 10 8540 NORMAL # 15 346 -25.9 -48.9 335 335 9 8623 ISOTERM # 16 335 -26.9 -41.9 337 338 22 8857 NORMAL # 17 333 -27.9 -47.9 336 337 12 8900 ADIABAT # 18 259 -41.7 -59.7 341 341 11 10654 NORMAL # 19 258 -41.7 -59.7 341 341 11 10680 ADIABAT # ::: NIVELES TIPO ::: # NIVEL PP(MB) TT(C) TD(C) HR Z(MGP) DD FFF CAPA AD.3HS # SUP. 996 26.2 23.9 87 52 20 7 # 1 1000 ***** ***** *** 17 *** *** 1000-850 ***** # 2 850 20.9 18.4 86 1442 330 44 850-700 0.6 # 3 700 11.5 8.5 82 3104 320 31 700-500 0.8 # 4 500 -5.4 -18.4 36 5836 285 32 500-400 0.0 # 5 400 -17.3 -36.1 18 7546 285 48 400-300 1.5 # 6 300 -33.6 -52.8 12 9628 270 68 300-250 ***** # ::VTOS NIV. FIJOS H:(MGP);NIV.SIG.P(MB.):: # H^P? DD FF(KT) H^P? DD FF(KT) H^P? DD FF(KT) # 996 20 7 940 350 48 845 325 43 # 645 315 33 562 290 22 424 290 50 # 374 280 47 320 270 72 317 270 72 # 269 270 67 0 20 7 300 15 15 # 600 35 17 900 50 16 2100 30 1 # VIENTO TERMICO DE LOS 196/ 31 KT ESPESOR(500/1000) 5819 MGP # V.MAX EN: 317 MBS 9240 MGP DE LOS 270 GR 72 KT CORT(KT/KM)****** # NCA: 963 MB 23.4 G.C. 296 MGP # NCC: 834 MB 19.7 G.C. 1554 MGP T.CRIT: 34.9 G.C. # ISOTERMA DE CERO GRADO # PRESION: 543 MB ALTURA: 5133 MGP # INDICES DE INESTABILIDAD: # K: 41.6 SH: -4.1 LI: -4.3 FM: -4.3 # CT:23.8 VT:26.2 TT:50.0 SWEAT: 491.8 # # AGUA PRECIPITABLE: 58.6 MM TEMP. POT. EQUIV. 850 MB: 354.8 # # TOPE AREA POSITIVA # PRES: 258 MB TEMP: ***** C ALT:10680 MGP AREA:2077.2 KJ/TON # GRUPO DE NUBES: 20970 # 1 from optparse import OptionParser import numpy as np from netCDF4 import Dataset as NetCDFFile import os import re import numpy.ma as ma # Importing generic tools file 'nc_var_tools.py' import nc_var_tools as ncvar # Importing generic tools file 'generic_tools.py' import generic_tools as gen import subprocess as sub import time main = 'snd_DCAO_netCDF.py' ###### ###### ##### #### ### ## # errormsg = 'ERROR -- error -- ERROR -- error' Lstring = 256 def station_inf(linev): """ Function to retrieve station information linev: values from line retrieved from file (detected by linev[0]=='ESTACION:') """ fname = 'station_inf' if linev[0] != 'ESTACION:': print errormsg print ' ' + fname + ": first value must be 'ESTACION:', but I got '" + \ linev[0] + "' !!" quit(-1) Lvals = len(linevals) stid = int(linevals[1]) stn = ' '.join(linevals[3:Lvals-5]) stlat = linevals[Lvals-5] stlon = linevals[Lvals-4] sth = np.float(linevals[Lvals-2]) # conversion lon, lat Lstlat = len(stlat) if stlat[Lstlat-1:Lstlat] == 'S': stlat = -np.float(stlat[0:Lstlat-1]) else: stlat = np.float(stlat[0:Lstlat-1]) Lstlon = len(stlon) if stlon[Lstlon-1:Lstlon] == 'S': stlon = -np.float(stlon[0:Lstlon-1]) else: stlon = np.float(stlon[0:Lstlon-1]) stinf = [stid, stn, stlat, stlon, sth] return stinf def station_timeinf(linev): """ Function to get date-time from record linev: values from line (linev has 'UTC') """ fname = 'station_timeinf' if not gen.searchInlist(linev, 'UTC'): print errormsg print ' ' + fname + ": values do not have 'UTC' !!" print ' values passed:', linev quit(-1) # Getting time data stdate = linevals[0] sttime = linevals[1].zfill(2) # Transforming to CFdate refdate = '1949-12-01 00:00:00' tunits = 'minutes' datev = stdate.split('-') dateeng = datev[2] + '-' + datev[1] + '-' + datev[0] stCFtime = gen.datetimeStr_conversion(dateeng+' '+sttime+':00:00', 'Y-m-d H:M:S',\ 'cfTime,' + tunits + ' since ' + refdate) sttinf = [stdate, sttime, stCFtime, refdate, tunits] return sttinf # Arguments ## parser = OptionParser() parser.add_option("-D", "--Debug", dest="debug", help="debug prints", metavar="BOOL") parser.add_option("-f", "--snd_file", dest="sndfile", help="UDCAO sounding (from Gustavo Pittaluga - Banco de datos DCAO ) file to use", metavar="FILE") (opts, args) = parser.parse_args() ####### ####### ## MAIN ####### if opts.debug is None: print gen.infmsg print ' ' + main + ": no debug value provided!!" print ' assuming:', False debug = False else: debug = gen.Str_Bool(opts.debug) if not os.path.isfile(opts.sndfile): print gen.errormsg print ' ' + main + ": sounding file '" + opts.sndfile + "' does not exist !!" quit(-1) # Reading sounding file osnd = open(opts.sndfile, 'r') # Dictionary with station data stations = {} siglev = False tipolev = False fijolev = False indices = False Nsiglev = 0 Ntipolev = 0 Nfijolev = 0 Nindices = 0 # Recovering information from file for line in osnd: if line[0:1] != '#' and len(line) > 1: # getting values removing spurious spaces linevals = gen.values_line(line, ' ', ['\t', '\n', '\r']) # Got trhought lines with data! if len(linevals) != 0: print linevals print siglev, Nsiglev, tipolev, Ntipolev, fijolev, Nfijolev, indices, Nindices # Starting of record by finding 'ESTACION:' if linevals[0] == 'ESTACION:': statinf = station_inf(linevals) siglev = False tipolev = False fijolev = False indices = False # date/time of record by finding 'UTC' elif gen.searchInlist(linevals, 'UTC'): statTinf = station_timeinf(linevals) statinf = statinf + statTinf # significative levels elif gen.searchInlist(linevals, 'SIGNIFICATIVOS'): siglev = True Nsiglev = 0 # tipo levels elif gen.searchInlist(linevals, 'TIPO'): siglev = False # Removing headers Nsiglev = Nsiglev - 2 tipolev = True Ntipolev = 0 # fijo levels elif gen.searchInlist(linevals, 'FIJOS'): tipolev = False # Removing headers Ntipolev = Ntipolev - 2 fijolev = True Nfijolev = 0 # indices elif gen.searchInlist(linevals, 'TERMICO'): fijolev = False # Removing headers Nfijolev = Nfijolev - 2 indices = True Nindices = 0 # End record elif linevals[0] == '1' and indices: indices = False stvals = statinf + [Nsiglev, Ntipolev, Nfijolev, Nindices] if not stations.has_key(statinf[0]): stations[statinf[0]] = [stvals] else: stv = stations[statinf[0]] stv.append(stvals) stations[statinf[0]] = stv print stvals quit(-1) elif tipolev: Ntipolev = Ntipolev + 1 elif siglev: Nsiglev = Nsiglev + 1 elif fijolev: Nfijolev = Nfijolev + 1 elif indices: Nindices = Nindices + 1 gen.printing_dictionary(stations) osnd.close()