def plot_figure1(self,S,A,bg=0,x=None,min=None,max=None,delta_isofill=None,delta_isoline=None,days_lines=None): title = 'Figure 1' displays=[] # store displays used if min is None: min = self.min if max is None: max = self.max if delta_isoline is None: delta_isoline = self.delta_isoline if days_lines is None: days_lines = self.days_lines if delta_isofill is None: delta_isofill = self.delta_isofill if x is None: x=self.x m =x.mode x.mode=1 x.landscape() tmpl,tmplnoleg,isof,isol1,isol2=graphics.createTemplateandGM(x,min,max,delta_isofill,delta_isoline,days_lines,ntemplate=2) for gm in isof,isol1,isol2: gm.datawc_x1=self.datawc_x1 gm.datawc_x2=self.datawc_x2 gm.datawc_y1=self.datawc_y1 gm.datawc_y2=self.datawc_y2 tmpl2=x.createtemplate(source=tmpl.name) tmpl2.moveto(.54,.2) tmpl2noleg=x.createtemplate(source=tmpl2.name) tmpl2noleg.legend.priority=0 for (sym,templ,templnoleg) in [(-1,tmpl,tmplnoleg),(1,tmpl2,tmpl2noleg)]: if sym==-1: power=A else: power=S id=power.id power=MV2.log10(power) power.id=id fq=power.getAxis(0) fq.id='Frequency (CPD)' w=power.getAxis(1) w.id='Westward Zonal Wave Number Eastward' displays.append(x.plot(power,isof,templ,bg=bg)) displays.append(x.plot(power,isol1,templnoleg,bg=bg)) displays.append(x.plot(power,isol2,templnoleg,bg=bg)) tt=x.createtext() tt.x=[.5] tt.y=[.97] tt.height=25 tt.halign='center' tt.string=[title,] displays.append(x.plot(tt,bg=bg)) x.update() x.mode=m return displays
def plot_figure1(self, S, A, bg=0, x=None, min=None, max=None, delta_isofill=None, delta_isoline=None, days_lines=None): title = 'Figure 1' displays = [] # store displays used if min is None: min = self.min if max is None: max = self.max if delta_isoline is None: delta_isoline = self.delta_isoline if days_lines is None: days_lines = self.days_lines if delta_isofill is None: delta_isofill = self.delta_isofill if x is None: x = self.x x.landscape() tmpl, tmplnoleg, isof, isol1, isol2 = graphics.createTemplateandGM( x, min, max, delta_isofill, delta_isoline, days_lines, ntemplate=2) for gm in isof, isol1, isol2: gm.datawc_x1 = self.datawc_x1 gm.datawc_x2 = self.datawc_x2 gm.datawc_y1 = self.datawc_y1 gm.datawc_y2 = self.datawc_y2 tmpl2 = x.createtemplate(source=tmpl.name) tmpl2.moveto(.54, .2) tmpl2noleg = x.createtemplate(source=tmpl2.name) tmpl2noleg.legend.priority = 0 for (sym, templ, templnoleg) in [(-1, tmpl, tmplnoleg), (1, tmpl2, tmpl2noleg)]: if sym == -1: power = A else: power = S id = power.id power = MV2.log10(power) power.id = id fq = power.getAxis(0) fq.id = 'Frequency (CPD)' w = power.getAxis(1) w.id = 'Westward Zonal Wave Number Eastward' displays.append(x.plot(power, isof, templ, bg=bg)) displays.append(x.plot(power, isol1, templnoleg, bg=bg)) displays.append(x.plot(power, isol2, templnoleg, bg=bg)) tt = x.createtext() tt.x = [.5] tt.y = [.97] tt.height = 25 tt.halign = 'center' tt.string = [ title, ] displays.append(x.plot(tt, bg=bg)) x.update() return displays
def calculate_Z(PET, P, WCTOP, WCBOT, year1, year2): """ Written by Kate Marvel. Adapted from code by Park Williams (LDEO). Calculates the Palmer z-index Inputs: PET: Potential evapotranspiration (mm) PR: Precipitation (mm). NOTE CMIP5 standard is kg/m s-2 so need to run convert_to_mm on CMIP5 output WCBOT: Soil moisture holding capacity in bottom layer (mm) WCTOP: Water holding capacity in top layer (mm) year1: start date of calibration period year2: stop date of calibration period Outputs: PL: Potential loss ET: Actual evapotranspiration TL: Total loss RO: Runoff R: Recharge SSS: Updated surface soil moisture SSU: Updated moisture of underlying soil layers """ #INITIALIZE VARS WCTOT = WCBOT + WCTOP # Total water holding capacity of the soil layers SS = WCTOP # Surface soil moisture start at full capacity SU = WCBOT # Underlying layer soil moisture start at full capacity SP = SS + SU # Combined surface and underlying soil moisture #Get arrays for output pldat = MV.zeros(PET.shape) spdat = MV.zeros(PET.shape) prdat = MV.zeros(PET.shape) rdat = MV.zeros(PET.shape) tldat = MV.zeros(PET.shape) etdat = MV.zeros(PET.shape) rodat = MV.zeros(PET.shape) sssdat = MV.zeros(PET.shape) ssudat = MV.zeros(PET.shape) #get rid of badly calibrated negative PET PET = MV.where(PET < 0, 0, PET) #fake 10 year spinup PET_ex = pad_by_10(PET, year1, year2) P_ex = pad_by_10(P, year1, year2) #get rid of badly calibrated negative PET PET = MV.where(PET < 0, 0, PET) #run 2-layer bucket model for i in range(PET_ex.shape[0]): PR = WCTOT - SP PL, ET, TL, RO, R, SSS, SSU = bucket2d(PET_ex[i], P_ex[i], WCBOT, WCTOP, SS, SU) ET = MV.where(ET < 0, 0, ET) SS = SSS SU = SSU SP = SS + SU if i >= 120: pldat[i - 120] = PL spdat[i - 120] = SS + SU prdat[i - 120] = PR rdat[i - 120] = R tldat[i - 120] = TL etdat[i - 120] = ET rodat[i - 120] = RO sssdat[i - 120] = SSS ssudat[i - 120] = SSU rdat = MV.where(rdat >= prdat, prdat, rdat) tldat = MV.where(tldat >= pldat, pldat, tldat) for X in [spdat, pldat, prdat, rdat, tldat, etdat, rodat]: X.setAxisList(PET.getAxisList()) #calculate means over calibration period SPSUM = cdutil.ANNUALCYCLE.climatology(spdat(time=(year1, year2))) PLSUM = cdutil.ANNUALCYCLE.climatology(pldat(time=(year1, year2))) PRSUM = cdutil.ANNUALCYCLE.climatology(prdat(time=(year1, year2))) RSUM = cdutil.ANNUALCYCLE.climatology(rdat(time=(year1, year2))) TLSUM = cdutil.ANNUALCYCLE.climatology(tldat(time=(year1, year2))) ETSUM = cdutil.ANNUALCYCLE.climatology(etdat(time=(year1, year2))) PESUM = cdutil.ANNUALCYCLE.climatology(PET(time=(year1, year2))) ROSUM = cdutil.ANNUALCYCLE.climatology(rodat(time=(year1, year2))) PSUM = cdutil.ANNUALCYCLE.climatology(P(time=(year1, year2))) # CAFEC: Climatology Appropriate for Existing Conditions (Palmer 1965, p 12) # Calculate the CAFEC coefficients #Coefficient of evaporation: fraction of mean ET to mean potential ET alpha = pdsi_coeff(ETSUM, PESUM) #Coef of Recharge: ratio of mean recharge to mean potential recharge beta = pdsi_coeff(RSUM, PRSUM) #Coefficient of Runoff: Ratio of mean runoff to mean potential runoff gamma = pdsi_coeff(ROSUM, SPSUM) #Coefficient of Loss: Ratio of mean moisture loss to mean potential moisture loss delta = pdsi_coeff(TLSUM, PLSUM) TRAT = (PESUM + RSUM + ROSUM) / (PSUM + TLSUM) #CAFEC precipitation (needed to maintain "normal" moisture) nyears = PET.shape[0] / 12 repeat_it = lambda coef: np.ma.repeat(coef, nyears, axis=0) Phat = PET * repeat_it(alpha) + prdat * repeat_it( beta) + spdat * repeat_it(gamma) - pldat * repeat_it(delta) # Moisture departure (difference between precip and precip needed for normal conditions) DD = P - Phat DD.setAxisList(P.getAxisList()) SABSD = MV.absolute(DD) DBAR = cdutil.ANNUALCYCLE.climatology(SABSD(time=(year1, year2))) # Weird empirical scaling thing to standardize moisture availability departures. THIS IS DUMB. AKHAT = 1.5 * MV.log10((TRAT + 2.8 * 25.4) / DBAR) + 0.5 AKHAT = MV.where(AKHAT < 0, 0, AKHAT) annsum = MV.sum(AKHAT * DBAR, axis=0) AK = 17.67 * 25.4 * AKHAT / annsum Z = DD / 25.4 * repeat_it(AK) #Force Z between -16 and 16 Z = MV.where(Z > 16, 16, Z) Z = MV.where(Z < -16, -16, Z) Z.setAxisList(P.getAxisList()) Z.id = "z" Z.units = "mm" Z.info = "Created by Kate Marvel using calc_Z.py" Z.creation_date = datetime.datetime.now().isoformat() Z.long_name = "Palmer Z index" Z.standard_name = "z_index" return Z