Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
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('############')
Exemple #4
0
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!')
Exemple #5
0
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()
Exemple #6
0
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
Exemple #7
0
    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
Exemple #8
0
    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
Exemple #9
0
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!')
Exemple #10
0
    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
Exemple #11
0
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()
Exemple #12
0
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()
Exemple #13
0
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!')
Exemple #14
0
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()
Exemple #15
0
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()
Exemple #16
0
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()
Exemple #17
0
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!')
Exemple #18
0
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()
Exemple #19
0
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!')
Exemple #20
0
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!')
Exemple #21
0
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('---------------------------------------')