def compare_potential_temp(sounding, date): theta1 = thermo.theta1(K=sounding.TE, hPa=sounding.P) theta2 = thermo.theta2(K=sounding.TE, hPa=sounding.P, mixing_ratio=sounding.MR / 1000) thetaeq1 = thermo.theta_equiv1(K=sounding.TE, hPa=sounding.P) thetaeq2 = thermo.theta_equiv2(K=sounding.TE, hPa=sounding.P, relh=sounding.RH, mixing_ratio=sounding.MR / 1000) foo = pd.DataFrame({ 'theta1': theta1, 'thetaeq1': thetaeq1, 'theta2': theta2, 'thetaeq2': thetaeq2 }) y = foo.index.values fig, ax = plt.subplots(figsize=(8.5, 11)) ln1 = ax.plot(theta1, y, label='theta=f(temp,press) - W&H') ln2 = ax.plot(theta2, y, label='theta=f(temp,press, w) - Bolton 1980') ln3 = ax.plot(thetaeq1, y, label='thetaeq=f(temp,press,ws) - W&H') ln4 = ax.plot(thetaeq2, y, label='thetaeq=f(temp,press, w, rh) - Bolton 1980') ax.set_xlim([280, 320]) ax.set_ylim([0, 5000]) ax.set_xlabel('Temperature [K]') ax.set_ylabel('Altitude [m]') ax2 = ax.twiny() ln5 = ax2.plot(sounding.MR, y, sns.xkcd_rgb["amber"], label='mixing ratio') ax2.set_xlim([0, 8]) ax2.set_ylim([0, 5000]) ax2.grid(False) ax2.set_xlabel('Mixing ratio [g kg-1]') ax3 = ax.twiny() ln6 = ax3.plot(sounding.RH, y, sns.xkcd_rgb["plum purple"], label='relative humidity') ax3.set_xlim([0, 100]) ax3.set_ylim([0, 5000]) ax3.grid(False) ax3.set_xlabel('Relative humidity [%]') ax3.xaxis.set_label_coords(0.5, 1.07) ax3.tick_params(direction='out', pad=35) lns = ln1 + ln2 + ln3 + ln4 + ln5 + ln6 labs = [l.get_label() for l in lns] ax3.legend(lns, labs, loc=0) plt.subplots_adjust(bottom=0.05, top=0.89) datestr = date.strftime('%Y%m%d_%H%M%S') plt.title('Comparison of Potential Temperature BBY sounding ' + datestr, y=0.99) plt.draw()
def compare_potential_temp(sounding, date): theta1 = thermo.theta1(K=sounding.TE, hPa=sounding.P) theta2 = thermo.theta2( K=sounding.TE, hPa=sounding.P, mixing_ratio=sounding.MR/1000) thetaeq1 = thermo.theta_equiv1(K=sounding.TE, hPa=sounding.P) thetaeq2 = thermo.theta_equiv2(K=sounding.TE, hPa=sounding.P, relh=sounding.RH, mixing_ratio=sounding.MR/1000) foo = pd.DataFrame( {'theta1': theta1, 'thetaeq1': thetaeq1, 'theta2': theta2, 'thetaeq2': thetaeq2}) y = foo.index.values fig, ax = plt.subplots(figsize=(8.5, 11)) ln1 = ax.plot(theta1, y, label='theta=f(temp,press) - W&H') ln2 = ax.plot(theta2, y, label='theta=f(temp,press, w) - Bolton 1980') ln3 = ax.plot(thetaeq1, y, label='thetaeq=f(temp,press,ws) - W&H') ln4 = ax.plot( thetaeq2, y, label='thetaeq=f(temp,press, w, rh) - Bolton 1980') ax.set_xlim([280, 320]) ax.set_ylim([0, 5000]) ax.set_xlabel('Temperature [K]') ax.set_ylabel('Altitude [m]') ax2 = ax.twiny() ln5 = ax2.plot(sounding.MR, y, sns.xkcd_rgb["amber"], label='mixing ratio') ax2.set_xlim([0, 8]) ax2.set_ylim([0, 5000]) ax2.grid(False) ax2.set_xlabel('Mixing ratio [g kg-1]') ax3 = ax.twiny() ln6 = ax3.plot( sounding.RH, y, sns.xkcd_rgb["plum purple"], label='relative humidity') ax3.set_xlim([0, 100]) ax3.set_ylim([0, 5000]) ax3.grid(False) ax3.set_xlabel('Relative humidity [%]') ax3.xaxis.set_label_coords(0.5, 1.07) ax3.tick_params(direction='out', pad=35) lns = ln1+ln2+ln3+ln4+ln5+ln6 labs = [l.get_label() for l in lns] ax3.legend(lns, labs, loc=0) plt.subplots_adjust(bottom=0.05, top=0.89) datestr = date.strftime('%Y%m%d_%H%M%S') plt.title( 'Comparison of Potential Temperature BBY sounding '+datestr, y=0.99) plt.draw()
def parse_surface_met(file_met, index_field=None, name_field=None, locelevation=None): from scipy import stats ''' Process surface meteorological files with .met extension Output dataframe assumes: - Each file is a 24h period observation - Frequency of observation is constant ''' casename = file_met.split('/')[-2] station_id = file_met.split('/')[-1][:3] usr_case = str(int(casename[-2:])) if usr_case in ['1', '2']: index_field = {'bby': [3, 4, 10, 5, 6, 11, 13], 'czc': [3, 4, 10, 5, 6, 11, 13]} elif usr_case in ['3', '4', '5', '6', '7']: index_field = {'bby': [3, 5, 8, 10, 12, 17, 26], 'czc': [3, 4, 5, 6, 8, 13, 22]} else: index_field = {'bby': [3, 4, 5, 6, 8, 13, 15], 'czc': [3, 4, 5, 6, 8, 13, 15], 'frs': [3, 4, 5, 6, 8, 13, 15]} elev = {'bby': 15, 'czc': 462, 'frs': 45} name_field = ['press', 'temp', 'rh', 'wspd', 'wdir', 'precip', 'mixr'] index_field = index_field[station_id] locelevation = elev[station_id] ''' read the csv file ''' raw_dframe = pd.read_csv(file_met, header=None) ''' parse date columns into a single date col ''' dates_col = [0, 1, 2] raw_dates = raw_dframe.ix[:, dates_col] raw_dates.columns = ['Y', 'j', 'HHMM'] raw_dates['HHMM'] = raw_dates['HHMM'].apply(lambda x: '{0:0>4}'.format(x)) raw_dates = raw_dates.apply( lambda x: '%s %s %s' % (x['Y'], x['j'], x['HHMM']), axis=1) dates_fmt = '%Y %j %H%M' dates = raw_dates.apply(lambda x: datetime.strptime(x, dates_fmt)) ''' make meteo df, assign datetime index, and name columns ''' meteo = raw_dframe.ix[:, index_field] meteo.index = dates meteo.columns = name_field ''' create a dataframe with regular and continuous 24h period time index (this works as a QC for time gaps) ''' nano = 1000000000 time_diff = np.diff(meteo.index) sample_freq = (stats.mode(time_diff)[0][0]/nano).astype(int) # [seconds] fidx = meteo.index[0] # (start date for dataframe) fidx_str = pd.to_datetime( fidx.year*10000 + fidx.month*100 + fidx.day, format='%Y%m%d') periods = (24*60*60)/sample_freq ts = pd.date_range(fidx_str, periods=periods, freq=str(sample_freq)+'s') nanarray = np.empty((periods, 1)) nanarray[:] = np.nan df = pd.DataFrame(nanarray, index=ts) meteo = df.join(meteo, how='outer') meteo.drop(0, axis=1, inplace=True) ''' make field with hourly acum precip ''' hour = pd.TimeGrouper('H') preciph = meteo.precip.groupby(hour).sum() meteo = meteo.join(preciph, how='outer', rsuffix='h') ''' add thermodynamics ''' theta = tm.theta1(C=meteo.temp, hPa=meteo.press) thetaeq = tm.theta_equiv1(C=meteo.temp, hPa=meteo.press) meteo.loc[:, 'theta'] = pd.Series(theta, index=meteo.index) meteo.loc[:, 'thetaeq'] = pd.Series(thetaeq, index=meteo.index) ''' add sea level pressure ''' Tv = tm.virtual_temperature(C=meteo.temp, mixing_ratio=meteo.mixr/1000.) slp = tm.sea_level_press(K=Tv+273.15, Pa=meteo.press*100, m=locelevation) meteo.loc[:, 'sea_levp'] = slp ''' assign metadata (prototype, not really used) ''' units = {'press': 'mb', 'temp': 'C', 'rh': '%', 'wspd': 'm s-1', 'wdir': 'deg', 'precip': 'mm', 'mixr': 'g kg-1'} agl = {'press': 'NaN', 'temp': '10 m', 'rh': '10 m', 'wspd': 'NaN', 'wdir': 'NaN', 'precip': 'NaN', 'mixr': 'NaN'} for n in name_field: meteo[n].units = units[n] meteo[n].agl = agl[n] meteo[n].nan = -9999.999 meteo[n].sampling_freq = '2 minute' return meteo
def parse_surface_met(file_met, index_field=None, name_field=None, locelevation=None): from scipy import stats ''' Process surface meteorological files with .met extension Output dataframe assumes: - Each file is a 24h period observation - Frequency of observation is constant ''' casename = file_met.split('/')[-2] station_id = file_met.split('/')[-1][:3] usr_case = str(int(casename[-2:])) if usr_case in ['1', '2']: index_field = { 'bby': [3, 4, 10, 5, 6, 11, 13], 'czc': [3, 4, 10, 5, 6, 11, 13] } elif usr_case in ['3', '4', '5', '6', '7']: index_field = { 'bby': [3, 5, 8, 10, 12, 17, 26], 'czc': [3, 4, 5, 6, 8, 13, 22] } else: index_field = { 'bby': [3, 4, 5, 6, 8, 13, 15], 'czc': [3, 4, 5, 6, 8, 13, 15], 'frs': [3, 4, 5, 6, 8, 13, 15] } elev = {'bby': 15, 'czc': 462, 'frs': 45} name_field = ['press', 'temp', 'rh', 'wspd', 'wdir', 'precip', 'mixr'] index_field = index_field[station_id] locelevation = elev[station_id] ''' read the csv file ''' raw_dframe = pd.read_csv(file_met, header=None) ''' parse date columns into a single date col ''' dates_col = [0, 1, 2] raw_dates = raw_dframe.ix[:, dates_col] raw_dates.columns = ['Y', 'j', 'HHMM'] raw_dates['HHMM'] = raw_dates['HHMM'].apply(lambda x: '{0:0>4}'.format(x)) raw_dates = raw_dates.apply(lambda x: '%s %s %s' % (x['Y'], x['j'], x['HHMM']), axis=1) dates_fmt = '%Y %j %H%M' dates = raw_dates.apply(lambda x: datetime.strptime(x, dates_fmt)) ''' make meteo df, assign datetime index, and name columns ''' meteo = raw_dframe.ix[:, index_field] meteo.index = dates meteo.columns = name_field ''' create a dataframe with regular and continuous 24h period time index (this works as a QC for time gaps) ''' nano = 1000000000 time_diff = np.diff(meteo.index) sample_freq = (stats.mode(time_diff)[0][0] / nano).astype(int) # [seconds] fidx = meteo.index[0] # (start date for dataframe) fidx_str = pd.to_datetime(fidx.year * 10000 + fidx.month * 100 + fidx.day, format='%Y%m%d') periods = (24 * 60 * 60) / sample_freq ts = pd.date_range(fidx_str, periods=periods, freq=str(sample_freq) + 's') nanarray = np.empty((periods, 1)) nanarray[:] = np.nan df = pd.DataFrame(nanarray, index=ts) meteo = df.join(meteo, how='outer') meteo.drop(0, axis=1, inplace=True) ''' make field with hourly acum precip ''' hour = pd.TimeGrouper('H') preciph = meteo.precip.groupby(hour).sum() meteo = meteo.join(preciph, how='outer', rsuffix='h') ''' add thermodynamics ''' theta = tm.theta1(C=meteo.temp, hPa=meteo.press) thetaeq = tm.theta_equiv1(C=meteo.temp, hPa=meteo.press) meteo.loc[:, 'theta'] = pd.Series(theta, index=meteo.index) meteo.loc[:, 'thetaeq'] = pd.Series(thetaeq, index=meteo.index) ''' add sea level pressure ''' Tv = tm.virtual_temperature(C=meteo.temp, mixing_ratio=meteo.mixr / 1000.) slp = tm.sea_level_press(K=Tv + 273.15, Pa=meteo.press * 100, m=locelevation) meteo.loc[:, 'sea_levp'] = slp ''' assign metadata (prototype, not really used) ''' units = { 'press': 'mb', 'temp': 'C', 'rh': '%', 'wspd': 'm s-1', 'wdir': 'deg', 'precip': 'mm', 'mixr': 'g kg-1' } agl = { 'press': 'NaN', 'temp': '10 m', 'rh': '10 m', 'wspd': 'NaN', 'wdir': 'NaN', 'precip': 'NaN', 'mixr': 'NaN' } for n in name_field: meteo[n].units = units[n] meteo[n].agl = agl[n] meteo[n].nan = -9999.999 meteo[n].sampling_freq = '2 minute' return meteo