def plot_metpy(data, title="", saveplot=None, showplot=True): # Convert data into a suitable format for metpy. _altitude = data[:,0] * units('m') p = mpcalc.height_to_pressure_std(_altitude) T = data[:,3] * units.degC Td = data[:,4] * units.degC wind_speed = data[:,1] * units('m/s') wind_direction = data[:,2] * units.degrees u, v = mpcalc.wind_components(wind_speed, wind_direction) fig = plt.figure(figsize=(6,8)) skew = SkewT(fig=fig) skew.plot(p, T, 'r') skew.plot(p, Td, 'g') my_interval = np.arange(300, 1000, 50) * units('mbar') ix = mpcalc.resample_nn_1d(p, my_interval) skew.plot_barbs(p[ix], u[ix], v[ix]) skew.ax.set_ylim(1000,300) skew.ax.set_xlim(-40, 30) skew.plot_dry_adiabats() heights = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]) * units.km std_pressures = mpcalc.height_to_pressure_std(heights) for height_tick, p_tick in zip(heights, std_pressures): trans, _, _ = skew.ax.get_yaxis_text1_transform(0) skew.ax.text(0.02, p_tick, '---{:~d}'.format(height_tick), transform=trans) plt.title("Sounding: " + title) if saveplot != None: fig.savefig(saveplot, bbox_inches='tight')
def test_heights_to_pressure_basic(array_type): """Test basic height to pressure calculation for standard atmosphere.""" mask = [False, True, False, True] heights = array_type([321.5, 216.5, 487.6, 601.7], 'meter', mask=mask) pressures = height_to_pressure_std(heights) values = array_type([975.2, 987.5, 956., 943.], 'mbar', mask=mask) assert_array_almost_equal(pressures, values, 1)
def get_tskew_plot(calc,field_height,field_temp,rot=0): # Create a new figure. The dimensions here give a good aspect ratio. Set rotation to 0 to achieve a non-skewet T axis, otherwise set to 30. fig = plt.figure(figsize=(12, 12)) skew = SkewT(fig,rotation=rot) heights = np.array([1000,2000,3000,4000,5000,6000,7000,8000,9000,10000,11000,12000,13000,14000,15000,16000,17000,18000]) * units.ft std_pressures = mpcalc.height_to_pressure_std(heights) ###################### DO THE PLOTTING MAGIC ################################################## # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot ############################################################################################### skew.plot(calc.p, calc.T.to(units.degC), 'r', linewidth=2,label='Temperature') skew.plot(calc.p, calc.Td, 'g', linewidth=2,label='Dew Point') skew.plot(calc.p, calc.wet_bulb.to(units.degC), 'b', linewidth=2,label='Wet Bulb Temperature') skew.plot_dry_adiabats() skew.plot_moist_adiabats() skew.ax.set_ylim(1000,450) skew.ax.set_xlim(-40,50) skew.ax.set_xticks([-40,-35,-30,-25,-20,-15,-10,-5,0,5,10,15,20,25,30,35,40,45,50]) skew.ax.set_yticks([]) #set aspect ratio for plot ratio = 0.3 xleft, xright = skew.ax.get_xlim() ybottom, ytop = skew.ax.get_ylim() skew.ax.set_aspect(abs((xright-xleft)/(ybottom-ytop))*1300) #set height labels for height_tick, p_tick in zip(heights, std_pressures): trans, _, _ = skew.ax.get_yaxis_text1_transform(0) skew.ax.text(-0.08, p_tick, '{:~d}'.format(height_tick), transform=trans) # Show the plot #ADD Height lines for height_tick, p_tick in zip(heights, std_pressures): skew.ax.axhline(y=p_tick,color='black',linewidth=0.5) #Add base height skew.ax.axhline(y=mpcalc.height_to_pressure_std(field_height*units.ft),linewidth=2,label='Field Height',color='black') #Relabel Y skew.ax.set_ylabel(ylabel="Height",labelpad=50) print(calc.adiabat_line) print(calc.lcl_pressure) #add dry adiabatic lapse rate line at the field height and max temperature skew.plot(calc.p,calc.adiabat_line.to(units.degC),'g',linewidth=2,linestyle='--',label='ADLR from Field Max Temp') #Add legend skew.ax.get_legend_handles_labels() skew.ax.legend() return plt
def h2p(x): """ x in m """ # x = x.values y = mpcalc.height_to_pressure_std(np.array(x) * units.m) # y = y.metpy.convert_units('hPa') y = y.to('hPa') return y.magnitude
def calculate_sounding_data(df,field_height,field_temp): ###################################### CALCULATION MAGIC ################################################# # We will pull the data out of the latest soudning into individual variables and assign units. # # This will Return a dictionary with all the vallculate values. Keys are: # # "pressure", "temperature", "dewpoint", "height", "windspeed","wind_dir" ###################################### CALCULATION MAGIC ################################################# cache = settings.AppCache #Retrieves Sounding Details and returns them key='calculation'+str(field_height)+'_'+str(field_temp) #If soundings are cached and valid, returns the cache, otherwise retreive new sounding calc = cache.get(key) if calc is not None: logging.info("Calculation Cache Hit") print("Calculation Cahce Hit") return calc logging.info("Calculation Cache Miss") print("Calculation Cahce Miss") p = df['pressure'].values * units.hPa T = df['temperature'].values * units.degC Td = df['dewpoint'].values * units.degC alt = df['height'].values * units.ft wind_speed = df['speed'].values * units.knots wind_dir = df['direction'].values * units.degrees wet_bulb = mpcalc.wet_bulb_temperature(p,T,Td) field_pressure = mpcalc.height_to_pressure_std(field_height*units.ft) adiabat_line = mpcalc.dry_lapse(p,field_temp*units.degC,ref_pressure=mpcalc.height_to_pressure_std(field_height*units.ft)) #Interpolate Missing Values using linear interpolation Td_linear = interp1d(alt.magnitude,Td.magnitude) T_linear = interp1d(alt.magnitude,T.magnitude) #Calculate the LCL Based on Max Temperature lcl_pressure, lcl_temperature = mpcalc.lcl(field_pressure,field_temp*units.degC ,Td_linear(field_height)*units.degC) #parcel_prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') calc = MeteoCast.UpperAtmData(df, p, T, Td,alt,wind_speed,wind_dir,wet_bulb,field_pressure,lcl_pressure,lcl_temperature,adiabat_line) cache.set(key, calc, expire=600,tag='Calculation Data ') return calc
# MetPy wants quantities in the pint format which stores an # array with the associate units. T = (InFile[TempVname][...] * units('kelvin')).to( units('degC')) # input temp is K, convert to deg C RH = (InFile[RhVname][...] / 100.0 * units('radian')).to( '') # convert to dimensionless, use # radian initially since it's a # dimensionless quantity Z = InFile[Zname][...] * units('meter') Nz = len(Z) InFile.close() # Convert the heights to pressure values P = metc.height_to_pressure_std(Z) # P comes back in millibars # Calculate the dew point temperature Td = metc.dewpoint_rh(T, RH) # Td comes back in deg C # Make the plot Ptitle = "{0:s} (averaged over final 20 days)".format(LabelScheme[Sim]) Fig = plt.figure(figsize=(9, 9)) skewt = metp.SkewT(Fig, rotation=30) skewt.plot(P, T, 'r') skewt.plot(P, Td, 'g') skewt.ax.set_xlim(-80, 30) skewt.ax.set_ylim(1000, 50) skewt.ax.title.set_text(Ptitle)
def test_heights_to_pressure_basic(): """Test basic height to pressure calculation for standard atmosphere.""" heights = np.array([321.5, 216.5, 487.6, 601.7]) * units.meter pressures = height_to_pressure_std(heights) values = np.array([975.2, 987.5, 956., 943.]) * units.mbar assert_almost_equal(pressures, values, 1)
def atmCalc(height, temp, humid): print("ATMCALC", height, temp, humid, file=sys.stderr) mtny = windh(MTNX, height, ratio=1, yoffset=0) windx = XVALUES windy = windh(windx, height) temp_ = temp * units.degC initp = mc.height_to_pressure_std(windy[0] * units.meters) dewpt = mc.dewpoint_from_relative_humidity(temp_, humid / 100.) lcl_ = mc.lcl(initp, temp_, dewpt, max_iters=50, eps=1e-5) LCL = mc.pressure_to_height_std(lcl_[0]) if (lcl_[0] > mc.height_to_pressure_std(max(windy) * units.meters) and LCL > windy[0] * units.meters * 1.000009): # add LCL to x xlcl = windh(LCL.to('meters').magnitude, height, inv=True) windx = np.sort(np.append(windx, xlcl)) windy = windh(windx, height) pressures = mc.height_to_pressure_std(windy * units.meters) wvmr0 = mc.mixing_ratio_from_relative_humidity(initp, temp_, humid / 100.) # now calculate the air parcel temperatures and RH at each position if (lcl_[0] <= min(pressures)): T = mc.dry_lapse(pressures, temp_) RH = [ mc.relative_humidity_from_mixing_ratio( wvmr0, t, p) for t, p in zip( T, pressures)] else: mini = np.argmin(pressures) p1 = pressures[:mini + 1] p2 = pressures[mini:] # with an overlap p11 = p1[p1 >= lcl_[0] * .9999999] # lower (with tol) with lcl p12 = p1[p1 < lcl_[0] * 1.000009] # upper (with tol) with lcl T11 = mc.dry_lapse(p11, temp_) T12 = mc.moist_lapse(p12, lcl_[1]) T1 = concatenate((T11[:-1], T12)) T2 = mc.dry_lapse(p2, T1[-1]) T = concatenate((T1, T2[1:])) wvmrtop = mc.saturation_mixing_ratio(pressures[mini], T[mini]) RH=[] for i in range(len(pressures)): if pressures[i] > lcl_[0] and i <= mini: v=mc.relative_humidity_from_mixing_ratio(pressures[i], T[i], wvmr0) else: if i < mini: v=1 else: v=mc.relative_humidity_from_mixing_ratio(pressures[i], T[i], wvmrtop) RH.append(v) #RH = [mc.relative_humidity_from_mixing_ratio(*tp, wvmr0) if tp[1] > lcl_[ #0] and i <= mini else 1.0 if i < mini else #mc.relative_humidity_from_mixing_ratio(*tp, wvmrtop) #for i, tp in enumerate(zip(pressures, T))] RH = concatenate(RH) return windx, mtny, windy, lcl_, LCL, T.to("degC"), RH
def readRadiometerData(fnme): def plot_fsi(parm,fsi_data,_date): import matplotlib.pyplot as plt; from pylab import savefig ; from matplotlib import cm C=fsi_data fig, ax1= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) ax2 = ax1.twinx() ax1 = C.iloc[:,2].plot.line(ax=ax1,marker='o',grid=False, legend=True, style=None, rot=45,linewidth=3,color='k',) ax2 = C.iloc[:,1].plot.line(ax=ax2,marker='o', grid=False, legend=True, style=None, rot=45,linewidth=3,color='r') leg1=ax1.legend(loc='upper left',fontsize=18) leg2=ax2.legend(loc='upper right',fontsize=18) ax1.axhline(y=25,linewidth=3, color='g') ax1.axhline(y=35,linewidth=3, color='b') ax2.axhline(y=1000,linewidth=3, color='r',linestyle='--') ax1.set_yticks(np.linspace(-15, ax1.get_ybound()[1]+1, 15)) ax2.set_yticks(np.linspace(0, ax2.get_ybound()[1]+1, 15)) ax1.tick_params(axis='y', colors='k',labelsize=18) ; ax1.set_ylabel('Fog Threat Index',color='k',fontsize=18) ; ax2.tick_params(axis='y', colors='r',labelsize=18) ; ax2.set_ylabel('Visibility',color='r',fontsize=18) ; plt.title('Fog Threat & Visibility',color='black',fontsize=18,y=1.05) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]+'/'+parm+'Fog_threat_visibility'+_date[0:8]+'.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) def plot_fsi_catg(parm,fsi_data,_date,catg): import matplotlib.pyplot as plt; from pylab import savefig ; from matplotlib import cm C=fsi_data fig, ax1= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) ax2 = ax1.twinx() ax1 = C.iloc[:,2].plot.line(ax=ax1,marker='o',grid=False, legend=True, style=None, rot=45,linewidth=3,color='k',) ax2 = C.iloc[:,1].plot.line(ax=ax2,marker='o', grid=False, legend=True, style=None, rot=45,linewidth=3,color='r') leg1=ax1.legend(loc='upper left',fontsize=18) leg2=ax2.legend(loc='upper right',fontsize=18) ax1.axhline(y=25,linewidth=3, color='g') ax1.axhline(y=35,linewidth=3, color='b') ax2.axhline(y=1000,linewidth=3, color='r',linestyle='--') ax1.set_yticks(np.linspace(-15, ax1.get_ybound()[1]+1, 15)) ax2.set_yticks(np.linspace(0, ax2.get_ybound()[1]+1, 15)) ax1.tick_params(axis='y', colors='k',labelsize=18) ; ax1.set_ylabel('Fog Threat Index',color='k',fontsize=18) ; ax2.tick_params(axis='y', colors='r',labelsize=18) ; ax2.set_ylabel('Visibility',color='r',fontsize=18) ; plt.title('Fog Threat & Visibility',color='black',fontsize=18,y=1.05) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]+'/'+parm+'_'+catg+'_Fog_threat_visibility'+_date[0:8]+'.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) def plot_contour_data(parm,vert_prof,catg,xtk): import matplotlib.pyplot as plt; from pylab import savefig ; from matplotlib import cm ; import matplotlib.colors as mcolors fig, ax= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) #ax4 = ax1.twinx() x =np.arange(0,vert_prof.iloc[:,4:41].T.shape[1],1) ; y = np.arange(0,vert_prof.iloc[:,4:41].T.shape[0]) X, Y = np.meshgrid(x, y) clevs=[260,262,264,266,268,270,272,274,276,278,280,282,284,285,286,287,288,289,290,291,292] #colors1 = plt.cm.binary(np.linspace(0., 1, 128)) #colors1 = plt.cm.gist_heat_r(np.linspace(0, 1, 128)) colors2 = plt.cm.Blues(np.linspace(0., 1, 128)) colors3 = plt.cm.Reds(np.linspace(0, 1, 128)) # combine them and build a new colormap colors = np.vstack((colors2,colors3)) mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors) cs =plt.contourf(X,Y,vert_prof.iloc[:,4:41].T,levels=clevs,cmap=mymap) #cs1 =plt.contour(X,Y,vert_prof.iloc[:,4:45].T,levels=clevs,colors='K',linewidths=0.3) #plt.clabel(cs1, inline=1, fontsize=16) cbar=plt.colorbar(cs, shrink=0.8, extend='both') ; cbar.set_ticks([clevs]) ; cbar.ax.invert_yaxis() ax.set_xticks(x[::xtk]) ; xTickMarks=vert_prof['Date'][::xtk] xtickNames = ax.set_xticklabels(xTickMarks) plt.setp(xtickNames, rotation=90, fontsize=10,family='sans-serif') ax.set_yticks(y[::5]) ; yTickMarks=vert_prof.columns[4:41][::5] ytickNames = ax.set_yticklabels(yTickMarks,fontsize=18) ax.tick_params(axis='x', colors='blue') ; ax.tick_params(axis='y', colors='blue') ax.set_ylabel('Height Levels',color='blue',fontsize=18) ; titl='Temperature Profile:'+_date plt.title(titl,color='black',fontsize=18,y=1.05) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:6]+'/'+parm+'_'+catg+'_hours_vertical_profile'+_date[0:6]+'_1km.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) ################################################################ fig, ax= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) #ax4 = ax1.twinx() x =np.arange(0,vert_prof.iloc[:,4:].T.shape[1],1) ; y = np.arange(0,vert_prof.iloc[:,4:].T.shape[0]) X, Y = np.meshgrid(x, y) clevs=[190,200,210,220,225,230,235,240,245,250,255,260,262,264,266,268,270,272,274,276,278,280,282,284,285,286,287,288,289,290,291,292] cs =plt.contourf(X,Y,vert_prof.iloc[:,4:].T,levels=clevs,cmap=cm.gist_rainbow_r ) cs1 =plt.contour(X,Y,vert_prof.iloc[:,4:].T,levels=clevs,colors='K',linewidths=0.3) plt.clabel(cs1, inline=1, fontsize=16) cbar=plt.colorbar(cs, shrink=0.8, extend='both') ; cbar.set_ticks([clevs]) ; cbar.ax.invert_yaxis() ax.set_xticks(x[::xtk]) ; xTickMarks=vert_prof['Date'][::xtk] xtickNames = ax.set_xticklabels(xTickMarks) plt.setp(xtickNames, rotation=90, fontsize=10,family='sans-serif') ax.set_yticks(y[::5]) ; yTickMarks=vert_prof.columns[4:][::5] ytickNames = ax.set_yticklabels(yTickMarks,fontsize=18) ax.tick_params(axis='x', colors='blue') ; ax.tick_params(axis='y', colors='blue') ax.set_ylabel('Height Levels',color='blue',fontsize=18) ; titl='Temperature Profile:'+_date plt.title(titl,color='black',fontsize=18,y=1.05) plt.xticks(size=18) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:6]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:6]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:6]+'/'+parm+'_'+catg+'_hours_vertical_profile'+_date[0:6]+'.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) def plot_contour_dailydata(parm,vert_prof,_date): import matplotlib.pyplot as plt; from pylab import savefig ; from matplotlib import cm ; import matplotlib.colors as mcolors from matplotlib.colors import from_levels_and_colors ; fig, ax= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) #ax4 = ax1.twinx() x =np.arange(0,vert_prof.iloc[:,4:].T.shape[1],1) ; y = np.arange(0,vert_prof.iloc[:,4:].T.shape[0]) X, Y = np.meshgrid(x, y) clevs=[190,200,210,220,225,230,235,240,245,250,255,260,262,264,266,268,270,272,274,276,278,280,282,284,285,286,287,288,289,290,291,292] # mymap = mcolors.ListedColormap(['peachpuff','navajowhite','mistyrose','steelblue','cornflowerblue','slateblue','royalblue','blue','dodgerblue','deepskyblue','skyblue','mediumturquoise',\ # 'mediumaquamarine','lightseagreen','seagreen','greenyellow','indianred','forestgreen','yellow','gold','orange','darkorange',\ # 'sandybrown','limegreen','coral','orangered','red','hotpink','darkorchid','blueviolet','purple']) # nice_cmap= plt.get_cmap(mymap) # colors = nice_cmap([0,1, 2, 3, 4, 5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]) # colors =nice_cmap([30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0]) # #cmap, norm = from_levels_and_colors(clevs, colors, extend='both') # #norml = mcolors.BoundaryNorm(clevs, ncolors=cmap.N, clip=True) colors2 = plt.cm.Blues(np.linspace(0., 1, 128)) colors3 = plt.cm.Reds(np.linspace(0, 1, 128)) # combine them and build a new colormap colors = np.vstack((colors2,colors3)) mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors) cs =plt.contourf(X,Y,vert_prof.iloc[:,4:].T,levels=clevs,cmap=cm.gist_rainbow_r ) #cm.gist_rainbow_r cbar=plt.colorbar(cs, shrink=0.8, extend='both') ; cbar.set_ticks([clevs]) ; cbar.ax.invert_yaxis() cs1 =plt.contour(X,Y,vert_prof.iloc[:,4:].T,levels=clevs,colors='K',linewidths=0.3) plt.clabel(cs1, inline=1, fontsize=13) ax.set_xticks(x[::5]) ; xTickMarks=vert_prof['Date'][::5] xtickNames = ax.set_xticklabels(xTickMarks) plt.setp(xtickNames, rotation=90, fontsize=10,family='sans-serif') ax.set_yticks(y[::5]) ; yTickMarks=vert_prof.columns[4:][::5] ytickNames = ax.set_yticklabels(yTickMarks,fontsize=18) ax.tick_params(axis='x', colors='blue') ; ax.tick_params(axis='y', colors='blue') ax.set_ylabel('Height Levels',color='blue',fontsize=18) ; titl='Temperature Profile:'+_date plt.title(titl,color='black',fontsize=18,y=1.05) plt.xticks(size=18) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]+'/'+parm+'_vertical_profile'+_date[0:8]+'.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) ############################################################## fig, ax= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) #ax4 = ax1.twinx() x =np.arange(0,vert_prof.iloc[:,4:41].T.shape[1],1) ; y = np.arange(0,vert_prof.iloc[:,4:41].T.shape[0]) X, Y = np.meshgrid(x, y) clevs=[260,262,264,266,268,270,272,274,276,278,280,282,284,285,286,287,288,289,290,291,292] colors2 = plt.cm.Blues(np.linspace(0., 1, 128)) colors3 = plt.cm.Reds(np.linspace(0, 1, 128)) # combine them and build a new colormap colors = np.vstack((colors2,colors3)) mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors) cs =plt.contourf(X,Y,vert_prof.iloc[:,4:41].T,levels=clevs,cmap=mymap ) #cm.gist_rainbow_r cbar=plt.colorbar(cs, shrink=0.8, extend='both') ; cbar.set_ticks([clevs]) ; cbar.ax.invert_yaxis() cs1 =plt.contour(X,Y,vert_prof.iloc[:,4:41].T,levels=clevs,colors='K',linewidths=0.3) plt.clabel(cs1, inline=1, fontsize=13) ax.set_xticks(x[::5]) ; xTickMarks=vert_prof['Date'][::5] xtickNames = ax.set_xticklabels(xTickMarks) plt.setp(xtickNames, rotation=90, fontsize=10,family='sans-serif') ax.set_yticks(y[::5]) ; yTickMarks=vert_prof.columns[4:41][::5] ytickNames = ax.set_yticklabels(yTickMarks,fontsize=18) ax.tick_params(axis='x', colors='blue') ; ax.tick_params(axis='y', colors='blue') ax.set_ylabel('Height Levels',color='blue',fontsize=18) ; titl='Temperature Profile:'+_date plt.title(titl,color='black',fontsize=18,y=1.05) plt.xticks(size=18) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]+'/'+parm+'_vertical_profile'+_date[0:8]+'_1km.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) ############################################################################################################################################# def plot_contour_prefog(parm,vert_prof,_date,catg): import matplotlib.pyplot as plt; from pylab import savefig ; from matplotlib import cm; import matplotlib.colors as mcolors fig, ax= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) #ax4 = ax1.twinx() x =np.arange(0,vert_prof.iloc[:,4:].T.shape[1],1) ; y = np.arange(0,vert_prof.iloc[:,4:].T.shape[0]) X, Y = np.meshgrid(x, y) clevs=[190,200,210,220,225,230,235,240,245,250,255,260,262,264,266,268,270,272,274,276,278,280,282,284,285,286,287,288,289,290,291,292] cs =plt.contourf(X,Y,vert_prof.iloc[:,4:].T,levels=clevs,cmap=cm.gist_rainbow_r ) cbar=plt.colorbar(cs, shrink=0.8, extend='both') ; cbar.set_ticks([clevs]) ; cbar.ax.invert_yaxis() cs1 =plt.contour(X,Y,vert_prof.iloc[:,4:].T,levels=clevs,colors='K',linewidths=0.3) plt.clabel(cs1, inline=1, fontsize=13) ax.set_xticks(x[::5]) ; xTickMarks=vert_prof['Date'][::5] xtickNames = ax.set_xticklabels(xTickMarks) plt.setp(xtickNames, rotation=90, fontsize=10,family='sans-serif') ax.set_yticks(y[::5]) ; yTickMarks=vert_prof.columns[4:][::5] ytickNames = ax.set_yticklabels(yTickMarks,fontsize=18) ax.tick_params(axis='x', colors='blue') ; ax.tick_params(axis='y', colors='blue') ax.set_ylabel('Height Levels',color='blue',fontsize=18) ; titl='Temperature Profile:'+_date plt.title(titl,color='black',fontsize=18,y=1.05) plt.xticks(size=18) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]+'/'+parm+catg+'_vertical_profile'+_date[0:8]+'.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) ############################################################## fig, ax= plt.subplots(1, sharex=True, sharey=False,figsize=(12,12),dpi=50) #ax4 = ax1.twinx() x =np.arange(0,vert_prof.iloc[:,4:41].T.shape[1],1) ; y = np.arange(0,vert_prof.iloc[:,4:41].T.shape[0]) X, Y = np.meshgrid(x, y) clevs=[260,262,264,266,268,270,272,274,276,278,280,282,284,285,286,287,288,289,290,291,292] colors2 = plt.cm.Blues(np.linspace(0., 1, 128)) colors3 = plt.cm.Reds(np.linspace(0, 1, 128)) # combine them and build a new colormap colors = np.vstack((colors2,colors3)) mymap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors) cs =plt.contourf(X,Y,vert_prof.iloc[:,4:41].T,levels=clevs,cmap=mymap ) #cm.gist_rainbow_r cbar=plt.colorbar(cs, shrink=0.8, extend='both') ; cbar.set_ticks([clevs]) ; cbar.ax.invert_yaxis() cs1 =plt.contour(X,Y,vert_prof.iloc[:,4:41].T,levels=clevs,colors='K',linewidths=0.3) plt.clabel(cs1, inline=1, fontsize=13) ax.set_xticks(x[::5]) ; xTickMarks=vert_prof['Date'][::5] xtickNames = ax.set_xticklabels(xTickMarks) plt.setp(xtickNames, rotation=90, fontsize=10,family='sans-serif') ax.set_yticks(y[::5]) ; yTickMarks=vert_prof.columns[4:41][::5] ytickNames = ax.set_yticklabels(yTickMarks,fontsize=18) ax.tick_params(axis='x', colors='blue') ; ax.tick_params(axis='y', colors='blue') ax.set_ylabel('Height Levels',color='blue',fontsize=18) ; titl='Temperature Profile:'+_date plt.title(titl,color='black',fontsize=18,y=1.05) plt.xticks(size=18) plt.tight_layout(h_pad=3) ; if not os.path.exists(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]): os.makedirs(outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]) outFile=outpath+'/FogAnalysis/'+parm+'/'+_date[0:8]+'/'+parm+catg+'_vertical_profile'+_date[0:8]+'_1km.png' savefig(outFile); plt.close(fig) ; fig.clf(fig) ########################################################################################################################################### hpc_file=main+'data/Files/hpc_201803.csv' rhp_file=main+'data/Files/rhp_201803.csv' tpc_file=main+'data/Files/tpc_201803.csv' tpb_file=main+'data/Files/tpb_201803.csv' met_file=main+'data/Files/met_minute_201803.csv' vis_file=main+'data/Files/vis_201803.csv' cbh_file=main+'data/Files/cbh_201803.csv' #################################################################################################################################### #tpb_data=pd.read_csv(tpb_file).as_matrix() tpb_data=np.genfromtxt(tpb_file,delimiter=',',dtype='S') ; columns=np.empty((1,94)).astype(str) ; columns[0,0]='Date' ; columns[0,1:]=tpb_data[0,7:] ; date_cols=tpb_data[1:,0:6].astype(int) date_ary=np.vstack([(dt.datetime(*x).replace(year=2000+dt.datetime(*x).year)).strftime('%Y%m%d%H%M%S') for x in date_cols[:]]) tpb_data_1=np.concatenate([columns,np.concatenate([date_ary,tpb_data[1:,7:]],axis=1)],axis=0) tpb_data_1=pd.DataFrame(data=tpb_data_1[1:,:],columns=tpb_data_1[0,:]) tpb_data_1['Date']=tpb_data_1['Date'].apply(pd.to_datetime, errors='ignore') ; tpb_data_1.iloc[:,1:]=tpb_data_1.iloc[:,1:].apply(pd.to_numeric,errors='coerce') tpb_data_1.index = pd.to_datetime(tpb_data_1.Date) ; tpb_data_1.index =tpb_data_1.index.tz_localize(pytz.utc).tz_convert(pytz.timezone('Asia/Dubai')) tpb_data_1['Date']=tpb_data_1.index tpb_data_1=tpb_data_1.iloc[:,:].resample('1Min').mean() ; tpb_data_1.insert(0,'Date', tpb_data_1.index) #tpb_data_hour=tpb_data_1.iloc[:,:].resample('1H').mean() ; tpb_data_hour.insert(0,'Date', tpb_data_hour.index) ; idx = pd.date_range('2018-03-01 00:00:00', '2018-03-31 23:59:00',freq='T').tz_localize(pytz.timezone('Asia/Dubai')) #Missing data filled with Nan tpb_data_2=tpb_data_1.reindex(idx, fill_value=np.nan) tpb_data_2['Date']=tpb_data_2.index ########################################################################################################################################## #tpc_data=pd.read_csv(tpc_file).as_matrix() tpc_data=np.genfromtxt(tpc_file,delimiter=',',dtype='S') ; columns=np.empty((1,94)).astype(str) ; columns[0,0]='Date' ; columns[0,1:]=tpc_data[0,7:] ; date_cols=tpc_data[1:,0:6].astype(int) date_ary=np.vstack([(dt.datetime(*x).replace(year=2000+dt.datetime(*x).year)).strftime('%Y%m%d%H%M%S') for x in date_cols[:]]) tpc_data_1=np.concatenate([columns,np.concatenate([date_ary,tpc_data[1:,7:]],axis=1)],axis=0) tpc_data_1=pd.DataFrame(data=tpc_data_1[1:,:],columns=tpc_data_1[0,:]) tpc_data_1['Date']=tpc_data_1['Date'].apply(pd.to_datetime, errors='ignore') ; tpc_data_1.iloc[:,1:]=tpc_data_1.iloc[:,1:].apply(pd.to_numeric,errors='coerce') tpc_data_1.index = pd.to_datetime(tpc_data_1.Date) ; tpc_data_1.index =tpc_data_1.index.tz_localize(pytz.utc).tz_convert(pytz.timezone('Asia/Dubai')) tpc_data_1['Date']=tpc_data_1.index tpc_data_1=tpc_data_1.iloc[:,:].resample('1Min').mean() ; tpc_data_1.insert(0,'Date', tpc_data_1.index) #tpc_data_hour=tpc_data_1.iloc[:,:].resample('1H').mean() ; tpc_data_hour.insert(0,'Date', tpc_data_hour.index) ; idx = pd.date_range('2018-03-01 00:00:00', '2018-03-31 23:59:00',freq='T').tz_localize(pytz.timezone('Asia/Dubai')) #Missing data filled with Nan tpc_data_2=tpc_data_1.reindex(idx, fill_value=np.nan) tpc_data_2['Date']=tpc_data_2.index ################################################################################################################################################## #hpc_data=pd.read_csv(hpc_file).as_matrix() hpc_data=np.genfromtxt(hpc_file,delimiter=',',dtype='S') ; columns=np.empty((1,94)).astype(str) ; columns[0,0]='Date' ; columns[0,1:]=hpc_data[0,7:] ; date_cols=hpc_data[1:,0:6].astype(int) date_ary=np.vstack([(dt.datetime(*x).replace(year=2000+dt.datetime(*x).year)).strftime('%Y%m%d%H%M%S') for x in date_cols[:]]) hpc_data_1=np.concatenate([columns,np.concatenate([date_ary,hpc_data[1:,7:]],axis=1)],axis=0) hpc_data_1=pd.DataFrame(data=hpc_data_1[1:,:],columns=hpc_data_1[0,:]) hpc_data_1['Date']=hpc_data_1['Date'].apply(pd.to_datetime, errors='ignore') ; hpc_data_1.iloc[:,1:]=hpc_data_1.iloc[:,1:].apply(pd.to_numeric,errors='coerce') hpc_data_1.index = pd.to_datetime(hpc_data_1.Date) ; hpc_data_1.index =hpc_data_1.index.tz_localize(pytz.utc).tz_convert(pytz.timezone('Asia/Dubai')) hpc_data_1['Date']=hpc_data_1.index hpc_data_1=hpc_data_1.iloc[:,:].resample('1Min').mean() ; hpc_data_1.insert(0,'Date', hpc_data_1.index) #hpc_data_hour=hpc_data_1.iloc[:,:].resample('1H').mean() ; hpc_data_hour.insert(0,'Date', hpc_data_hour.index) ; hpc_data_2=hpc_data_1.reindex(idx, fill_value=np.nan) hpc_data_2['Date']=hpc_data_2.index #rhp_data=pd.read_csv(rhp_file).as_matrix() rhp_data=np.genfromtxt(rhp_file,delimiter=',',dtype='S') ; columns=np.empty((1,94)).astype(str) ; columns[0,0]='Date' ; columns[0,1:]=rhp_data[0,7:] ; date_cols=rhp_data[1:,0:6].astype(int) date_ary=np.vstack([(dt.datetime(*x).replace(year=2000+dt.datetime(*x).year)).strftime('%Y%m%d%H%M%S') for x in date_cols[:]]) rhp_data_1=np.concatenate([columns,np.concatenate([date_ary,rhp_data[1:,7:]],axis=1)],axis=0) rhp_data_1=pd.DataFrame(data=rhp_data_1[1:,:],columns=rhp_data_1[0,:]) rhp_data_1['Date']=rhp_data_1['Date'].apply(pd.to_datetime, errors='ignore') ; rhp_data_1.iloc[:,1:]=rhp_data_1.iloc[:,1:].apply(pd.to_numeric,errors='coerce') rhp_data_1.index = pd.to_datetime(rhp_data_1.Date) ; rhp_data_1.index =rhp_data_1.index.tz_localize(pytz.utc).tz_convert(pytz.timezone('Asia/Dubai')) rhp_data_1['Date']=rhp_data_1.index rhp_data_1=rhp_data_1.iloc[:,:].resample('1Min').mean() ; rhp_data_1.insert(0,'Date', rhp_data_1.index) #rhp_data_hour=rhp_data_1.iloc[:,:].resample('1H').mean() ; rhp_data_hour.insert(0,'Date', rhp_data_hour.index) ; rhp_data_2=rhp_data_1.reindex(idx, fill_value=np.nan) rhp_data_2['Date']=rhp_data_2.index spc_data_2=calculateSPH(tpc_data_2,hpc_data_2) ################################################################################################################################ # met_data=pd.read_csv(met_file).as_matrix() # columns=np.empty((1,7)).astype(str) ; columns[0,0]='Date' ; columns[0,1]='pressure' ; columns[0,2]='Temperature' ; # columns[0,3]='RH' ; columns[0,4]='WS' ; columns[0,5]='WD'; columns[0,6]='RainRate' # date_cols=met_data[1:,0:6].astype(int) # date_ary=np.vstack([(dt.datetime(*x).replace(year=2000+dt.datetime(*x).year)).strftime('%Y%m%d%H%M%S') for x in date_cols[:]]) # met_data_1=np.concatenate([columns,np.concatenate([date_ary,met_data[1:,7:]],axis=1)],axis=0) met_data=pd.read_csv(met_file) met_data_1=met_data.drop(['Date.1'],axis=1) met_data_1['Date']=met_data_1['Date'].apply(pd.to_datetime, errors='ignore') ; met_data_1[['pressure','Temperature','RH','WS','WD','RainRate']]=met_data_1[['pressure','Temperature','RH','WS','WD','RainRate']].apply(pd.to_numeric,errors='coerce') #met_data_1['WS']=met_data_1['WS']*0.2777 #(5/18 km/h to m/sec) met_data_1.index = met_data_1.Date ; met_data_1.index =met_data_1.index.tz_localize(pytz.utc).tz_convert(pytz.timezone('Asia/Dubai')) met_data_1['Date']=met_data_1.index #met_data_1=met_data_1.iloc[:,:].resample('1Min').mean() ; met_data_1.insert(0,'Date', met_data_1.index) #met_data_hour=met_data_1.iloc[:,:].resample('1H').mean() ; met_data_hour.insert(0,'Date', met_data_hour.index) ; met_data_2=met_data_1.reindex(idx, fill_value=pd.np.nan) met_data_2['Date']=met_data_2.index ############################################################################################################################### vis_data=pd.read_csv(vis_file) vis_data['Date']=vis_data['Date'].apply(pd.to_datetime, errors='ignore',format='%Y-%m-%d-%H-%M') ; vis_data[['Ex.Coeff','Visibility(m)','Lux(KM)','DN_Flag','ErrorCode','ctrlrelay']]=\ vis_data[['Ex.Coeff','Visibility(m)','Lux(KM)','DN_Flag','ErrorCode','ctrlrelay']].apply(pd.to_numeric,errors='coerce') vis_data.index = vis_data.Date ; vis_data.index =vis_data.index.tz_localize(pytz.timezone('Asia/Dubai')) #.tz_convert(pytz.utc)) vis_data['Date']=vis_data.index vis_data_2=vis_data.reindex(idx, fill_value=np.nan) vis_data_2['Date']=vis_data_2.index ################################################################################################################################## cbh_data=pd.read_csv(cbh_file).as_matrix() columns=np.empty((1,2)).astype(str) ; columns[0,0]='Date' ; columns[0,-1]='cbh' date_cols=cbh_data[1:,0:6].astype(int) date_ary=np.vstack([(dt.datetime(*x).replace(year=2000+dt.datetime(*x).year)).strftime('%Y%m%d%H%M%S') for x in date_cols[:]]) cbh_data_1=np.concatenate([columns,np.concatenate([date_ary,cbh_data[1:,7:10]],axis=1)],axis=0) cbh_data_1=pd.DataFrame(data=cbh_data_1[1:,:],columns=cbh_data_1[0,:]) cbh_data_1['Date']=cbh_data_1['Date'].apply(pd.to_datetime, errors='ignore') ; cbh_data_1[['cbh']]=cbh_data_1[['cbh']].apply(pd.to_numeric,errors='coerce') cbh_data_1.index = cbh_data_1.Date ; cbh_data_1=cbh_data_1.iloc[:,:].resample('1Min').mean() ; cbh_data_1.insert(0,'Date', cbh_data_1.index) cbh_data_1.index =cbh_data_1.index.tz_localize(pytz.utc).tz_convert(pytz.timezone('Asia/Dubai')) cbh_data_1['Date']=cbh_data_1.index cbh_data_2=cbh_data_1.reindex(idx, fill_value=pd.np.nan) cbh_data_2['Date']=cbh_data_2.index ################################################################################################################# ## dewpoint calculated from RH tpb_hour=tpb_data_2.iloc[:,:].resample('30Min').mean() ; tpb_hour.insert(0,'Date', tpb_hour.index) ; rhp_hour=rhp_data_2.iloc[:,:].resample('30Min').mean() ; rhp_hour.insert(0,'Date', rhp_hour.index) ; tpc_hour=tpc_data_2.iloc[:,:].resample('30Min').mean() ; tpc_hour.insert(0,'Date', tpc_hour.index) ; met_hour=met_data_2.iloc[:,:].resample('30Min').mean() ; met_hour.insert(0,'Date', met_hour.index) ; vis_hour=vis_data_2.iloc[:,:].resample('30Min').mean() ; vis_hour.insert(0,'Date', vis_hour.index) ; cbh_hour=cbh_data_2.iloc[:,:].resample('30Min').mean() ; cbh_hour.insert(0,'Date', cbh_hour.index) ; dpt_data=dewpoint_rh(np.array(tpc_hour.iloc[:,1:])*units('K'),(np.array(rhp_hour.iloc[:,1:])/100.)).to(units('K')) dpt_data_1=pd.DataFrame(dpt_data.m,columns=rhp_hour.columns[1:]) dpt_data_1.index=rhp_hour.Date dpt_data_1.insert(0,'Date',rhp_hour.Date) dpt_data_tpb=dewpoint_rh(np.array(tpb_hour.iloc[:,1:])*units('K'),(np.array(rhp_hour.iloc[:,1:])/100.)).to(units('K')) dpt_data_1_tpb=pd.DataFrame(dpt_data_tpb.m,columns=rhp_hour.columns[1:]) dpt_data_1_tpb.index=rhp_hour.Date dpt_data_1_tpb.insert(0,'Date',rhp_hour.Date) ######################################################################################################################### ## Wet bulb Potential Temperature import aoslib ; metpy.calc.potential_temperature hght=np.array(rhp_hour.columns[1:].astype(int)) h_to_ps=(list(np.round(height_to_pressure_std(np.array(rhp_hour.columns[1:].astype(int))*units('meter')).m))) h_to_pss=pd.concat([pd.DataFrame(h_to_ps).transpose()]*tpb_hour.shape[0]) tpb_hour_wet=aoslib.calctw(h_to_pss,tpb_hour.iloc[:,1:],rhp_hour.iloc[:,1:]) tpb_hour_wet_1=pd.DataFrame(tpb_hour_wet,columns=h_to_ps) #tpb_hour.columns[1:] tpb_hour_wet_1.index=tpb_hour.Date tpb_hour_wet_1.insert(0,'Date',tpb_hour.Date) mix_ratio_1=aoslib.mixrat(h_to_pss,tpb_hour.iloc[:,1:],rhp_hour.iloc[:,1:]) mix_ratio_2=pd.DataFrame(mix_ratio_1,columns=h_to_ps) mix_ratio_2.index=tpb_hour.Date mix_ratio_2.insert(0,'Date',tpb_hour.Date) #tpb_hour_wet_2=aoslib.awips.thetawa(tpb_hour.iloc[0:2,1:],dpt_data_1_tpb.iloc[0:2,1:],h_to_pss.iloc[0:2,:],mix_ratio_1[0:2,:]) A_w=pd.concat([tpb_hour['Date'],tpb_hour[' 1440'],dpt_data_1_tpb[' 1440'] ,mix_ratio_2[852.0]],axis=1).dropna(axis=0, how='any') A_w.columns=['Date','T','Td','Mr'] tpb_hour_wet_2=pd.DataFrame([aoslib.awips.thetawa(np.round(A_w['T'][ii],1),np.round(A_w['Td'][ii],1) ,850,A_w['Mr'][ii]) for ii in range(0,A_w.shape[0])]) tpb_hour_wet_2.index=A_w.Date tpb_hour_wet_2.insert(0,'Date',A_w.Date) #mix_ratio_1=metpy.calc.mixing_ratio_from_relative_humidity(np.array(rhp_hour.iloc[:,1:])/100.,np.array(tpc_hour.iloc[:,1:])*units('K'),h_to_pss.as_matrix()*units.hectopascal) ###### Fog Stability Index ############################## h_to_ps=(list(np.round(height_to_pressure_std(np.array(rhp_hour.columns[1:].astype(int))*units('meter')).m))) h_to_ps.insert(0,'Date') dpt_data_2=dpt_data_1 ; dpt_data_2.columns=h_to_ps A=pd.concat([dpt_data_2['Date'],met_hour['Temperature'],tpc_hour['0'],dpt_data_2[1013.0],tpc_hour[' 10'],met_hour['WS']],axis=1) A.columns=['Date','met_tmp','TPC_0','Dew_0','tpc_10','met_ws'] fsi_index=(4*(A['Temperature']))-2*((A['Temperature']) + (A[1013.0]))+ (A['WS']*1.94384) fsi_index_1=pd.concat([dpt_data_2['Date'],vis_hour['Visibility(m)'],fsi_index],axis=1) fsi_hig=(fsi_index_1.iloc[np.where(fsi_index_1['Visibility(m)'] >5000)]) #.between_time('22:00','06:00') ; fsi_mod=(fsi_index_1.iloc[np.where((fsi_index_1['Visibility(m)'] >1000)&(fsi_index_1['Visibility(m)'] <5000) )]) #.between_time('22:00','06:00') ; fsi_fog=fsi_index_1.iloc[np.where(fsi_index_1['Visibility(m)'] <=1000)] [[fsi_fog[0].min(), fsi_fog[0].max()],[fsi_mod[0].min(), fsi_mod[0].max()],[fsi_hig[0].min(), fsi_hig[0].max()]] fog_point = (0.044 * A['met_tmp']) + (0.844 * A['Dew_0']) - 0.55 fog_threat= tpb_hour_wet_1[852.0]-fog_point ########################################################################################################################### h_to_ps=(list(np.round(height_to_pressure_std(np.array(rhp_hour.columns[1:].astype(int))*units('meter')).m))) h_to_ps.insert(0,'Date') dpt_data_2_tpb=dpt_data_1_tpb ; dpt_data_2_tpb.columns=h_to_ps ############################## TPB A=pd.concat([dpt_data_2_tpb['Date'],met_hour['Temperature'],tpb_hour['0'],tpb_hour[' 1000'],dpt_data_2_tpb[1013.0],dpt_data_2_tpb[852.0],met_hour['WS'],\ met_hour['RH'],vis_hour['Ex.Coeff'],cbh_hour['cbh']],axis=1) fsi_index_tpb_1=np.round((4*(A['Temperature']))-2*((A[' 1000']) + (A[1013.0]))+ (A['WS']*1.94384)+4*(A['cbh']/1000)) ####################### # A=pd.concat([dpt_data_2_tpb['Date'],met_hour['Temperature'],tpb_hour['0'],tpb_hour[' 460'],dpt_data_2_tpb[1013.0],dpt_data_2_tpb[959.0],met_hour['WS'],met_hour['RH']],axis=1) # # fsi_index_tpb_2=(A['0']-A[' 460']) + (A[1013.0]-A[959.0]) + (A['WS']*1.94384) #+A['RH'] # # # fsi_index_tpb_3=(A['0']-A[1013.0]) + (A[' 460']-A[959.0]) + (A['WS']*1.94384) #+A['RH'] # # #fsi_index_tpb=(A['0']-A[1013.0]) + (A['0']-A[' 1440']) + (A['WS']*1.94384) #+A['RH'] fsi_index_1=pd.concat([dpt_data_2_tpb['Date'],vis_hour['Visibility(m)'],fsi_index_tpb_1,met_hour['RH'],met_hour['WS']],axis=1) fsi_index_1.columns=['Date','Visibility(m)','fsi','RH','WS'] fsi_index_1=fsi_index_1 #.between_time('23:00','06:00') fsi_hig=(fsi_index_1.iloc[np.where(fsi_index_1['Visibility(m)'] >3000)]) #.between_time('22:00','06:00') ; fsi_mod=(fsi_index_1.iloc[np.where((fsi_index_1['Visibility(m)'] >1000)&(fsi_index_1['Visibility(m)'] <=3000) )]) #.between_time('22:00','06:00') ; fsi_fog=fsi_index_1.iloc[np.where(fsi_index_1['Visibility(m)'] <=1000)] [[fsi_fog['fsi'].min(), fsi_fog['fsi'].max()],[fsi_mod['fsi'].min(), fsi_mod['fsi'].max()],[fsi_hig['fsi'].min(), fsi_hig['fsi'].max()]] #################### TPC A=pd.concat([dpt_data_1['Date'],met_hour['Temperature'],tpc_hour['0'],tpc_hour[' 1000'],dpt_data_1[1013.0],dpt_data_1[852.0],met_hour['WS'],\ met_hour['RH'],vis_hour['Ex.Coeff'],cbh_hour['cbh']],axis=1) fsi_index_tpb_1=np.round((4*(A['Temperature']))-2*((A[' 1000']) + (A[1013.0]))+ (A['WS']*1.94384)+(A['cbh']/1000)) ####################### # A=pd.concat([dpt_data_2_tpb['Date'],met_hour['Temperature'],tpb_hour['0'],tpb_hour[' 460'],dpt_data_2_tpb[1013.0],dpt_data_2_tpb[959.0],met_hour['WS'],met_hour['RH']],axis=1) # # fsi_index_tpb_2=(A['0']-A[' 460']) + (A[1013.0]-A[959.0]) + (A['WS']*1.94384) #+A['RH'] # # # fsi_index_tpb_3=(A['0']-A[1013.0]) + (A[' 460']-A[959.0]) + (A['WS']*1.94384) #+A['RH'] # # #fsi_index_tpb=(A['0']-A[1013.0]) + (A['0']-A[' 1440']) + (A['WS']*1.94384) #+A['RH'] fsi_index_1=pd.concat([dpt_data_2['Date'],vis_hour['Visibility(m)'],fsi_index_tpb_1,met_hour['RH'],met_hour['WS']],axis=1) fsi_index_1.columns=['Date','Visibility(m)','fsi','RH','WS'] fsi_index_1=fsi_index_1 #.between_time('23:00','06:00') fsi_hig=(fsi_index_1.iloc[np.where(fsi_index_1['Visibility(m)'] >3000)]) #.between_time('22:00','06:00') ; fsi_mod=(fsi_index_1.iloc[np.where((fsi_index_1['Visibility(m)'] >1000)&(fsi_index_1['Visibility(m)'] <=3000) )]) #.between_time('22:00','06:00') ; fsi_fog=fsi_index_1.iloc[np.where(fsi_index_1['Visibility(m)'] <=1000)] [[fsi_fog['fsi'].min(), fsi_fog['fsi'].max()],[fsi_mod['fsi'].min(), fsi_mod['fsi'].max()],[fsi_hig['fsi'].min(), fsi_hig['fsi'].max()]] ############################################################################################################################################################# parm='DPT' ; _date='201803' A1=pd.concat([vis_data_2['Date'],vis_data_2['Visibility(m)'], met_data_2['RH'],met_data_2['WS']], axis=1) A_hour=A1.iloc[:,:].resample('30Min').mean() ; A_hour.insert(0,'Date', A_hour.index) ; B_hour=pd.concat([A_hour,dpt_data_1_tpb.iloc[:,1:]],axis=1) for indx in np.unique([x.strftime('%Y%m%d') for x in B_hour.index.date]) : B1_hour=B_hour.loc[indx] ################# contour plots plot_contour_dailydata(parm,B1_hour,indx) fog_st_time=(B1_hour.iloc[np.where((B1_hour['Visibility(m)'] <=1300) & (B1_hour['RH'] >=88) & (B1_hour['WS'] <=3.0))]).between_time('00:00','10:00') if not fog_st_time.empty : pre_fg_st_time=(dt.datetime.strptime(fog_st_time.index.to_datetime()[0].strftime('%Y-%m-%d %H:%M:%S'),'%Y-%m-%d %H:%M:%S')-dt.timedelta(hours=3)).strftime('%Y-%m-%d %H:%M:%S') pre_fg_ed_time=fog_st_time.index.to_datetime()[0].strftime('%Y-%m-%d %H:%M:%S') pre_fg_data=(B_hour.loc[pre_fg_st_time:pre_fg_ed_time]).dropna(axis=0, how='any') if not pre_fg_data.shape[0] <=1 : plot_contour_prefog(parm,pre_fg_data,indx,'pre_fog') fg_stt_time=fog_st_time.index.to_datetime()[0].strftime('%Y-%m-%d %H:%M:%S') fg_ed_time=fog_st_time.index.to_datetime()[-1].strftime('%Y-%m-%d %H:%M:%S') fg_data=(B1_hour.loc[fg_stt_time:fg_ed_time]).dropna(axis=0, how='any') if not fg_data.shape[0] <=1 : plot_contour_prefog(parm,fg_data,indx,'fog') post_fg_stt_time=(dt.datetime.strptime(fog_st_time.index.to_datetime()[-1].strftime('%Y-%m-%d %H:%M:%S'),'%Y-%m-%d %H:%M:%S')+dt.timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') post_fg_ed_time=(dt.datetime.strptime(fog_st_time.index.to_datetime()[-1].strftime('%Y-%m-%d %H:%M:%S'),'%Y-%m-%d %H:%M:%S')+dt.timedelta(hours=3)).strftime('%Y-%m-%d %H:%M:%S') post_fog_data=(B1_hour.loc[post_fg_stt_time:post_fg_ed_time]).dropna(axis=0, how='any') if not post_fog_data.empty : plot_contour_prefog(parm,post_fog_data,indx,'post_fog') ############################################################################################# B_data_hig=(B_hour.iloc[np.where(B_hour['Visibility(m)'] >1000)]) #.between_time('22:00','06:00') ; #B_data_low=(A.iloc[np.where((A['Visibility(m)'] >1000)&(A['Visibility(m)'] <5000) )]) #.between_time('22:00','06:00') ; B_data_fog=B_hour.iloc[np.where(B_hour['Visibility(m)'] <=1000)] B_data_fog_1=(B_data_fog.iloc[np.where((B_data_fog['RH'] >88) & (B_data_fog['WS'] <3.0))]) #.between_time('22:00','06:00') B_hour_fog=B_data_fog_1.iloc[:,:].resample('30Min').mean() ; B_hour_fog.insert(0,'Date', B_hour_fog.index) ; B1_hour_fog=B_hour_fog.dropna(axis=0, how='any') plot_contour_data(parm,B1_hour_fog,'fog',5) B_hour_hig=B_data_hig.iloc[:,:].resample('30Min').mean() ; B_hour_hig.insert(0,'Date', B_hour_hig.index) ; B1_hour_hig=B_hour_hig.dropna(axis=0, how='any') plot_contour_data(parm,B_hour_hig,'high',30) # B_hour_low=B_data_low.iloc[:,:].resample('30Min').mean() ; B_hour_low.insert(0,'Date', B_hour_low.index) ; # B1_hour_low=B_hour_low.dropna(axis=0, how='any') # # plot_contour_data(parm,B1_hour_low,'low') # plot_contour_data_1km(parm,B1_hour_low,'low') ########################################################################### parm='DPT' ; _date='201803' fsi_index_1=fsi_index_1.dropna(axis=0,how='any') for indx in np.unique([x.strftime('%Y%m%d') for x in fsi_index_1.index.date]) : B1_hour=fsi_index_1.loc[indx] if not B1_hour.empty : plot_fsi(parm,B1_hour,indx) fog_st_time=(B1_hour.iloc[np.where((B1_hour['Visibility(m)'] <=1000) & (B1_hour['RH'] >=88) & (B1_hour['WS'] <=3.0))]).between_time('00:00','10:00') if not fog_st_time.empty : pre_fg_st_time=(dt.datetime.strptime(fog_st_time.index.to_datetime()[0].strftime('%Y-%m-%d %H:%M:%S'),'%Y-%m-%d %H:%M:%S')-dt.timedelta(hours=3)).strftime('%Y-%m-%d %H:%M:%S') pre_fg_ed_time=fog_st_time.index.to_datetime()[0].strftime('%Y-%m-%d %H:%M:%S') pre_fg_data=(fsi_index_1.loc[pre_fg_st_time:pre_fg_ed_time]).dropna(axis=0, how='any') if not pre_fg_data.shape[0] <=1 : plot_fsi_catg(parm,pre_fg_data,indx,'pre_fog') fg_stt_time=fog_st_time.index.to_datetime()[0].strftime('%Y-%m-%d %H:%M:%S') fg_ed_time=fog_st_time.index.to_datetime()[-1].strftime('%Y-%m-%d %H:%M:%S') fg_data=(fsi_index_1.loc[fg_stt_time:fg_ed_time]).dropna(axis=0, how='any') if not fg_data.shape[0] <=1 : plot_fsi_catg(parm,fg_data,indx,'fog') post_fg_stt_time=(dt.datetime.strptime(fog_st_time.index.to_datetime()[-1].strftime('%Y-%m-%d %H:%M:%S'),'%Y-%m-%d %H:%M:%S')+dt.timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S') post_fg_ed_time=(dt.datetime.strptime(fog_st_time.index.to_datetime()[-1].strftime('%Y-%m-%d %H:%M:%S'),'%Y-%m-%d %H:%M:%S')+dt.timedelta(hours=3)).strftime('%Y-%m-%d %H:%M:%S') post_fog_data=(fsi_index_1.loc[post_fg_stt_time:post_fg_ed_time]).dropna(axis=0, how='any') if not post_fog_data.empty : plot_fsi_catg(parm,post_fog_data,indx,'post_fog')
def test_heights_to_pressure_basic(): """Test basic height to pressure calculation for standard atmosphere.""" heights = np.array([321.5, 216.5, 487.6, 601.7]) * units.meter pressures = height_to_pressure_std(heights) values = np.array([975.2, 987.5, 956., 943.]) * units.mbar assert_almost_equal(pressures, values, 1)
def radisonde_cross_section(stns, data, start=1000, end=100, step=10): """This function takes a list of radiosonde observation sites with a dictionary of Pandas Dataframes with the requesite data for each station. Input ----- stns : List of statition three-letter identifiers data : A dictionary of Pandas Dataframes containing the radiosonde observations for the stations start : interpolation start value, optional (default = 1000 hPa) end : Interpolation end value, optional (default = 100 hPa) step : Interpolation interval, option (default = 10 hPa) Return ------ cross_section : A dictionary that contains the following variables grid_data : An interpolated grid with 100 points between the first and last station, with the corresponding number of vertical points based on start, end, and interval (default is 90) obs_distance : An array of distances between each radiosonde observation location x_grid : A 2D array of horizontal direction grid points p_grid : A 2D array of vertical pressure levels ground_elevation : A representation of the terrain between radiosonde observation sites based on the elevation of each station converted to pressure using the standard atmosphere """ # Set up vertical grid, largest value first (high pressure nearest surface) vertical_levels = np.arange(start, end - 1, -step) # Number of vertical levels and stations plevs = len(vertical_levels) nstns = len(stns) # Create dictionary of interpolated values and include neccsary attribute data # including lat, lon, and elevation of each station lats = [] lons = [] elev = [] keys = data[stns[0]].keys()[:8] tmp_grid = dict.fromkeys(keys) # Interpolate all variables for each radiosonde observation # Temperature, Dewpoint, U-wind, V-wind for key in tmp_grid.keys(): tmp_grid[key] = np.empty((nstns, plevs)) for station, loc in zip(stns, range(nstns)): if key == 'pressure': lats.append(data[station].latitude[0]) lons.append(data[station].longitude[0]) elev.append(data[station].elevation[0]) tmp_grid[key][loc, :] = vertical_levels else: tmp_grid[key][loc, :] = vertical_interpolate( data[station]['pressure'].values, data[station][key].values, vertical_levels) # Compute distance between each station using Pyproj g = Geod(ellps='sphere') _, _, dist = g.inv(nstns * [lons[0]], nstns * [lats[0]], lons[:], lats[:]) # Compute sudo ground elevation in pressure from standard atmsophere and the elevation # of each station ground_elevation = mpcalc.height_to_pressure_std( np.array(elev) * units('meters')) # Set up grid for 2D interpolation grid = dict.fromkeys(keys) x = np.linspace(dist[0], dist[-1], 100) nx = len(x) pp, xx = np.meshgrid(vertical_levels, x) pdist, ddist = np.meshgrid(vertical_levels, dist) # Interpolate to 2D grid using scipy.interpolate.griddata for key in grid.keys(): grid[key] = np.empty((nx, plevs)) grid[key][:] = griddata((ddist.flatten(), pdist.flatten()), tmp_grid[key][:].flatten(), (xx, pp), method='cubic') # Gather needed data in dictionary for return cross_section = { 'grid_data': grid, 'obs_distance': dist, 'x_grid': xx, 'p_grid': pp, 'elevation': ground_elevation } return cross_section
def skewt_plots(dt, station, p, T, Td, u, v, outdir, idxij, utch, z): # skewt_plots(dt,station,p,T,Td,u,v,outdir,idxij,utch) # Function to make the graphic ploting of the sounding. # ---INPUTS: # dt = "2016-10-26 13h CET (12 UTC)" # string of valid time # station = "Piedtahita" station name # p pressure colmn on coordinates # T temp colmn on coordinates # Td dew point colmn on coordinates # u,v wind vectors colmn on coordinates # outdir='plots/' #output directory # idxij matrix coordinates of the sounding # utch="1200" #string of utc hour for filename # z geopotential height # ---OUTPUTS: # plot in outdir p = p.interp(south_north=idxij[1], west_east=idxij[0]) lon = p.XLONG.values lat = p.XLAT.values dx = p.projection.dx dy = p.projection.dy p = p.values T = T.interp(south_north=idxij[1], west_east=idxij[0]).values Td = Td.interp(south_north=idxij[1], west_east=idxij[0]).values u = u.interp(south_north=idxij[1], west_east=idxij[0]).values v = v.interp(south_north=idxij[1], west_east=idxij[0]).values z = z.interp(south_north=idxij[1], west_east=idxij[0]).values ###################################################################### # Make Skew-T Plot # ---------------- # The code below makes a basic skew-T plot using the MetPy plot module # that contains a SkewT class. # Change default to be better for skew-T fig = plt.figure(figsize=(11, 9)) plt.rcParams.update({'font.size': 12}) # Initiate the skew-T plot type from MetPy class loaded earlier skew = SkewT(fig, rotation=45) # Plot the data using normal plotting functions, in this case using # log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.plot(p, Td, 'g') skew.plot_barbs(p[::3], u[::3], v[::3], y_clip_radius=0.03) # Set some appropriate axes limits for x and y #skew.ax.set_xlim(-30, 40) skew.ax.set_ylim(1020, 200) skew.ax.set_ylabel('Pressure [hPa]') skew.ax.set_xlabel('Temperature [ºC]') heights = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) * units.km std_pressures = mpcalc.height_to_pressure_std(heights) for height_tick, p_tick in zip(heights, std_pressures): trans, _, _ = skew.ax.get_yaxis_text1_transform(0) skew.ax.text(0.02, p_tick, '---{:~d}'.format(height_tick), transform=trans) # Calculate LCL height and plot as black dot. Because `p`'s first value is # ~1000 mb and its last value is ~250 mb, the `0` index is selected for # `p`, `T`, and `Td` to lift the parcel from the surface. If `p` was inverted, # i.e. start from low value, 250 mb, to a high value, 1000 mb, the `-1` index # should be selected. lcl_pressure, lcl_temperature = mpcalc.lcl(p[0] * units.hPa, T[0] * units.degC, Td[0] * units.degC) skew.plot(lcl_pressure, lcl_temperature, 'ko', markerfacecolor='black') # Calculate full parcel profile and add to plot as black line prof = mpcalc.parcel_profile(p * units.hPa, T[0] * units.degC, Td[0] * units.degC).to('degC') skew.plot(p, prof, 'k', linewidth=2) # Shade areas of CAPE and CIN skew.shade_cin(p * units.hPa, T * units.degC, prof) skew.shade_cape(p * units.hPa, T * units.degC, prof) # An example of a slanted line at constant T -- in this case the 0 # isotherm skew.ax.axvline(0, color='c', linestyle='--', linewidth=2) # Add the relevant special lines to plot throughout the figure skew.plot_dry_adiabats(t0=np.arange(233, 533, 10) * units.K, alpha=0.6, color='orangered') skew.plot_moist_adiabats(t0=np.arange(233, 400, 5) * units.K, alpha=0.6, color='tab:green') #skew.plot_mixing_lines(p=np.arange(1000, 99, -20) * units.hPa, # linestyle='dotted', color='tab:blue') # Add some descriptive titles plt.title('Sounding ' + station + '\n(' + str('{0:.6f}'.format(lat)) + ' , ' + str('{0:.6f}'.format(lon)) + ') ', loc='left') plt.title('Valid for: ' + dt + '\n by RASPURI ', loc='right') UTC_time = time.gmtime() plt.figtext( 0.99, 0.01, time.strftime('Computed on %d/%m/%y %H:%M:%S UTC \n', UTC_time) + 'dx: ' + str(dx) + 'm dy: ' + str(dy) + 'm ', horizontalalignment='right', fontsize=10) #plt.figtext(0.01, 0.01, 'RASPURI by Oriol Cevrelló ', horizontalalignment='right') plt.tight_layout() filename = outdir + station + '_' + utch + '.png' #plt.show() plt.savefig(filename) plt.close()
def write_file(self, elev_file, punits=0, datetag=None, filename=None, append=False): if datetag is None: datetag = str(datetime.datetime.now().strftime('%Y_%m_%d')) if not append: ncfile = netCDF4.Dataset(self.opath / (self.fileprefix + 'climate_' + datetag.strftime("%Y_%m_%d") + '.nc'), mode='w', format='NETCDF4_CLASSIC') def getxy(pt): return pt.x, pt.y centroidseries = self.gdf1.geometry.centroid.to_crs(epsg=4327) tlon, tlat = [list(t) for t in zip(*map(getxy, centroidseries))] # Global Attributes ncfile.Conventions = 'CF-1.8' ncfile.featureType = 'timeSeries' ncfile.history = '' sp_dim = len(self.gdf1.index) # Create dimensions ncfile.createDimension('geomid', size=sp_dim) # hru_id ncfile.createDimension( 'time', size=None) # unlimited axis (can be appended to). # Create Variables time = ncfile.createVariable('time', 'f4', ('time', )) time.long_name = 'time' time.standard_name = 'time' time.units = 'days since ' + self.str_start time.calendar = 'standard' time[:] = np.arange(0, self.current_time_index, dtype=np.float) hru = ncfile.createVariable('geomid', 'i', ('geomid', )) hru.cf_role = 'timeseries_id' hru.long_name = 'local model hru id' hru[:] = np.asarray(self.gdf1.index) lat = ncfile.createVariable('hru_lat', np.dtype(np.float32).char, ('geomid', )) lat.long_name = 'Latitude of HRU centroid' lat.units = 'degrees_north' lat.standard_name = 'hru_latitude' lat[:] = tlat lon = ncfile.createVariable('hru_lon', np.dtype(np.float32).char, ('geomid', )) lon.long_name = 'Longitude of HRU centroid' lon.units = 'degrees_east' lon.standard_name = 'hru_longitude' lon[:] = tlon # crs = ncfile.createVariable('crs', np.dtype(np.int)) # crs.GeoTransform = self.grd[0].crs.GeoTransform # # crs.NAME = self.grd[0].crs.NAME # crs.grid_mapping_name = self.grd[0].crs.grid_mapping_name # crs.inverse_flattening = self.grd[0].crs.inverse_flattening # crs.long_name = self.grd[0].crs.long_name # crs.longitude_of_prime_meridian = self.grd[0].crs.longitude_of_prime_meridian # crs.semi_major_axis = self.grd[0].crs.semi_major_axis # crs.spatial_ref = self.grd[0].crs.spatial_ref else: ncfile = netCDF4.Dataset( self.opath / (self.fileprefix + 'climate_' + str(datetime.datetime.now().strftime('%Y%m%d')) + '.nc'), mode='a', format='NETCDF_CLASSIC') for index, tvar in enumerate(self.var_output): vartype = self.grd[index][self.var[index]].dtype ncvar = ncfile.createVariable(tvar, vartype, ('time', 'geomid')) ncvar.fill_value = netCDF4.default_fillvals['f8'] ncvar.long_name = self.grd[index][self.var[index]].long_name ncvar.standard_name = self.grd[index][ self.var[index]].standard_name ncvar.description = self.grd[index][self.var[index]].description # ncvar.grid_mapping = 'crs' ncvar.units = self.grd[index][self.var[index]].units if tvar in ['tmax', 'tmin']: if punits == 1: conv = units.degC ncvar[:, :] = units.Quantity(self._np_var[index, 0:self.current_time_index, :], ncvar.units)\ .to(conv).magnitude ncvar.units = conv.format_babel() else: conv = units.degF # ncvar[:,:] = ((self._np_var[index, 0:self.current_time_index, :]-273.15)*1.8)+32.0 ncvar[:, :] = units.Quantity(self._np_var[index, 0:self.current_time_index, :], ncvar.units)\ .to(conv).magnitude ncvar.units = conv.format_babel() elif tvar == 'prcp': if punits == 1: conv = units('mm') ncvar[:, :] = units.Quantity(self._np_var[index, 0:self.current_time_index, :], ncvar.units)\ .to(conv).magnitude ncvar.units = conv.units.format_babel() else: conv = units('inch') ncvar[:, :] = units.Quantity(self._np_var[index, 0:self.current_time_index, :], ncvar.units)\ .to(conv).magnitude ncvar.units = conv.units.format_babel() # else units are already in mm # ncvar[:,:] = np.multiply(self._np_var[index, 0:self.current_time_index, :], conv.magnitude) else: ncvar[:, :] = self._np_var[index, 0:self.current_time_index, :] ncvar.units = self.grd[index][self.var[index]].units elevf = gpd.read_file(elev_file, layer='hru_elev') elev = elevf['hru_elev'].values if all(x in self.var_output for x in ['tmax', 'tmin', 'shum']): tmax_ind = self.var_output.index('tmax') tmin_ind = self.var_output.index('tmin') shum_ind = self.var_output.index('shum') print(f'tmaxind: {tmax_ind}, tminind: {tmin_ind}, shumind: {shum_ind}') rel_h = np.zeros((self.current_time_index, self.numgeom)) for j in np.arange(np.int(self.numgeom)): pr = mpcalc.height_to_pressure_std(units.Quantity(elev[j], "m")) for i in np.arange(np.int(self.current_time_index)): tmax = units.Quantity(self._np_var[tmax_ind, i, j], units.kelvin) tmin = units.Quantity(self._np_var[tmin_ind, i, j], units.kelvin) spch = units.Quantity(self._np_var[shum_ind, i, j], "kg/kg") rhmax = mpcalc.relative_humidity_from_specific_humidity( pr, tmax, spch) rhmin = mpcalc.relative_humidity_from_specific_humidity( pr, tmin, spch) rel_h[i, j] = (rhmin.magnitude + rhmax.magnitude) / 2.0 ncvar = ncfile.createVariable('humidity', rel_h.dtype, ('time', 'geomid')) ncvar.units = "1" ncvar.fill_value = netCDF4.default_fillvals['f8'] ncvar[:, :] = rel_h[0:self.current_time_index, :] ncfile.close()