示例#1
0
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')
示例#2
0
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)
示例#3
0
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
示例#4
0
 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
示例#5
0
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
示例#6
0
    # 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)
示例#7
0
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)
示例#8
0
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
示例#9
0
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')             
示例#10
0
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
示例#12
0
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()
示例#13
0
    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()