Example #1
0
    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
Example #2
0
    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
Example #3
0
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