#!/usr/bin/env python """ mmarvin 20200221 (mmarvin@ed.ac.uk) This Python script processes GFED4.1s files for input to GEOS-Chem. It can be used to process standard emissions, as well as preliminary 'beta' emissions. To start: enter year, whether this year requires beta emissions, whether this is a leap year, and the path to the original hdf5 GFED4.1s source files. """ import xarray as xr import pandas as pd import numpy as np import h5py #Select options yyyy = '2017' isbeta = True isleap = False path2hdf5 = "./source_gfed_hdf5" months = ['01','02','03','04','05','06','07','08','09','10','11','12'] #Open yearly HDF5 file if isbeta == True: fn = path2hdf5+"/GFED4.1s_"+yyyy+"_beta.hdf5" else: fn = path2hdf5+"/GFED4.1s_"+yyyy+".hdf5" hf = h5py.File(fn, 'r') lat = hf['lat'] lat = np.flip(lat[:,0]) nlat = np.size(lat) lon = hf['lon'] lon = lon[0,:] nlon = np.size(lon) #Create monthly NetCDF files for mm in months: if mm == '04' or mm == '06' or mm == '09' or mm == '11': dd = 30 elif mm == '02'and isleap == True: dd = 29 elif mm == '02' and isleap == False: dd = 28 else: dd = 31 time_mm = pd.date_range(yyyy+'-'+mm+'-01',yyyy+'-'+mm+'-01') time_dd = pd.date_range(yyyy+'-'+mm+'-01',yyyy+'-'+mm+'-'+str(dd)) time_hh = pd.date_range(yyyy+'-'+mm+'-01T00:00:00',yyyy+'-'+mm+'-01T21:00:00',periods=8) #Read total DM emissions: kg/m2/month => kg/m2/s data = hf['emissions/'+mm+'/DM'] data_dm = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon)/(60*60*24*dd) #Calculate partitioned emissions from total DM data = hf['emissions/'+mm+'/partitioning/DM_AGRI'] data_frac = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon) data_agri = data_dm*data_frac data = hf['emissions/'+mm+'/partitioning/DM_BORF'] data_frac = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon) data_borf = data_dm*data_frac data = hf['emissions/'+mm+'/partitioning/DM_DEFO'] data_frac = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon) data_defo = data_dm*data_frac data = hf['emissions/'+mm+'/partitioning/DM_SAVA'] data_frac = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon) data_sava = data_dm*data_frac data = hf['emissions/'+mm+'/partitioning/DM_PEAT'] data_frac = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon) data_peat = data_dm*data_frac data = hf['emissions/'+mm+'/partitioning/DM_TEMF'] data_frac = np.flip(data[:,:],axis=0).reshape(1,nlat,nlon) data_temf = data_dm*data_frac #Read daily scaling factors daily_fraction = np.zeros([dd,nlat,nlon]) for ndays in np.arange(dd): day_string = str(ndays+1) frac = hf['emissions/'+mm+'/daily_fraction/day_'+day_string] dfrac = np.flip(frac[:,:],axis=0).reshape(1,nlat,nlon) daily_fraction[ndays,:,:] = dfrac*dd daily_fraction = np.where(np.sum(daily_fraction,axis=0) > 0,daily_fraction,1.0) #Read diurnal scaling factors hours = ['UTC_0-3h','UTC_3-6h','UTC_6-9h','UTC_9-12h','UTC_12-15h','UTC_15-18h','UTC_18-21h','UTC_21-24h'] diurnal_fraction = np.zeros([8,nlat,nlon]) for hrs in np.arange(len(hours)): frac = hf['emissions/'+mm+'/diurnal_cycle/'+hours[hrs]] dfrac = np.flip(frac[:,:],axis=0).reshape(1,nlat,nlon) diurnal_fraction[hrs,:,:] = dfrac*8 diurnal_fraction = np.where(np.sum(diurnal_fraction,axis=0) > 0,diurnal_fraction,1.0) #Creat NetCDF datasets data_file = 'GFED4_gen.025x025.'+yyyy+mm+'.nc' dailyfrac_file = 'GFED4_dailyfrac_gen.025x025.'+yyyy+mm+'.nc' diurnalfrac_file = 'GFED4_3hrfrac_gen.025x025.'+yyyy+mm+'.nc' ds = xr.Dataset(coords={'time':time_mm,'lat':lat,'lon':lon}) # "time", "lat", "lon" ds['time'].attrs['standard_name'] = 'time' ds['time'].attrs['axis'] = 'T' ds['lat'].attrs['standard_name'] = 'latitude' ds['lat'].attrs['long_name'] = 'latitude' ds['lat'].attrs['units'] = 'degrees_north' ds['lat'].attrs['axis'] = 'Y' ds['lon'].attrs['standard_name'] = 'longitude' ds['lon'].attrs['long_name'] = 'longitude' ds['lon'].attrs['units'] = 'degrees_east' ds['lon'].attrs['axis'] = 'X' #Assign data variables to dataset ds_data = ds.copy() ds_data['DM_TOTL'] = (['time','lat','lon'], data_dm) ds_data['DM_AGRI'] = (['time','lat','lon'], data_agri) ds_data['DM_BORF'] = (['time','lat','lon'], data_borf) ds_data['DM_DEFO'] = (['time','lat','lon'], data_defo) ds_data['DM_SAVA'] = (['time','lat','lon'], data_sava) ds_data['DM_PEAT'] = (['time','lat','lon'], data_peat) ds_data['DM_TEMP'] = (['time','lat','lon'], data_temf) ds_data = ds_data.astype('float32') for v in ds_data.data_vars.keys(): ds_data[v].attrs['units'] = 'kg/m2/s' #Assign daily scale factors to dataset ds_daily = ds.copy() ds_daily.coords['time'] = time_dd ds_daily['GFED_FRACDAY'] = (['time','lat','lon'], daily_fraction) ds_daily['GFED_FRACDAY'].attrs['units'] = '1' ds_daily = ds_daily.astype('float32') #Assign diurnal scale factors to dataset ds_diurnal = ds.copy() ds_diurnal.coords['time'] = time_hh ds_diurnal['GFED_FRAC3HR'] = (['time','lat','lon'], diurnal_fraction) ds_diurnal['GFED_FRAC3HR'].attrs['units'] = '1' ds_diurnal = ds_diurnal.astype('float32') #Create NetCDF files ds_data.to_netcdf(data_file) ds_daily.to_netcdf(dailyfrac_file) ds_diurnal.to_netcdf(diurnalfrac_file)