def add_curves_Wyoming(ax, datetime, station, linewidth=1.0, LH_Tdepend=False): """ overlaying new curves of multiple soundings from Wyoming datasets date: using datetime module. ex. datetime(2018,06,06) station: station name. ex. 'MFL' Miami, Florida """ from siphon.simplewebservice.wyoming import WyomingUpperAir date = datetime station = station df = WyomingUpperAir.request_data(date, station) pressure = df['pressure'].values Temp = df['temperature'].values Temp_dew = df['dewpoint'].values altitude = df['height'].values q = mpcalc.mixing_ratio( mpcalc.saturation_vapor_pressure(Temp_dew * units('degC')), pressure * units('mbar')) q = mpcalc.specific_humidity_from_mixing_ratio(q) qs = mpcalc.mixing_ratio( mpcalc.saturation_vapor_pressure(Temp * units('degC')), pressure * units('mbar')) # specific energies if LH_Tdepend == False: mse = mpcalc.moist_static_energy(altitude * units('meter'), Temp * units('degC'), q) mse_s = mpcalc.moist_static_energy(altitude * units('meter'), Temp * units('degC'), qs) dse = mpcalc.dry_static_energy(altitude * units('meter'), Temp * units('degC')) else: # A short course in cloud physics, Roger and Yau (1989) Lvt = (2500.8 - 2.36 * T.magnitude + 0.0016 * T.magnitude**2 - 0.00006 * T.magnitude**3) * units( 'joule/gram') # latent heat of evaporation #Lf = 2834.1 - 0.29*T - 0.004*T**2 # latent heat of fusion mse = Cp_d * T + g * altitude + Lvt * q mse_s = Cp_d * T + g * altitude + Lvt * qs dse = mpcalc.dry_static_energy(altitude, T) # adding curves on the main axes ax.plot(dse.magnitude, pressure, 'k', linewidth=linewidth) ax.plot(mse.magnitude, pressure, 'b', linewidth=linewidth) ax.plot(mse_s.magnitude, pressure, 'r', linewidth=linewidth)
def get_weather(self): #------------------------------------------------------ #------------------------------------------------------ # Load TMY2 if self.file_ext == TMY2EXT: f = open(self.weatherpath + self.city + self.file_ext, 'r') # Header read for lat and lon head = f.readline() self.lat = int(head[39:41]) + int(head[42:44]) / 60.0 self.lon = int(head[47:50]) + int(head[51:53]) / 60.0 line = f.readline() ind = 0 while line: # Process the line self.tothor[ind] = float( line[17:21]) #Total horizontal solar Wh/m2 self.dirnorm[ind] = float( line[23:27]) #Direct normal solar Wh/m2 self.difhor[ind] = float( line[29:33]) #Diffuse Horizontal Solar Wh/m2 self.tdry[ind] = float(line[67:71]) * 0.1 #tdrybulb (deg C) self.rhs[ind] = float(line[79:82]) * 0.01 #relative humidity (%) self.tdew[ind] = float(line[73:77]) * 0.1 #tdew (deg C) to conform with TB code self.press[ind] = float(line[84:88]) #atmospheric pressure (mbar) mb = 100 Pascals #self.wind_speed[ind] = float(line[95:98]) * 0.1; #windspeed m/s #self.wind_dir[ind] = float(line[90:93]); #wind direction azimuth #self.cloud[ind] = float(line[59:61])/10.0; #Could cover fraction #wd.ocloud = getint(line,63,2)/10.0; #Opaque cloud cover fraction #wd.ceilht = getint(line,106,5); #Cloud ceiling height m # Calculate specfic humidity from dry bulb, dew point, and atm pressure using MetPy self.huss[ind] = mpcalc.specific_humidity_from_mixing_ratio( mpcalc.mixing_ratio_from_relative_humidity( mpcalc.relative_humidity_from_dewpoint( self.tdry[ind] * units.degC, self.tdew[ind] * units.degC), self.tdry[ind] * units.degC, self.press[ind] * units.mbar)) #Next line line = f.readline() ind = ind + 1 f.close() #------------------------------------------------------ #------------------------------------------------------ # Load TMY3 elif self.file_ext == TMY3EXT: f = open( self.weatherpath + TMY3NUMBER[CITY.index(self.city)] + self.file_ext, 'r') # Header read for lat and lon head = f.readline().split(',') self.lat = float(head[4]) self.lon = float(head[5]) #Burn a line for the second part of the header. line = f.readline() line = f.readline() ind = 0 while line: line = line.split(',') if len(line) < 20: print('line is short!') # Process the line self.tothor[ind] = float( line[4]) #Total horizontal solar Wh/m2 self.dirnorm[ind] = float(line[7]) #Direct normal solar Wh/m2 self.difhor[ind] = float( line[10]) #Diffuse Horizontal Solar Wh/m2 self.tdry[ind] = float(line[31]) #tdrybulb (deg C) self.rhs[ind] = float(line[37]) * 0.01 #relative humidity (%) self.tdew[ind] = float(line[34]) #tdew (deg C) to conform with TB code self.press[ind] = float(line[40]) #atmospheric pressure (mbar) mb = 100 Pascals #self.wind_speed[ind] = float(line[46]); #windspeed m/s #self.wind_dir[ind] = float(line[43]); #wind direction azimuth # Calculate specfic humidity from dry bulb, dew point, and atm pressure using MetPy self.huss[ind] = mpcalc.specific_humidity_from_mixing_ratio( mpcalc.mixing_ratio_from_relative_humidity( mpcalc.relative_humidity_from_dewpoint( self.tdry[ind] * units.degC, self.tdew[ind] * units.degC), self.tdry[ind] * units.degC, self.press[ind] * units.mbar)) #Next line line = f.readline() ind = ind + 1 f.close()
def test_specific_humidity_from_mixing_ratio(): """Test specific humidity from mixing ratio.""" w = 0.01215 * units.dimensionless q = specific_humidity_from_mixing_ratio(w) assert_almost_equal(q, 0.01200, 5)
def get_specific_humidity(profiles): qv = mpcalc.specific_humidity_from_mixing_ratio(profiles["mr"]) profiles["qv"] = (["launch_time", "zlay"], qv.magnitude) return profiles
def gradient_fluxes(df): # This method is very sensitive to input data quality """Returns Sensible Heat Flux and Latent Heat Flux based on Steffen & DeMaria (1996) method""" g = 9.81 # m/s**2 cp = 1005 # J/kg/K k = 0.4 # von Karman Lv = 2.50e6 # J/kg fillvalue = common.fillvalue_float ht_low, ht_high, ta_low, ta_high, wspd_low, wspd_high, rh_low, rh_high, phi_m, phi_h = ([] for _ in range(10)) # Average temp from both sensors for height1 and height2 ta1 = df.loc[:, ("ta_tc1", "ta_cs1")] ta2 = df.loc[:, ("ta_tc2", "ta_cs2")] df['ta1'] = ta1.mean(axis=1) df['ta2'] = ta2.mean(axis=1) # Assign low and high depending on height of sensors idx = 0 while idx < len(df): if df['wind_sensor_height_1'][idx] == fillvalue or df['wind_sensor_height_2'][idx] == fillvalue: ht_low.append(np.nan) ht_high.append(np.nan) ta_low.append(df['ta1'][idx]) ta_high.append(df['ta2'][idx]) wspd_low.append(df['wspd1'][idx]) wspd_high.append(df['wspd2'][idx]) rh_low.append(df['rh1'][idx]) rh_high.append(df['rh2'][idx]) elif df['wind_sensor_height_1'][idx] > df['wind_sensor_height_2'][idx]: ht_low.append(df['wind_sensor_height_2'][idx]) ht_high.append(df['wind_sensor_height_1'][idx]) ta_low.append(df['ta2'][idx]) ta_high.append(df['ta1'][idx]) wspd_low.append(df['wspd2'][idx]) wspd_high.append(df['wspd1'][idx]) rh_low.append(df['rh2'][idx]) rh_high.append(df['rh1'][idx]) else: ht_low.append(df['wind_sensor_height_1'][idx]) ht_high.append(df['wind_sensor_height_2'][idx]) ta_low.append(df['ta1'][idx]) ta_high.append(df['ta2'][idx]) wspd_low.append(df['wspd1'][idx]) wspd_high.append(df['wspd2'][idx]) rh_low.append(df['rh1'][idx]) rh_high.append(df['rh2'][idx]) idx += 1 # Convert lists to arrays ht_low = np.asarray(ht_low) ht_high = np.asarray(ht_high) ta_low = np.asarray(ta_low) ta_high = np.asarray(ta_high) wspd_low = np.asarray(wspd_low) wspd_high = np.asarray(wspd_high) rh_low = np.asarray(rh_low) rh_high = np.asarray(rh_high) ps = np.asarray(df['ps'].values) # Potential Temperature pot_tmp_low = potential_temperature(ps * units.pascal, ta_low * units.kelvin).magnitude pot_tmp_high = potential_temperature(ps * units.pascal, ta_high * units.kelvin).magnitude pot_tmp_avg = (pot_tmp_low + pot_tmp_high)/2 ta_avg = (ta_low + ta_high)/2 # Ri du = wspd_high-wspd_low du = np.asarray([fillvalue if i == 0 else i for i in du]) pot_tmp_avg = np.asarray([fillvalue if i == 0 else i for i in pot_tmp_avg]) ri = g*(pot_tmp_high - pot_tmp_low)*(ht_high - ht_low)/(pot_tmp_avg*du) # Phi for val in ri: if val < -0.03: phi = (1-18*val)**-0.25 phi_m.append(phi) phi_h.append(phi/1.3) elif -0.03 <= val < 0: phi = (1-18*val)**-0.25 phi_m.append(phi) phi_h.append(phi) else: phi = (1-5.2*val)**-1 phi_m.append(phi) phi_h.append(phi) phi_e = phi_h # air density rho = density(ps * units.pascal, ta_avg * units.kelvin, 0).magnitude # Use average temperature # SH ht_low = np.asarray([fillvalue if i == 0 else i for i in ht_low]) num = np.asarray([-a1 * cp * k**2 * (b1 - c1) * (d1 - e1) for a1, b1, c1, d1, e1 in zip(rho, pot_tmp_high, pot_tmp_low, wspd_high, wspd_low)]) dnm = [a2 * b2 * np.log(c2 / d2)**2 for a2, b2, c2, d2 in zip(phi_h, phi_m, ht_high, ht_low)] dnm = np.asarray([fillvalue if i == 0 else i for i in dnm]) sh = num/dnm sh = [fillvalue if abs(i) >= 100 else i for i in sh] # Specific Humidity mixing_ratio_low = mixing_ratio_from_relative_humidity(rh_low, ta_low * units.kelvin, ps * units.pascal) mixing_ratio_high = mixing_ratio_from_relative_humidity(rh_high, ta_high * units.kelvin, ps * units.pascal) q_low = specific_humidity_from_mixing_ratio(mixing_ratio_low).magnitude q_high = specific_humidity_from_mixing_ratio(mixing_ratio_high).magnitude q_low = q_low/100 # Divide by 100 to make it in range [0,1] q_high = q_high/100 # LH num = np.asarray([-a1 * Lv * k**2 * (b1 - c1) * (d1 - e1) for a1, b1, c1, d1, e1 in zip(rho, q_high, q_low, wspd_high, wspd_low)]) dnm = [a2 * b2 * np.log(c2 / d2)**2 for a2, b2, c2, d2 in zip(phi_e, phi_m, ht_high, ht_low)] dnm = np.asarray([fillvalue if i == 0 else i for i in dnm]) lh = num/dnm lh = [fillvalue if abs(i) >= 100 else i for i in lh] return sh, lh