Example #1
0
    def test_i_photo(self):
        """tests function which computes photoperiod index"""
        frac = np.arange(0.0, 1.0, 0.2)
        photo = frac * (gsi.PHOTO_MAX - gsi.PHOTO_MIN) + gsi.PHOTO_MIN

        i_photo = gsi.calc_i_photo(photo)
        self.assertTrue(np.all(np.abs(i_photo - frac) < 1e-5))
Example #2
0
    def test_i_photo(self):
        """tests function which computes photoperiod index"""
        frac = np.arange(0.0, 1.0, 0.2)
        photo = frac * (gsi.PHOTO_MAX - gsi.PHOTO_MIN) + gsi.PHOTO_MIN

        i_photo = gsi.calc_i_photo(photo)
        self.assertTrue(np.all(np.abs(i_photo - frac) < 1e-5))
Example #3
0
def indices_year(y, forcing_template, out_template) : 
    """Processes one year.
    
    Runs the calculation of indices for one year given an orchidee forcing
    file for that year."""
    
    # figure out filenames and open dataset.
    forcing_file = forcing_template % (y,)
    out_file = out_template % (y,)
    ds = ForcingDataset(forcing_file, out_file)
    
    # register required variables from NetCDF file so they are tracked
    qair = ds.register_variable("Qair", u.dimensionless_unscaled)
    tair = ds.register_variable("Tair", u.Kelvin)
    ds.register_variable("PSurf", u.Pa)
    rainf = ds.register_variable("Rainf", u.kg / (u.m**2) / u.s )
    swdown = ds.register_variable("SWdown", u.W / (u.m**2))
    
    print "NetCDF variables registered"
    # setup netcdf dimensions in output file
    ds.copyDimension("land")
    ds.copyDimension("y")
    ds.copyDimension("tstep")
    ds.createDimension("days", 365)
    
    # copy basic data
    ds.copyVariable('nav_lat')
    ds.copyVariable('nav_lon')

    
    print "Variables copied from forcing file"
    
    # create netcdf variables to hold indices in output file
    daylength = ds.create_variable("daylength", ("days","y"), np.float32)
    daylength.title = "Day Length"
    daylength.units = "hours"
    
    rh = ds.create_variable("rh", ("tstep","land"), np.float32)
    rh.long_name = "Relative Humidity"
    rh.units = "fraction"
    
    rh_max = ds.create_variable("rh_max", ("days","land"), np.float32)
    rh_max.long_name = "Maximum RH" 
    rh_max.units = "fraction"
    
    rh_min = ds.create_variable("rh_min", ("days","land"), np.float32)
    rh_min.long_name = "Minimum RH"
    rh_min.units = "fraction"
    
    rh_afternoon = ds.create_variable("rh_afternoon", ('days', 'land'),np.float32)
    rh_afternoon.long_name = "RH in the afternoon"
    rh_afternoon.units = "fraction"
    
    t_min = ds.create_variable("t_min", ('days','land'), np.float32)
    t_min.long_name = "minimum temperature for the 24 hours preceeding burning period"
    t_min.units = "K"
    
    t_max = ds.create_variable("t_max", ('days', 'land'), np.float32)
    t_max.long_name = "maximum temperature for the 24 hours preceeding burning period"
    t_max.units = "K"
    
    t_afternoon = ds.create_variable("t_afternoon", ('days','land'), np.float32)
    t_afternoon.long_name = "mid-burning-period temperature"
    t_afternoon.units = "K"
    
    i_tmin = ds.create_variable("i_tmin", ('days','land'), np.float32)
    i_tmin.long_name = "GSI minimum temperature index component"
    i_tmin.units = 'dimensionless'
    
    i_photo = ds.create_variable('i_photo', ('days','land'), np.float32)
    i_photo.long_name = 'GSI photoperiod index component'
    i_photo.units = 'dimensionless'
    
    i_vpd = ds.create_variable('i_vpd', ('days','land'), np.float32)
    i_vpd.long_name = 'GSI vapor pressure deficit index component'
    i_vpd.units = 'dimensionless'
    
    i_gsi = ds.create_variable('gsi', ('days','land'), np.float32)
    i_gsi.long_name = 'GSI Index'
    i_gsi.units = 'dimensionless'

    gsi_days = 10
    i_gsi_avg = ds.create_variable('gsi_avg', ('days','land'), np.float32)
    i_gsi_avg.long_name = 'GSI Index (%d day running average)' % gsi_days
    i_gsi_avg.units = 'dimensionless'
    
    precip = ds.create_variable('precip_duration', ('days','land'), np.float32)
    precip.long_name = "Duration of precipitation"
    precip.units = 'hours'
    
    tot_precip = ds.create_variable('total_precip', ('days','land'), np.float32)
    tot_precip.long_name = 'total precipitation over last 24 hours'
    tot_precip.units = 'kg / m^2'
    
    dd_days = 30
    dd = ds.create_variable('dd', ('days','land'), np.int)
    dd.long_name = 'dry day weighting (%d day window)' % dd_days
    dd.units = 'none'
    
    eqmc_bar = ds.create_variable('eqmc_bar', ('days','land'), np.float32)
    eqmc_bar.long_name = 'Weighted daily average equilibrium moisture content'
    eqmc_bar.units = 'percent'
    
    fm1000 = ds.create_variable('fm1000', ('days','land'), np.float32)
    fm1000.long_name = '1000 hour fuel moisture'
    fm1000.units = 'percent'
    
    fm100  = ds.create_variable('fm100', ('days','land'), np.float32)
    fm100.long_name = '100 hour fuel moisture'
    fm100.units = 'percent'
    
    fm10 = ds.create_variable('fm10', ('days','land'), np.float32)
    fm10.long_name = '10 hour fuel moisture'
    fm10.units = 'percent'
    
    fm1 = ds.create_variable('fm1', ('days','land'), np.float32)
    fm1.long_name = '1 hour fuel moisture'
    fm1.units = 'percent'
    
    print "Output NetCDF variables created"
    
    
    # moving window of GSI data
    gsi_window = w.MovingWindow(i_gsi.shape, 0, gsi_days)
    
    # moving window to compute dry day weights
    dd_window = w.SequenceWindow(dd.shape, 0, dd_days)
    
    # initialize fuel moisture calculators
    fm1000_calc = fm.ThousandHourFM(fm1000.shape, 0)
    fm100_calc  = fm.HundredHourFM(fm100.shape, 0)
        
    # base time
    time_start = t.Time('%04d:001'%y, format='yday', scale='ut1')
    if ( (y < 1960) or (y > 2013) ) :
        time_start.delta_ut1_utc=0
    
    # loop over days
    # the cur_day property is the index of the next day to read in from the file.
    # since the netcdf file is 0-based, indices are [0, 365)
    while qair.cur_day < 365 : 
        i_day = qair.cur_day - 1 
        print qair.cur_day
        
        # calculate daylengths, store as hours
        day = time_start + (i_day*u.day)
        if (hasattr(time_start,"delta_ut1_utc")) : 
            day.delta_ut1_utc = time_start.delta_ut1_utc
            
        daylength_lut = ds.get_daylength_lookup(day)
        daylength[i_day,:] = daylength_lut.values
        
        # pull out/store minimum, maximum and afternoon temps
        t_min[i_day,:] = tair.min(unitted=False)
        t_max[i_day,:] = tair.max(unitted=False)
        t_afternoon[i_day,:] = tair.ref_val(unitted=False)
        
        # calculate RH & store
        rh_dlts = ds.compute_rh()
        rh_dlts.store_day(rh)
        rh_max[i_day,:] = rh_dlts.max(unitted=False)
        rh_min[i_day,:] = rh_dlts.min(unitted=False)
        rh_afternoon[i_day,:] = rh_dlts.ref_val(unitted=False)
        
        # calculate GSI indices and store
        i_tmin[i_day,:] = gsi.calc_i_tmin(tair.min())
        cell_daylengths = daylength_lut.get(ds.get_latitudes())
        i_photo[i_day,:] = gsi.calc_i_photo(cell_daylengths)
        i_vpd[i_day,:] = gsi.calc_i_vpd(ds.compute_afternoon_vpd())
        gsi_vals = i_tmin[i_day,:] * i_photo[i_day,:] * i_vpd[i_day,:]
        i_gsi[i_day,:] = gsi_vals

        # calculate running GSI average and store
        gsi_window.put(gsi_vals)
        if gsi_window.ready() : 
            i_gsi_avg[i_day,:] = gsi_window.mean()
            
        # calculate precipitation duration and store
        precip_val = ds.compute_precip_duration()
        precip[i_day,:] = precip_val
        
        # calculate total precip over last 24 hours, and dry day flag
        tot_precip_val = (rainf.sum() * ds.get_timestep()).to(u.kg/(u.m**2))
        tot_precip[i_day,:] = tot_precip_val
        dd_window.put( tot_precip_val < DRY_DAY_PRECIP )
        dd[i_day,:] = dd_window.all_runs()
        
        # calculate daily avg equilibrium moisture content
        eqmc_bar_val = ds.compute_eqmc_bar(cell_daylengths)
        eqmc_bar[i_day,:] = eqmc_bar_val
        
        # calculate fuel moisture content
        fm1000[i_day,:] = fm1000_calc.compute(eqmc_bar_val, precip_val).to(u.percent)
        fm100_today  = fm100_calc.compute(eqmc_bar_val, precip_val)
        fm100[i_day,:] = fm100_today.to(u.percent)
        fm1_today, fm10_today = fm.oneten_ofdm(
                t_afternoon[i_day,:]*u.K, 
                rh_afternoon[i_day,:]*u.dimensionless_unscaled,
                swdown.ref_val(), fm100_today)
        fm10[i_day,:] = fm10_today.to(u.percent)
        fm1[i_day,:] = fm1_today.to(u.percent)              
                
        
        # first time through, store the first day's data
        if i_day == 1 : 
            rh_dlts.store_day(rh, current=False)
        
        # load next day for all variables
        ds.next()
    
    ds.close()
