def divergence(u, v, x=None, y=None): ''' Calculates the horizontal divergence using finite differencing. The data should be lon/lat projection. :param u: (*array*) U component array. :param v: (*array*) V component array. :param x: (*array*) X coordinate. :param y: (*array*) Y coordinate. :returns: Array of the horizontal divergence. ''' ny = u.shape[-2] nx = u.shape[-1] if x is None: if isinstance(u, DimArray): x = u.dimvalue(-1) else: x = np.arange(nx) elif isinstance(x, (list, tuple)): x = np.array(x) if y is None: if isinstance(v, DimArray): y = u.dimvalue(-2) else: y = np.arange(ny) elif isinstance(y, (list, tuple)): y = np.array(y) r = MeteoMath.divergence(u.asarray(), v.asarray(), x.asarray(), y.asarray()) if isinstance(u, DimArray): return DimArray(NDArray(r), u.dims, u.fill_value, u.proj) else: return NDArray(r)
def vorticity(u, v, x=None, y=None): """ Calculates the vertical component of the curl (ie, vorticity). The data should be lon/lat projection. :param u: (*array*) U component array (2D). :param v: (*array*) V component array (2D). :param x: (*array*) X coordinate array (1D). :param y: (*array*) Y coordinate array (1D). :returns: Array of the vertical component of the curl. """ ny = u.shape[-2] nx = u.shape[-1] if x is None: if isinstance(u, DimArray): x = u.dimvalue(-1) else: x = np.arange(nx) elif isinstance(x, (list, tuple)): x = np.array(x) if y is None: if isinstance(v, DimArray): y = u.dimvalue(-2) else: y = np.arange(ny) elif isinstance(y, (list, tuple)): y = np.array(y) r = MeteoMath.vorticity(u.asarray(), v.asarray(), x.asarray(), y.asarray()) return DimArray(NDArray(r), u.dims, u.fill_value, u.proj)
def merge_output(year, months, model_grid, mechanism_name): """ Merge EMIPS output emission data of MEIC CAMS and HTAP data Applicable to the situation that MEIC data are nan outside China mainland(nan in taiwan)!!! :param year: (*int*) Year. :param months: (*list*) Months. :param model_grid: (*GridDesc*) Model data grid describe. :param mechanism_name: (*string*) mechanism's name. """ print('---------------------------------') print('-----Merge output data.....------') print('---------------------------------') #Set directories dir_meic1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\MEIC', str(year)) dir_cams1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\CAMS', str(year)) dir_htap1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\HTAP\2010') dir_out1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\merge', str(year)) #Set sectors sectors = [SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, \ SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT, SectorEnum.SHIPS, \ SectorEnum.AIR] #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] for month in months: print('##########') print('Month: {}'.format(month)) print('##########') dir_meic = os.path.join(dir_meic1, '{}{:>02d}'.format(year, month)) dir_cams = os.path.join(dir_cams1, '{}{:>02d}'.format(year, month)) dir_htap = os.path.join(dir_htap1, '{}{:>02d}'.format(2010, month)) dir_out = os.path.join(dir_out1, '{}{:>02d}'.format(year, month)) if not os.path.exists(dir_out): os.mkdir(dir_out) print('------------------Filepath------------------') print('dir_meic: {}\ndir_cams: {}\ndir_htap: {}\ndir_out: {}'.format(dir_meic, dir_cams, dir_htap, dir_out)) #Sector loop for sector in sectors: print('############')
def run_proj(year, month, dir_inter, model_grid, target_grid, out_species, out_species_aer, global_attributes, z): """ Write Times variable, add global attributes, convert data's projection. io_style_emissions = 2 :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) The directory where data is stored. :param model_grid: (*GridDesc*) Model data grid describe. :param target_grid: (*GridDesc*) Target data grid describe. :param out_species: (*list*) The name of the output species(gases and aerosol). :param out_species_aer: (*list*) The name of the output species(aerosol). :param global_attributes: (*OrderedDict*) The global attributes of the output file. :param z: (*int*) The zdim of the output data. """ print('Add input file...') fn_in = dir_inter + '\emis_{}_{}_hour_transform.nc'.format(year, month) print(fn_in) f_in = dataset.addfile(fn_in) #set dimension tdim = np.dimension(np.arange(24), 'Time') ydim = np.dimension(target_grid.y_coord, 'south_north', 'Y') xdim = np.dimension(target_grid.x_coord, 'west_east', 'X') zdim = np.dimension(np.arange(z), 'emissions_zdim') sdim = np.dimension(np.arange(19), 'DateStrLen') dims = [tdim, zdim, ydim, xdim] all_dims = [tdim, sdim, xdim, ydim, zdim] fn_out = dir_inter + '\wrfchemi_d01_{}-{:0>2d}'.format(year, month) #set variables dimvars = [] dimvar = dataset.DimVariable() dimvar.name = 'Times' dimvar.dtype = np.dtype.char dimvar.dims = [tdim, sdim] #dimvar.addattr('_ChunkSizes', [1, 19]) dimvars.append(dimvar) for out_specie in out_species: dimvar = dataset.DimVariable() dimvar.name = out_specie dimvar.dtype = np.dtype.float dimvar.dims = dims dimvar.addattr('FieldType', 104) dimvar.addattr('MemoryOrder', "XYZ") dimvar.addattr('description', "EMISSION_{}".format(out_specie[2:])) if out_specie in out_species_aer: #g/m2/s to ug/m^3 m/s dimvar.addattr('units', 'ug/m3 m/s') else: #mole/m2/s to mol/km^2/hr dimvar.addattr('units', 'mol km^-2 hr^-1') dimvar.addattr('stagger', "") dimvar.addattr('coordinates', "XLONG XLAT XTIME") #dimvar.addattr('_ChunkSizes', [1, 3, 137, 167]) dimvars.append(dimvar) print('Create output data file...') print(fn_out) ncfile = dataset.addfile(fn_out, 'c', largefile=True) print('Define dimensions, global attributes and variables...') ncfile.nc_define(all_dims, global_attributes, dimvars, write_dimvars=False) #Times print('Write Times variable...') s_out = [] for i in range(24): s = '{}-{:0>2d}-01_{:0>2d}:00:00'.format(year, month, i) s_out.append(s) s_out = np.array(s_out, dtype=np.dtype.char) ncfile.write('Times', s_out) print('Write variable data except times...') for out_specie in out_species: data = np.zeros((tdim.length, zdim.length, ydim.length, xdim.length)) if out_specie in f_in.varnames(): print(out_specie) dd = f_in[out_specie][:] #Conversion proj dd = transform(dd, model_grid, target_grid) #Set default values dd[dd == np.nan] = 0 data[:, :, :, :] = dd ##########test############ #data[:, 1:8, :, :] = 0 ##########test############ ncfile.write(out_specie, data) f_in.close() ncfile.close() print('Convert projection finished!')
def run(year, month, dir_inter, emission, model_grid): """ Process emission data by spatial allocation, temporal allocation and chemical speciation except VOC pollution. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) Data output path. :param emission: (*module*) Emission module. :param model_grid: (*GridDesc*) Model data grid describe. """ #Set profile files temp_profile_fn = os.path.join(ge_data_dir, 'amptpro.m3.default.us+can.txt') temp_ref_fn = os.path.join(ge_data_dir, 'amptref.m3.us+can.cair.txt') spec_profile_fn = os.path.join(ge_data_dir, 'gspro.cmaq.radm2p25_rev.txt') spec_ref_fn = os.path.join(ge_data_dir, 'gsref.cmaq.radm2p25.txt') #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Set sectors and pollutants sectors = [SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT] pollutants = [PollutantEnum.BC, PollutantEnum.CO, PollutantEnum.NH3, \ PollutantEnum.NOx, PollutantEnum.OC, PollutantEnum.PM2_5, \ PollutantEnum.SO2, PollutantEnum.PMcoarse, PollutantEnum.PM10more] out_species = [SpeciesEnum.PEC, SpeciesEnum.CO, SpeciesEnum.NH3, \ None, SpeciesEnum.POA, None, SpeciesEnum.SO2, SpeciesEnum.PMC, \ SpeciesEnum.PMC] #Loop for sector in sectors: print('####################################') print(sector) print('####################################') #Get SCC scc = emis_util.get_scc(sector) #Get pollutant profiles pollutant_profiles = emips.chem_spec.read_file(spec_ref_fn, spec_profile_fn, scc) for pollutant, out_spec in zip(pollutants, out_species): print(pollutant) print('Read emission data...') emis_data = emission.read_emis(sector, pollutant, month) #### Spatial allocation print('Convert emission data untis from Mg/grid/month to g/m2/month...') emis_data = emis_data * 1e6 / emission.grid_areas print('Spatial allocation of emission grid to model grid...') emis_data = transform(emis_data, emission.emis_grid, model_grid) #### Temporal allocation print('Temporal allocation...') month_profile, week_profile, diurnal_profile, diurnal_profile_we = \ emips.temp_alloc.read_file(temp_ref_fn, temp_profile_fn, scc) print('To daily emission (g/m2/day)...') weekday_data, weekend_data = emips.temp_alloc.week_allocation(emis_data, week_profile, year, month) print('To hourly emission (g/m2/s)...') hour_data = emips.temp_alloc.diurnal_allocation(weekday_data, diurnal_profile) / 3600 #### Chemical speciation poll_prof = emips.chem_spec.get_pollutant_profile(pollutant_profiles, pollutant) if (pollutant == PollutantEnum.NOx) and (poll_prof is None): poll_prof = PollutantProfile(pollutant) poll_prof.append(SpeciesProfile(pollutant, Species('NO'), 0.9, 1.0, 0.9)) poll_prof.append(SpeciesProfile(pollutant, Species('NO2'), 0.1, 1.0, 0.1)) outfn = os.path.join(dir_inter, \ '{}_emis_{}_{}_{}_hour.nc'.format(pollutant.name, sector.name, year, month)) print outfn if poll_prof is None: #### Save hourly emission data print('Save hourly emission data...') if out_spec.molar_mass is None: attrs = dict(units='g/m2/s') else: attrs = dict(units='mole/m2/s') print('To (mole/m2/s)') hour_data = hour_data / out_spec.molar_mass dataset.ncwrite(outfn, hour_data, out_spec.name, dims, attrs) else: print('Chemical speciation...') specs = poll_prof.get_species() gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') dimvars = [] for spec in specs: dimvar = dataset.DimVariable() dimvar.name = spec.name dimvar.dtype = np.dtype.float dimvar.dims = dims if spec.molar_mass is None: dimvar.addattr('units', 'g/m2/s') else: dimvar.addattr('units', 'mole/m2/s') dimvars.append(dimvar) ncfile = dataset.addfile(outfn, 'c') ncfile.nc_define(dims, gattrs, dimvars) for spec_prof,dimvar,spec in zip(poll_prof.species_profiles, dimvars, specs): print(dimvar.name) spec_data = hour_data * spec_prof.mass_fraction if not spec.molar_mass is None: print('To (mole/m2/s)') spec_data = spec_data / spec.molar_mass ncfile.write(dimvar.name, spec_data) ncfile.close()
def cumsimp(y): """ Simpson-rule column-wise cumulative summation. Numerical approximation of a function F(x) such that Y(X) = dF/dX. Each column of the input matrix Y represents the value of the integrand Y(X) at equally spaced points X = 0,1,...size(Y,1). The output is a matrix F of the same size as Y. The first row of F is equal to zero and each following row is the approximation of the integral of each column of matrix Y up to the givem row. CUMSIMP assumes continuity of each column of the function Y(X) and uses Simpson rule summation. Similar to the command F = CUMSUM(Y), exept for zero first row and more accurate summation (under the assumption of continuous integrand Y(X)). Transferred from MATLAT code by Kirill K. Pankratov, March 7, 1994. :param y: (*array*) Input 2-D array. :returns: (*array*) Summation result. """ # 3-points interpolation coefficients to midpoints. # Second-order polynomial (parabolic) interpolation coefficients # from Xbasis = [0 1 2] to Xint = [.5 1.5] c1 = 3. / 8 c2 = 6. / 8 c3 = -1. / 8 # Determine the size of the input and make column if vector ist = 0 # If to be transposed lv = y.shape[0] if lv == 1: ist = 1 y = y.T lv = len(y) f = np.zeros(y.shape) # If only 2 elements in columns - simple sum divided by 2 if lv == 2: f[1, :] = (y[0, :] + y[1]) / 2 if ist: f = f.T # Transpose output if necessary return f # If more than two elements in columns - Simpson summation num = np.arange(0, lv - 2) # Interpolate values of Y to all midpoints f[num + 1, :] = c1 * y[num, :] + c2 * y[num + 1, :] + c3 * y[num + 2, :] f[num + 2, :] = f[ num + 2, :] + c3 * y[num, :] + c2 * y[num + 1, :] + c1 * y[num + 2, :] f[1, :] = f[1, :] * 2 f[lv - 1, :] = f[lv - 1, :] * 2 # Now Simpson (1,4,1) rule f[1:lv, :] = 2 * f[1:lv, :] + y[0:lv - 1, :] + y[1:lv, :] f = np.cumsum( f, axis=0) / 6 # Cumulative sum, 6 - denom. from the Simpson rule if ist: f = f.T # Transpose output if necessary return f
def streamplot(self, *args, **kwargs): """ Plot stream lines in 3D axes. :param x: (*array_like*) X coordinate array. :param y: (*array_like*) Y coordinate array. :param z: (*array_like*) Z coordinate array. :param u: (*array_like*) U component of the arrow vectors (wind field). :param v: (*array_like*) V component of the arrow vectors (wind field). :param w: (*array_like*) W component of the arrow vectors (wind field). :param density: (*int*) Streamline density. Default is 4. :return: Streamlines """ ls = kwargs.pop('symbolspec', None) cmap = plotutil.getcolormap(**kwargs) density = kwargs.pop('density', 4) iscolor = False cdata = None if len(args) < 6: u = args[0] v = args[1] w = args[2] u = np.asarray(u) nz, ny, nx = u.shape x = np.arange(nx) y = np.arange(ny) z = np.arange(nz) args = args[3:] else: x = args[0] y = args[1] z = args[2] u = args[3] v = args[4] w = args[5] args = args[6:] if len(args) > 0: cdata = args[0] iscolor = True args = args[1:] x = plotutil.getplotdata(x) y = plotutil.getplotdata(y) z = plotutil.getplotdata(z) u = plotutil.getplotdata(u) v = plotutil.getplotdata(v) w = plotutil.getplotdata(w) if ls is None: if iscolor: if len(args) > 0: cn = args[0] ls = LegendManage.createLegendScheme( cdata.min(), cdata.max(), cn, cmap) else: levs = kwargs.pop('levs', None) if levs is None: ls = LegendManage.createLegendScheme( cdata.min(), cdata.max(), cmap) else: if isinstance(levs, NDArray): levs = levs.tolist() ls = LegendManage.createLegendScheme( cdata.min(), cdata.max(), levs, cmap) else: if cmap.getColorCount() == 1: c = cmap.getColor(0) else: c = Color.black ls = LegendManage.createSingleSymbolLegendScheme( ShapeTypes.Polyline, c, 1) ls = plotutil.setlegendscheme_line(ls, **kwargs) if not kwargs.has_key('headwidth'): kwargs['headwidth'] = 1 if not kwargs.has_key('headlength'): kwargs['headlength'] = 2.5 for i in range(ls.getBreakNum()): lb = plotutil.line2stream(ls.getLegendBreak(i), **kwargs) ls.setLegendBreak(i, lb) if not cdata is None: cdata = plotutil.getplotdata(cdata) min_points = kwargs.pop('min_points', 3) start_x = kwargs.pop('start_x', None) start_y = kwargs.pop('start_y', None) start_z = kwargs.pop('start_z', None) if start_x is None or start_y is None or start_z is None: graphics = GraphicFactory.createStreamlines3D( x, y, z, u, v, w, cdata, density, ls, min_points) else: start_x = np.asarray(start_x).flatten() start_y = np.asarray(start_y).flatten() start_z = np.asarray(start_z).flatten() graphics = GraphicFactory.createStreamlines3D( x, y, z, u, v, w, cdata, density, ls, min_points, start_x._array, start_y._array, start_z._array) lighting = kwargs.pop('lighting', None) if not lighting is None: graphics.setUsingLight(lighting) self.add_graphic(graphics) return graphics
def streamslice(self, *args, **kwargs): """ Plot stream lines slice in 3D axes. :param x: (*array_like*) X coordinate array. :param y: (*array_like*) Y coordinate array. :param z: (*array_like*) Z coordinate array. :param u: (*array_like*) U component of the arrow vectors (wind field). :param v: (*array_like*) V component of the arrow vectors (wind field). :param w: (*array_like*) W component of the arrow vectors (wind field). :param xslice: (*list*) X slice locations. :param yslice: (*list*) Y slice locations. :param zslice: (*list*) Z slice locations. :param density: (*int*) Streamline density. Default is 4. :return: Streamline slices """ ls = kwargs.pop('symbolspec', None) cmap = plotutil.getcolormap(**kwargs) density = kwargs.pop('density', 4) iscolor = False cdata = None if len(args) < 6: u = args[0] v = args[1] w = args[2] u = np.asarray(u) nz, ny, nx = u.shape x = np.arange(nx) y = np.arange(ny) z = np.arange(nz) args = args[3:] else: x = args[0] y = args[1] z = args[2] u = args[3] v = args[4] w = args[5] args = args[6:] if len(args) > 0: cdata = args[0] iscolor = True args = args[1:] x = plotutil.getplotdata(x) y = plotutil.getplotdata(y) z = plotutil.getplotdata(z) u = plotutil.getplotdata(u) v = plotutil.getplotdata(v) w = plotutil.getplotdata(w) if ls is None: if iscolor: if len(args) > 0: cn = args[0] ls = LegendManage.createLegendScheme( cdata.min(), cdata.max(), cn, cmap) else: levs = kwargs.pop('levs', None) if levs is None: ls = LegendManage.createLegendScheme( cdata.min(), cdata.max(), cmap) else: if isinstance(levs, NDArray): levs = levs.tolist() ls = LegendManage.createLegendScheme( cdata.min(), cdata.max(), levs, cmap) else: if cmap.getColorCount() == 1: c = cmap.getColor(0) else: c = Color.black ls = LegendManage.createSingleSymbolLegendScheme( ShapeTypes.Polyline, c, 1) ls = plotutil.setlegendscheme_line(ls, **kwargs) if not kwargs.has_key('headwidth'): kwargs['headwidth'] = 1 if not kwargs.has_key('headlength'): kwargs['headlength'] = 2.5 for i in range(ls.getBreakNum()): lb = plotutil.line2stream(ls.getLegendBreak(i), **kwargs) ls.setLegendBreak(i, lb) if not cdata is None: cdata = plotutil.getplotdata(cdata) min_points = kwargs.pop('min_points', 3) zslice_index = kwargs.pop('zslice_index', None) if zslice_index is None: xslice = kwargs.pop('xslice', []) if isinstance(xslice, numbers.Number): xslice = [xslice] yslice = kwargs.pop('yslice', []) if isinstance(yslice, numbers.Number): yslice = [yslice] zslice = kwargs.pop('zslice', []) if isinstance(zslice, numbers.Number): zslice = [zslice] graphics = GraphicFactory.streamSlice(x, y, z, u, v, w, cdata, xslice, yslice, zslice, density, ls) else: if isinstance(zslice_index, int): zslice_index = [zslice_index] graphics = GraphicFactory.streamSlice(x, y, z, u, v, w, cdata, zslice_index, density, ls) lighting = kwargs.pop('lighting', None) if not lighting is None: for gg in graphics: gg.setUsingLight(lighting) visible = kwargs.pop('visible', True) if visible: for gg in graphics: self.add_graphic(gg) return graphics
def run_transform(year, month, dir_inter, model_grid, out_species, out_species_aer): """ Distribution of particulate matter and change unit. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) The directory where data is stored. :param model_grid: (*GridDesc*) Model data grid describe. :param out_species: (*list*) The name of the output species(gases and aerosol). :param out_species_aer: (*list*) The name of the output species(aerosol). """ print('Add input file...') fn_in = dir_inter + '\emis_{}_{}_hour.nc'.format(year, month) f_in = dataset.addfile(fn_in) #Set example data rdata = f_in[f_in.varnames()[4]][:, :, :] rdata[rdata != np.nan] = 0. #Set dimension print('Define dimensions and global attributes...') tdim = np.dimension(np.arange(24), 'Time') ydim = np.dimension(model_grid.y_coord, 'south_north', 'Y') xdim = np.dimension(model_grid.x_coord, 'west_east', 'X') dims = [tdim, ydim, xdim] gattrs = OrderedDict() gattrs['Conventions'] = 'CF-1.6' gattrs['Tools'] = 'Created using MeteoInfo' #Set the definition of the output variable and ncfile fn_out = dir_inter + '\emis_{}_{}_hour_transform.nc'.format(year, month) print('Define variables...') dimvars = [] for out_specie in out_species: dimvar = dataset.DimVariable() dimvar.name = out_specie dimvar.dtype = np.dtype.float dimvar.dims = dims dimvar.addattr('FieldType', '104') dimvar.addattr('MemoryOrder', "XYZ") dimvar.addattr('description', "EMISSION_{}".format(out_specie[2:])) if out_specie in out_species_aer: #g/m2/s to ug/m^3 m/s dimvar.addattr('units', 'ug/m3 m/s') else: #mole/m2/s to mol/km^2/hr dimvar.addattr('units', 'mol km^-2 hr^-1') dimvar.addattr('stagger', "") dimvar.addattr('coordinates', "XLONG XLAT XTIME") #dimvar.addattr('_ChunkSizes', '1U, 3U, 137U, 167U') dimvars.append(dimvar) ncfile = dataset.addfile(fn_out, 'c', largefile=True) ncfile.nc_define(dims, gattrs, dimvars) #add data to ncfile print('Process data and write to file...') for name in out_species: data = None sname = name[2:] print(sname) if sname in f_in.varnames(): data = f_in[sname][:, :, :] data = data * 3600 * 1e6 ncfile.write(name, data) elif sname == 'PM25I': data = f_in['PMFINE'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.2) elif sname == 'PM25J': data = f_in['PMFINE'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.8) elif sname == 'PM_10': data = f_in['PMC'][:, :, :] data = data * 1e6 ncfile.write(name, data) elif sname == 'ECI': data = f_in['PEC'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.2) elif sname == 'ECJ': data = f_in['PEC'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.8) elif sname == 'ORGI': data = f_in['POA'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.2) elif sname == 'ORGJ': data = f_in['POA'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.8) elif sname == 'SO4I': data = f_in['PSO4'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.2) elif sname == 'SO4J': data = f_in['PSO4'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.8) elif sname == 'NO3I': data = f_in['PNO3'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.2) elif sname == 'NO3J': data = f_in['PNO3'][:, :, :] data = data * 1e6 ncfile.write(name, data * 0.8) else: ncfile.write(name, rdata) ncfile.close() print('Distribution of particulate matter and change unit finised!')
def imshow(self, *args, **kwargs): """ Display an image on the 3D axes. :param x: (*array_like*) Optional. X coordinate array. :param y: (*array_like*) Optional. Y coordinate array. :param z: (*array_like*) 2-D or 3-D (RGB) z value array. :param levs: (*array_like*) Optional. A list of floating point numbers indicating the level curves to draw, in increasing order. :param cmap: (*string*) Color map string. :param colors: (*list*) If None (default), the colormap specified by cmap will be used. If a string, like ‘r’ or ‘red’, all levels will be plotted in this color. If a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. :returns: (*RasterLayer*) RasterLayer created from array data. """ n = len(args) cmap = plotutil.getcolormap(**kwargs) fill_value = kwargs.pop('fill_value', -9999.0) xaxistype = None isrgb = False if n <= 2: if isinstance(args[0], (list, tuple)): isrgb = True rgbdata = args[0] if isinstance(rgbdata[0], NDArray): x = np.arange(0, rgbdata[0].shape[1]) y = np.arange(0, rgbdata[0].shape[0]) else: x = rgbdata[0].dimvalue(1) y = rgbdata[0].dimvalue(0) elif args[0].ndim > 2: isrgb = True rgbdata = args[0] if isinstance(rgbdata, NDArray): x = np.arange(0, rgbdata.shape[1]) y = np.arange(0, rgbdata.shape[0]) else: x = rgbdata.dimvalue(1) y = rgbdata.dimvalue(0) else: gdata = np.asgridarray(args[0]) if isinstance(args[0], DimArray): if args[0].islondim(1): xaxistype = 'lon' elif args[0].islatdim(1): xaxistype = 'lat' elif args[0].istimedim(1): xaxistype = 'time' args = args[1:] elif n <= 4: x = args[0] y = args[1] a = args[2] if isinstance(a, (list, tuple)): isrgb = True rgbdata = a elif a.ndim > 2: isrgb = True rgbdata = a else: gdata = np.asgridarray(a, x, y, fill_value) args = args[3:] offset = kwargs.pop('offset', 0) zdir = kwargs.pop('zdir', 'z') interpolation = kwargs.pop('interpolation', None) if isrgb: if isinstance(rgbdata, (list, tuple)): rgbd = [] for d in rgbdata: rgbd.append(d.asarray()) rgbdata = rgbd else: rgbdata = rgbdata.asarray() x = plotutil.getplotdata(x) y = plotutil.getplotdata(y) graphics = GraphicFactory.createImage(x, y, rgbdata, offset, zdir, interpolation) ls = None else: if len(args) > 0: level_arg = args[0] if isinstance(level_arg, int): cn = level_arg ls = LegendManage.createImageLegend(gdata, cn, cmap) else: if isinstance(level_arg, NDArray): level_arg = level_arg.aslist() ls = LegendManage.createImageLegend(gdata, level_arg, cmap) else: ls = plotutil.getlegendscheme(args, gdata.min(), gdata.max(), **kwargs) ls = ls.convertTo(ShapeTypes.Image) plotutil.setlegendscheme(ls, **kwargs) if zdir == 'xy': sepoint = kwargs.pop('sepoint', [0, 0, 1, 1]) else: sepoint = None graphics = GraphicFactory.createImage(gdata, ls, offset, zdir, sepoint, interpolation) visible = kwargs.pop('visible', True) if visible: self.add_graphic(graphics) return graphics
def run(year, month, dir_inter, emission, model_grid): """ Process emission data by spatial allocation, temporal allocation and chemical speciation except VOC pollution. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) Data output path. :param emission: (*module*) Emission module. :param model_grid: (*GridDesc*) Model data grid describe. """ #Set profile files temp_profile_fn = os.path.join(ge_data_dir, 'amptpro.m3.default.us+can.txt') temp_ref_fn = os.path.join(ge_data_dir, 'amptref.m3.us+can.cair.txt') spec_profile_fn = os.path.join(ge_data_dir, 'gspro.cmaq.radm2p25_rev.txt') spec_ref_fn = os.path.join(ge_data_dir, 'gsref.cmaq.radm2p25.txt') #Set data dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Set sectors and pollutants sectors = [SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, \ SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT, SectorEnum.SHIPS, \ SectorEnum.AIR] pollutants = [PollutantEnum.BC, PollutantEnum.CH4, PollutantEnum.CO, \ PollutantEnum.NH3, PollutantEnum.NOx, PollutantEnum.OC, PollutantEnum.PM2_5, \ PollutantEnum.SO2, PollutantEnum.PM10] out_species = [SpeciesEnum.PEC, SpeciesEnum.CH4, SpeciesEnum.CO, SpeciesEnum.NH3, \ None, SpeciesEnum.POA, None, SpeciesEnum.SO2, SpeciesEnum.PMC] #Read Mongolia shape and mask data lmongolia = geolib.shaperead('mongolia.shp') #Loop for sector in sectors: print('####################################') print(sector) print('####################################') #Get SCC scc = emis_util.get_scc(sector) #Get pollutant profiles pollutant_profiles = emips.chem_spec.read_file(spec_ref_fn, spec_profile_fn, scc) for pollutant, out_spec in zip(pollutants, out_species): print(pollutant) print('Read emission data (kg/m2/s)...') emis_data = emission.read_emis(sector, pollutant, year, month) if emis_data is None: #No emission of a pollutant for some sectors continue #### Decrease PM2.5 emission of Energy sector in Mongolia if sector == SectorEnum.ENERGY and pollutant == PollutantEnum.PM2_5: mdata = emis_data.maskout(lmongolia.shapes()) mdata[mdata != np.nan] = 0.05 mdata[mdata == np.nan] = 1 emis_data = emis_data * mdata #### Spatial allocation print('Spatial allocation of emission grid to model grid...') emis_data = transform(emis_data, emission.emis_grid, model_grid) #### Temporal allocation print('Temporal allocation...') month_profile, week_profile, diurnal_profile, diurnal_profile_we = \ emips.temp_alloc.read_file(temp_ref_fn, temp_profile_fn, scc) if pollutant == PollutantEnum.CH4 or sector == SectorEnum.AIR or \ sector == SectorEnum.SHIPS: print('To (kg/m2/year)') emis_data = emis_data * 3600 * 24 * emis_util.get_year_days( year) print('To monthly emission (kg/m2/month)...') emis_data = emips.temp_alloc.month_allocation( emis_data, month_profile) emis_data = emis_data[month - 1] else: print('To (kg/m2/month)') emis_data = emis_data * 3600 * 24 * emis_util.get_month_days( year, month) print('To daily emission (kg/m2/day)...') weekday_data, weekend_data = emips.temp_alloc.week_allocation( emis_data, week_profile, year, month) print('To hourly emission (g/m2/s)...') hour_data = emips.temp_alloc.diurnal_allocation( weekday_data, diurnal_profile) / 3.6 #### Chemical speciation poll_prof = emips.chem_spec.get_pollutant_profile( pollutant_profiles, pollutant) if (pollutant == PollutantEnum.NOx) and (poll_prof is None): poll_prof = PollutantProfile(pollutant) poll_prof.append( SpeciesProfile(pollutant, SpeciesEnum.NO, 0.9, 1.0, 0.9)) poll_prof.append( SpeciesProfile(pollutant, SpeciesEnum.NO2, 0.1, 1.0, 0.1)) #### Set output netcdf file path outfn = os.path.join(dir_inter, \ '{}_emis_{}_{}_{}_hour.nc'.format(pollutant.name, sector.name, year, month)) print outfn if poll_prof is None: #### Save hourly emission data print('Save hourly emission data...') if out_spec.molar_mass is None: attrs = dict(units='g/m2/s') else: attrs = dict(units='mole/m2/s') hour_data = hour_data / out_spec.molar_mass dataset.ncwrite(outfn, hour_data, out_spec.name, dims, attrs) else: print('Chemical speciation...') specs = poll_prof.get_species() gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') dimvars = [] for spec in specs: dimvar = dataset.DimVariable() dimvar.name = spec.name dimvar.dtype = np.dtype.float dimvar.dims = dims if spec.molar_mass is None: dimvar.addattr('units', 'g/m2/s') else: dimvar.addattr('units', 'mole/m2/s') dimvars.append(dimvar) ncfile = dataset.addfile(outfn, 'c') ncfile.nc_define(dims, gattrs, dimvars) for spec_prof, dimvar, spec in zip(poll_prof.species_profiles, dimvars, specs): print(dimvar.name) if spec.molar_mass is None: spec_data = hour_data * spec_prof.mass_fraction else: spec_data = hour_data * spec_prof.mass_fraction / spec.molar_mass ncfile.write(dimvar.name, spec_data) ncfile.close()
def ncwrite(fn, data, varname, dims=None, attrs=None, gattrs=None, largefile=False): """ Write a netCDF data file from an array. :param: fn: (*string*) netCDF data file path. :param data: (*array_like*) A numeric array variable of any dimensionality. :param varname: (*string*) Variable name. :param dims: (*list of dimensions*) Dimension list. :param attrs: (*dict*) Variable attributes. :param gattrs: (*dict*) Global attributes. :param largefile: (*boolean*) Create netCDF as large file or not. """ if dims is None: if isinstance(data, DimArray): dims = data.dims else: dims = [] for s in data.shape: dimvalue = np.arange(s) dimname = 'dim' + str(len(dims)) dims.append(dimension(dimvalue, dimname)) #New netCDF file ncfile = addfile(fn, 'c', largefile=largefile) #Add dimensions ncdims = [] for dim in dims: ncdims.append(ncfile.adddim(dim.getShortName(), dim.getLength())) #Add global attributes ncfile.addgroupattr('Conventions', 'CF-1.6') ncfile.addgroupattr('Tools', 'Created using MeteoInfo') if not gattrs is None: for key in gattrs: ncfile.addgroupattr(key, gattrs[key]) #Add dimension variables dimvars = [] wdims = [] for dim,midim in zip(ncdims,dims): dimtype = midim.getDimType() dimname = dim.getShortName() if dimtype == DimensionType.T: var = ncfile.addvar(dimname, 'int', [dim]) var.addattr('units', 'hours since 1900-01-01 00:00:0.0') var.addattr('long_name', 'Time') var.addattr('standard_name', 'time') var.addattr('axis', 'T') tvar = var elif dimtype == DimensionType.Z: var = ncfile.addvar(dimname, 'float', [dim]) var.addattr('axis', 'Z') elif dimtype == DimensionType.Y: var = ncfile.addvar(dimname, 'float', [dim]) var.addattr('axis', 'Y') elif dimtype == DimensionType.X: var = ncfile.addvar(dimname, 'float', [dim]) var.addattr('axis', 'X') else: var = None if not var is None: dimvars.append(var) wdims.append(midim) #Add variable var = ncfile.addvar(varname, data.dtype, ncdims) if attrs is None: var.addattr('name', varname) else: for key in attrs: var.addattr(key, attrs[key]) #Create netCDF file ncfile.create() #Write variable data for dimvar, dim in zip(dimvars, wdims): if dim.getDimType() == DimensionType.T: sst = datetime.datetime(1900,1,1) tt = miutil.nums2dates(dim.getDimValue()) hours = [] for t in tt: hours.append((t - sst).total_seconds() // 3600) ncfile.write(dimvar, np.array(hours)) else: ncfile.write(dimvar, np.array(dim.getDimValue())) ncfile.write(var, data) #Close netCDF file ncfile.close()
def run_merge(year, month, dir_inter, model_grid, sectors): """ Combine all sectors into one file :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) The directory where data is stored. :param model_grid: (*GridDesc*) Model data grid describe. :param sectors: (*list*) Sectors that needs to be merged. """ #Set the definition of the output variable print('Define variables...') dimvars = [] dict_spec = {} for sector in sectors: fn = dir_inter + '\emis_{}_{}_{}_hour.nc'.format(sector, year, month) if os.path.exists(fn): f = dataset.addfile(fn) for var in f.variables(): if var.ndim == 3: if dict_spec.has_key(var.name): dict_spec[var.name].append(fn) else: dimvars.append(var) dict_spec[var.name] = [fn] f.close() else: print('File not exist: {}'.format(fn)) continue #Set dimension and define ncfile print('Define dimension and global attributes...') tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] out_fn = dir_inter + '\emis_{}_{}_hour.nc'.format(year, month) gattrs = OrderedDict() gattrs['Conventions'] = 'CF-1.6' gattrs['Tools'] = 'Created using MeteoInfo' print('Create output data file...') ncfile = dataset.addfile(out_fn, 'c', largefile=True) ncfile.nc_define(dims, gattrs, dimvars) #read, merge and output print('Write variable data...') for sname, fns in dict_spec.iteritems(): print(sname) spec_data = None dd = None for fn in fns: f = dataset.addfile(fn) dd = f[sname][:] #turn nan to zero dd[dd == np.nan] = 0 if spec_data is None: spec_data = dd else: spec_data = spec_data + dd f.close() ncfile.write(sname, spec_data) ncfile.close() print('Merge sector data finished!')
def run(year, month, dir_inter, chem_mech, model_grid): """ Lump VOC species according chemical mechanism. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) Data input and output path. :param chem_mech: (*ChemicalMechanism*) Chemical mechanism. :param model_grid: (*GridDesc*) Model data grid describe. """ #Set sectors and pollutants sectors = [SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT] pollutant = PollutantEnum.NMVOC #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Sector loop for sector in sectors: print('####################################') print(sector) print('####################################') #Set input file infn = os.path.join(dir_inter, \ '{}_emis_{}_{}_{}_hour.nc'.format(pollutant.name, sector.name, year, month)) print('Input file: {}'.format(infn)) #Open input file inf = dataset.addfile(infn) #Read a reference data vname = inf.varnames()[4] rdata = inf[vname][:] rdata[rdata!=np.nan] = 0. #Set output file outfn = os.path.join(dir_inter, \ '{}_emis_lump_{}_{}_{}_hour.nc'.format(pollutant.name, sector.name, year, month)) print('Output file: {}'.format(outfn)) #Create output netcdf file ncfile = dataset.addfile(outfn, 'c') #Set global attribute gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') #Set variables dimvars = [] for spec in chem_mech.nmvoc_species(): dimvar = dataset.DimVariable() dimvar.name = spec.name dimvar.dtype = np.dtype.float dimvar.dims = dims #dimvar.addattr('units', 'mol/m2/s') if spec.molar_mass is None: dimvar.addattr('units', 'g/m2/s') else: dimvar.addattr('units', 'mole/m2/s') dimvars.append(dimvar) #Define dimensions, global attributes and variables ncfile.nc_define(dims, gattrs, dimvars) #Write variable values for spec, dimvar in zip(chem_mech.nmvoc_species(), dimvars): print('{} species: {}'.format(chem_mech.name, spec)) rspecs = chem_mech.lump_RETRO(spec) print('RETRO species: {}'.format(rspecs)) data = None for rspec, ratio in rspecs.iteritems(): if rspec.name in inf.varnames(): if data is None: data = inf[rspec.name][:] * ratio else: data = data + inf[rspec.name][:] * ratio if data is None: print('No RETRO species!') ncfile.write(dimvar.name, rdata) else: if spec.molar_mass is not None: print('Convert (g/m2/s) to (mole/m2/s)') data = data / spec.molar_mass ncfile.write(dimvar.name, data) #Close output netcdf file ncfile.close()
def run(year, month, dir_inter): """ Merge all pollutant emission files in one file for each sector. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) Data input and output path. """ #Set sectors and pollutants sectors = [SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, \ SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT, SectorEnum.SHIPS, \ SectorEnum.AIR] pollutants = [PollutantEnum.BC, PollutantEnum.CH4, PollutantEnum.CO, \ PollutantEnum.NH3, PollutantEnum.NOx, PollutantEnum.OC, PollutantEnum.PM2_5, \ PollutantEnum.SO2, PollutantEnum.PM10, PollutantEnum.NMVOC] #Set model grids proj = geolib.projinfo() model_grid = GridDesc(proj, x_orig=70., x_cell=0.15, x_num=502, y_orig=15., y_cell=0.15, y_num=330) #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Sector loop for sector in sectors: print('Sector: {}'.format(sector)) #Set output sector emission file name outfn = os.path.join(dir_inter, \ 'emis_{}_{}_{}_hour.nc'.format(sector, year, month)) print('Sector emission file: {}'.format(outfn)) #Pollutant loop dimvars = [] dict_spec = {} for pollutant in pollutants: #Read data in pollutant file if pollutant == PollutantEnum.NMVOC: fn = os.path.join(dir_inter, \ '{}_emis_lump_{}_{}_{}_hour.nc'.format(pollutant.name, \ sector.name, year, month)) else: fn = os.path.join(dir_inter, \ '{}_emis_{}_{}_{}_hour.nc'.format(pollutant.name, \ sector.name, year, month)) if not os.path.exists(fn): #No emission data print('\tAlarm! The file not exists: {}'.format(fn)) continue print('\t{}'.format(fn)) f = dataset.addfile(fn) for var in f.variables(): if var.ndim == 3: if dict_spec.has_key(var.name): dict_spec[var.name].append(fn) else: dimvars.append(var) dict_spec[var.name] = [fn] #Create output merged netcdf data file gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') ncfile = dataset.addfile(outfn, 'c') ncfile.nc_define(dims, gattrs, dimvars) for sname, fns in dict_spec.iteritems(): spec_data = None for fn in fns: f = dataset.addfile(fn) if spec_data is None: spec_data = f[sname][:] else: spec_data = spec_data + f[sname][:] ncfile.write(sname, spec_data) ncfile.close()
def run(year, month, dir_inter, emission, model_grid): """ Process VOC emission data by spatial allocation, temporal allocation and chemical speciation. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) Data output path. :param emission: (*module*) Emission module. :param model_grid: (*GridDesc*) Model data grid describe. """ #Set profile files temp_profile_fn = os.path.join(ge_data_dir, 'amptpro.m3.default.us+can.txt') temp_ref_fn = os.path.join(ge_data_dir, 'amptref.m3.us+can.cair.txt') #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Set sectors and pollutants sectors = [ SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT ] fn_sectors = ['inc', 'agr', 'pow', 'res', 'tra'] pollutant = PollutantEnum.NMVOC pollutant.units = Units(Weight.MG, Area.GRID, Period.MONTH) #Loop for sector, fn_sector in zip(sectors, fn_sectors): print('####################################') print(sector) print('####################################') #Get SCC scc = emis_util.get_scc(sector) print('Read emission data...') emis_data = emission.read_emis(sector, pollutant, month) #### Spatial allocation print( 'Convert emission data untis from Mg/grid/month to g/m2/month...') emis_data = emis_data * 1e6 / emission.grid_areas print('Spatial allocation of emission grid to model grid...') emis_data = transform(emis_data, emission.emis_grid, model_grid) #### Temporal allocation print('Temporal allocation...') month_profile, week_profile, diurnal_profile, diurnal_profile_we = \ emips.temp_alloc.read_file(temp_ref_fn, temp_profile_fn, scc) print('To daily emission (g/m2/day)...') weekday_data, weekend_data = emips.temp_alloc.week_allocation( emis_data, week_profile, year, month) print('To hourly emission (g/m2/s)...') hour_data = emips.temp_alloc.diurnal_allocation( weekday_data, diurnal_profile) / 3600 #### Chemical speciation print('Chemical speciation...') outfn = os.path.join(dir_inter, \ '{}_emis_{}_{}_{}_hour.nc'.format(pollutant.name, sector, year, month)) print('Output file: {}'.format(outfn)) print('Set grid speciation data...') fn = r'Z:\chen\MEIC_data\Grid_speciation_data(VOC)\retro_nmvoc_ratio_{}_2000_0.1deg.nc'.format( fn_sector) print('Grid speciation file: {}'.format(fn)) f = dataset.addfile(fn) #Create output netcdf file and define dimensions, global attributes and variables gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') dimvars = [] for var in f.variables(): if var.ndim == 2: dimvar = dataset.DimVariable() dimvar.name = var.name dimvar.dtype = np.dtype.float dimvar.dims = dims dimvar.addattr('units', 'g/m2/s') dimvars.append(dimvar) ncfile = dataset.addfile(outfn, 'c') ncfile.nc_define(dims, gattrs, dimvars) #Write variable values ratio_grid = GridDesc(x_orig=0.05, x_cell=0.1, x_num=3600, y_orig=-89.95, y_cell=0.1, y_num=1800) for dimvar in dimvars: print(dimvar.name) rdata = f[dimvar.name][:] rdata = transform(rdata, ratio_grid, model_grid) spec_data = hour_data * rdata ncfile.write(dimvar.name, spec_data) #Close output netcdf file ncfile.close()
def run_merge(year, month, dir_inter, model_grid, sectors, z): """ Combine all sectors into one file :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) The directory where data is stored. :param model_grid: (*GridDesc*) Model data grid describe. :param sectors: (*list*) Sectors that needs to be merged. :param z: (*int*) The zdim of the output data. """ print('Define dimension and global attributes...') tdim = np.dimension(np.arange(24), 'hour') zdim = np.dimension(np.arange(z), 'emissions_zdim') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, zdim, ydim, xdim] #Set the definition of the output variable print('Define variables...') dimvars = [] dict_spec = {} print('Add files...') for sector in sectors: fn = dir_inter + '\emis_{}_{}_{}_hour_height.nc'.format(sector, year, month) if os.path.exists(fn): print(fn) f = dataset.addfile(fn) for var in f.variables(): if var.ndim == 4: if dict_spec.has_key(var.name): dict_spec[var.name].append(fn) else: dict_spec[var.name] = [fn] for var in f.varnames(): if var == 'lat' or var == 'lon': continue else: dimvar = dataset.DimVariable() dimvar.name = var dimvar.dtype = np.dtype.float dimvar.dims = dims dimvar.addattr('description', "EMISSION_{}".format(var)) if var in out_species_aer: dimvar.addattr('units', 'g/m2/s') else: dimvar.addattr('units', 'mole/m2/s') dimvars.append(dimvar) f.close() else: print('File not exist: {}'.format(fn)) continue #Set dimension and define ncfile out_fn = dir_inter + '\emis_{}_{}_hour.nc'.format(year, month) gattrs = OrderedDict() gattrs['Conventions'] = 'CF-1.6' gattrs['Tools'] = 'Created using MeteoInfo' print('Create output data file...') ncfile = dataset.addfile(out_fn, 'c', largefile=True) ncfile.nc_define(dims, gattrs, dimvars) #read, merge and output print('Write variables data...') for sname, fns in dict_spec.iteritems(): print(sname) spec_data = np.zeros((tdim.length, z, ydim.length, xdim.length)) dd = np.zeros((tdim.length, z, ydim.length, xdim.length)) for fn in fns: f = dataset.addfile(fn) dd = f[sname][:] #turn nan to zero dd[dd==np.nan] = 0.0 if spec_data.sum() == 0.0: spec_data = dd else: spec_data = spec_data + dd f.close() ncfile.write(sname, spec_data) ncfile.close() print('Merge data finished!')
def run(year, month, dir_inter, model_grid): """ Merge all pollutant emission files in one file for each sector. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) Data input and output path. :param model_grid: (*GridDesc*) Model data grid describe. """ #Set sectors and pollutants sectors = [ SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT ] pollutants = [PollutantEnum.BC, PollutantEnum.CO, PollutantEnum.NH3, \ PollutantEnum.NOx, PollutantEnum.OC, PollutantEnum.PM2_5, \ PollutantEnum.SO2, PollutantEnum.PMcoarse, PollutantEnum.PM10more, \ PollutantEnum.NMVOC] #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Sector loop for sector in sectors: print('Sector: {}'.format(sector)) #Set output sector emission file name outfn = os.path.join(dir_inter, \ 'emis_{}_{}_{}_hour.nc'.format(sector.name, year, month)) print('Sector emission file: {}'.format(outfn)) #Pollutant loop dimvars = [] dict_spec = {} for pollutant in pollutants: #Read data in pollutant file if pollutant == PollutantEnum.NMVOC: fn = os.path.join(dir_inter, \ '{}_emis_lump_{}_{}_{}_hour.nc'.format(pollutant.name, \ sector.name, year, month)) else: fn = os.path.join(dir_inter, \ '{}_emis_{}_{}_{}_hour.nc'.format(pollutant.name, \ sector.name, year, month)) print('\t{}'.format(fn)) #Determine whether the PM10more file exists if os.path.exists(fn): f = dataset.addfile(fn) else: print('File not exist: {}'.format(fn)) continue for var in f.variables(): if var.ndim == 3: if dict_spec.has_key(var.name): dict_spec[var.name].append(fn) else: dimvars.append(var) dict_spec[var.name] = [fn] #Create output merged netcdf data file gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') ncfile = dataset.addfile(outfn, 'c', largefile=True) ncfile.nc_define(dims, gattrs, dimvars) for sname, fns in dict_spec.iteritems(): spec_data = None for fn in fns: f = dataset.addfile(fn) if spec_data is None: spec_data = f[sname][:] else: spec_data = spec_data + f[sname][:] ncfile.write(sname, spec_data) ncfile.close()
def run_allocate(year, month, dir_inter, model_grid, sectors, z): """ Assign data to different heights. If not specified, data is allocated to the first layer. :param year: (*int*) Year. :param month: (*int*) Month. :param dir_inter: (*string*) The directory where data is stored. :param model_grid: (*GridDesc*) Model data grid describe. :param sectors: (*GridDesc*) The sectors need to be processed. :param z: (*int*) The zdim of the output data. """ print('Define dimension and global attributes...') tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') zdim = np.dimension(np.arange(z), 'emissions_zdim') dims = [tdim, zdim, ydim, xdim] gattrs = OrderedDict() gattrs['Conventions'] = 'CF-1.6' gattrs['Tools'] = 'Created using MeteoInfo' for sector in sectors: fn = dir_inter + '\emis_{}_{}_{}_hour.nc'.format(sector, year, month) print('File input: {}'.format(fn)) dimvars = [] if os.path.exists(fn): f = dataset.addfile(fn) for var in f.varnames(): if var == 'lat' or var == 'lon': continue else: dimvar = dataset.DimVariable() dimvar.name = var dimvar.dtype = np.dtype.float dimvar.dims = dims dimvar.addattr('description', "EMISSION_{}".format(var)) if var in out_species_unit: dimvar.addattr('units', 'g/m2/s') else: dimvar.addattr('units', 'mole/m2/s') dimvars.append(dimvar) print('Create output data file...') out_fn = dir_inter + '\emis_{}_{}_{}_hour_height.nc'.format( sector, year, month) ncfile = dataset.addfile(out_fn, 'c', largefile=True) ncfile.nc_define(dims, gattrs, dimvars) data = np.zeros((tdim.length, z, ydim.length, xdim.length)) dd = np.zeros((tdim.length, z, ydim.length, xdim.length)) #read, merge and output if sector in sectors_al: print('Allocating: {}'.format(sector)) else: print('Do not need to be allocated: {}'.format(sector)) print('Write data to file...') for var in f.varnames(): if var == 'lat' or var == 'lon': continue else: print(var) dd[:, 0, :, :] = f[var][:] if sector in sectors_al: if sector == 'energy': data[:, 1, :, :] = dd[:, 0, :, :] * 0.1 data[:, 2, :, :] = dd[:, 0, :, :] * 0.1 data[:, 3, :, :] = dd[:, 0, :, :] * 0.3 data[:, 4, :, :] = dd[:, 0, :, :] * 0.2 data[:, 5, :, :] = dd[:, 0, :, :] * 0.2 data[:, 6, :, :] = dd[:, 0, :, :] * 0.1 if sector == 'industry': data[:, 0, :, :] = dd[:, 0, :, :] * 0.5 data[:, 1, :, :] = dd[:, 0, :, :] * 0.3 data[:, 2, :, :] = dd[:, 0, :, :] * 0.2 else: data[:, 0, :, :] = dd[:, 0, :, :] #Turn nan to zero data[data == np.nan] = 0 ###test### ''' if sector == 'energy': data[:, 0, :, :] = 0 ''' ###test### ncfile.write(var, data) ncfile.close() f.close() else: print('File not exist: {}'.format(fn)) continue print('Allocate of height finished!')
def run_proj(year, month, dir_inter, model_grid, target_grid): print('Add input file...') fn_in = dir_inter + '\emis_{}_{}_hour_transform.nc'.format(year, month) print(fn_in) f_in = dataset.addfile(fn_in) #set dimension tdim = np.dimension(np.arange(24), 'Time') ydim = np.dimension(target_grid.y_coord, 'south_north', 'Y') xdim = np.dimension(target_grid.x_coord, 'west_east', 'X') zdim = np.dimension(np.arange(3), 'emissions_zdim') sdim = np.dimension(np.arange(19), 'DateStrLen') dims = [tdim, zdim, ydim, xdim] all_dims = [tdim, sdim, xdim, ydim, zdim] #set global attributes gattrs = OrderedDict() #gattrs['Conventions'] = 'CF-1.6' #gattrs['Tools'] = 'Created using MeteoInfo' gattrs[ 'TITLE'] = ' OUTPUT FROM * PROGRAM:WRF-Chem V4.1.5 MODEL' gattrs['START_DATE'] = "2017-01-01_00:00:00" gattrs['WEST-EAST_GRID_DIMENSION'] = 335 gattrs['SOUTH-NORTH_GRID_DIMENSION'] = 275 gattrs['BOTTOM-TOP_GRID_DIMENSION'] = 28 gattrs['DX'] = 15000.0 gattrs['DY'] = 15000.0 gattrs['AERCU_OPT'] = 0 gattrs['AERCU_FCT'] = 1.0 gattrs['IDEAL_CASE'] = 0 gattrs['DIFF_6TH_SLOPEOPT'] = 0 gattrs['AUTO_LEVELS_OPT'] = 2 gattrs['DIFF_6TH_THRESH'] = 0.1 gattrs['DZBOT'] = 50.0 gattrs['DZSTRETCH_S'] = 1.3 gattrs['DZSTRETCH_U'] = 1.1 gattrs['GRIDTYPE'] = "C" gattrs['DIFF_OPT'] = 1 gattrs['KM_OPT'] = 4 gattrs['DAMP_OPT'] = 3 gattrs['DAMPCOEF'] = 0.2 gattrs['KHDIF'] = 0.0 gattrs['KVDIF'] = 0.0 gattrs['MP_PHYSICS'] = 2 gattrs['RA_LW_PHYSICS'] = 4 gattrs['RA_SW_PHYSICS'] = 4 gattrs['SF_SFCLAY_PHYSICS'] = 2 gattrs['SF_SURFACE_PHYSICS'] = 2 gattrs['BL_PBL_PHYSICS'] = 2 gattrs['CU_PHYSICS'] = 10 gattrs['SF_LAKE_PHYSICS'] = 0 gattrs['SURFACE_INPUT_SOURCE'] = 3 gattrs['SST_UPDATE'] = 0 gattrs['GRID_FDDA'] = 1 gattrs['GFDDA_INTERVAL_M'] = 0 gattrs['GFDDA_END_H'] = 0 gattrs['GRID_SFDDA'] = 0 gattrs['SGFDDA_INTERVAL_M'] = 0 gattrs['SGFDDA_END_H'] = 0 gattrs['HYPSOMETRIC_OPT'] = 2 gattrs['USE_THETA_M'] = 1 gattrs['GWD_OPT'] = 1 gattrs['SF_URBAN_PHYSICS'] = 0 gattrs['SF_SURFACE_MOSAIC'] = 0 gattrs['SF_OCEAN_PHYSICS'] = 0 gattrs['WEST-EAST_PATCH_START_UNSTAG '] = 1 gattrs['WEST-EAST_PATCH_END_UNSTAG'] = 334 gattrs['WEST-EAST_PATCH_START_STAG'] = 1 gattrs['WEST-EAST_PATCH_END_STAG'] = 335 gattrs['SOUTH-NORTH_PATCH_START_UNSTAG'] = 1 gattrs['SOUTH-NORTH_PATCH_END_UNSTAG'] = 274 gattrs['SOUTH-NORTH_PATCH_START_STAG'] = 1 gattrs['SOUTH-NORTH_PATCH_END_STAG'] = 275 gattrs['BOTTOM-TOP_PATCH_START_UNSTAG'] = 1 gattrs['BOTTOM-TOP_PATCH_END_UNSTAG'] = 27 gattrs['BOTTOM-TOP_PATCH_START_STAG'] = 1 gattrs['BOTTOM-TOP_PATCH_END_STAG'] = 28 gattrs['GRID_ID'] = 1 gattrs['PARENT_ID'] = 0 gattrs['I_PARENT_START'] = 1 gattrs['J_PARENT_START'] = 1 gattrs['PARENT_GRID_RATIO'] = 1 gattrs['DT'] = 90.0 gattrs['CEN_LAT'] = 36.500008 gattrs['CEN_LON'] = 103.5 gattrs['TRUELAT1'] = 30.0 gattrs['TRUELAT2'] = 60.0 gattrs['MOAD_CEN_LAT'] = 36.500008 gattrs['STAND_LON'] = 103.5 gattrs['POLE_LAT'] = 90.0 gattrs['POLE_LON'] = 0.0 gattrs['GMT'] = 0.0 gattrs['JULYR'] = 2016 gattrs['JULDAY'] = 365 gattrs['MAP_PROJ'] = 1 gattrs['MAP_PROJ_CHAR'] = 'Lambert Conformal' gattrs['MMINLU'] = 'MODIFIED_IGBP_MODIS_NOAH' gattrs['NUM_LAND_CAT'] = 21 gattrs['ISWATER'] = 17 gattrs['ISLAKE'] = 21 gattrs['ISICE'] = 15 gattrs['ISURBAN'] = 13 gattrs['ISOILWATER'] = 14 gattrs['HYBRID_OPT'] = 2 gattrs['ETAC'] = 0.15 fn_out = dir_inter + '\emis_{}_{}_hour_proj_nc4.nc'.format(year, month) #fn_out = dir_inter + '\emis_{}_{}_hour_proj_chunk.nc'.format(year, month) #set variables dimvars = [] dimvar = dataset.DimVariable() dimvar.name = 'Times' dimvar.dtype = np.dtype.char dimvar.dims = [tdim, sdim] dimvar.addattr('_ChunkSizes', np.array([1, 19], dtype=np.dtype.uint)) #dimvar.addattr('_ChunkSizes', [1, 19]) dimvars.append(dimvar) for out_specie in out_species: dimvar = dataset.DimVariable() dimvar.name = out_specie dimvar.dtype = np.dtype.float dimvar.dims = dims dimvar.addattr('FieldType', 104) dimvar.addattr('MemoryOrder', "XYZ") dimvar.addattr('description', "EMISSION_{}".format(out_specie[2:])) if out_specie in out_species_unit: #g/m2/s to ug/m^3 m/s dimvar.addattr('units', 'ug/m3 m/s') else: #mole/m2/s to mol/km^2/hr dimvar.addattr('units', 'mol km^-2 hr^-1') dimvar.addattr('stagger', "") dimvar.addattr('coordinates', "XLONG XLAT XTIME") dimvar.addattr('_ChunkSizes', array([1, 3, 137, 167], dtype=np.dtype.uint)) #dimvar.addattr('_ChunkSizes', [1, 3, 137, 167]) dimvars.append(dimvar) print('Create output data file...') print(fn_out) ncfile = dataset.addfile(fn_out, 'c', version='netcdf4', largefile=True) #ncfile = dataset.addfile(fn_out, 'c', largefile=True) print('Define dimensions, global attributes and variables...') ncfile.nc_define(all_dims, gattrs, dimvars, write_dimvars=False) #Times print('Write Times variable...') s_out = [] for i in range(24): s = '{}-{:0>2d}-01_{:0>2d}:00:00'.format(year, month, i) s_out.append(s) s_out = np.array(s_out, dtype=np.dtype.char) ncfile.write('Times', s_out) print('Write variable data except times...') for out_specie in out_species: if out_specie in f_in.varnames(): print(out_specie) data = f_in[out_specie][:] #Conversion data = transform(data, model_grid, target_grid) #Set the fourth dimension data = data.reshape(24, 1, 274, 334) #Set default values data[data == np.nan] = 0 ncfile.write(out_specie, data) ncfile.close() print('Conversion projection finished!')
def merge_output(year, months, model_grid, mechanism_name): """ Merge EMIPS output emission data of MEIC CAMS and HTAP data Applicable to the situation that MEIC data are nan outside China, and 0 in Taiwan!!! :param year: (*int*) Year. :param months: (*list*) Months. :param model_grid: (*GridDesc*) Model data grid describe. :param mechanism_name: (*string*) mechanism's name. """ print('-----------------------------------') print('----Merge output data(tw).....-----') print('-----------------------------------') #Set directories dir_meic1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\MEIC', str(year)) dir_cams1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\CAMS', str(year)) dir_htap1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\HTAP\2010') dir_out1 = os.path.join(r'G:\test_data', mechanism_name, r'region_0.15\merge', str(year)) #Set sectors sectors = [SectorEnum.INDUSTRY, SectorEnum.AGRICULTURE, SectorEnum.ENERGY, \ SectorEnum.RESIDENTIAL, SectorEnum.TRANSPORT, SectorEnum.SHIPS, \ SectorEnum.AIR] #Set dimensions tdim = np.dimension(np.arange(24), 'hour') ydim = np.dimension(model_grid.y_coord, 'lat', 'Y') xdim = np.dimension(model_grid.x_coord, 'lon', 'X') dims = [tdim, ydim, xdim] #Add data of taiwan area use CAMS/HTAP data tw = geolib.shaperead('taiwan.shp') for month in months: print('##########') print('Month: {}'.format(month)) print('##########') dir_meic = os.path.join(dir_meic1, '{}{:>02d}'.format(year, month)) dir_cams = os.path.join(dir_cams1, '{}{:>02d}'.format(year, month)) dir_htap = os.path.join(dir_htap1, '{}{:>02d}'.format(2010, month)) dir_out = os.path.join(dir_out1, '{}{:>02d}'.format(year, month)) if not os.path.exists(dir_out): os.mkdir(dir_out) print('------------------Filepath------------------') print('dir_meic: {}\ndir_cams: {}\ndir_htap: {}\ndir_out: {}'.format(dir_meic, dir_cams, dir_htap, dir_out)) #Sector loop for sector in sectors: print('############') print(sector) print('############') #MEIC data file fn_meic = os.path.join(dir_meic, 'emis_{}_{}_{}_hour.nc'.format(sector.name, year, month)) #CAMS data file fn_cams = os.path.join(dir_cams, 'emis_{}_{}_{}_hour.nc'.format(sector.name, year, month)) #HTAP data file fn_htap = os.path.join(dir_htap, 'emis_{}_{}_{}_hour.nc'.format(sector.name, 2010, month)) #Output data file fn_out = os.path.join(dir_out, 'emis_{}_{}_{}_hour.nc'.format(sector.name, year, month)) if os.path.exists(fn_meic) and (not os.path.exists(fn_cams)): shutil.copyfile(fn_meic, fn_out) print('Data from MEIC...') elif os.path.exists(fn_cams) and (not os.path.exists(fn_meic)): shutil.copyfile(fn_cams, fn_out) print('Data from CAMS...') else: f_meic = addfile(fn_meic) f_cams = addfile(fn_cams) f_htap = addfile(fn_htap) #Create output netcdf file ncfile = addfile(fn_out, 'c', largefile=True) #Set global attribute gattrs = dict(Conventions='CF-1.6', Tools='Created using MeteoInfo') #Get all variable dimvars = [] varnames = [] for var in f_meic.variables(): if var.ndim == 3: varnames.append(var.name) dimvar = DimVariable() dimvar.name = var.name dimvar.dtype = var.dtype dimvar.dims = dims dimvar.attributes = var.attributes dimvars.append(dimvar) for var in f_htap.variables(): if var.ndim == 3 and (not var.name in varnames): varnames.append(var.name) dimvar = DimVariable() dimvar.dtype = var.dtype dimvar.name = var.name dimvar.dims = dims dimvar.attributes = var.attributes dimvars.append(dimvar) #Define dimensions, global attributes and variables ncfile.nc_define(dims, gattrs, dimvars) #Write variable values for varname in varnames: print('\t{}'.format(varname)) data = None tda = np.zeros((24, len(model_grid.y_coord), len(model_grid.x_coord))) if varname in f_meic.varnames(): data = f_meic[varname][:] if varname in f_cams.varnames(): data1 = f_cams[varname][:] for i in range(24): tda[i] = data1[i].maskout(tw.shapes()) tda[tda==np.nan] = 0 if data is None: data = data1 else: mask = data.copy() mask[mask!=np.nan] = 0 mask[mask==np.nan] = 1 data[data==np.nan] = 0 data = data1 * mask + data data = data + tda elif varname in f_htap.varnames(): data1 = f_htap[varname][:] for i in range(24): tda[i] = data1[i].maskout(tw.shapes()) tda[tda==np.nan] = 0 if data is None: data = data1 else: mask = data.copy() mask[mask!=np.nan] = 0 mask[mask==np.nan] = 1 data[data==np.nan] = 0 data = data1 * mask + data data = data + tda ncfile.write(varname, data) #Close file f_meic.close() f_cams.close() f_htap.close() ncfile.close() print('---------------------------------------') print('-----Merge output data completed!------') print('---------------------------------------')