def get_mb(self, year=None): """Get the mass balance at the requested height and time. Optimized so that no mb model call is necessary at each step. """ if year is None: year = self.yr # Do we have to optimise? if self.mb_elev_feedback == 'always': return self._mb_call(self.bed_topo + self.ice_thick, year) date = utils.floatyear_to_date(year) if self.mb_elev_feedback == 'annual': # ignore month changes date = (date[0], date[0]) if self._mb_current_date != date or (self._mb_current_out is None): # We need to reset all self._mb_current_date = date _mb = self._mb_call(self.surface_h.flatten(), year) self._mb_current_out = _mb.reshape((self.ny, self.nx)) return self._mb_current_out
def get_monthly_climate(self, heights, year=None): """Monthly climate information at given heights. Note that prcp is corrected with the precipitation factor. Returns ------- (temp, tempformelt, prcp, prcpsol) """ y, m = floatyear_to_date(year) pok = np.where((self.years == y) & (self.months == m))[0][0] # Read timeseries itemp = self.temp[pok] + self.temp_bias iprcp = self.prcp[pok] igrad = self.grad[pok] # For each height pixel: # Compute temp and tempformelt (temperature above melting threshold) npix = len(heights) temp = np.ones(npix) * itemp + igrad * (heights - self.ref_hgt) tempformelt = temp - self.t_melt tempformelt[:] = np.clip(tempformelt, 0, tempformelt.max()) # Compute solid precipitation from total precipitation prcp = np.ones(npix) * iprcp fac = 1 - (temp - self.t_solid) / (self.t_liq - self.t_solid) prcpsol = prcp * np.clip(fac, 0, 1) return temp, tempformelt, prcp, prcpsol
def get_monthly_mb(self, heights, year=None): _, tmelt, _, prcpsol = self.get_monthly_climate(heights, year=year) y, m = floatyear_to_date(year) mb_month = prcpsol - self.mu_star * tmelt mb_month -= self.bias * SEC_IN_MONTH / SEC_IN_YEAR return mb_month / SEC_IN_MONTH / cfg.RHO
def get_monthly_mb(self, heights, year=None, add_climate=False, **kwargs): yr, m = floatyear_to_date(year) if add_climate: t, tmelt, prcp, prcpsol = self.get_monthly_climate(heights, year=year) return self.interp_m[m - 1](heights), t, tmelt, prcp, prcpsol return self.interp_m[m - 1](heights)
def get_monthly_climate(self, heights, year=None): """Average climate information at given heights. Note that prcp is corrected with the precipitation factor and that all other biases (precipitation, temp) are applied Returns ------- (temp, tempformelt, prcp, prcpsol) """ _, m = floatyear_to_date(year) yrs = [date_to_floatyear(y, m) for y in self.years] heights = np.atleast_1d(heights) nh = len(heights) shape = (len(yrs), nh) temp = np.zeros(shape) tempformelt = np.zeros(shape) prcp = np.zeros(shape) prcpsol = np.zeros(shape) for i, yr in enumerate(yrs): t, tm, p, ps = self.mbmod.get_monthly_climate(heights, year=yr) temp[i, :] = t tempformelt[i, :] = tm prcp[i, :] = p prcpsol[i, :] = ps return (np.mean(temp, axis=0), np.mean(tempformelt, axis=0), np.mean(prcp, axis=0), np.mean(prcpsol, axis=0))
def get_monthly_mb(self, heights, year=None, add_climate=False, **kwargs): _, m = floatyear_to_date(year) mb_on_h = heights * 0. for yr in self.years: yr = date_to_floatyear(yr, m) mb_on_h += self.mbmod.get_monthly_mb(heights, year=yr) mb_on_h /= len(self.years) if add_climate: t, tmelt, prcp, prcpsol = self.get_monthly_climate(heights, year=year) return mb_on_h, t, tmelt, prcp, prcpsol return mb_on_h
def test_date_to_floatyear(self): r = utils.date_to_floatyear(0, 1) self.assertEqual(r, 0) r = utils.date_to_floatyear(1, 1) self.assertEqual(r, 1) r = utils.date_to_floatyear([0, 1], [1, 1]) np.testing.assert_array_equal(r, [0, 1]) yr = utils.date_to_floatyear([1998, 1998], [6, 7]) y, m = utils.floatyear_to_date(yr) np.testing.assert_array_equal(y, [1998, 1998]) np.testing.assert_array_equal(m, [6, 7]) yr = utils.date_to_floatyear([1998, 1998], [2, 3]) y, m = utils.floatyear_to_date(yr) np.testing.assert_array_equal(y, [1998, 1998]) np.testing.assert_array_equal(m, [2, 3]) time = pd.date_range('1/1/1800', periods=300 * 12 - 11, freq='MS') yr = utils.date_to_floatyear(time.year, time.month) y, m = utils.floatyear_to_date(yr) np.testing.assert_array_equal(y, time.year) np.testing.assert_array_equal(m, time.month) myr = utils.monthly_timeseries(1800, 2099) y, m = utils.floatyear_to_date(myr) np.testing.assert_array_equal(y, time.year) np.testing.assert_array_equal(m, time.month) myr = utils.monthly_timeseries(1800, ny=300) y, m = utils.floatyear_to_date(myr) np.testing.assert_array_equal(y, time.year) np.testing.assert_array_equal(m, time.month) time = pd.period_range('0001-01', '6000-1', freq='M') myr = utils.monthly_timeseries(1, 6000) y, m = utils.floatyear_to_date(myr) np.testing.assert_array_equal(y, time.year) np.testing.assert_array_equal(m, time.month) time = pd.period_range('0001-01', '6000-12', freq='M') myr = utils.monthly_timeseries(1, 6000, include_last_year=True) y, m = utils.floatyear_to_date(myr) np.testing.assert_array_equal(y, time.year) np.testing.assert_array_equal(m, time.month) with self.assertRaises(ValueError): utils.monthly_timeseries(1)
def get_monthly_climate(self, heights, year=None): """Monthly climate information at given heights. Note that prcp is corrected with the precipitation factor and that all other model biases (temp and prcp) are applied. Returns ------- (temp, tempformelt, prcp, prcpsol) """ y, m = floatyear_to_date(year) if self.repeat: y = self.ys + (y - self.ys) % (self.ye - self.ys + 1) if y < self.ys or y > self.ye: raise ValueError('year {} out of the valid time bounds: ' '[{}, {}]'.format(y, self.ys, self.ye)) pok = np.where((self.years == y) & (self.months == m))[0][0] # Read timeseries itemp = self.temp[pok] + self.temp_bias iprcp = self.prcp[pok] * self.prcp_bias igrad = self.grad[pok] # For each height pixel: # Compute temp and tempformelt (temperature above melting threshold) npix = len(heights) temp = np.ones(npix) * itemp + igrad * (heights - self.ref_hgt) tempformelt = temp - self.t_melt tempformelt[:] = np.clip(tempformelt, 0, tempformelt.max()) # Compute solid precipitation from total precipitation prcp = np.ones(npix) * iprcp fac = 1 - (temp - self.t_solid) / (self.t_liq - self.t_solid) prcpsol = prcp * np.clip(fac, 0, 1) return temp, tempformelt, prcp, prcpsol
def test_floatyear_to_date(self): r = utils.floatyear_to_date(0) self.assertEqual(r, (0, 1)) y, m = utils.floatyear_to_date([0, 1]) np.testing.assert_array_equal(y, [0, 1]) np.testing.assert_array_equal(m, [1, 1]) y, m = utils.floatyear_to_date([0.00001, 1.00001]) np.testing.assert_array_equal(y, [0, 1]) np.testing.assert_array_equal(m, [1, 1]) y, m = utils.floatyear_to_date([0.99999, 1.99999]) np.testing.assert_array_equal(y, [0, 1]) np.testing.assert_array_equal(m, [12, 12]) yr = 1998 + 2 / 12 r = utils.floatyear_to_date(yr) self.assertEqual(r, (1998, 3)) yr = 1998 + 1 / 12 r = utils.floatyear_to_date(yr) self.assertEqual(r, (1998, 2))
def get_monthly_mb(self, heights, year=None): ryr, m = floatyear_to_date(year) ryr = date_to_floatyear(self.get_state_yr(ryr), m) return self.mbmod.get_monthly_mb(heights, year=ryr)
def get_monthly_mb(self, heights, year=None): yr, m = floatyear_to_date(year) return self.interp_m[m - 1](heights)
def _get_climate(self, heights, climate_type, year=None): """Climate information at given heights. year has to be given as float hydro year from what the month is taken, hence year 2000 -> y=2000, m = 1, & year = 2000.09, y=2000, m=2 ... which corresponds to the real year 1999 an months October or November if hydro year starts in October Note that prcp is corrected with the precipitation factor and that all other model biases (temp and prcp) are applied. same as in OGGM default except that tempformelt is computed by self._get_tempformelt Parameters ------- heights : np.array or list heights along flowline climate_type : str either 'monthly' or 'annual', if annual floor of year is used, if monthly float year is converted into month and year Returns ------- (temp, tempformelt, prcp, prcpsol) """ y, m = floatyear_to_date(year) if self.repeat: y = self.ys + (y - self.ys) % (self.ye - self.ys + 1) if y < self.ys or y > self.ye: raise ValueError('year {} out of the valid time bounds: ' '[{}, {}]'.format(y, self.ys, self.ye)) if self.mb_type == 'mb_real_daily' or climate_type == 'annual': if climate_type == 'annual': pok = np.where(self.years == year)[0] if len(pok) < 1: raise ValueError('Year {} not in record'.format(int(year))) else: pok = np.where((self.years == y) & (self.months == m))[0] if len(pok) < 28: warnings.warn('something goes wrong with amount of entries\ per month for mb_real_daily') else: pok = np.where((self.years == y) & (self.months == m))[0][0] # Read timeseries itemp = self.temp[pok] + self.temp_bias iprcp = self.prcp[pok] * self.prcp_bias igrad = self.grad[pok] # For each height pixel: # Compute temp and tempformelt (temperature above melting threshold) heights = np.asarray(heights) npix = len(heights) if self.mb_type == 'mb_real_daily' or climate_type == 'annual': grad_temp = np.atleast_2d(igrad).repeat(npix, 0) if len(pok) != 12 and self.mb_type != 'mb_real_daily': warnings.warn('something goes wrong with amount of entries' 'per year') grad_temp *= (heights.repeat(len(pok)).reshape(grad_temp.shape) - self.ref_hgt) temp2d = np.atleast_2d(itemp).repeat(npix, 0) + grad_temp # temp_for_melt is computed separately depending on mb_type temp2dformelt = self._get_tempformelt(temp2d, pok) # Compute solid precipitation from total precipitation prcp = np.atleast_2d(iprcp).repeat(npix, 0) fac = 1 - (temp2d - self.t_solid) / (self.t_liq - self.t_solid) prcpsol = prcp * clip_array(fac, 0, 1) return temp2d, temp2dformelt, prcp, prcpsol else: temp = np.ones(npix) * itemp + igrad * (heights - self.ref_hgt) # temp_for_melt is computed separately depending on mb_type tempformelt = self._get_tempformelt(temp, pok) prcp = np.ones(npix) * iprcp fac = 1 - (temp - self.t_solid) / (self.t_liq - self.t_solid) prcpsol = prcp * clip_array(fac, 0, 1) return temp, tempformelt, prcp, prcpsol
def get_monthly_mb(self, heights, year=None, fl_id=None): ryr, m = floatyear_to_date(year) ryr = date_to_floatyear(self.get_state_yr(ryr), m) return self.mbmod.get_monthly_mb(heights, year=ryr)
def get_monthly_mb(self, heights, year=None, fl_id=None): yr, m = floatyear_to_date(year) return self.interp_m[m-1](heights)