Beispiel #1
0
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')
Beispiel #2
0
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')
Beispiel #3
0
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))