Example #4
0
def indices_year(y, forcing_template, out_template):
    """Processes one year.
    
    Runs the calculation of indices for one year given an orchidee forcing
    file for that year."""

    # figure out filenames and open dataset.
    forcing_file = forcing_template % (y, )
    out_file = out_template % (y, )
    ds = ForcingDataset(forcing_file, out_file)

    # register required variables from NetCDF file so they are tracked
    qair = ds.register_variable("Qair", u.dimensionless_unscaled)
    tair = ds.register_variable("Tair", u.Kelvin)
    ds.register_variable("PSurf", u.Pa)
    rainf = ds.register_variable("Rainf", u.kg / (u.m**2) / u.s)
    swdown = ds.register_variable("SWdown", u.W / (u.m**2))

    print "NetCDF variables registered"
    # setup netcdf dimensions in output file
    ds.copyDimension("land")
    ds.copyDimension("y")
    ds.copyDimension("tstep")
    ds.createDimension("days", 365)

    # copy basic data
    ds.copyVariable('nav_lat')
    ds.copyVariable('nav_lon')

    print "Variables copied from forcing file"

    # create netcdf variables to hold indices in output file
    daylength = ds.create_variable("daylength", ("days", "y"), np.float32)
    daylength.title = "Day Length"
    daylength.units = "hours"

    rh = ds.create_variable("rh", ("tstep", "land"), np.float32)
    rh.long_name = "Relative Humidity"
    rh.units = "fraction"

    rh_max = ds.create_variable("rh_max", ("days", "land"), np.float32)
    rh_max.long_name = "Maximum RH"
    rh_max.units = "fraction"

    rh_min = ds.create_variable("rh_min", ("days", "land"), np.float32)
    rh_min.long_name = "Minimum RH"
    rh_min.units = "fraction"

    rh_afternoon = ds.create_variable("rh_afternoon", ('days', 'land'),
                                      np.float32)
    rh_afternoon.long_name = "RH in the afternoon"
    rh_afternoon.units = "fraction"

    t_min = ds.create_variable("t_min", ('days', 'land'), np.float32)
    t_min.long_name = "minimum temperature for the 24 hours preceeding burning period"
    t_min.units = "K"

    t_max = ds.create_variable("t_max", ('days', 'land'), np.float32)
    t_max.long_name = "maximum temperature for the 24 hours preceeding burning period"
    t_max.units = "K"

    t_afternoon = ds.create_variable("t_afternoon", ('days', 'land'),
                                     np.float32)
    t_afternoon.long_name = "mid-burning-period temperature"
    t_afternoon.units = "K"

    i_tmin = ds.create_variable("i_tmin", ('days', 'land'), np.float32)
    i_tmin.long_name = "GSI minimum temperature index component"
    i_tmin.units = 'dimensionless'

    i_photo = ds.create_variable('i_photo', ('days', 'land'), np.float32)
    i_photo.long_name = 'GSI photoperiod index component'
    i_photo.units = 'dimensionless'

    i_vpd = ds.create_variable('i_vpd', ('days', 'land'), np.float32)
    i_vpd.long_name = 'GSI vapor pressure deficit index component'
    i_vpd.units = 'dimensionless'

    i_gsi = ds.create_variable('gsi', ('days', 'land'), np.float32)
    i_gsi.long_name = 'GSI Index'
    i_gsi.units = 'dimensionless'

    gsi_days = 10
    i_gsi_avg = ds.create_variable('gsi_avg', ('days', 'land'), np.float32)
    i_gsi_avg.long_name = 'GSI Index (%d day running average)' % gsi_days
    i_gsi_avg.units = 'dimensionless'

    precip = ds.create_variable('precip_duration', ('days', 'land'),
                                np.float32)
    precip.long_name = "Duration of precipitation"
    precip.units = 'hours'

    tot_precip = ds.create_variable('total_precip', ('days', 'land'),
                                    np.float32)
    tot_precip.long_name = 'total precipitation over last 24 hours'
    tot_precip.units = 'kg / m^2'

    dd_days = 30
    dd = ds.create_variable('dd', ('days', 'land'), np.int)
    dd.long_name = 'dry day weighting (%d day window)' % dd_days
    dd.units = 'none'

    eqmc_bar = ds.create_variable('eqmc_bar', ('days', 'land'), np.float32)
    eqmc_bar.long_name = 'Weighted daily average equilibrium moisture content'
    eqmc_bar.units = 'percent'

    fm1000 = ds.create_variable('fm1000', ('days', 'land'), np.float32)
    fm1000.long_name = '1000 hour fuel moisture'
    fm1000.units = 'percent'

    fm100 = ds.create_variable('fm100', ('days', 'land'), np.float32)
    fm100.long_name = '100 hour fuel moisture'
    fm100.units = 'percent'

    fm10 = ds.create_variable('fm10', ('days', 'land'), np.float32)
    fm10.long_name = '10 hour fuel moisture'
    fm10.units = 'percent'

    fm1 = ds.create_variable('fm1', ('days', 'land'), np.float32)
    fm1.long_name = '1 hour fuel moisture'
    fm1.units = 'percent'

    print "Output NetCDF variables created"

    # moving window of GSI data
    gsi_window = w.MovingWindow(i_gsi.shape, 0, gsi_days)

    # moving window to compute dry day weights
    dd_window = w.SequenceWindow(dd.shape, 0, dd_days)

    # initialize fuel moisture calculators
    fm1000_calc = fm.ThousandHourFM(fm1000.shape, 0)
    fm100_calc = fm.HundredHourFM(fm100.shape, 0)

    # base time
    time_start = t.Time('%04d:001' % y, format='yday', scale='ut1')
    if ((y < 1960) or (y > 2013)):
        time_start.delta_ut1_utc = 0

    # loop over days
    # the cur_day property is the index of the next day to read in from the file.
    # since the netcdf file is 0-based, indices are [0, 365)
    while qair.cur_day < 365:
        i_day = qair.cur_day - 1
        print qair.cur_day

        # calculate daylengths, store as hours
        day = time_start + (i_day * u.day)
        if (hasattr(time_start, "delta_ut1_utc")):
            day.delta_ut1_utc = time_start.delta_ut1_utc

        daylength_lut = ds.get_daylength_lookup(day)
        daylength[i_day, :] = daylength_lut.values

        # pull out/store minimum, maximum and afternoon temps
        t_min[i_day, :] = tair.min(unitted=False)
        t_max[i_day, :] = tair.max(unitted=False)
        t_afternoon[i_day, :] = tair.ref_val(unitted=False)

        # calculate RH & store
        rh_dlts = ds.compute_rh()
        rh_dlts.store_day(rh)
        rh_max[i_day, :] = rh_dlts.max(unitted=False)
        rh_min[i_day, :] = rh_dlts.min(unitted=False)
        rh_afternoon[i_day, :] = rh_dlts.ref_val(unitted=False)

        # calculate GSI indices and store
        i_tmin[i_day, :] = gsi.calc_i_tmin(tair.min())
        cell_daylengths = daylength_lut.get(ds.get_latitudes())
        i_photo[i_day, :] = gsi.calc_i_photo(cell_daylengths)
        i_vpd[i_day, :] = gsi.calc_i_vpd(ds.compute_afternoon_vpd())
        gsi_vals = i_tmin[i_day, :] * i_photo[i_day, :] * i_vpd[i_day, :]
        i_gsi[i_day, :] = gsi_vals

        # calculate running GSI average and store
        gsi_window.put(gsi_vals)
        if gsi_window.ready():
            i_gsi_avg[i_day, :] = gsi_window.mean()

        # calculate precipitation duration and store
        precip_val = ds.compute_precip_duration()
        precip[i_day, :] = precip_val

        # calculate total precip over last 24 hours, and dry day flag
        tot_precip_val = (rainf.sum() * ds.get_timestep()).to(u.kg / (u.m**2))
        tot_precip[i_day, :] = tot_precip_val
        dd_window.put(tot_precip_val < DRY_DAY_PRECIP)
        dd[i_day, :] = dd_window.all_runs()

        # calculate daily avg equilibrium moisture content
        eqmc_bar_val = ds.compute_eqmc_bar(cell_daylengths)
        eqmc_bar[i_day, :] = eqmc_bar_val

        # calculate fuel moisture content
        fm1000[i_day, :] = fm1000_calc.compute(eqmc_bar_val,
                                               precip_val).to(u.percent)
        fm100_today = fm100_calc.compute(eqmc_bar_val, precip_val)
        fm100[i_day, :] = fm100_today.to(u.percent)
        fm1_today, fm10_today = fm.oneten_ofdm(
            t_afternoon[i_day, :] * u.K,
            rh_afternoon[i_day, :] * u.dimensionless_unscaled,
            swdown.ref_val(), fm100_today)
        fm10[i_day, :] = fm10_today.to(u.percent)
        fm1[i_day, :] = fm1_today.to(u.percent)

        # first time through, store the first day's data
        if i_day == 1:
            rh_dlts.store_day(rh, current=False)

        # load next day for all variables
        ds.next()

    ds.close()