def plot_sounding_data_csv(filename, output): """Plot SkewT from a CSV sounding data file :param filename: The name of the file to open. :type filename: str :param output: The name of the file to output plot :type output: str The datafile format is CSV with the following columns: - pressure (mb) - height (m) - temperature (C) - dew point (C) - wind direction (degrees) - wind speed (m/s) Missing values should be filled with the value -9999.00 """ p, z, T, Td, wdir, wspd = np.loadtxt(filename, delimiter=',', unpack=True) # Pressure to Pa p = p * 100. # z to km #z = z / 1000. # interpolate missing wind nk = len(z) u = np.empty(nk, np.float32) v = np.empty(nk, np.float32) for k in range(nk): if wdir[k] == -9999. and wspd[k] == -9999.: u[k] = v[k] = -9999. else: u[k], v[k] = dyn.wind_deg_to_uv(wdir[k], wspd[k]) #print('{0:5.2f} {1:5.2f} = {2:5.2f} {3:5.2f}'.format(wdir[k], wspd[k], u[k], v[k])) _z = np.empty(2, np.float32) _u = np.empty(2, np.float32) _v = np.empty(2, np.float32) print('INTERPOLATING') for k in range(nk): if wdir[k] == -9999. and wspd[k] == -9999.: kb = ke = k while kb >= 0 and wdir[kb] == -9999. and wspd[kb] == -9999.: kb -= 1 while ke <= nk - 1 and wdir[ke] == -9999. and wspd[ke] == -9999.: ke += 1 # everything in bounds if kb >= 0 and ke <= nk - 1: _z[0] = z[kb] _z[1] = z[ke] _u[0] = u[kb] _u[1] = u[ke] _v[0] = v[kb] _v[1] = v[ke] u[k] = pymeteo.interp.linear(_z, _u, z[k]) v[k] = pymeteo.interp.linear(_z, _v, z[k]) elif kb < 0: u[k] = u[ke] v[k] = v[ke] elif ke > nk - 1: u[k] = u[kb] v[k] = v[kb] for k in range(nk): # kt to m/s u[k] = u[k] * 0.5144444 v[k] = v[k] * 0.5144444 # print('{0:5.2f} {1:5.2f} = {2:5.2f} {3:5.2f}'.format(wdir[k], wspd[k], u[k], v[k])) # calc theta th = np.empty(nk, np.float32) # calc qv qv = np.empty(nk, np.float32) for k in range(nk): th[k] = met.theta(T[k] + met.T00, p[k]) w = met.es(Td[k] + met.T00) / met.es(T[k] + met.T00) pp = met.es(T[k] + met.T00) / p[k] qv[k] = 0.622 * pp * w #qv[k] = met.es(Td[k]+met.T00) / (met.Rv * (T[k]+met.T00)) #print(z, th, p, qv, u, v) plot(None, z, th, p, qv, u, v, output, title='Sounding Data')
def plot_sounding_data_csv(filename, output): """Plot SkewT from a CSV sounding data file :param filename: The name of the file to open. :type filename: str :param output: The name of the file to output plot :type output: str The datafile format is CSV with the following columns: - pressure (mb) - height (m) - temperature (C) - dew point (C) - wind direction (degrees) - wind speed (m/s) Missing values should be filled with the value -9999.00 """ p,z,T,Td,wdir,wspd = np.loadtxt(filename, delimiter=',', unpack=True) # Pressure to Pa p = p * 100. # z to km #z = z / 1000. # interpolate missing wind nk = len(z) u = np.empty(nk, np.float32) v = np.empty(nk, np.float32) for k in range(nk): if wdir[k] == -9999. and wspd[k] == -9999.: u[k] = v[k] = -9999. else: u[k], v[k] = dyn.wind_deg_to_uv(wdir[k], wspd[k]) #print('{0:5.2f} {1:5.2f} = {2:5.2f} {3:5.2f}'.format(wdir[k], wspd[k], u[k], v[k])) _z = np.empty(2,np.float32) _u = np.empty(2,np.float32) _v = np.empty(2,np.float32) print('INTERPOLATING') for k in range(nk): if wdir[k] == -9999. and wspd[k] == -9999.: kb = ke = k while kb >= 0 and wdir[kb] == -9999. and wspd[kb] == -9999.: kb -= 1 while ke <= nk-1 and wdir[ke] == -9999. and wspd[ke] == -9999.: ke += 1 # everything in bounds if kb >= 0 and ke <= nk-1: _z[0] = z[kb] _z[1] = z[ke] _u[0] = u[kb] _u[1] = u[ke] _v[0] = v[kb] _v[1] = v[ke] u[k] = pymeteo.interp.linear(_z, _u, z[k]) v[k] = pymeteo.interp.linear(_z, _v, z[k]) elif kb < 0: u[k] = u[ke] v[k] = v[ke] elif ke > nk-1: u[k] = u[kb] v[k] = v[kb] for k in range(nk): # kt to m/s u[k] = u[k] * 0.5144444 v[k] = v[k] * 0.5144444 # print('{0:5.2f} {1:5.2f} = {2:5.2f} {3:5.2f}'.format(wdir[k], wspd[k], u[k], v[k])) # calc theta th = np.empty(nk, np.float32) # calc qv qv = np.empty(nk, np.float32) for k in range(nk): th[k] = met.theta(T[k]+met.T00, p[k]) w = met.es(Td[k]+met.T00) / met.es(T[k]+met.T00) pp = met.es(T[k]+met.T00) / p[k] qv[k] = 0.622 * pp * w #qv[k] = met.es(Td[k]+met.T00) / (met.Rv * (T[k]+met.T00)) #print(z, th, p, qv, u, v) plot(None, z, th, p, qv, u, v, output, title='Sounding Data')
def processDataSet(data): print("[+] Writing data into temporary file") tdata = tempfile.NamedTemporaryFile() tdata.write(data.read()) print("[-] Data written to {0}".format(tdata.name)) print("[+] Opening data as NetCDF") d = data.read() with netCDF4.Dataset(tdata.name, mode='r') as nc: print("[-] Dataset open with") _z = nc["altitude"][:] _T = nc["temperature"][:] _qv = nc["waterVaporMR"][:] windSpeed = nc["windSpeed"][:] windDir = nc["windDir"][:] _lon = nc["longitude"][:] _lat = nc["latitude"][:] flag = nc["sounding_flag"][:] _airport = nc["sounding_airport_id"][:] time = nc["soundingSecs"][:] print("[-] {0} Records".format(len(_z))) #conversions _p = thermo.p_from_pressure_altitude(_z, _T) _u, _v = dynamics.wind_deg_to_uv(windDir, windSpeed) _th = thermo.theta(_T, _p) # split the arrays when the flag changes sign splits = np.where(np.diff(time))[0] + 1 _z = np.split(_z, splits) _p = np.split(_p, splits) _th = np.split(_th, splits) _qv = np.split(_qv, splits) _u = np.split(_u, splits) _v = np.split(_v, splits) _lat = np.split(_lat, splits) _lon = np.split(_lon, splits) _airport = np.split(_airport, splits) time = np.split(time, splits) flag = np.split(flag, splits) print("[-] Found {0} profiles".format(len(_z))) #re-shape data outputData = [] for i in range(len(_z)): ts = time[i].compressed() if len(ts) == 0: # profiles without timestamps invalid? continue profileDir = flag[i][0] if (profileDir == 0): continue z = _z[i].filled() p = _p[i].filled() th = _th[i].filled() qv = _qv[i].filled() u = _u[i].filled() v = _v[i].filled() lat = _lat[i].filled() lon = _lon[i].filled() airport = getAirportByCode(_airport[i][0]) profileData = { "i": i, "n": len(z), "z": z if profileDir > 0 else z[::-1], "p": p if profileDir > 0 else p[::-1], "th": th if profileDir > 0 else th[::-1], "qv": qv if profileDir > 0 else qv[::-1], "u": u if profileDir > 0 else u[::-1], "v": v if profileDir > 0 else v[::-1], "lat": lat if profileDir > 0 else lat[::-1], "lon": lon if profileDir > 0 else lon[::-1], "airport": airport, "time": datetime.utcfromtimestamp(ts.mean()).strftime("%H%MZ"), "flag": profileDir } outputData.append(profileData) return outputData
file = sys.argv[0] # Read data ds = xr.open_dataset(file) p = ds['pressure'].isel({'sounding': 0}).values * units.hPa z = ds['altitude'].isel({'sounding': 0}).values * units.meters T = ds['temperature'].isel({'sounding': 0}).values * units.degC Td = ds['dewPoint'].isel({'sounding': 0}).values * units.degC wind_speed = ds['windSpeed'].isel({ 'sounding': 0 }).values * (units.meter / units.second) wind_dir = ds['windDirection'].isel({'sounding': 0}).values * units.degrees # Calculate input for skewt u, v = mpcalc.wind_components(wind_speed, wind_dir) th = met.theta(np.array(T) + met.T00, np.array(p) * 100) w = met.es(np.array(Td) + met.T00) / met.es(np.array(T) + met.T00) pp = met.es(np.array(T) + met.T00) / (np.array(p) * 100) qv = 0.622 * pp * w # Create skewt skewt.plot(None, np.array(z), th, np.array(p) * 100, qv, np.array(u), np.array(v), 'sounding.pdf', title=os.path.basename(file))