def read_result_parallel(gdir): t_e = gdir.rgi_date ex = [f for f in os.listdir(gdir.dir) if f.startswith('model_run_ad')] if len(ex) == 1: path = os.path.join(gdir.dir, ex[0]) ex_mod = FileModel(path) ye = ex_mod.volume_km3_ts().index[-1] bias = float(ex[0].split('_')[-1].split('.nc')[0]) ts = ex_mod.volume_km3_ts() if ye < 2016: try: ex_mod.run_until(ye) tasks.run_from_climate_data(gdir, ys=ye, ye=2016, bias=bias, output_filesuffix='_to_2016', init_model_fls=copy.deepcopy( ex_mod.fls)) res_mod = FileModel( gdir.get_filepath('model_run', filesuffix='_to_2016')) ts2 = res_mod.volume_km3_ts() ts2 = ts2[ts2.index[1:]] ts = pd.concat([ts, ts2]) except: pass ts['rgi_id'] = gdir.rgi_id return ts else: return pd.Series({'rgi_id': gdir.rgi_id})
def _run_file_model(suffix, gdir, ye): """ Read FileModel and run it until ye """ rp = gdir.get_filepath('model_run', filesuffix=suffix) fmod = FileModel(rp) fmod.run_until(ye) return copy.deepcopy(fmod)
def find_candidates(gdir, experiment, df, ys,ye,n): indices = [] for q in np.linspace(0,1,n): # indices of all to test index = df[df['ts_section'] >= (df['ts_section'].quantile(q))]['ts_section'].idxmin() indices = np.append(indices,int(index)) candidates = df.ix[indices] candidates = candidates.sort_values(['suffix','time']) candidates['fls_t0']=None for suffix in candidates['suffix'].unique(): rp = gdir.get_filepath('model_run', filesuffix=suffix) fmod = FileModel(rp) for i,t in candidates[candidates['suffix']==suffix]['time'].iteritems(): fmod.run_until(t) candidates.at[i,'random_model_t0'] = copy.deepcopy(fmod) candidates = candidates.drop_duplicates() fls_list =[] for i in candidates.index: s = candidates.loc[int(i),'suffix'].split('_random')[-1] suffix = str(ys)+'_past'+s+'_'+str(int(candidates.loc[int(i),'time'])) fls = candidates.loc[int(i),'random_model_t0'] fls_list.append([suffix,fls]) # run candidates until present pool = Pool() path_list = pool.map(partial(run_to_present, gdir=gdir, ys=ys, ye=2000), fls_list) pool.close() pool.join() candidates = candidates.assign(past_suffix=path_list) candidates['model_t0'] = candidates['past_suffix'].apply(read_file_model, args=([gdir])) candidates['model_t'] = candidates['past_suffix'].apply(run_file_model, args=([ye])) candidates['objective'] = candidates['model_t'].apply(objective_value, args=([experiment['y_t']])) return candidates
) f.delaxes(axs[0]) f.delaxes(axs[1]) f.delaxes(axs[1].cax) tx, ty = 0.019, .975 letkm = dict(color='black', ha='left', va='top', fontsize=14, bbox=dict(facecolor='white', edgecolor='black')) llkw = {'interval': 0} fp = gdir.get_filepath('model_run', filesuffix='_2000_def') model = FileModel(fp) model.run_until(800) ax = axs[3] graphics.plot_modeloutput_map(gdir, model=model, ax=ax, title='', lonlat_contours_kwargs=llkw, cbar_ax=ax.cax, linewidth=1.5, add_scalebar=False, vmax=300) ax.text(tx, ty, 'c: [1985-2015]', transform=ax.transAxes, **letkm) fp = gdir.get_filepath('model_run', filesuffix='_1920_def') model = FileModel(fp) model.run_until(800)
def spinup_plus_histalp(gdir, meta=None, mb_bias=None, runsuffix=''): # take care of merged glaciers rgi_id = gdir.rgi_id.split('_')[0] # select meta meta = meta.loc[rgi_id].copy() # we want to simulate as much as possible -> histalp till 2014 obs_ye = 2014 # --------- SPIN IT UP --------------- tbias = systematic_spinup(gdir, meta, mb_bias=mb_bias) if tbias == -999: rval = { 'rgi_id': gdir.rgi_id, 'name': meta['name'], 'histalp': np.nan, 'spinup': np.nan, 'tbias': np.nan, 'tmean': np.nan, 'pmean': np.nan } return rval # --------- GET SPINUP STATE --------------- tmp_mod = FileModel(gdir.get_filepath('model_run', filesuffix='_spinup')) tmp_mod.run_until(tmp_mod.last_yr) # --------- HIST IT DOWN -------------- try: run_from_climate_data(gdir, ys=meta['first'], ye=obs_ye, init_model_fls=tmp_mod.fls, climate_filename='climate_monthly', output_filesuffix='_histalp' + runsuffix, bias=mb_bias) except RuntimeError as err: if 'Glacier exceeds domain boundaries' in err.args[0]: log.info('(%s) histalp run exceeded domain bounds' % gdir.rgi_id) return else: raise RuntimeError('other error') ds1 = xr.open_dataset( gdir.get_filepath('model_diagnostics', filesuffix='_histalp' + runsuffix)) ds2 = xr.open_dataset( gdir.get_filepath('model_diagnostics', filesuffix='_spinup')) # store mean temperature and precipitation yindex = np.arange(meta['first'], obs_ye + 1) try: cm = xr.open_dataset(gdir.get_filepath('climate_monthly')) except FileNotFoundError: cm = xr.open_dataset( gdir.get_filepath('climate_monthly', filesuffix='_' + rgi_id)) tmean = cm.temp.groupby('time.year').mean().loc[yindex].to_pandas() pmean = cm.prcp.groupby('time.year').mean().loc[yindex].to_pandas() rval = { 'rgi_id': gdir.rgi_id, 'name': meta['name'], 'histalp': ds1.length_m.to_dataframe()['length_m'], 'spinup': ds2.length_m.to_dataframe()['length_m'], 'tbias': tbias, 'tmean': tmean, 'pmean': pmean } # relative length change rval['rel_dl'] = relative_length_change(meta, rval['spinup'], rval['histalp']) # if merged, store tributary flowline change as well if '_merged' in gdir.rgi_id: trib = rval['histalp'].copy() * np.nan # choose the correct flowline index, use model_fls as they have rgiids fls = gdir.read_pickle('model_flowlines') flix = np.where([fl.rgi_id != rgi_id for fl in fls])[0][-1] fmod = FileModel( gdir.get_filepath('model_run', filesuffix='_histalp' + runsuffix)) assert fmod.fls[flix].nx == fls[flix].nx, ('filemodel and gdir ' 'flowlines do not match') for yr in rval['histalp'].index: fmod.run_until(yr) trib.loc[yr] = fmod.fls[flix].length_m trib -= trib.iloc[0] rval['trib_dl'] = trib return rval
def run_file_model(suffix,ye): rp = gdir.get_filepath('model_run', filesuffix=suffix) fmod = FileModel(rp) fmod.run_until(ye) return copy.deepcopy(fmod)
def plot_surface_col(gdir, df, experiment, ys): #df = df[df['objective']<=100] x = np.arange(experiment['y_t'].fls[-1].nx) * \ experiment['y_t'].fls[-1].dx * experiment['y_t'].fls[-1].map_dx fig = plt.figure(figsize=(20, 15)) grid = plt.GridSpec(2, 2, hspace=0.2, wspace=0.2) ax1 = plt.subplot(grid[0, 0]) ax2 = plt.subplot(grid[0, 1]) ax3 = plt.subplot(grid[1, :]) p2 = ax2.get_position() if gdir.name != '': plt.suptitle(gdir.rgi_id + ':' + gdir.name, x=p2.x1 / 2, fontsize=20) else: plt.suptitle(gdir.rgi_id, x=p2.x1 / 2, fontsize=20) import matplotlib as mpl import matplotlib.cm as cm norm = mpl.colors.LogNorm(vmin=0.1, vmax=1e5) cmap = matplotlib.cm.get_cmap('RdYlGn_r') df = df.sort_values('objective', ascending=False) for i, model in df['model_t0'].iteritems(): color = cmap(norm(df.loc[i, 'objective'])) ax1.plot(x, model.fls[-1].surface_h, color=color, linewidth=2) model.volume_m3_ts().plot(ax=ax3, color=color, linewidth=2) for i, model in df['model_t'].iteritems(): color = cmap(norm(df.loc[i, 'objective'])) ax2.plot(x, model.fls[-1].surface_h, color=color, linewidth=2) ax2.plot(x, experiment['y_t'].fls[-1].surface_h, 'k:', linewidth=3) ax2.plot(x, model.fls[-1].bed_h, 'k', linewidth=3) # create volume plot from experiment model = experiment['y_t0'] tasks.run_from_climate_data(gdir, ys=1850, ye=2000, init_model_fls=model.fls, output_filesuffix='experiment') rp = gdir.get_filepath('model_run', filesuffix='experiment') ex_mod = FileModel(rp) ex_mod.volume_m3_ts().plot(ax=ax3, color='k', linestyle=':', linewidth=3) ex_mod.run_until(ys) ax1.plot(x, ex_mod.fls[-1].surface_h, 'k:', linewidth=3) ax1.plot(x, ex_mod.fls[-1].bed_h, 'k', linewidth=3) ax1.annotate(r'$t = ' + str(ys) + '$', xy=(0.8, 0.9), xycoords='axes fraction', fontsize=15) ax2.annotate(r'$t = 2000$', xy=(0.8, 0.9), xycoords='axes fraction', fontsize=15) ax1.set_ylabel('Altitude (m)', fontsize=15) ax1.set_xlabel('Distance along the main flowline (m)', fontsize=15) ax2.set_ylabel('Altitude (m)', fontsize=15) ax2.set_xlabel('Distance along the main flowline (m)', fontsize=15) ax3.set_ylabel(r'Volume ($m^3$)', fontsize=15) ax3.set_xlabel('Time (years)', fontsize=15) sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm) sm.set_array([]) cax, kw = mpl.colorbar.make_axes([ax1, ax2, ax3]) cbar = fig.colorbar(sm, cax=cax, **kw) cbar.ax.tick_params(labelsize=15) cbar.set_label('objective', fontsize=15) ax1.tick_params(axis='both', which='major', labelsize=15) ax2.tick_params(axis='both', which='major', labelsize=15) ax3.tick_params(axis='both', which='major', labelsize=15) ax3.yaxis.offsetText.set_fontsize(15) plot_dir = '/home/juliaeis/Dokumente/OGGM/work_dir/find_initial_state/past_state_information/plots' plt.savefig(os.path.join(plot_dir, 'surface_' + str(ys) + '_' + gdir.rgi_id + '.pdf'), dpi=200) plt.savefig(os.path.join(plot_dir, 'surface_' + str(ys) + '_' + gdir.rgi_id + '.png'), dpi=200)
def run_ensemble(allgdirs, rgi_id, ensemble, tbiasdict, allmeta, storedir, runsuffix='', spinup_y0=1999): # default glena default_glena = 2.4e-24 # loop over all combinations for nr, run in enumerate(ensemble): pdict = ast.literal_eval('{' + run + '}') cfg.PARAMS['glen_a'] = pdict['glena_factor'] * default_glena cfg.PARAMS['inversion_glen_a'] = pdict['glena_factor'] * default_glena mbbias = pdict['mbbias'] cfg.PARAMS['prcp_scaling_factor'] = pdict['prcp_scaling_factor'] log.info('Current parameter combination: %s' % str(run)) log.info('This is combination %d out of %d.' % (nr + 1, len(ensemble))) # ok, we need the ref_glaciers here for calibration # they should be initialiced so, just recreate them from the directory ref_gdirs = [ GlacierDirectory(refid) for refid in preprocessing.ADDITIONAL_REFERENCE_GLACIERS ] # do the mass balance calibration compute_ref_t_stars(ref_gdirs + allgdirs) task_list = [ tasks.local_t_star, tasks.mu_star_calibration, tasks.prepare_for_inversion, tasks.mass_conservation_inversion, tasks.filter_inversion_output, tasks.init_present_time_glacier ] for task in task_list: execute_entity_task(task, allgdirs) # check for glaciers to merge: gdirs_merged = [] gdirs2sim = allgdirs.copy() for gid in allmeta.index: merg = merge_pair_dict(gid) if merg is not None: # main and tributary glacier gd2merge = [ gd for gd in allgdirs if gd.rgi_id in [gid] + merg[0] ] # actual merge task log.warning('DeprecationWarning: If downloadlink is updated ' + 'to gdirs_v1.2, remove filename kwarg') gdir_merged = merge_glacier_tasks(gd2merge, gid, buffer=merg[1], filename='climate_monthly') # remove the entity glaciers from the simulation list gdirs2sim = [ gd for gd in gdirs2sim if gd.rgi_id not in [gid] + merg[0] ] gdirs_merged.append(gdir_merged) # add merged glaciers to the left over entity glaciers gdirs2sim += gdirs_merged # now only select the 1 glacier gdir = [gd for gd in gdirs2sim if gd.rgi_id == rgi_id][0] rgi_id0 = rgi_id.split('_')[0] meta = allmeta.loc[rgi_id0].copy() # do the actual simulations # spinup fls = gdir.read_pickle('model_flowlines') tbias = tbiasdict[run] mb = MultipleFlowlineMassBalance(gdir, fls=fls, mb_model_class=ConstantMassBalance, filename='climate_monthly', y0=spinup_y0, bias=mbbias) minimize_dl(tbias, mb, fls, None, None, gdir, False, runsuffix='_{:02d}'.format(nr)) # histalp # --------- GET SPINUP STATE --------------- tmp_mod = FileModel( gdir.get_filepath('model_run', filesuffix='_spinup_{:02d}'.format(nr))) tmp_mod.run_until(tmp_mod.last_yr) # --------- HIST IT DOWN --------------- histrunsuffix = '_histalp{}_{:02d}'.format(runsuffix, nr) # now actual simulation run_from_climate_data(gdir, ys=meta['first'], ye=2014, init_model_fls=tmp_mod.fls, output_filesuffix=histrunsuffix, climate_filename='climate_monthly', bias=mbbias) # save the calibration parameter to the climate info file out = gdir.get_climate_info() out['ensemble_calibration'] = pdict gdir.write_json(out, 'climate_info') # copy stuff to storage basedir = os.path.join(storedir, rgi_id) ensdir = os.path.join(basedir, '{:02d}'.format(nr)) mkdir(ensdir, reset=True) deep_path = os.path.join(ensdir, rgi_id[:8], rgi_id[:11], rgi_id) # copy whole GDir copy_to_basedir(gdir, base_dir=ensdir, setup='run') # copy run results fn1 = 'model_diagnostics_spinup_{:02d}.nc'.format(nr) shutil.copyfile( gdir.get_filepath('model_diagnostics', filesuffix='_spinup_{:02d}'.format(nr)), os.path.join(deep_path, fn1)) fn2 = 'model_diagnostics{}.nc'.format(histrunsuffix) shutil.copyfile( gdir.get_filepath('model_diagnostics', filesuffix=histrunsuffix), os.path.join(deep_path, fn2)) fn3 = 'model_run_spinup_{:02d}.nc'.format(nr) shutil.copyfile( gdir.get_filepath('model_run', filesuffix='_spinup_{:02d}'.format(nr)), os.path.join(deep_path, fn3)) fn4 = 'model_run{}.nc'.format(histrunsuffix) shutil.copyfile( gdir.get_filepath('model_run', filesuffix=histrunsuffix), os.path.join(deep_path, fn4)) log.warning('DeprecationWarning: If downloadlink is updated to ' + 'gdirs_v1.2 remove this copyfile:') # copy (old) climate monthly files which for fn in os.listdir(gdir.dir): if 'climate_monthly' in fn: shutil.copyfile(os.path.join(gdir.dir, fn), os.path.join(deep_path, fn))
def run_from_magicc_data(gdir, magicc_ts=None, ys=None, ye=None, y0=2014, halfsize=5, use_dt_per_dt=True, use_dp_per_dt=True, climate_filename='climate_historical', climate_input_filesuffix='', output_filesuffix='', init_model_filesuffix=None, init_model_yr=None, bias=None, **kwargs): """Runs a glacier with climate input from MAGICC. Parameters ---------- gdir : :py:class:`oggm.GlacierDirectory` the glacier directory to process gdir : :py:class:`oggm.GlacierDirectory` the glacier directory to process ys : int start year of the model run (default: from the glacier geometry date if init_model_filesuffix is None, else init_model_yr) ye : int end year of the model run (default: last year of the magicc file) y0 : int central year where to apply the MAGICC anomaly method halfsize : int half-size of the MAGICC anomaly window climate_filename : str name of the climate file, e.g. 'climate_historical' (default) or 'gcm_data' climate_input_filesuffix: str filesuffix for the input climate file output_filesuffix : str for the output file init_model_filesuffix : str if you want to start from a previous model run state. Can be combined with `init_model_yr` init_model_yr : int the year of the initial run you want to start from. The default is to take the y0 - halfsize bias : float bias of the mb model. Default is to use the calibrated one, which is often a better idea. For t* experiments it can be useful to set it to zero kwargs : dict kwargs to pass to the FluxBasedModel instance """ if init_model_yr is None: init_model_yr = y0 - halfsize if init_model_filesuffix is not None: fp = gdir.get_filepath('model_geometry', filesuffix=init_model_filesuffix) fmod = FileModel(fp) if init_model_yr is None: init_model_yr = fmod.last_yr # Avoid issues here if init_model_yr > fmod.y0: fmod.run_until(init_model_yr) else: fmod.run_until(fmod.y0) init_model_fls = fmod.fls if ys is None: ys = init_model_yr else: raise InvalidParamsError('We strongly recommend to start from ' 'prepro for this task.') # Take from rgi date if not set yet if ys is None: raise InvalidParamsError('ys should not be guessed at this point') dt_per_dt = 1. dp_per_dt = 0. if use_dt_per_dt: dt_per_dt = np.asarray(gdir.get_diagnostics()['magicc_dt_per_dt']) if use_dp_per_dt: dp_per_dt = np.asarray(gdir.get_diagnostics()['magicc_dp_per_dt']) # Final crop mb = MagiccMassBalance(gdir, magicc_ts=magicc_ts, y0=y0, halfsize=halfsize, dt_per_dt=dt_per_dt, dp_per_dt=dp_per_dt, filename=climate_filename, bias=bias, input_filesuffix=climate_input_filesuffix) if ye is None: # Decide from climate ye = mb.ye return flowline_model_run(gdir, output_filesuffix=output_filesuffix, mb_model=mb, ys=ys, ye=ye, init_model_fls=init_model_fls, **kwargs)
def elevation_profiles(rgi, meta, histalp_storage, pout): name = name_plus_id(rgi) df1850 = pd.DataFrame() df2003 = pd.DataFrame() df2003b = pd.DataFrame() dfbed = pd.DataFrame() for i in np.arange(999): # Local working directory (where OGGM will write its output) rgipath = os.path.join(histalp_storage, rgi, '{:02d}'.format(i), rgi[:8], rgi[:11], rgi) fn = os.path.join(rgipath, 'model_run_histalp_{:02d}.nc'.format(i)) try: tmpmod = FileModel(fn) except FileNotFoundError: break df1850.loc[:, i] = tmpmod.fls[-1].surface_h # get bed surface dfbed.loc[:, i] = tmpmod.fls[-1].bed_h # HISTALP surface tmpmod.run_until(2003) df2003.loc[:, i] = tmpmod.fls[-1].surface_h df2003b.loc[:, i] = tmpmod.fls[-1].thick # RGI init surface, once is enough fn2 = os.path.join(histalp_storage, rgi, '00', rgi[:8], rgi[:11], rgi, 'model_run_spinup_00.nc') tmpmod2 = FileModel(fn2) initsfc = tmpmod2.fls[-1].surface_h # get distance on line dx_meter = tmpmod.fls[-1].dx_meter meanbed = dfbed.mean(axis=1).values maxbed = dfbed.max(axis=1).values minbed = dfbed.min(axis=1).values # 1850 mean1850 = df1850.mean(axis=1).values # where is mean glacier thinner than 1m ix50 = np.where(mean1850-meanbed < 1)[0][0] mean1850[ix50:] = np.nan min1850 = df1850.min(axis=1).values min1850[ix50:] = np.nan min1850[min1850 <= meanbed] = meanbed[min1850 <= meanbed] max1850 = df1850.max(axis=1).values max1850[max1850 <= meanbed] = meanbed[max1850 <= meanbed] # 2003 mean2003 = df2003.mean(axis=1).values # where is mean glacier thinner than 1m ix03 = np.where(mean2003-meanbed < 1)[0][0] mean2003[ix03:] = np.nan min2003 = df2003.min(axis=1).values min2003[ix03:] = np.nan min2003[min2003 <= meanbed] = meanbed[min2003 <= meanbed] max2003 = df2003.max(axis=1).values max2003[max2003 <= meanbed] = meanbed[max2003 <= meanbed] lastx = np.where(initsfc-meanbed < 1)[0][0] initsfc[lastx:] = np.nan initsfc[lastx] = meanbed[lastx] dis = np.arange(len(meanbed)) * dx_meter / 1000 xmax = sum(np.isfinite(mean1850)) ymax = np.nanmax(mean1850) + 50 ymin = minbed[np.where(np.isfinite(mean1850))].min() - 50 fig, ax = plt.subplots(1, figsize=[15, 9]) ax.fill_between(dis[:xmax+1], dis[:xmax+1] * 0 + ymin, minbed[:xmax+1], color='0.7', alpha=0.5) ax.fill_between(dis[:xmax+1], minbed[:xmax+1], maxbed[:xmax+1], color='xkcd:tan', alpha=0.5) ax.plot(dis[:xmax+1], meanbed[:xmax+1], 'k-', color='xkcd:tan', linewidth=3, label='Glacier bed elevation [m]') ax.fill_between(dis, min1850, max1850, color='xkcd:azure', alpha=0.5) ax.plot(dis, mean1850, 'k-', color='xkcd:azure', linewidth=4, label=('Surface elevation [m] year {:d}\n' '(initialization state after spinup)'. format(meta['first']))) ax.fill_between(dis, min2003, max2003, color='xkcd:teal', alpha=0.5) ax.plot(dis, mean2003, 'k-', color='xkcd:teal', linewidth=4, label=('Surface elevation [m] year 2003\n' '(from HISTALP ensemble simulations)')) ax.plot(dis, initsfc, 'k-', color='xkcd:crimson', linewidth=4, label=('Surface elevation [m] year 2003\n' '(from RGI initialization)')) ax.legend(loc=1, fontsize=20) ax.set_ylim(ymin, ymax) ax.set_xlim(0, dis[xmax]) ax.set_xlabel('Distance along major flowline [km]', fontsize=28) ax.set_ylabel('Elevation [m a.s.l.]', fontsize=28) ax.tick_params(axis='both', which='major', labelsize=26) ax.grid(True) ax.set_title(name, fontsize=30) fig.tight_layout() fn = os.path.join(pout, 'profile_%s' % rgi) if ('3643' in rgi) or ('1450' in rgi) or ('2051' in rgi) or ('897' in rgi): fig.savefig('{}.svg'.format(fn)) fig.savefig('{}.png'.format(fn))
def run_and_store_from_disk(rgi, histalp_storage, commit_storage, y0=1999, years=300, seed=None, unique_samples=False, halfsize=15): for i in np.arange(999): # Local working directory (where OGGM will write its output) storage_dir = os.path.join(histalp_storage, rgi, '{:02d}'.format(i), rgi[:8], rgi[:11], rgi) new_dir = os.path.join(cfg.PATHS['working_dir'], 'per_glacier', rgi[:8], rgi[:11], rgi) # make sure directory is empty: try: shutil.rmtree(new_dir) except FileNotFoundError: pass # if path does not exist, we handled all ensemble members: try: shutil.copytree(storage_dir, new_dir) except FileNotFoundError: log.info('processed {:02d} ensemble members'.format(i)) break gdir = GlacierDirectory(rgi) pdict = gdir.get_climate_info()['ensemble_calibration'] cfg.PARAMS['prcp_scaling_factor'] = pdict['prcp_scaling_factor'] default_glena = 2.4e-24 cfg.PARAMS['glen_a'] = pdict['glena_factor'] * default_glena cfg.PARAMS['inversion_glen_a'] = pdict['glena_factor'] * default_glena mbbias = pdict['mbbias'] tmp_mod = FileModel( gdir.get_filepath('model_run', filesuffix='_histalp_{:02d}'.format(i))) tmp_mod.run_until(tmp_mod.last_yr) mb = MultipleFlowlineMassBalance(gdir, mb_model_class=RandomMassBalance, filename='climate_monthly', bias=mbbias, y0=y0, seed=seed, unique_samples=unique_samples, halfsize=halfsize) robust_model_run(gdir, output_filesuffix='commitment{:04d}_{:02d}'.format( y0, i), mb_model=mb, ys=0, ye=years, init_model_fls=tmp_mod.fls) fn1 = 'model_diagnostics_commitment{:04d}_{:02d}.nc'.format(y0, i) shutil.copyfile( gdir.get_filepath('model_diagnostics', filesuffix='commitment{:04d}_{:02d}'.format( y0, i)), os.path.join(commit_storage, fn1)) fn4 = 'model_run_commitment{:04d}_{:02d}.nc'.format(y0, i) shutil.copyfile( gdir.get_filepath('model_run', filesuffix='commitment{:04d}_{:02d}'.format( y0, i)), os.path.join(commit_storage, fn4))
def run_constant_climate_with_bias(gdir, temp_bias_ts=None, prcp_fac_ts=None, ys=None, ye=None, y0=2014, halfsize=5, climate_filename='climate_historical', climate_input_filesuffix='', output_filesuffix='', init_model_fls=None, init_model_filesuffix=None, init_model_yr=None, bias=None, **kwargs): """Runs a glacier with temperature and precipitation correction timeseries. Parameters ---------- gdir : :py:class:`oggm.GlacierDirectory` the glacier directory to process temp_bias_ts : pandas DataFrame the temperature bias timeseries (in °C) (index: time as years) prcp_fac_ts : pandas DataFrame the precipitaion bias timeseries (in % change, positive or negative) (index: time as years) y0 : int central year of the constant climate period halfsize : int half-size of the constant climate period climate_filename : str name of the climate file, e.g. 'climate_historical' (default) or 'gcm_data' climate_input_filesuffix: str filesuffix for the input climate file output_filesuffix : str for the output file init_model_filesuffix : str if you want to start from a previous model run state. Can be combined with `init_model_yr` init_model_yr : int the year of the initial run you want to start from. The default is to take the last year available bias : float bias of the mb model. Default is to use the calibrated one, which is often a better idea. For t* experiments it can be useful to set it to zero kwargs : dict kwargs to pass to the FluxBasedModel instance """ if init_model_filesuffix is not None: fp = gdir.get_filepath('model_geometry', filesuffix=init_model_filesuffix) fmod = FileModel(fp) if init_model_yr is None: init_model_yr = fmod.last_yr # Avoid issues here if init_model_yr > fmod.y0: fmod.run_until(init_model_yr) else: fmod.run_until(fmod.y0) init_model_fls = fmod.fls # Final crop mb = BiasedConstantMassBalance(gdir, temp_bias_ts=temp_bias_ts, prcp_fac_ts=prcp_fac_ts, y0=y0, bias=bias, halfsize=halfsize, filename=climate_filename, input_filesuffix=climate_input_filesuffix) # Decide from climate if ye is None: ye = mb.ye if ys is None: ys = mb.ys return flowline_model_run(gdir, output_filesuffix=output_filesuffix, mb_model=mb, ys=ys, ye=ye, init_model_fls=init_model_fls, **kwargs)
def plot_modeloutput_map(gdirs, ax=None, smap=None, model=None, vmax=None, linewidth=3, filesuffix='', modelyr=None): """Plots the result of the model output.""" gdir = gdirs[0] with utils.ncDataset(gdir.get_filepath('gridded_data')) as nc: topo = nc.variables['topo'][:] # Dirty optim try: smap.set_topography(topo) except ValueError: pass toplot_th = np.array([]) toplot_lines = [] toplot_crs = [] if model is None: models = [] for gdir in gdirs: model = FileModel(gdir.get_filepath('model_run', filesuffix=filesuffix)) model.run_until(modelyr) models.append(model) else: models = utils.tolist(model) for gdir, model in zip(gdirs, models): geom = gdir.read_pickle('geometries') poly_pix = geom['polygon_pix'] crs = gdir.grid.center_grid smap.set_geometry(poly_pix, crs=crs, fc='none', zorder=2, linewidth=.2) poly_pix = utils.tolist(poly_pix) for _poly in poly_pix: for l in _poly.interiors: smap.set_geometry(l, crs=crs, color='black', linewidth=0.5) # plot Centerlines cls = model.fls for l in cls: smap.set_geometry(l.line, crs=crs, color='gray', linewidth=1.2, zorder=50) toplot_th = np.append(toplot_th, l.thick) widths = l.widths.copy() widths = np.where(l.thick > 0, widths, 0.) for wi, cur, (n1, n2) in zip(widths, l.line.coords, l.normals): line = shpg.LineString([shpg.Point(cur + wi/2. * n1), shpg.Point(cur + wi/2. * n2)]) toplot_lines.append(line) toplot_crs.append(crs) dl = salem.DataLevels(cmap=SECTION_THICKNESS_CMAP, nlevels=256, data=toplot_th, vmin=0, vmax=vmax) colors = dl.to_rgb() for l, c, crs in zip(toplot_lines, colors, toplot_crs): smap.set_geometry(l, crs=crs, color=c, linewidth=linewidth, zorder=50) smap.plot(ax) return dict(cbar_label='Section thickness [m]', cbar_primitive=dl, title_comment=' -- year: {:d}'.format(np.int64(model.yr)))
def find_residual(gdir, temp_bias_list, ys, a=-2000, b=2000): best_df = pd.DataFrame() fls = gdir.read_pickle('model_flowlines') mod = FluxBasedModel(flowlines=fls) for temp_bias in temp_bias_list: print(temp_bias) try: ye = gdir.rgi_date max_it = 15 i = 0 bounds = [a, b] df = pd.DataFrame() while i < max_it: bias = round((bounds[0] + bounds[1]) / 2, 1) ex_mod2 = _run_experiment(gdir, temp_bias, bias, ys, ye) fit = fitness_function(ye, ex_mod2, mod) df = df.append(pd.Series({ 'bias': bias, 'fitness': fit }), ignore_index=True) if (abs(mod.area_km2 - ex_mod2.area_km2) < 1e-4 and fit < 125) or bounds[1] - bounds[0] <= 1: break elif ex_mod2.area_km2 > mod.area_km2: bounds[0] = bias else: bounds[1] = bias i += 1 # best bias found bias = df.iloc[df.fitness.idxmin()].bias rp = gdir.get_filepath('model_run', filesuffix='_advanced_experiment_' + str(temp_bias) + '_' + str(bias)) model = FileModel(rp) model.run_until(ye) rp = gdir.get_filepath('model_run', filesuffix='_advanced_experiment_' + str(temp_bias) + '_' + str(0.0)) ex_mod = FileModel(rp) ex_mod.run_until(ye) ''' plt.figure(figsize=(15,10)) plt.plot(model.fls[-1].surface_h,'r',label='best') plt.plot(mod.fls[-1].surface_h, 'orange', label='original') plt.plot(ex_mod.fls[-1].surface_h, 'r:', label='old experiment') plt.plot(model.fls[-1].bed_h,'k', label='bed') plt.legend() utils.mkdir(os.path.join(cfg.PATHS['plot_dir'],'bias_test')) plt.savefig(os.path.join(cfg.PATHS['plot_dir'],'bias_test',gdir.rgi_id+'.png'),dpi=200) ''' diff = mod.area_km2 - model.area_km2_ts()[gdir.rgi_date] model.reset_y0(ys) series = pd.Series({ 'rgi_id': gdir.rgi_id, 'bias': bias, 'iterations': i, 'fitness': df.fitness.min(), 'area_diff': diff, 'model': model, 'temp_bias': temp_bias }) except: series = pd.Series({'rgi_id': gdir.rgi_id, 'temp_bias': temp_bias}) best_df = best_df.append(series, ignore_index=True) plt.figure() x = np.arange(mod.fls[-1].nx) * mod.fls[-1].dx * mod.fls[-1].map_dx for temp_bias, model in zip(best_df.temp_bias, best_df.model): model.run_until(model.length_m_ts().index[-1]) plt.plot(x, model.fls[-1].surface_h, label=str(temp_bias)) #model.volume_km3_ts().plot() plt.plot(x, mod.fls[-1].surface_h, 'r:') plt.plot(x, mod.fls[-1].bed_h, 'k') plt.legend(title='temp_bias') plt.xlabel('Distance along the main flowline (m)') plt.ylabel('Altitude (m)') plt.title(gdir.rgi_id) utils.mkdir(os.path.join(cfg.PATHS['plot_dir'], 'bias_test')) plt.savefig(os.path.join(cfg.PATHS['plot_dir'], 'bias_test', gdir.rgi_id + '.png'), dpi=200) plt.show() return best_df
def run_and_plot_merged_montmine(pout): # Set-up cfg.initialize(logging_level='WORKFLOW') cfg.PATHS['working_dir'] = utils.gettempdir(dirname='OGGM-merging', reset=True) # Use a suitable border size for your domain cfg.PARAMS['border'] = 80 cfg.PARAMS['use_intersects'] = False montmine = workflow.init_glacier_directories(['RGI60-11.02709'], from_prepro_level=3)[0] gdirs = workflow.init_glacier_directories(['RGI60-11.02709', 'RGI60-11.02715'], from_prepro_level=3) workflow.execute_entity_task(tasks.init_present_time_glacier, gdirs) gdirs_merged = workflow.merge_glacier_tasks(gdirs, 'RGI60-11.02709', return_all=False, filename='climate_monthly', buffer=2.5) # plot centerlines fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[20, 10]) plot_centerlines(montmine, ax=ax1, use_flowlines=True) xt = ax1.get_xticks() ax1.set_xticks(xt[::2]) ax1.tick_params(axis='both', which='major', labelsize=20) ax1.set_title('entity glacier', fontsize=24) plot_centerlines(gdirs_merged, ax=ax2, use_model_flowlines=True) ax2.tick_params(axis='both', which='major', labelsize=20) ax2.set_title('merged with Glacier de Ferpecle', fontsize=24) axs = fig.get_axes() axs[3].remove() axs[2].tick_params(axis='y', labelsize=16) axs[2].set_ylabel('Altitude [m]', fontsize=18) fig.suptitle('Glacier du Mont Mine', fontsize=24) fig.subplots_adjust(left=0.04, right=0.99, bottom=0.08, top=0.89, wspace=0.3) fn = os.path.join(pout, 'merged_montmine.png') fig.savefig(fn) # run glaciers with negative t bias # some model settings years = 125 tbias = -1.5 # model Mont Mine glacier as entity and complile the output tasks.run_constant_climate(montmine, nyears=years, output_filesuffix='_entity', temperature_bias=tbias) ds_entity = utils.compile_run_output([montmine], path=False, filesuffix='_entity') # model the merged glacier and complile the output tasks.run_constant_climate(gdirs_merged, nyears=years, output_filesuffix='_merged', temperature_bias=tbias, climate_filename='climate_monthly') ds_merged = utils.compile_run_output([gdirs_merged], path=False, filesuffix='_merged') # # bring them to same size again tbias = -2.2 years = 125 tasks.run_constant_climate(montmine, nyears=years, output_filesuffix='_entity1', temperature_bias=tbias) ds_entity1 = utils.compile_run_output([montmine], path=False, filesuffix='_entity1') # and let them shrink again # some model settings tbias = -0.5 years = 100 # load the previous entity run tmp_mine = FileModel( montmine.get_filepath('model_run', filesuffix='_entity1')) tmp_mine.run_until(years) tasks.run_constant_climate(montmine, nyears=years, output_filesuffix='_entity2', init_model_fls=tmp_mine.fls, temperature_bias=tbias) ds_entity2 = utils.compile_run_output([montmine], path=False, filesuffix='_entity2') # model the merged glacier and complile the output tmp_merged = FileModel( gdirs_merged.get_filepath('model_run', filesuffix='_merged')) tmp_merged.run_until(years) tasks.run_constant_climate(gdirs_merged, nyears=years, output_filesuffix='_merged2', init_model_fls=tmp_merged.fls, temperature_bias=tbias, climate_filename='climate_monthly') ds_merged2 = utils.compile_run_output([gdirs_merged], path=False, filesuffix='_merged2') fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[20, 7]) dse = ds_entity.length.to_series().rolling(5, center=True).mean() dsm = ds_merged.length.to_series().rolling(5, center=True).mean() ax1.plot(dse.values, 'C1', label='Entity glacier', linewidth=3) ax1.plot(dsm.values, 'C2', label='Merged glacier', linewidth=3) ax1.set_xlabel('Simulation time [yr]', fontsize=20) ax1.set_ylabel('Glacier length[m]', fontsize=20) ax1.grid(True) ax1.legend(loc=2, fontsize=18) dse2 = ds_entity2.length.to_series().rolling(5, center=True).mean() dsm2 = ds_merged2.length.to_series().rolling(5, center=True).mean() ax2.plot(dse2.values, 'C1', label='Entity glacier', linewidth=3) ax2.plot(dsm2.values, 'C2', label='Merged glacier', linewidth=3) ax2.set_xlabel('Simulation time [yr]', fontsize=22) ax2.set_ylabel('Glacier length [m]', fontsize=22) ax2.grid(True) ax2.legend(loc=1, fontsize=18) ax1.set_xlim([0, 120]) ax2.set_xlim([0, 100]) ax1.set_ylim([7500, 12000]) ax2.set_ylim([7500, 12000]) ax1.tick_params(axis='both', which='major', labelsize=20) ax2.tick_params(axis='both', which='major', labelsize=20) fig.subplots_adjust(left=0.08, right=0.96, bottom=0.11, top=0.93, wspace=0.3) fn = os.path.join(pout, 'merged_montmine_timeseries.png') fig.savefig(fn)
def plot_modeloutput_map(gdirs, ax=None, smap=None, model=None, vmax=None, linewidth=3, filesuffix='', modelyr=None): """Plots the result of the model output.""" gdir = gdirs[0] with utils.ncDataset(gdir.get_filepath('gridded_data')) as nc: topo = nc.variables['topo'][:] # Dirty optim try: smap.set_topography(topo) except ValueError: pass toplot_th = np.array([]) toplot_lines = [] toplot_crs = [] if model is None: models = [] for gdir in gdirs: model = FileModel( gdir.get_filepath('model_run', filesuffix=filesuffix)) model.run_until(modelyr) models.append(model) else: models = utils.tolist(model) for gdir, model in zip(gdirs, models): geom = gdir.read_pickle('geometries') poly_pix = geom['polygon_pix'] crs = gdir.grid.center_grid smap.set_geometry(poly_pix, crs=crs, fc='none', zorder=2, linewidth=.2) poly_pix = utils.tolist(poly_pix) for _poly in poly_pix: for l in _poly.interiors: smap.set_geometry(l, crs=crs, color='black', linewidth=0.5) # plot Centerlines cls = model.fls for l in cls: smap.set_geometry(l.line, crs=crs, color='gray', linewidth=1.2, zorder=50) toplot_th = np.append(toplot_th, l.thick) widths = l.widths.copy() widths = np.where(l.thick > 0, widths, 0.) for wi, cur, (n1, n2) in zip(widths, l.line.coords, l.normals): line = shpg.LineString([ shpg.Point(cur + wi / 2. * n1), shpg.Point(cur + wi / 2. * n2) ]) toplot_lines.append(line) toplot_crs.append(crs) dl = salem.DataLevels(cmap=OGGM_CMAPS['section_thickness'], data=toplot_th, vmin=0, vmax=vmax) colors = dl.to_rgb() for l, c, crs in zip(toplot_lines, colors, toplot_crs): smap.set_geometry(l, crs=crs, color=c, linewidth=linewidth, zorder=50) smap.plot(ax) return dict(cbar_label='Section thickness [m]', cbar_primitive=dl, title_comment=' -- year: {:d}'.format(np.int64(model.yr)))
def identification(gdir, list, ys, ye, n): """ Determine glacier candidates and run them to the date of observation :param gdir: oggm.GlacierDirectories :param df: pd.DataFrame (volume_m3_ts() from random climate runs) :param ys: starting year :param ye: year of observation :param n: number of candidates :return: """ i = 0 t_stag = 0 # find t_stag for suffix in list['suffix'].values: if i < 10: try: rp = gdir.get_filepath('model_run', filesuffix=suffix) if not os.path.exists(rp): rp = os.path.join(gdir.dir, str(ys), 'model_run' + suffix + '.nc') fmod = FileModel(rp) t = _find_extrema(fmod.volume_m3_ts()) if t > t_stag: t_stag = t i = i + 1 except: pass # make sure that t_stag is not close to the end if t_stag > 550: t_stag = 550 df = pd.DataFrame() for suffix in list['suffix']: try: rp = gdir.get_filepath('model_run', filesuffix=suffix) if not os.path.exists(rp): rp = os.path.join(gdir.dir, str(ys), 'model_run' + suffix + '.nc') fmod = FileModel(rp) v = pd.DataFrame(fmod.volume_m3_ts()).reset_index() v = v[v['time'] >= t_stag] v = v.assign(suffix=lambda x: suffix) df = df.append(v, ignore_index=True) except: pass indices = [] # find nearest glacier state for each of the n volume classes (equidistant) for val in np.linspace(df.ts_section.min(), df.ts_section.max(), n): index = df.iloc[(df['ts_section'] - val).abs().argsort()][:1].index[0] if not index in indices: indices = np.append(indices, index) candidates = df.ix[indices] candidates = candidates.sort_values(['suffix', 'time']) candidates['fls_t0'] = None for suffix in candidates['suffix'].unique(): rp = gdir.get_filepath('model_run', filesuffix=suffix) if not os.path.exists(rp): rp = os.path.join(gdir.dir, str(ys), 'model_run' + suffix + '.nc') fmod = FileModel(rp) for i, t in candidates[candidates['suffix'] == suffix]['time'].iteritems(): fmod.run_until(t) candidates.at[i, 'random_model_t0'] = copy.deepcopy(fmod) candidates = candidates.drop_duplicates() fls_list = [] for i in candidates.index: s = candidates.loc[int(i), 'suffix'].split('_random')[-1] suffix = str(ys) + '_past' + s + '_' + str( int(candidates.loc[int(i), 'time'])) fls = candidates.loc[int(i), 'random_model_t0'] fls_list.append([suffix, fls]) return fls_list
def run_and_store_from_disk(rgi, histalp_storage, storage): cmip = [ 'CCSM4', 'CNRM-CM5', 'CSIRO-Mk3-6-0', 'CanESM2', 'GFDL-CM3', 'GFDL-ESM2G', 'GISS-E2-R', 'IPSL-CM5A-LR', 'MPI-ESM-LR', 'NorESM1-M' ] bp = 'https://cluster.klima.uni-bremen.de/~oggm/cmip5-ng/pr/pr_mon_{}_{}_r1i1p1_g025.nc' bt = 'https://cluster.klima.uni-bremen.de/~oggm/cmip5-ng/tas/tas_mon_{}_{}_r1i1p1_g025.nc' for i in np.arange(999): # Local working directory (where OGGM will write its output) storage_dir = os.path.join(histalp_storage, rgi, '{:02d}'.format(i), rgi[:8], rgi[:11], rgi) new_dir = os.path.join(cfg.PATHS['working_dir'], 'per_glacier', rgi[:8], rgi[:11], rgi) # make sure directory is empty: try: shutil.rmtree(new_dir) except FileNotFoundError: pass # if path does not exist, we handled all ensemble members: try: shutil.copytree(storage_dir, new_dir) except FileNotFoundError: log.info('processed {:02d} ensemble members'.format(i)) break gdir = GlacierDirectory(rgi) pdict = gdir.get_climate_info()['ensemble_calibration'] cfg.PARAMS['prcp_scaling_factor'] = pdict['prcp_scaling_factor'] default_glena = 2.4e-24 cfg.PARAMS['glen_a'] = pdict['glena_factor'] * default_glena cfg.PARAMS['inversion_glen_a'] = pdict['glena_factor'] * default_glena mbbias = pdict['mbbias'] tmp_mod = FileModel( gdir.get_filepath('model_run', filesuffix='_histalp_{:02d}'.format(i))) tmp_mod.run_until(tmp_mod.last_yr) for cm in cmip: for rcp in ['rcp26', 'rcp45', 'rcp60', 'rcp85']: ft = utils.file_downloader(bt.format(cm, rcp)) fp = utils.file_downloader(bp.format(cm, rcp)) if ft is None: log.warning('no {} for model {}'.format(rcp, cm)) continue filesuffix = '_{}_{}'.format(cm, rcp) # bias correct them if '_merged' in rgi: process_cmip_for_merged_glacier(gdir, filesuffix, ft, fp) else: gcm_climate.process_cmip5_data(gdir, filesuffix=filesuffix, fpath_temp=ft, fpath_precip=fp) rid = '_{}_{}'.format(cm, rcp) rid_out = '{}_{:02d}'.format(rid, i) run_from_climate_data(gdir, ys=2014, ye=2100, climate_filename='gcm_data', climate_input_filesuffix=rid, init_model_fls=tmp_mod.fls, output_filesuffix=rid_out, bias=mbbias) fn1 = 'model_diagnostics{}.nc'.format(rid_out) shutil.copyfile( gdir.get_filepath('model_diagnostics', filesuffix=rid_out), os.path.join(storage, fn1)) fn4 = 'model_run{}.nc'.format(rid_out) shutil.copyfile( gdir.get_filepath('model_run', filesuffix=rid_out), os.path.join(storage, fn4))
def get_mean_temps_eq(rgi, histalp_storage, comit_storage, ensmembers): from oggm import cfg, utils, GlacierDirectory from oggm.core.massbalance import MultipleFlowlineMassBalance from oggm.core.flowline import FileModel import shutil # 1. get mean surface heights df85 = pd.DataFrame([]) df99 = pd.DataFrame([]) for i in range(ensmembers): fnc1 = os.path.join(comit_storage, rgi, 'model_run_commitment1885_{:02d}.nc'.format(i)) fnc2 = os.path.join(comit_storage, rgi, 'model_run_commitment1999_{:02d}.nc'.format(i)) tmpmod1 = FileModel(fnc1) tmpmod2 = FileModel(fnc2) for j in np.arange(270, 301): tmpmod1.run_until(j) df85.loc[:, '{}{}'.format(i, j)] = tmpmod1.fls[-1].surface_h tmpmod2.run_until(j) df99.loc[:, '{}{}'.format(i, j)] = tmpmod2.fls[-1].surface_h meanhgt99 = df99.mean(axis=1).values meanhgt85 = df85.mean(axis=1).values # 2. get the climate # Initialize OGGM cfg.initialize() wd = utils.gettempdir(reset=True) cfg.PATHS['working_dir'] = wd utils.mkdir(wd, reset=True) cfg.PARAMS['baseline_climate'] = 'HISTALP' # and set standard histalp values cfg.PARAMS['temp_melt'] = -1.75 i = 0 storage_dir = os.path.join(histalp_storage, rgi, '{:02d}'.format(i), rgi[:8], rgi[:11], rgi) new_dir = os.path.join(cfg.PATHS['working_dir'], 'per_glacier', rgi[:8], rgi[:11], rgi) shutil.copytree(storage_dir, new_dir) gdir = GlacierDirectory(rgi) mb = MultipleFlowlineMassBalance(gdir, filename='climate_monthly', check_calib_params=False) # need to do the above for every ensemble member if I consider PRECIP! # and set cfg.PARAMS['prcp_scaling_factor'] = pdict['prcp_scaling_factor'] df99_2 = pd.DataFrame() df85_2 = pd.DataFrame() for i in np.arange(9, 12): for y in np.arange(1870, 1901): flyear = utils.date_to_floatyear(y, i) tmp = mb.flowline_mb_models[-1].get_monthly_climate(meanhgt85, flyear)[0] df85_2.loc[y, i] = tmp.mean() for y in np.arange(1984, 2015): tmp = mb.flowline_mb_models[-1].get_monthly_climate(meanhgt99, flyear)[0] df99_2.loc[y, i] = tmp.mean() t99 = df99_2.mean().mean() t85 = df85_2.mean().mean() return t85, t99