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 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 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_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 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()