def get_timestep_ipw(tstep, input_list, ppt_list, myawsm): """ Pull out a time step from the forcing files (IPW) and place that time step into a dict Args: tstep: datetime of timestep input_list: numpy array (1D) of integer timesteps given ppt_list: numpy array(1D) of integer timesteps for ppt_list myawsm: AWSM instance for current run Returns: inpt: dictionary of forcing variable images """ inpt = {} # map function from these values to the ones requried by snobal map_val = {1: 'T_a', 5: 'S_n', 0: 'I_lw', 2: 'e_a', 3: 'u'} map_val_prec = {0: 'm_pp', 1: 'percent_snow', 2: 'rho_snow', 3: 'T_pp'} # get wy hour wyhr = int(utils.water_day(tstep)[0] * 24) # if we have inputs matching this water year hour if np.any(input_list == wyhr): i_in = ipw.IPW(os.path.join(myawsm.pathi, 'in.%04i' % (wyhr))) # assign soil temp inpt['T_g'] = myawsm.soil_temp * np.ones( (myawsm.topo.ny, myawsm.topo.nx)) # myawsm._logger.info('T_g: {}'.format(myawsm.soil_temp)) # inpt['T_g'] = -2.5*np.ones((myawsm.topo.ny, myawsm.topo.nx)) for f, v in map_val.items(): # if no solar data, give it zero if f == 5 and len(i_in.bands) < 6: # myawsm._logger.info('No solar data for {}'.format(tstep)) inpt[v] = np.zeros((myawsm.topo.ny, myawsm.topo.nx)) else: inpt[v] = i_in.bands[f].data # assign ppt data if there else: raise ValueError('No input timesteps for {}'.format(tstep)) if np.any(ppt_list == wyhr): i_ppt = ipw.IPW(os.path.join(myawsm.path_ppt, 'ppt.4b_%04i' % (wyhr))) for f, v in map_val_prec.items(): inpt[v] = i_ppt.bands[f].data else: for f, v in map_val_prec.items(): inpt[v] = np.zeros((myawsm.topo.ny, myawsm.topo.nx)) # convert from C to K inpt['T_a'] += FREEZE inpt['T_pp'] += FREEZE inpt['T_g'] += FREEZE return inpt
def write_init(self): """ Write the iSnobal init file """ # get mask mask = self.topo.mask # make ipw init file i_out = ipw.IPW() i_out.new_band(self.init['elevation']) i_out.new_band(self.init['z_0']) i_out.new_band(self.init['z_s']*mask) # snow depth i_out.new_band(self.init['rho']*mask) # snow density i_out.new_band(self.init['T_s_0']*mask) # active layer temp if self.start_wyhr > 0 or self.restart_crash: i_out.new_band(self.init['T_s_l']*mask) # lower layer temp i_out.new_band(self.init['T_s']*mask) # avgerage snow temp i_out.new_band(self.init['h2o_sat']*mask) # percent saturatio i_out.add_geo_hdr([self.topo.u, self.topo.v], [self.topo.du, self.topo.dv], self.topo.units, self.csys) i_out.write(self.fp_init, 16)
def snow_nc(self): ''' Takes directory of ipw files from Hedrick18 and squishes them into a netCDF ''' # S is a dictionary list or something which is hardcoded band names and attributes for netCDF # from AWSM/convertfiles/convertFiles s = {} s['name'] = [ 'thickness', 'snow_density', 'specific_mass', 'liquid_water', 'temp_surf', 'temp_lower', 'temp_snowcover', 'thickness_lower', 'water_saturation' ] s['units'] = [ 'm', 'kg m-3', 'kg m-2', 'kg m-2', 'C', 'C', 'C', 'm', 'percent' ] s['description'] = [ 'Predicted thickness of the snowcover', 'Predicted average snow density', 'Predicted specific mass of the snowcover', 'Predicted mass of liquid water in the snowcover', 'Predicted temperature of the surface layer', 'Predicted temperature of the lower layer', 'Predicted temperature of the snowcover', 'Predicted thickness of the lower layer', 'Predicted percentage of liquid water' ] # Tell file where to save and name self.nc_file = os.path.join(self.file_path_out, self.file_name_out) # Get X,Y and Time saved to nc file snow = self.base_nc() for i, v in enumerate(self.file_path_ipw): snow.variables['time'][i] = self.file_num[ i] #file number is actually the hours after WY i.e. 23, 47, etc. for i2, v2 in enumerate(s['name']): # snow.createVariable(v, 'f', self.dimensions[:3], chunksizes=(6, 10, 10)) if i == 0: snow.createVariable(v2, 'f', self.dimensions[:3]) setattr(snow.variables[v2], 'units', s['units'][i2]) setattr(snow.variables[v2], 'description', s['description'][i2]) snow.variables[v2][i, :, :] = ipw.IPW(v).bands[i2].data else: snow.variables[v2][i, :, :] = ipw.IPW(v).bands[i2].data # snow.variables[v][0,:,:] = self.var_data[v] # print(snow.variables[v][0,:,:].shape) # print(self.var_data[v].shape) print('Adding WY day: ', i) self.finish_nc(snow)
def readImages(self): """ Read in the images from the config file """ if 'dem' not in self.topoConfig: raise ValueError('DEM file not specified') # read in the images for v in self.images: if v in self.topoConfig: i = ipw.IPW(self.topoConfig[v]) setattr(self, v, i.bands[0].data.astype(np.float64)) if v == 'dem': # get some general information about the model # domain from the dem self.ny = i.nlines self.nx = i.nsamps self.u = i.bands[0].bline self.v = i.bands[0].bsamp self.du = i.bands[0].dline self.dv = i.bands[0].dsamp self.units = i.bands[0].geounits self.coord_sys_ID = i.bands[0].coord_sys_ID else: setattr(self, v, None) # set roughness if not given if 'roughness' in self.topoConfig: self.roughness = ipw.IPW( self.topoConfig['roughness']).bands[0].data.astype(np.float64) else: print('No surface roughness given in topo, setting to 5mm') self.roughness = 0.005 * np.ones((self.ny, self.nx)) # create the x,y vectors self.x = self.v + self.dv * np.arange(self.nx) self.y = self.u + self.du * np.arange(self.ny) [self.X, self.Y] = np.meshgrid(self.x, self.y)
def get_ipw_out(self): """ Set init fields for iSnobal out as init file """ i_in = ipw.IPW(self.init_file) self.init['z_s'] = i_in.bands[0].data*self.topo.mask # snow depth self.init['rho'] = i_in.bands[1].data*self.topo.mask # snow density self.init['T_s_0'] = i_in.bands[4].data*self.topo.mask # active layer temp self.init['T_s_l'] = i_in.bands[5].data*self.topo.mask # lower layer temp self.init['T_s'] = i_in.bands[6].data*self.topo.mask # avgerage snow temp self.init['h2o_sat'] = i_in.bands[8].data*self.topo.mask # percent saturation
def height_to_type(veg_height): '''ZRU: this takes veg_height.ipw, reclassifies as 1,2,...N (N = number of distinct veg heights), and outputs nparray. Note: classifications are ordered from shortest to tallest heights''' mat = ipw.IPW( veg_height).bands[0].data # grab veg_height array from ipw image hts = [] #init list to collect unique heights for i in np.arange(mat.shape[0]): for j in np.arange(mat.shape[1]): if mat[i, j] in hts: pass else: hts.append(mat[i, j]) cls = mat.copy() hts.sort() for idx, vals in enumerate(hts): cls[cls == vals] = idx + 1 return cls
def __init__(self, topoConfig, mask_isnobal, model_type, csys, dir_m): """ Args: topoConfig: config section for topo from smrf config mask_isnobal: Boolean for masking iSnobal model_type: Type of snow model csys: Coordinate system id dir_m: Directory in which to write mask if needed """ self.topoConfig = topoConfig #logger.debug('Reading in topo info for AWSM') # read images self.img_type = self.topoConfig['type'] if self.img_type == 'ipw': self.readImages() elif self.img_type == 'netcdf': self.readNetCDF() # assign path to mask, write mask if needed # only needed if running iSnobal from ipw, not PySnobal if mask_isnobal and model_type == 'isnobal': if self.img_type == 'netcdf': # assign path self.fp_mask = os.path.join(dir_m, 'run_mask.ipw') # write mask ipw file i_out = ipw.IPW() i_out.new_band(self.mask) i_out.add_geo_hdr([self.u, self.v], [self.du, self.dv], self.units, csys) i_out.write(self.fp_mask, 16) elif self.img_type == 'ipw': self.fp_mask = self.topoConfig['mask'] else: self.fp_mask = None # make masks one if not masking model if not mask_isnobal: self.mask = np.ones_like(self.dem)
def get_topo_stats(fp, filetype='netcdf'): """ Get stats about topo from the topo file Returns: ts - dictionary of topo header data """ fp = os.path.abspath(fp) ts = {} if filetype == 'netcdf': ds = Dataset(fp, 'r') ts['units'] = ds.variables['y'].units y = ds.variables['y'][:] x = ds.variables['x'][:] ts['nx'] = len(x) ts['ny'] = len(y) ts['du'] = y[1] - y[0] ts['dv'] = x[1] - x[0] ts['v'] = x[0] ts['u'] = y[0] ts['x'] = x ts['y'] = y ds.close() if filetype == 'ipw': i = ipw.IPW(fp) ts['nx'] = i.nsamps ts['ny'] = i.nlines ts['units'] = i.bands[0].units ts['du'] = i.bands[0].dline ts['dv'] = i.bands[0].dsamp ts['v'] = float(i.bands[0].bsamp) ts['u'] = float(i.bands[0].bline) ts['csys'] = i.bands[0].coord_sys_ID ts['x'] = ts['v'] + ts['dv'] * np.arange(ts['nx']) ts['y'] = ts['u'] + ts['du'] * np.arange(ts['ny']) return ts
def get_ipw(self): """ Set init fields for iSnobal out as init file """ i_in = ipw.IPW(self.init_file) self.init['z_0'] = i_in.bands[1].data*self.topo.mask # snow depth self.logger.warning('Using roughness from iSnobal ipw init file for initializing of model!') self.init['z_s'] = i_in.bands[2].data*self.topo.mask # snow depth self.init['rho'] = i_in.bands[3].data*self.topo.mask # snow density self.init['T_s_0'] = i_in.bands[4].data*self.topo.mask # active layer temp # get bands depending on if there is a lower layer or not if len(i_in.bands) == 8: self.init['T_s_l'] = i_in.bands[5].data*self.topo.mask # lower layer temp self.init['T_s'] = i_in.bands[6].data*self.topo.mask # avgerage snow temp self.init['h2o_sat'] = i_in.bands[7].data*self.topo.mask # percent saturation elif len(i_in.bands) == 7: self.init['T_s'] = i_in.bands[5].data*self.topo.mask # avgerage snow temp self.init['h2o_sat'] = i_in.bands[6].data*self.topo.mask # percent saturation
du = -100 dv = 100 units = 'm' csys = 'UTM' nx = 1500 ny = 1500 nbits = 16 # create the x,y vectors x = v + dv * np.arange(nx) y = u + du * np.arange(ny) #------------------------------------------------------------------------------ # band 0 - DEM d = ipw.IPW('dem.ipw') dem = d.bands[0].data #------------------------------------------------------------------------------ # band 1 - roughness length rough = 0.005 * np.ones(dem.shape) #------------------------------------------------------------------------------ # band 2 - total snowcover depth depth = np.zeros(dem.shape) #------------------------------------------------------------------------------ # band 3 - average snowcover density density = np.zeros(dem.shape) #------------------------------------------------------------------------------
def do_update_isnobal(self, myawsm, update_info, update_snow, x, y): """ Function to read in an output file and update it with the lidar depth field Argument: myawsm: instantiated awsm class update_info: update info pandas at correct index update_snow: file pointer to snow update image x: x vector y: y vector Returns: init_file: file pointer to init image """ # get some info update_number = update_info['number'] date = update_info['date_time'] wyhr = update_info['wyhr'] last_snow_image = ipw.IPW(update_snow) z_s = last_snow_image.bands[0].data # Get modeled depth image. # z_s(mask==0) = NaN; ## Continue as before: density = last_snow_image.bands[1].data.copy() # Get density image. ## ## ## ## ## ## ## ## ## % # SPECIAL CASE... insert adjusted densities here: # density = arcgridread_v2(['/Volumes/data/blizzard/Tuolumne/lidar/snowon/2017' ... # '/adjusted_rho/TB2017' date_mmdd '_operational_rho_ARSgrid_50m.asc']); ## ## ## ## ## ## ## ## ## % m_s = last_snow_image.bands[2].data.copy() # Get SWE image. T_s_0 = last_snow_image.bands[4].data.copy( ) # Get active snow layer temperature image T_s_l = last_snow_image.bands[5].data.copy( ) # Get lower snow layer temperature image T_s = last_snow_image.bands[6].data.copy( ) # Get average snowpack temperature image h2o_sat = last_snow_image.bands[8].data.copy( ) # Get liquid water saturation image updated_fields = self.hedrick_updating_procedure( m_s, T_s_0, T_s_l, T_s, h2o_sat, density, z_s, x, y, update_info) # write init file out_file = 'init_update_{}_wyhr{:04d}.ipw'.format(update_number, wyhr) init_file = os.path.join(self.pathinit, out_file) i_out = ipw.IPW() i_out.new_band(updated_fields['dem']) i_out.new_band(updated_fields['z0']) i_out.new_band(updated_fields['D']) i_out.new_band(updated_fields['rho']) i_out.new_band(updated_fields['T_s_0']) i_out.new_band(updated_fields['T_s_l']) i_out.new_band(updated_fields['T_s']) i_out.new_band(updated_fields['h2o_sat']) #i_out.add_geo_hdr([u, v], [du, dv], units, csys) i_out.add_geo_hdr([self.topo.u, self.topo.v], [self.topo.du, self.topo.dv], self.topo.units, self.csys) i_out.write(init_file, self.nbits) ## Import newly-created init file and look at images to make sure they line up: self._logger.info('Wrote ipw image for update {}'.format(wyhr)) return init_file
# ZRU 5/10/2019 # file pointers (mostly) fp_veg_height = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_vegheight_50m.ipw' fp_veg_type = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_vegnlcd_50m.ipw' fp_veg_tau = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_vegtau_50m.ipw' fp_veg_k = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_vegk_50m.ipw' fp_dem = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_dem_50m.ipw' fp_mask = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_hetchy_mask_50m.ipw' ts = get_topo_stats(fp_veg_height, filetype='ipw') # collects all the coordinate data # Add all the layers var_data = {} var_data['veg_type'] = ipw.IPW(fp_veg_type).bands[0].data var_data['veg_height'] = ipw.IPW(fp_veg_height).bands[0].data var_data['veg_tau'] = ipw.IPW(fp_veg_tau).bands[0].data var_data['veg_k'] = ipw.IPW(fp_veg_k).bands[0].data var_data['dem'] = ipw.IPW(fp_dem).bands[0].data var_data['mask'] = ipw.IPW(fp_mask).bands[0].data var_data['x'] = ts['x'] var_data['y'] = ts['y'] tmp = var_data['veg_type'].round() print('41 ', ((tmp == 41).sum()) / (tmp.shape[0] * tmp.shape[1])) x = np.where(tmp == 41) print(x[1][2]) print(x[0][2]) # # Not quite automated, but it will do # var_list = ['veg_type', 'veg_height', 'veg_tau', 'veg_k', 'dem', 'mask']
def run(): fmt_file = fmt = '%Y%m%d' #basin = 'SJ' basin = 'TB' wy = 2017 fpdir = '/home/micahsandusky/Code/awsfTesting/newupdatetest' sj_updates = {} sj_updates[2018] = ['2018-04-23', '2018-05-28'] sj_updates[2017] = [] # date_lst = ['2018-04-23', '2018-05-28'] tuol_updates = {} tuol_updates[2013] = ['2013-04-03', '2013-04-29', '2013-05-03', '2013-05-25', '2013-06-01', '2013-06-08'] tuol_updates[2014] = ['2014-03-23', '2014-04-07', '2014-04-13', '2014-04-20', '2014-04-28', '2014-05-02', '2014-05-11', '2014-05-17', '2014-05-27', '2014-05-31', '2014-06-05'] tuol_updates[2015] = ['2015-02-18', '2015-03-06', '2015-03-25', '2015-04-03', '2015-04-09', '2015-04-15', '2015-04-27', '2015-05-01', '2015-05-28', '2015-06-08'] tuol_updates[2016] = ['2016-03-26', '2016-04-07', '2016-04-16', '2016-04-26', '2016-05-09', '2016-05-27', '2016-06-07', '2016-06-13', '2016-06-20', '2016-06-25', '2016-07-01', '2016-07-08'] tuol_updates[2017] = ['2017-01-29', '2017-03-03', '2017-04-01', '2017-05-02', '2017-06-04', '2017-07-09', '2017-07-17', '2017-08-16'] #tuol_updates[2016] = ['2016-04-16', '2016-04-26'] if basin == 'TB': date_lst = tuol_updates[wy] # put into datetime date_lst = [pd.to_datetime(dt+' 23:00') for dt in date_lst] tzinfo = pytz.timezone('UTC') tmp_date = date_lst[0] tmp_date = tmp_date.replace(tzinfo=tzinfo) # find start of water year tmpwy = utils.water_day(tmp_date)[1] wy = tmpwy start_date = pd.to_datetime('{:d}-10-01'.format(tmpwy-1)) # get the paths fp_lst = ['wy{}/{}{}_SUPERsnow_depth.asc'.format(wy, basin, dt.strftime(fmt_file)) for dt in date_lst] fp_lst = [os.path.join(fpdir,fpu) for fpu in fp_lst] if basin == 'TB': dem_fp = '/data/blizzard/tuolumne/common_data/topo/tuolx_dem_50m.ipw' gisPath = '/home/micahsandusky/Code/awsfTesting/initUpdate/' maskPath = os.path.join(gisPath, 'tuolx_mask_50m.ipw') if wy < 2017: maskPath = os.path.join(gisPath, 'tuolx_hetchy_mask_50m.ipw') elif basin == 'SJ': dem_fp = '/data/blizzard/sanjoaquin/common_data/topo/SJ_dem_50m.ipw' gisPath = '/data/blizzard/sanjoaquin/common_data/topo/' maskPath = os.path.join(gisPath, 'SJ_Millerton_mask_50m.ipw') else: raise ValueError('Wrong basin name') mask = ipw.IPW(maskPath).bands[0].data[:] output_path = os.path.join(fpdir, 'wy{}'.format(wy)) fname = 'flight_depths_{}'.format(basin) nanval = -9999.0 nanup = 1000.0 # #### Now actually do the stuff #### # date to use for finding wy fname = fname+'_{}'.format(tmpwy) # get topo stats from dem ts = get_topo_stats(dem_fp, filetype = 'ipw') x = ts['x'] # + ts['dv']*np.arange(ts['nx']) y = ts['y'] # + ts['du']*np.arange(ts['ny']) # get depth array depth_arr = read_flight(fp_lst, ts, nanval = nanval, nanup = nanup) print(depth_arr) # create netcdfs ds = output_files(output_path, fname, start_date, x, y) # write to file for idt, dt in enumerate(date_lst): data = depth_arr[idt,:]#*mask' data[mask == 0.0] = np.nan output_timestep(ds, data, dt, idt, start_date) # close file ds.close()
update_num)) previous_update_dir = 'run.{}'.format(q) output_dir = 'output_update' add_in = '_update' else: previous_update_dir = 'run.'.format(previous_update_dir) output_dir = 'output_update' #gisPath = '/data/blizzard/Tuolumne/common_data/topo/' gisPath = '/home/micahsandusky/Code/awsfTesting/initUpdate/' ###chdir(os.path.join(basePath,dataDir)) ###runPath = os.path.join(basePath,runDir,previous_update_dir,output_dir) #last_snow_image = ipw.IPW(os.path.join(runPath, 'snow.{}'.format(wyhr))) #last_snow_image = ipw.IPW('/home/micahsandusky/Code/awsfTesting/initUpdate/snow.5999') #last_snow_image = ipw.IPW('/home/micahsandusky/Code/awsfTesting/newupdatetest/snow.5999') last_snow_image = ipw.IPW( '/home/micahsandusky/Code/awsfTesting/newupdatetest/snow.2879') demPath = os.path.join(gisPath, 'tuolx_dem_50m.{}'.format(filetype[0:3])) if int(wy) <= 2015: # Model domain was only above Hetchy before 2016. maskPath = os.path.join(gisPath, 'tuolx_hetchy_mask_50m.{}'.format(filetype[0:3])) else: maskPath = os.path.join(gisPath, 'tuolx_mask_50m.{}'.format(filetype[0:3])) z0Path = os.path.join(gisPath, 'tuolx_z0_50m.{}'.format(filetype[0:3])) if filetype == 'ipw': demstruct = ipw.IPW(demPath) dem = demstruct.bands[0].data mask = ipw.IPW(maskPath) mask = mask.bands[0].data z0 = ipw.IPW(z0Path)
import h5py from smrf import ipw import numpy as np import matplotlib.pyplot as plt import getCDF as gcdf ''' sanity check to make sure topo_wrr18.nc was created properly. really, why 42s are where there should be 41 in vegtype''' fp_topo = '/home/zachuhlmann/projects/Hedrick_WRR_2018/tuol_topo_wrr18.nc' fp_veg_type = '/home/zachuhlmann/projects/zenodo_WRR_data/static_grids/tuolx_vegnlcd_50m.ipw' gcdf_obj = gcdf.GetCDF() gcdf_obj.get_topo(fp_topo) ipw_array = ipw.IPW(fp_veg_type).bands[0].data ipw_array = ipw_array.astype(np.int8) nc_array = np.array(gcdf_obj.topo['veg_type']) # ipw_array[gcdf_obj.mask == False] = np.nan ipw_array = np.ma.masked_where(gcdf_obj.mask == False, nc_array) ipw_array = ipw_array[gcdf_obj.trim_to_NA_extent()] ipw_array = np.reshape(ipw_array, (gcdf_obj.nrows_trim, gcdf_obj.ncols_trim)) nc_array = np.ma.masked_where(gcdf_obj.mask == False, nc_array) nc_array = nc_array[gcdf_obj.trim_to_NA_extent()] nc_array = np.reshape(nc_array, (gcdf_obj.nrows_trim, gcdf_obj.ncols_trim)) fig, axs = plt.subplots(ncols =3, nrows =1) axs[0].imshow(ipw_array) axs[1].imshow(nc_array) mp = axs[2].imshow(ipw_array - nc_array) fig.colorbar(mp, ax=axs[2], fraction=0.04, pad=0.04, orientation = 'horizontal', extend = 'max')
from smrf import ipw file_name = 'topo.nc' f = { 'dem': 'dem.ipw', 'mask': 'mask.ipw', 'veg_height': 'veg_height.ipw', 'veg_k': 'veg_k.ipw', 'veg_tau': 'veg_tau.ipw', 'veg_type': 'veg_type.ipw' } # get the x,y d = ipw.IPW(f['dem']) x = d.bands[0].x y = d.bands[0].y # create the netCDF file s = nc.Dataset(file_name, 'w', format='NETCDF4', clobber=True) # add dimensions dimensions = ['y', 'x'] s.createDimension(dimensions[0], y.shape[0]) s.createDimension(dimensions[1], x.shape[0]) # create the variables s.createVariable('y', 'f', dimensions[0]) s.createVariable('x', 'f', dimensions[1])
def ipw2nc_mea(myawsm, runtype): ''' Function to create netcdf files from iSnobal output. Reads the snow and em ouptuts in the 'output' folder and stores them in snow.nc and em.nc one directory up. Args: myawsm: AWSM instance runtype: either 'smrf' for standard run or 'forecast' for gridded data run ''' myawsm._logger.info("making the NetCDF files from ipw" " files for {}".format(runtype)) if runtype != 'smrf' and runtype != 'forecast': myawsm._logger.error('Wrong run type given to ipw2nc. ' 'not smrf or forecast') sys.exit() myawsm._logger.info("convert all .ipw output files to netcdf files") ####################################################################### # Convert all .ipw output files to netcdf files ##################### ####################################################################### time_zone = myawsm.tmz # create the x,y vectors x = myawsm.topo.x y = myawsm.topo.y # ======================================================================== # NetCDF EM image # ======================================================================== m = {} m['name'] = [ 'net_rad', 'sensible_heat', 'latent_heat', 'snow_soil', 'precip_advected', 'sum_EB', 'evaporation', 'snowmelt', 'SWI', 'cold_content' ] m['units'] = [ 'W m-2', 'W m-2', 'W m-2', 'W m-2', 'W m-2', 'W m-2', 'kg m-2', 'kg m-2', 'kg or mm m-2', 'J m-2' ] m['description'] = [ 'Average net all-wave radiation', 'Average sensible heat transfer', 'Average latent heat exchange', 'Average snow/soil heat exchange', 'Average advected heat from precipitation', 'Average sum of EB terms for snowcover', 'Total evaporation', 'Total snowmelt', 'Total runoff', 'Snowcover cold content' ] if runtype == 'smrf': netcdfFile = os.path.join(myawsm.pathrr, 'em.nc') elif runtype == 'forecast': netcdfFile = os.path.join(myawsm.pathrr, 'em_forecast.nc') dimensions = ('time', 'y', 'x') em = nc.Dataset(netcdfFile, 'w') # create the dimensions em.createDimension('time', None) em.createDimension('y', myawsm.topo.ny) em.createDimension('x', myawsm.topo.nx) # create some variables em.createVariable('time', 'f', dimensions[0]) em.createVariable('y', 'f', dimensions[1]) em.createVariable('x', 'f', dimensions[2]) setattr(em.variables['time'], 'units', 'hours since %s' % myawsm.wy_start) setattr(em.variables['time'], 'calendar', 'standard') setattr(em.variables['time'], 'time_zone', time_zone) em.variables['x'][:] = x em.variables['y'][:] = y # em image for i, v in enumerate(m['name']): em.createVariable(v, 'f', dimensions[:3], chunksizes=(24, 10, 10)) setattr(em.variables[v], 'units', m['units'][i]) setattr(em.variables[v], 'description', m['description'][i]) em.setncattr_string('source', 'AWSM {}'.format(myawsm.gitVersion)) # ======================================================================== # NetCDF SNOW image # ======================================================================== s = {} s['name'] = [ 'thickness', 'snow_density', 'specific_mass', 'liquid_water', 'temp_surf', 'temp_lower', 'temp_snowcover', 'thickness_lower', 'water_saturation' ] s['units'] = [ 'm', 'kg m-3', 'kg m-2', 'kg m-2', 'C', 'C', 'C', 'm', 'percent' ] s['description'] = [ 'Predicted thickness of the snowcover', 'Predicted average snow density', 'Predicted specific mass of the snowcover', 'Predicted mass of liquid water in the snowcover', 'Predicted temperature of the surface layer', 'Predicted temperature of the lower layer', 'Predicted temperature of the snowcover', 'Predicted thickness of the lower layer', 'Predicted percentage of liquid water' ' saturation of the snowcover' ] if runtype == 'smrf': netcdfFile = os.path.join(myawsm.pathrr, 'snow.nc') elif runtype == 'forecast': netcdfFile = os.path.join(myawsm.pathrr, 'snow_forescast.nc') dimensions = ('time', 'y', 'x') snow = nc.Dataset(netcdfFile, 'w') # create the dimensions snow.createDimension('time', None) snow.createDimension('y', myawsm.topo.ny) snow.createDimension('x', myawsm.topo.nx) # create some variables snow.createVariable('time', 'f', dimensions[0]) snow.createVariable('y', 'f', dimensions[1]) snow.createVariable('x', 'f', dimensions[2]) setattr(snow.variables['time'], 'units', 'hours since %s' % myawsm.wy_start) setattr(snow.variables['time'], 'calendar', 'standard') setattr(snow.variables['time'], 'time_zone', time_zone) snow.variables['x'][:] = x snow.variables['y'][:] = y # snow image for i, v in enumerate(s['name']): snow.createVariable(v, 'f', dimensions[:3], chunksizes=(6, 10, 10)) setattr(snow.variables[v], 'units', s['units'][i]) setattr(snow.variables[v], 'description', s['description'][i]) h = '[{}] Data added or updated'.format(datetime.now().strftime("%Y%m%d")) snow.setncattr_string('last modified', h) snow.setncattr_string('AWSM version', myawsm.gitVersion) if myawsm.do_smrf: snow.setncattr_string('SMRF version', myawsm.smrf_version) # ======================================================================= # Get all files in the directory, open ipw file, and add to netCDF # ======================================================================= # get all the files in the directory d = sorted(glob.glob("%s/snow*" % myawsm.pathro), key=os.path.getmtime) d.sort(key=lambda f: os.path.splitext(f)) # find a drop any netcdfs in directory d = [ddp for ddp in d if '.nc' not in ddp] # pbar = progressbar.ProgressBar(max_value=len(d)).start() j = 0 for idf, f in enumerate(d): # print out counter at certain percentages. pbar doesn't play nice # with logging if j == int(len(d) / 4): myawsm._logger.info("25 percent finished with " "making NetCDF files!") if j == int(len(d) / 2): myawsm._logger.info("50 percent finished with " "making NetCDF files!") if j == int(3 * len(d) / 4): myawsm._logger.info("75 percent finished with " "making NetCDF files!") # get the hr nm = os.path.basename(f) head = os.path.dirname(f) hr = int(nm.split('.')[1]) # hr = int(hr) snow.variables['time'][j] = hr # +1 em.variables['time'][j] = hr # +1 # Read the IPW file i = ipw.IPW(f) # output to the snow netcdf file for b, var in enumerate(s['name']): snow.variables[var][j, :] = i.bands[b].data # output to the em netcdf file # emFile = "%s/%s.%04i" % (head, 'em', hr) emFile = os.path.join(head, 'em.%04i' % (hr)) i_em = ipw.IPW(emFile) for b, var in enumerate(m['name']): em.variables[var][j, :] = i_em.bands[b].data snow.setncattr_string('last modified', h) snow.setncattr_string('AWSM version', myawsm.gitVersion) if myawsm.do_smrf: snow.setncattr_string('SMRF version', myawsm.smrf_version) em.sync() snow.sync() j += 1 # pbar.update(j) # pbar.finish() snow.close() em.close() myawsm._logger.info("Finished making the NetCDF " "files from iSnobal output!")
nc_topo.variables['x'][:] = x nc_topo.variables['y'][:] = y # snow image for i, v in enumerate(s['name']): nc_topo.createVariable(v, 'f', ['y', 'x'], chunksizes=(10, 10)) setattr(nc_topo.variables[v], 'units', s['units'][i]) setattr(nc_topo.variables[v], 'description', s['description'][i]) setattr(nc_topo.variables[v], 'long_name', s['long_name'][i]) #=============================================================================== # open ipw file, and add to netCDF #=============================================================================== for f, var in zip(s['file'], s['name']): # Read the IPW file i = ipw.IPW(f) # assign to netcdf tmp = i.bands[0].data plt.imshow(tmp) plt.colorbar() plt.show() nc_topo.variables[var][:] = i.bands[0].data nc_topo.sync() #=============================================================================== # set attributes #=============================================================================== # the y variable attributes nc_topo.variables['y'].setncattr('units', 'meters') nc_topo.variables['y'].setncattr('description', 'UTM, north south') nc_topo.variables['y'].setncattr('long_name', 'y coordinate')