def test_multiple_inversion(): # test directory testdir = os.path.join(get_test_dir(), 'tmp_mdir') if not os.path.exists(testdir): os.makedirs(testdir) # Init cfg.initialize() cfg.set_intersects_db(get_demo_file('rgi_intersect_oetztal.shp')) cfg.PATHS['dem_file'] = get_demo_file('hef_srtm.tif') cfg.PATHS['climate_file'] = get_demo_file('histalp_merged_hef.nc') cfg.PARAMS['border'] = 40 cfg.PARAMS['run_mb_calibration'] = True cfg.PARAMS['baseline_climate'] = 'CUSTOM' cfg.PATHS['working_dir'] = testdir # Get the RGI ID hef_rgi = gpd.read_file(get_demo_file('divides_hef.shp')) hef_rgi.loc[0, 'RGIId'] = 'RGI50-11.00897' gdirs = workflow.init_glacier_regions(hef_rgi) workflow.gis_prepro_tasks(gdirs) workflow.climate_tasks(gdirs) workflow.inversion_tasks(gdirs) fig, ax = plt.subplots() graphics.plot_inversion(gdirs, ax=ax) fig.tight_layout() shutil.rmtree(testdir) return fig
def up_to_climate(reset=False): """Run the tasks you want.""" # test directory if not os.path.exists(_TEST_DIR): os.makedirs(_TEST_DIR) if reset: clean_dir(_TEST_DIR) if not os.path.exists(CLI_LOGF): with open(CLI_LOGF, 'wb') as f: pickle.dump('none', f) # Init cfg.initialize() # Use multiprocessing cfg.PARAMS['use_multiprocessing'] = use_multiprocessing() # Working dir cfg.PATHS['working_dir'] = _TEST_DIR cfg.PATHS['dem_file'] = get_demo_file('srtm_oetztal.tif') cfg.set_intersects_db(get_demo_file('rgi_intersect_oetztal.shp')) # Read in the RGI file rgi_file = get_demo_file('rgi_oetztal.shp') rgidf = gpd.read_file(rgi_file) # Make a fake marine and lake terminating glacier cfg.PARAMS['tidewater_type'] = 4 # make lake also calve rgidf.loc[0, 'GlacType'] = '0199' rgidf.loc[1, 'GlacType'] = '0299' # Use RGI6 rgidf['RGIId'] = [s.replace('RGI50', 'RGI60') for s in rgidf.RGIId] # Be sure data is downloaded cru.get_cru_cl_file() # Params cfg.PARAMS['border'] = 70 cfg.PARAMS['tstar_search_window'] = [1902, 0] cfg.PARAMS['prcp_scaling_factor'] = 1.75 cfg.PARAMS['temp_melt'] = -1.75 cfg.PARAMS['use_kcalving_for_inversion'] = True cfg.PARAMS['use_kcalving_for_run'] = True # Go gdirs = workflow.init_glacier_directories(rgidf) try: tasks.catchment_width_correction(gdirs[0]) except Exception: reset = True if reset: # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) return gdirs
def test_ice_cap(): testdir = os.path.join(get_test_dir(), 'tmp_icecap') utils.mkdir(testdir, reset=True) cfg.initialize() cfg.PARAMS['use_intersects'] = False cfg.PATHS['dem_file'] = get_demo_file('dem_RGI50-05.08389.tif') cfg.PARAMS['border'] = 60 cfg.PATHS['working_dir'] = testdir df = gpd.read_file(get_demo_file('divides_RGI50-05.08389.shp')) df['Area'] = df.Area * 1e-6 # cause it was in m2 df['RGIId'] = ['RGI50-05.08389_d{:02d}'.format(d + 1) for d in df.index] gdirs = workflow.init_glacier_regions(df) workflow.gis_prepro_tasks(gdirs) from salem import mercator_grid, Map smap = mercator_grid((gdirs[0].cenlon, gdirs[0].cenlat), extent=[20000, 23000]) smap = Map(smap) fig, ax = plt.subplots() graphics.plot_catchment_width(gdirs, ax=ax, add_intersects=True, add_touches=True, smap=smap) fig.tight_layout() shutil.rmtree(testdir) return fig
def preprocessing(gdirs): """ oggm workflow for preparing initializing :param gdirs: list of oggm.GlacierDirectories :return None, but creates required files """ workflow.gis_prepro_tasks(gdirs) workflow.climate_tasks(gdirs) workflow.inversion_tasks(gdirs) workflow.execute_entity_task(tasks.init_present_time_glacier, gdirs)
def plot_issue(gdir, plot_dir): #plt.style.use('ggplot') workflow.gis_prepro_tasks([gdir]) workflow.climate_tasks([gdir]) workflow.inversion_tasks([gdir]) tasks.init_present_time_glacier(gdir) # Observed length changes df = gdir.get_ref_length_data() df = df.loc[1855:2003]['dL'] df = df - df.iloc[-1] tasks.run_from_climate_data(gdir, ys=1855, ye=2003, output_filesuffix='hist_from_current') ds = xr.open_dataset( gdir.get_filepath('model_diagnostics', filesuffix='hist_from_current')) (ds.length_m.to_series().rolling(36, center=True).mean() - ds.length_m.to_series().iloc[0]).plot(c='C0', label='OGGM') #s = s - s.iloc[-1] #print(s) ax = df.plot(c='k', label='Observations') #s.plot(c='C0', label='OGGM'); plt.legend() ax.set_ylabel('Glacier Length Change [m]') plt.title('Hintereisferner length changes Experiment 2') plt.tight_layout() plt.show() ''' fls = gdir.read_pickle('model_flowlines') x = np.arange(fls[-1].nx) *fls[-1].dx * fls[-1].map_dx plt.figure(figsize=(13,10)) rc('axes', linewidth=3) plt.plot(x,fls[-1].surface_h,linewidth=3, label='Surface Elevation') plt.plot(x,fls[-1].bed_h,'k',linewidth=3,label='Bed Topography') plt.ylabel('Altitude (m)',size=30) plt.xlabel('Distance along the Flowline (m)',size=30) plt.legend(loc='best',fontsize=30) #plt.annotate('?', xy=(5000, 2700), fontsize=40) plt.tick_params(axis='both', which='major', labelsize=30) plt.title(gdir.rgi_id+ ': '+gdir.name,size=35) plt.savefig(os.path.join(plot_dir, 'issue_today.png'),dpi=200) ''' #plt.savefig(os.path.join(plot_dir, 'issue_1850.pdf'),dpi=200) plt.show() return
def up_to_climate(reset=False): """Run the tasks you want.""" # test directory if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) if reset: clean_dir(TEST_DIR) if not os.path.exists(CLI_LOGF): with open(CLI_LOGF, 'wb') as f: pickle.dump('none', f) # Init cfg.initialize() # Use multiprocessing # We don't use mp on TRAVIS because unsure if compatible with test coverage cfg.PARAMS['use_multiprocessing'] = not ON_TRAVIS # Working dir cfg.PATHS['working_dir'] = TEST_DIR cfg.PATHS['dem_file'] = get_demo_file('srtm_oetztal.tif') # Read in the RGI file rgi_file = get_demo_file('rgi_oetztal.shp') rgidf = gpd.GeoDataFrame.from_file(rgi_file) # Be sure data is downloaded because lock doesn't work cl = utils.get_cru_cl_file() # Params cfg.PARAMS['border'] = 70 cfg.PARAMS['use_optimized_inversion_params'] = True cfg.PARAMS['tstar_search_window'] = [1902, 0] cfg.PARAMS['invert_with_rectangular'] = False # Go gdirs = workflow.init_glacier_regions(rgidf) assert gdirs[14].name == 'Hintereisferner' try: tasks.catchment_width_correction(gdirs[0]) except Exception: reset = True if reset: # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) return gdirs
def up_to_climate(reset=False): """Run the tasks you want.""" # test directory if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) if reset: clean_dir(TEST_DIR) if not os.path.exists(CLI_LOGF): with open(CLI_LOGF, 'wb') as f: pickle.dump('none', f) # Init cfg.initialize() # Use multiprocessing cfg.PARAMS['use_multiprocessing'] = use_multiprocessing() # Working dir cfg.PATHS['working_dir'] = TEST_DIR cfg.PATHS['dem_file'] = get_demo_file('srtm_oetztal.tif') # Read in the RGI file rgi_file = get_demo_file('rgi_oetztal.shp') rgidf = gpd.read_file(rgi_file) # Be sure data is downloaded cl = utils.get_cru_cl_file() # Params cfg.PARAMS['border'] = 70 cfg.PARAMS['optimize_inversion_params'] = True cfg.PARAMS['use_optimized_inversion_params'] = True cfg.PARAMS['tstar_search_window'] = [1902, 0] cfg.PARAMS['invert_with_rectangular'] = False cfg.PARAMS['run_mb_calibration'] = True # Go gdirs = workflow.init_glacier_regions(rgidf) try: tasks.catchment_width_correction(gdirs[0]) except Exception: reset = True if reset: # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) return gdirs
def up_to_climate(reset=False): """Run the tasks you want.""" # test directory if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) if reset: clean_dir(TEST_DIR) if not os.path.exists(CLI_LOGF): with open(CLI_LOGF, 'wb') as f: pickle.dump('none', f) # Init cfg.initialize() # Use multiprocessing cfg.PARAMS['use_multiprocessing'] = use_multiprocessing() # Working dir cfg.PATHS['working_dir'] = TEST_DIR cfg.PATHS['dem_file'] = get_demo_file('srtm_oetztal.tif') cfg.set_intersects_db(get_demo_file('rgi_intersect_oetztal.shp')) # Read in the RGI file rgi_file = get_demo_file('rgi_oetztal.shp') rgidf = gpd.read_file(rgi_file) # Be sure data is downloaded utils.get_cru_cl_file() # Params cfg.PARAMS['border'] = 70 cfg.PARAMS['tstar_search_window'] = [1902, 0] cfg.PARAMS['run_mb_calibration'] = True # Go gdirs = workflow.init_glacier_regions(rgidf) try: tasks.catchment_width_correction(gdirs[0]) except Exception: reset = True if reset: # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) return gdirs
def test_chhota_shigri(): testdir = os.path.join(get_test_dir(), 'tmp_chhota') utils.mkdir(testdir, reset=True) # Init cfg.initialize() cfg.PATHS['dem_file'] = get_demo_file('dem_chhota_shigri.tif') cfg.PARAMS['border'] = 80 cfg.PARAMS['use_intersects'] = False cfg.PATHS['working_dir'] = testdir hef_file = get_demo_file('divides_RGI50-14.15990.shp') df = gpd.read_file(hef_file) df['Area'] = df.Area * 1e-6 # cause it was in m2 df['RGIId'] = ['RGI50-14.15990' + d for d in ['_d01', '_d02']] gdirs = workflow.init_glacier_regions(df) workflow.gis_prepro_tasks(gdirs) for gdir in gdirs: climate.apparent_mb_from_linear_mb(gdir) workflow.execute_entity_task(inversion.prepare_for_inversion, gdirs) workflow.execute_entity_task(inversion.volume_inversion, gdirs, glen_a=cfg.A, fs=0) workflow.execute_entity_task(inversion.filter_inversion_output, gdirs) workflow.execute_entity_task(flowline.init_present_time_glacier, gdirs) models = [] for gdir in gdirs: flowline.init_present_time_glacier(gdir) fls = gdir.read_pickle('model_flowlines') models.append(flowline.FlowlineModel(fls)) fig, ax = plt.subplots() graphics.plot_modeloutput_map(gdirs, ax=ax, model=models) fig.tight_layout() shutil.rmtree(testdir) return fig
def test_multiple_models(): # test directory testdir = os.path.join(get_test_dir(), 'tmp_mdir') utils.mkdir(testdir, reset=True) # Init cfg.initialize() cfg.set_intersects_db(get_demo_file('rgi_intersect_oetztal.shp')) cfg.PATHS['dem_file'] = get_demo_file('hef_srtm.tif') cfg.PATHS['climate_file'] = get_demo_file('histalp_merged_hef.nc') cfg.PATHS['working_dir'] = testdir cfg.PARAMS['baseline_climate'] = 'CUSTOM' cfg.PARAMS['trapezoid_lambdas'] = 1 cfg.PARAMS['border'] = 40 apply_test_ref_tstars() # Get the RGI ID hef_rgi = gpd.read_file(get_demo_file('divides_hef.shp')) hef_rgi.loc[0, 'RGIId'] = 'RGI50-11.00897' gdirs = workflow.init_glacier_directories(hef_rgi) workflow.gis_prepro_tasks(gdirs) workflow.climate_tasks(gdirs) workflow.inversion_tasks(gdirs) models = [] for gdir in gdirs: flowline.init_present_time_glacier(gdir) fls = gdir.read_pickle('model_flowlines') models.append(flowline.FlowlineModel(fls)) fig, ax = plt.subplots() graphics.plot_modeloutput_map(gdirs, ax=ax, model=models) fig.tight_layout() shutil.rmtree(testdir) return fig
def test_multiple_models(): # test directory testdir = os.path.join(get_test_dir(), 'tmp_mdir') utils.mkdir(testdir, reset=True) # Init cfg.initialize() cfg.PATHS['dem_file'] = get_demo_file('hef_srtm.tif') cfg.PARAMS['optimize_inversion_params'] = True cfg.PATHS['climate_file'] = get_demo_file('histalp_merged_hef.nc') cfg.PATHS['working_dir'] = testdir cfg.PARAMS['run_mb_calibration'] = True cfg.PARAMS['border'] = 40 # Get the RGI ID hef_rgi = gpd.read_file(get_demo_file('divides_hef.shp')) hef_rgi.loc[0, 'RGIId'] = 'RGI50-11.00897' gdirs = workflow.init_glacier_regions(hef_rgi) workflow.gis_prepro_tasks(gdirs) workflow.climate_tasks(gdirs) workflow.inversion_tasks(gdirs) models = [] for gdir in gdirs: flowline.init_present_time_glacier(gdir) fls = gdir.read_pickle('model_flowlines') models.append(flowline.FlowlineModel(fls)) fig, ax = plt.subplots() graphics.plot_modeloutput_map(gdirs, ax=ax, model=models) fig.tight_layout() shutil.rmtree(testdir) return fig
def up_to_inversion(reset=False): """Run the tasks you want.""" # test directory if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) if reset: clean_dir(TEST_DIR) # Init cfg.initialize() # Use multiprocessing cfg.PARAMS['use_multiprocessing'] = not ON_TRAVIS # Working dir cfg.PATHS['working_dir'] = TEST_DIR cfg.set_divides_db(get_demo_file('HEF_divided.shp')) cfg.PATHS['dem_file'] = get_demo_file('srtm_oeztal.tif') # Set up the paths and other stuffs cfg.set_divides_db(get_demo_file('HEF_divided.shp')) cfg.PATHS['wgms_rgi_links'] = get_demo_file('RGI_WGMS_oeztal.csv') cfg.PATHS['glathida_rgi_links'] = get_demo_file('RGI_GLATHIDA_oeztal.csv') # Read in the RGI file rgi_file = get_demo_file('rgi_oeztal.shp') rgidf = gpd.GeoDataFrame.from_file(rgi_file) # Params cfg.PARAMS['border'] = 70 cfg.PARAMS['use_inversion_params'] = True # Go gdirs = workflow.init_glacier_regions(rgidf) try: flowline.init_present_time_glacier(gdirs[0]) except Exception: reset = True if reset: # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) # Climate related tasks # See if CRU is running cfg.PARAMS['temp_use_local_gradient'] = False cfg.PATHS['climate_file'] = '~' cru_dir = get_demo_file('cru_ts3.23.1901.2014.tmp.dat.nc') cfg.PATHS['cru_dir'] = os.path.dirname(cru_dir) workflow.climate_tasks(gdirs) # Use histalp for the actual test cfg.PARAMS['temp_use_local_gradient'] = True cfg.PATHS['climate_file'] = get_demo_file('HISTALP_oeztal.nc') cfg.PATHS['cru_dir'] = '~' workflow.climate_tasks(gdirs) # Inversion workflow.inversion_tasks(gdirs) return gdirs
def compute_scaling_params(rgi_ids, path=None): """ The routine computes scaling parameters by fitting a linear regression to the volume/area and volume/length scatter in log-log space, using the inversion volume, the RGI area and the longest centerline as "observations" Thereby, the following two cases apply: - compute only scaling constants, since scaling exponents have a physical basis and should not be changed - compute only scaling constants and scaling exponents Returns parameters in a 2-level dictionary. The upper level differentiates between the two cases, the lower level indicates the parameters. Parameters ---------- rgi_ids: array-like List of RGI IDs for which the equilibrium experiments are performed. Returns ------- Dictionary containing the computed parameters. """ log.info('Starting scaling parameter computation') # compute RGI region and version from RGI IDs # assuming all they are all the same rgi_region = (rgi_ids[0].split('-')[-1]).split('.')[0] rgi_version = (rgi_ids[0].split('-')[0])[-2:-1] # load default parameter file vascaling.initialize() # get environmental variables for working and output directories WORKING_DIR = os.environ["WORKDIR"] OUTPUT_DIR = os.environ["OUTDIR"] # create working directory utils.mkdir(WORKING_DIR) utils.mkdir(OUTPUT_DIR) # set path to working directory cfg.PATHS['working_dir'] = WORKING_DIR # set RGI version and region cfg.PARAMS['rgi_version'] = rgi_version # define how many grid points to use around the glacier, # if you expect the glacier to grow large use a larger border cfg.PARAMS['border'] = 120 # we use HistAlp climate data cfg.PARAMS['baseline_climate'] = 'HISTALP' # set the mb hyper parameters accordingly cfg.PARAMS['prcp_scaling_factor'] = 1.75 cfg.PARAMS['temp_melt'] = -1.75 # set minimum ice thickness to include in glacier length computation # this reduces weird spikes in length records cfg.PARAMS['min_ice_thick_for_length'] = 0.1 # read RGI entry for the glaciers as DataFrame # containing the outline area as shapefile rgidf = utils.get_rgi_glacier_entities(rgi_ids) # get and set path to intersect shapefile intersects_db = utils.get_rgi_intersects_region_file(region=rgi_region) cfg.set_intersects_db(intersects_db) # the bias is defined to be zero during the calibration process, # which is why we don't use it here to reproduce the results cfg.PARAMS['use_bias_for_run'] = True # sort by area for more efficient parallel computing rgidf = rgidf.sort_values('Area', ascending=False) cfg.PARAMS['use_multiprocessing'] = True # operational run, all glaciers should run cfg.PARAMS['continue_on_error'] = True # initialize the GlacierDirectory gdirs = workflow.init_glacier_directories(rgidf, reset=False, force=True) # run gis tasks workflow.gis_prepro_tasks(gdirs) # run climate tasks workflow.execute_entity_task(climate.process_climate_data, gdirs) # compute local t* and the corresponding mu* workflow.execute_entity_task(climate.local_t_star, gdirs) workflow.execute_entity_task(climate.mu_star_calibration, gdirs) # run inversion tasks workflow.inversion_tasks(gdirs) # finalize preprocessing workflow.execute_entity_task(flowline.init_present_time_glacier, gdirs) # create empty dictionary params = dict() # compute scaling constants for given (fixed) slope params['const_only'] = vascaling.get_scaling_constant(gdirs) # compute scaling constants and scaling exponent via linear regression params['const_expo'] = vascaling.get_scaling_constant_exponent(gdirs) # store to file if path: if not isinstance(path, str): # set default path and filename path = os.path.join(OUTPUT_DIR, 'scaling_params.json') json.dump(params, open(path, 'w')) return params
##Added in section to convert to pandas dataframe and print out file if needed/check data #rgidf.to_file('/Users/louis/workflow_test/rgidf.shp') ##Convert to pandas dataframe then print #rgipdf = pd.DataFrame(rgidf) #rgipdf.to_csv('/Users/louis/workflow_test/rgipdf.csv') #Start the run log.workflow('Starting OGGM run') log.workflow('Number of glaciers: {}'.format(len(rgidf))) #Go get the pre-processed glacier directories, this will eventually be reduced to prepro = 1 but for now need the climate files in the glacier directories. gdirs = workflow.init_glacier_directories(rgidf, from_prepro_level=1) #Run the prepro tasks on the dem to get flowlines using the generic processing etc. This could be broken down if we don't want certain tasks. workflow.gis_prepro_tasks(gdirs) #Process the climate data log.info('Process the climate data...') workflow.execute_entity_task(tasks.process_climate_data, gdirs, y1=2018) #Run the climate calibrations based on the new mass balance data, this mass balance data should be in the Working directory folder. workflow.execute_entity_task(tasks.local_t_star, gdirs) workflow.execute_entity_task(tasks.mu_star_calibration, gdirs) #Run the inversion tools ahead of the model runs #First set the paramters we can change, currently OGGM default ones: # Deformation: from Cuffey and Patterson 2010 glen_a = 2.4e-24 # Sliding: from Oerlemans 1997 fs = 5.7e-20 #Prep the data for inversion workflow.execute_entity_task(tasks.prepare_for_inversion, gdirs) #Run the inversion
def up_to_inversion(reset=False): """Run the tasks you want.""" # test directory if not os.path.exists(TEST_DIR): os.makedirs(TEST_DIR) if reset: clean_dir(TEST_DIR) # Init cfg.initialize() # Use multiprocessing cfg.PARAMS['use_multiprocessing'] = not ON_TRAVIS # Working dir cfg.PATHS['working_dir'] = TEST_DIR cfg.PATHS['dem_file'] = get_demo_file('srtm_oetztal.tif') # Set up the paths and other stuffs cfg.set_divides_db(get_demo_file('divides_workflow.shp')) cfg.PATHS['wgms_rgi_links'] = get_demo_file('RGI_WGMS_oetztal.csv') cfg.PATHS['glathida_rgi_links'] = get_demo_file('RGI_GLATHIDA_oetztal.csv') # Read in the RGI file rgi_file = get_demo_file('rgi_oetztal.shp') rgidf = gpd.GeoDataFrame.from_file(rgi_file) # Be sure data is downloaded because lock doesn't work cl = utils.get_cru_cl_file() # Params cfg.PARAMS['border'] = 70 cfg.PARAMS['use_optimized_inversion_params'] = True # Go gdirs = workflow.init_glacier_regions(rgidf) try: flowline.init_present_time_glacier(gdirs[0]) except Exception: reset = True if reset: # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) # Climate related tasks # See if CRU is running cfg.PARAMS['temp_use_local_gradient'] = False cfg.PATHS['climate_file'] = '~' cru_dir = get_demo_file('cru_ts3.23.1901.2014.tmp.dat.nc') cfg.PATHS['cru_dir'] = os.path.dirname(cru_dir) with warnings.catch_warnings(): # There is a warning from salem warnings.simplefilter("ignore") workflow.execute_entity_task(tasks.distribute_cru_style, gdirs) tasks.compute_ref_t_stars(gdirs) tasks.distribute_t_stars(gdirs) # Use histalp for the actual test cfg.PARAMS['temp_use_local_gradient'] = True cfg.PATHS['climate_file'] = get_demo_file('HISTALP_oetztal.nc') cfg.PATHS['cru_dir'] = '~' workflow.climate_tasks(gdirs) # Inversion workflow.inversion_tasks(gdirs) return gdirs
def climate_run_fl(rgi_ids, path=True, temp_biases=[0, +0.5, -0.5], use_bias_for_run=False, suffixes=['_bias_zero', '_bias_p', '_bias_n'], tstar=None, nyears=None, **kwargs): """Computes 'only' the massbalance in analogy to the `equilibrium_run_...` routines, without running the evolution (flowline) model. Dataset containing yearly values of specific mass balance is returned. Parameters ---------- rgi_ids: array-like List of RGI IDs for which the equilibrium experiments are performed. path: bool or str, optional, default=True If a path is given (or True), the resulting dataset is stored to file. temp_biases: array-like, optional, default=(0, +0.5, -0.5) List of temperature biases (float, in degC) for the mass balance model. suffixes: array-like, optional, default=['_normal', '_bias_p', '_bias_n'] Descriptive suffixes corresponding to the given temperature biases. tstar: float 'Equilibrium year' used for the mass balance calibration. nyears: int, optional, default=None Number of years for which to compute the random mass balance kwargs: Additional key word arguments for massbalance model. Returns ------- Dataset containing yearly values of specific massbalance. """ # assert correct output file suffixes for temp biases if len(temp_biases) != len(suffixes): raise RuntimeError("Each given temperature bias must have its " "corresponding suffix") # compute RGI region and version from RGI IDs # assuming all they are all the same rgi_region = (rgi_ids[0].split('-')[-1]).split('.')[0] rgi_version = (rgi_ids[0].split('-')[0])[-2:] # load default parameter file cfg.initialize() # create working directory wdir = '/Users/oberrauch/work/master/working_directories/' wdir += 'test_cluster' if not os.path.exists(wdir): os.makedirs(wdir) # shutil.rmtree(wdir) # os.makedirs(wdir) # set path to working directory cfg.PATHS['working_dir'] = wdir # set RGI verion and region cfg.PARAMS['rgi_version'] = rgi_version # define how many grid points to use around the glacier, # if you expect the glacier to grow large use a larger border cfg.PARAMS['border'] = 120 # we use HistAlp climate data cfg.PARAMS['baseline_climate'] = 'HISTALP' # set the mb hyper parameters accordingly cfg.PARAMS['prcp_scaling_factor'] = 1.75 cfg.PARAMS['temp_melt'] = -1.75 # the bias is defined to be zero during the calibration process, # which is why we don't use it here to reproduce the results cfg.PARAMS['use_bias_for_run'] = use_bias_for_run # operational run, all glaciers should run cfg.PARAMS['continue_on_error'] = True # read RGI entry for the glaciers as DataFrame # containing the outline area as shapefile rgidf = utils.get_rgi_glacier_entities(rgi_ids) # get and set path to intersect shapefile intersects_db = utils.get_rgi_intersects_region_file(region=rgi_region) cfg.set_intersects_db(intersects_db) # initialize the GlacierDirectory gdirs = workflow.init_glacier_directories(rgidf, reset=False, force=True) # run gis tasks workflow.gis_prepro_tasks(gdirs) # run climate tasks workflow.execute_entity_task(climate.process_climate_data, gdirs) workflow.execute_entity_task(climate.local_t_star, gdirs, tstar=tstar, bias=0) workflow.execute_entity_task(climate.mu_star_calibration, gdirs) # run inversion tasks workflow.inversion_tasks(gdirs) # finalize preprocessing workflow.execute_entity_task(flowline.init_present_time_glacier, gdirs) # use t* as center year, even if specified differently kwargs['y0'] = tstar # run for 3000 years if not specified otherwise if nyears is None: nyears = 10000 years = np.arange(0, nyears + 1) # create dataset ds = list() # run RandomMassBalance model centered around t*, once without # temperature bias and once with positive and negative temperature bias # of 0.5 °C each. for gdir in gdirs: # set random seed to get reproducible results kwargs.setdefault('seed', 12) kwargs.setdefault('halfsize', 15) kwargs.setdefault('mb_model_class', flowline.RandomMassBalance) kwargs.setdefault('filename', 'climate_historical') kwargs.setdefault('input_filesuffix', '') kwargs.setdefault('unique_samples', False) ds_ = list() fls = gdir.read_pickle('model_flowlines') for suffix, temp_bias in zip(suffixes, temp_biases): # instance mass balance model mb_mod = flowline.MultipleFlowlineMassBalance(gdir, **kwargs) if temp_bias is not None: # add given temperature bias to mass balance model mb_mod.temp_bias = temp_bias # create empty container spec_mb = list() # iterate over all years for yr in years: spec_mb.append(mb_mod.get_specific_mb(fls=fls, year=yr)) # add to dataset da = xr.DataArray(spec_mb, dims=('year'), coords={'year': years}) ds_.append(xr.Dataset({'spec_mb': da})) ds_ = xr.concat(ds_, pd.Index(temp_biases, name='temp_bias')) ds_.coords['rgi_id'] = gdir.rgi_id ds.append(ds_) ds = xr.concat(ds, 'rgi_id') # store datasets if path: if path is True: path = os.path.join(cfg.PATHS['working_dir'], 'mb_output_fl.nc') ds.to_netcdf(path) # ds_normal.to_netcdf(path[1]) # return ds, ds_normal return ds
def equilibrium_run_fl(rgi_ids, use_random_mb=True, path=True, temp_biases=(0, +0.5, -0.5), use_bias_for_run=False, suffixes=['_bias_zero', '_bias_p', '_bias_n'], tstar=None, **kwargs): """ The routine runs all steps for the equilibrium experiments using the flowline model. For details see docstring of `sensitivity_run_vas`. Parameters ---------- rgi_ids: array-like List of RGI IDs for which the equilibrium experiments are performed. use_random_mb: bool, optional, default=True Choose between random massbalance model and constant massbalance model. path: bool or str, optional, default=True If a path is given (or True), the resulting dataset is stored to file. temp_biases: array-like, optional, default=(0, +0.5, -0.5) List of temperature biases (float, in degC) for the mass balance model. suffixes: array-like, optional, default=['_normal', '_bias_p', '_bias_n'] Descriptive suffixes corresponding to the given temperature biases. tstar: float 'Equilibrium year' used for the mass balance calibration. kwargs: Additional key word arguments for the `run_random_climate` or `run_constant_climate` routines of the vascaling module. Returns ------- Dataset containing yearly values of all glacier geometries. """ # assert correct output file suffixes for temp biases if len(temp_biases) != len(suffixes): raise RuntimeError("Each given temperature bias must have its " "corresponding suffix") # compute RGI region and version from RGI IDs # assuming all they are all the same rgi_region = (rgi_ids[0].split('-')[-1]).split('.')[0] rgi_version = (rgi_ids[0].split('-')[0])[-2:] # load default parameter file cfg.initialize() # create working directory wdir = '/Users/oberrauch/work/master/working_directories/' wdir += 'test_cluster' if not os.path.exists(wdir): os.makedirs(wdir) # shutil.rmtree(wdir) # os.makedirs(wdir) # set path to working directory cfg.PATHS['working_dir'] = wdir # set RGI verion and region cfg.PARAMS['rgi_version'] = rgi_version # define how many grid points to use around the glacier, # if you expect the glacier to grow large use a larger border cfg.PARAMS['border'] = 120 # we use HistAlp climate data cfg.PARAMS['baseline_climate'] = 'HISTALP' # set the mb hyper parameters accordingly cfg.PARAMS['prcp_scaling_factor'] = 1.75 cfg.PARAMS['temp_melt'] = -1.75 # the bias is defined to be zero during the calibration process, # which is why we don't use it here to reproduce the results cfg.PARAMS['use_bias_for_run'] = use_bias_for_run # read RGI entry for the glaciers as DataFrame # containing the outline area as shapefile rgidf = utils.get_rgi_glacier_entities(rgi_ids) # get and set path to intersect shapefile intersects_db = utils.get_rgi_intersects_region_file(region=rgi_region) cfg.set_intersects_db(intersects_db) # sort by area for more efficient parallel computing rgidf = rgidf.sort_values('Area', ascending=False) cfg.PARAMS['use_multiprocessing'] = True # operational run, all glaciers should run cfg.PARAMS['continue_on_error'] = True # initialize the GlacierDirectory gdirs = workflow.init_glacier_directories(rgidf, reset=False, force=True) # run gis tasks workflow.gis_prepro_tasks(gdirs) # run climate tasks workflow.execute_entity_task(climate.process_climate_data, gdirs) workflow.execute_entity_task(climate.local_t_star, gdirs, tstar=tstar, bias=0) workflow.execute_entity_task(climate.mu_star_calibration, gdirs) # run inversion tasks workflow.inversion_tasks(gdirs) # finalize preprocessing workflow.execute_entity_task(flowline.init_present_time_glacier, gdirs) # use t* as center year, even if specified differently kwargs['y0'] = tstar # run for 3000 years if not specified otherwise kwargs.setdefault('nyears', 3000) # disregard glaciers exceeding their domain boundaries # to not dirsupt the entire run kwargs.setdefault('check_for_boundaries', True) if use_random_mb: # set random seed to get reproducible results kwargs.setdefault('seed', 12) # run RandomMassBalance model centered around t*, once without # temperature bias and once with positive and negative temperature bias # of 0.5 °C each. for suffix, temp_bias in zip(suffixes, temp_biases): workflow.execute_entity_task( flowline.run_random_climate, gdirs, temperature_bias=temp_bias, output_filesuffix=suffix, **kwargs, ) else: # run RandomMassBalance model centered around t*, once without # temperature bias and once with positive and negative temperature bias # of 0.5 °C each. for suffix, temp_bias in zip(suffixes, temp_biases): workflow.execute_entity_task( flowline.run_constant_climate, gdirs, temperature_bias=temp_bias, output_filesuffix=suffix, **kwargs, ) ds = list() for suffix, temp_bias in zip(suffixes, temp_biases): # compile the output for each run and store to file ds_ = utils.compile_run_output(np.atleast_1d(gdirs), input_filesuffix=suffix, path=False) ds.append(ds_) # concat into one dataset with temperature bias as coordinate ds = xr.concat(ds, pd.Index(temp_biases, name='temp_bias')) # add model type as coordinate ds.coords['model'] = 'fl' # add mb model type as coordinate ds.coords['mb_model'] = 'random' if use_random_mb else 'constant' # compute mean and sum over all glaciers ds_mean = ds.mean(dim='rgi_id') ds_mean.coords['rgi_id'] = 'mean' ds_sum = ds.sum(dim='rgi_id') ds_sum.coords['rgi_id'] = 'sum' # add to dataset ds = xr.concat([ds, ds_mean, ds_sum], dim='rgi_id') # normalize glacier geometries (length/area/volume) with start value ds_normal = normalize_ds_with_start(ds) # add coordinate to distinguish between normalized and absolute values ds.coords['normalized'] = int(False) ds_normal.coords['normalized'] = int(True) # combine datasets ds = xr.concat([ds, ds_normal], 'normalized') # store datasets if path: if path is True: mb = 'random' if use_random_mb else 'constant' path = os.path.join(cfg.PATHS['working_dir'], 'run_output_{}_fl.nc'.format(mb)) ds.to_netcdf(path) return ds
def up_to_inversion(): """Run the tasks you want.""" # test directory testdir = os.path.join(current_dir, 'tmp') if not os.path.exists(testdir): os.makedirs(testdir) clean_dir(testdir) # Init cfg.initialize() # Prevent multiprocessing cfg.use_mp = False # Working dir cfg.paths['working_dir'] = testdir cfg.set_divides_db(get_demo_file('HEF_divided.shp')) cfg.paths['srtm_file'] = get_demo_file('srtm_oeztal.tif') # Set up the paths and other stuffs cfg.set_divides_db(get_demo_file('HEF_divided.shp')) cfg.paths['histalp_file'] = get_demo_file('HISTALP_oeztal.nc') # Get test glaciers (all glaciers with MB or Thickness data) cfg.paths['wgms_rgi_links'] = get_demo_file('RGI_WGMS_oeztal.csv') cfg.paths['glathida_rgi_links'] = get_demo_file('RGI_GLATHIDA_oeztal.csv') # Read in the RGI file rgi_file = get_demo_file('rgi_oeztal.shp') rgidf = gpd.GeoDataFrame.from_file(rgi_file) # Go gdirs = workflow.init_glacier_regions(rgidf) # First preprocessing tasks workflow.gis_prepro_tasks(gdirs) # Climate related tasks workflow.climate_tasks(gdirs) # Merge climate and catchments workflow.execute_task(inversion.prepare_for_inversion, gdirs) fs, fd = inversion.optimize_inversion_params(gdirs) # Tests dfids = cfg.paths['glathida_rgi_links'] gtd_df = pd.read_csv(dfids).sort_values(by=['RGI_ID']) dfids = gtd_df['RGI_ID'].values ref_gdirs = [gdir for gdir in gdirs if gdir.rgi_id in dfids] # Account for area differences between glathida and rgi ref_area_km2 = gtd_df.RGI_AREA.values ref_cs = gtd_df.VOLUME.values / (gtd_df.GTD_AREA.values**1.375) ref_volume_km3 = ref_cs * ref_area_km2**1.375 vol = [] area = [] rgi = [] for gdir in ref_gdirs: v, a = inversion.inversion_parabolic_point_slope(gdir, fs=fs, fd=fd, write=True) vol.append(v) area.append(a) rgi.append(gdir.rgi_id) df = pd.DataFrame() df['rgi'] = rgi df['area'] = area df['ref_vol'] = ref_volume_km3 df['oggm_vol'] = np.array(vol) * 1e-9 df['vas_vol'] = 0.034*(ref_area_km2**1.375) df = df.set_index('rgi') shutil.rmtree(testdir) return df
def climate_run_fl(rgi_ids, path=True, temp_biases=[0, +0.5, -0.5], suffixes=['_bias_zero', '_bias_p', '_bias_n'], use_bias_for_run=False, use_default_tstar=True, tstar=None, nyears=None, **kwargs): """Computes 'only' the massbalance in analogy to the `equilibrium_run_...` routines, without running the (flowline) evolution model. Dataset containing yearly values of specific mass balance is returned. Note: the task is not parallelized, hence it can take long if many glaciers are given. TODO: could/should be fixed sometime... TODO: add logging information Parameters ---------- rgi_ids: array-like List of RGI IDs for which the equilibrium experiments are performed. path: bool or str, optional, default=True If a path is given (or True), the resulting dataset is stored to file. temp_biases: array-like, optional, default=(0, +0.5, -0.5) List of temperature biases (float, in degC) for the mass balance model. suffixes: array-like, optional, default=['_normal', '_bias_p', '_bias_n'] Descriptive suffixes corresponding to the given temperature biases. use_bias_for_run: bool, optional, default=False Flag deciding whether or not the mass balance residual is used tstar: float, optional, default=None 'Equilibrium year' used for the mass balance calibration. Using the `ref_tstars.csv` table if not supplied. use_default_tstar : bool, optional, default=True Flag deciding whether or not to use the default ref_tstar.csv list. If `False`the `oggm_ref_tstars_rgi6_histalp.csv` reference table is used. nyears: int, optional, default=None Number of years for which to compute the random mass balance kwargs: Additional key word arguments for massbalance model. Returns ------- Dataset containing yearly values of specific massbalance. """ # assert correct output file suffixes for temp biases if len(temp_biases) != len(suffixes): raise RuntimeError("Each given temperature bias must have its " "corresponding suffix") # compute RGI region and version from RGI IDs # assuming all they are all the same rgi_region = (rgi_ids[0].split('-')[-1]).split('.')[0] rgi_version = (rgi_ids[0].split('-')[0])[-2:-1] # load default parameter file cfg.initialize() # get environmental variables for working and output directories WORKING_DIR = os.environ["WORKDIR"] OUTPUT_DIR = os.environ["OUTDIR"] # create working directory utils.mkdir(WORKING_DIR) # set path to working directory cfg.PATHS['working_dir'] = WORKING_DIR # set RGI version and region cfg.PARAMS['rgi_version'] = rgi_version # define how many grid points to use around the glacier, # if you expect the glacier to grow large use a larger border cfg.PARAMS['border'] = 120 # we use HistAlp climate data cfg.PARAMS['baseline_climate'] = 'HISTALP' # set the mb hyper parameters accordingly cfg.PARAMS['prcp_scaling_factor'] = 1.75 cfg.PARAMS['temp_melt'] = -1.75 # the bias is defined to be zero during the calibration process, # which is why we don't use it here to reproduce the results cfg.PARAMS['use_bias_for_run'] = use_bias_for_run # operational run, all glaciers should run cfg.PARAMS['continue_on_error'] = False # read RGI entry for the glaciers as DataFrame # containing the outline area as shapefile rgidf = utils.get_rgi_glacier_entities(rgi_ids) # get and set path to intersect shapefile intersects_db = utils.get_rgi_intersects_region_file(region=rgi_region) cfg.set_intersects_db(intersects_db) # initialize the GlacierDirectory gdirs = workflow.init_glacier_directories(rgidf, reset=False, force=True) # run gis tasks workflow.gis_prepro_tasks(gdirs) # run climate tasks workflow.execute_entity_task(climate.process_climate_data, gdirs) # compute local t* and the corresponding mu* if tstar or use_default_tstar: # compute mustar from given tstar workflow.execute_entity_task(climate.local_t_star, gdirs, tstar=tstar, bias=0) else: # compute mustar from the reference table for the flowline model # RGI v6 and HISTALP baseline climate ref_df = pd.read_csv(utils.get_demo_file('oggm_ref_tstars_rgi6_histalp.csv')) workflow.execute_entity_task(climate.local_t_star, gdirs, ref_df=ref_df) workflow.execute_entity_task(climate.mu_star_calibration, gdirs) # run inversion tasks workflow.inversion_tasks(gdirs) # finalize preprocessing workflow.execute_entity_task(flowline.init_present_time_glacier, gdirs) # use t* as center year, even if specified differently kwargs['y0'] = tstar # run for 3000 years if not specified otherwise if nyears is None: nyears = 10000 years = np.arange(0, nyears + 1) # create dataset ds = list() # run RandomMassBalance model centered around t*, once without # temperature bias and once with positive and negative temperature bias # of 0.5 deg C each. for gdir in gdirs: kwargs.setdefault('halfsize', 15) kwargs.setdefault('mb_model_class', flowline.ConstantMassBalance) kwargs.setdefault('filename', 'climate_historical') kwargs.setdefault('input_filesuffix', '') ds_ = list() # open the flowline file if it exists try: fls = gdir.read_pickle('model_flowlines') except: # continue with the next glacier or raise exception # depending on `continue_on_error` flag if cfg.PARAMS['continue_on_error']: continue else: raise for suffix, temp_bias in zip(suffixes, temp_biases): # instance mass balance model try: mb_mod = flowline.MultipleFlowlineMassBalance(gdir, **kwargs) except: # continue with the next glacier or raise exception # depending on `continue_on_error` flag if cfg.PARAMS['continue_on_error']: continue else: raise if temp_bias is not None: # add given temperature bias to mass balance model mb_mod.temp_bias = temp_bias # create empty container spec_mb = list() # iterate over all years for yr in years: spec_mb.append(mb_mod.get_specific_mb(fls=fls, year=yr)) # add to dataset da = xr.DataArray(spec_mb, dims=('year'), coords={'year': years}) ds_.append(xr.Dataset({'spec_mb': da})) if ds_: ds_ = xr.concat(ds_, pd.Index(temp_biases, name='temp_bias')) ds_.coords['rgi_id'] = gdir.rgi_id ds.append(ds_) if ds: # combine output from single glaciers into one dataset ds = xr.concat(ds, 'rgi_id') # store dataset to file if path: if path is True: path = os.path.join(OUTPUT_DIR, 'mb_output_fl.nc') ds.to_netcdf(path) # return ds return ds