Skip to content
Snippets Groups Projects
FireFuncs.py 7.13 KiB
Newer Older
Yang's avatar
Yang committed
def get_CONNECTIVITY_FIRE(fire):
Yang's avatar
Yang committed
    """ set the CONNECTIVITY_FIRE_KM value (km) for a given fire. Within this
Yang's avatar
Yang committed
    buffer of the fire exterior, new pixels will be appended to the fire.

    Constants
    ---------
    CONT_opt : int
        option number of CONNECTIVITY_FIRE_KM calculation
    CONT_preset : float
        the preset CONNECTIVITY_FIRE_KM value for option 0
    CONT_CA : dict
        the preset CONNECTIVITY_FIRE_KM lookup table for option 1
    FTYP_Glb : dict
        the preset CONNECTIVITY_FIRE_KM lookup table for option 2

    Parameters
    ----------
    fire : fire object
        the fire associated with the CONNECTIVITY_FIRE_KM

    Returns
    -------
    v : float
        the CONNECTIVITY_FIRE_KM (km)
Yang's avatar
Yang committed
    """
Yang's avatar
Yang committed
    from FireConsts import CONT_opt

Yang's avatar
Yang committed
    if CONT_opt == 0:  # use preset values
Yang's avatar
Yang committed
        from FireConsts import CONT_preset
Yang's avatar
Yang committed
        return CONT_preset
Yang's avatar
Yang committed
    elif CONT_opt == 1:  # use lookup table from CAFEDS
Yang's avatar
Yang committed
        from FireConsts import CONT_CA
Yang's avatar
Yang committed
        return CONT_CA[fire.ftype]
Yang's avatar
Yang committed
    elif CONT_opt == 2:  # use lookup table for global universal run
Yang's avatar
Yang committed
        from FireConsts import FTYP_Glb
Yang's avatar
Yang committed
        ftype = FTYP_Glb[fire.ftype]
        
        fnpix = min(fire.n_pixels, 25)  # set an upper limit 
        
Yang's avatar
Yang committed
        if ftype == "Temp Forest":
            v = fnpix * 2 / 25 + 0.8  # 0.8 (0) - 2.8 (25)
        elif ftype == "Trop Forest":
            v = fnpix * 0.7 / 25 + 0.7  # 0.7 (0) - 1.4 (25)
        elif ftype == "Bore Forest":
            v = fnpix * 3.2 / 25 + 1.0  # 1.0 (0) - 4.2 (25)
        elif ftype == "Savana":
            v = fnpix * 2.5 / 25 + 0.9  # 0.9 (0) - 3.4 (25)
Yang's avatar
Yang committed
        else:
            v = 0.7
        return v

Yang's avatar
Yang committed
def get_CONNECTIVITY_CLUSTER():
Yang's avatar
Yang committed
    """ get the connectivity spatial threshold for initial clustering
Yang's avatar
Yang committed

    Returns:
    --------
    CONNECTIVITY_CLUSTER_KM : float
        the connectivity spatial threshold for initial clustering, km
Yang's avatar
Yang committed
    """
Yang's avatar
Yang committed
    CONNECTIVITY_CLUSTER_KM = 0.7
    return CONNECTIVITY_CLUSTER_KM

Yang's avatar
Yang committed
def get_CONNECTIVITY_SLEEPER():
Yang's avatar
Yang committed
    """ get the CONNECTIVITY_SLEEPER_KM value
Yang's avatar
Yang committed

    Returns:
    --------
    CONNECTIVITY_SLEEPER_KM : float
        the connectivity spatial threshold (to previous fire line), km
Yang's avatar
Yang committed
    """
Yang's avatar
Yang committed
    CONNECTIVITY_SLEEPER_KM = 1  # 1km
    return CONNECTIVITY_SLEEPER_KM

Yang's avatar
Yang committed
def set_ftype(fire):
Yang's avatar
Yang committed
    """ set fire type and dominant LCT for newly activated fires
Yang's avatar
Yang committed

    Parameters
    ----------
    fire : fire object
        the fire associated with the CONNECTIVITY_FIRE_KM

Yang's avatar
Yang committed
    """
    import numpy as np
Yang's avatar
Yang committed
    from FireConsts import FTYP_opt
    import FireIO
    from datetime import date
Yang's avatar
Yang committed
    import random
Yang's avatar
Yang committed

    # 0 - use preset ftype (defined as FTYP_preset in FireConsts) for all fires
    # 1 - use the CA type classification (dtermined using LCTmax)
    # 2 - use the global type classfication (need more work...)

Yang's avatar
Yang committed
    if FTYP_opt == 0:  # use preset ftype for all fires
Yang's avatar
Yang committed
        from FireConsts import FTYP_preset
Yang's avatar
Yang committed
        ftype = FTYP_preset[0]
Yang's avatar
Yang committed
    elif FTYP_opt == 1:  # use CA type classifications (determined using LCTmax)
Yang's avatar
Yang committed
        # update or read LCTmax; calculated using all newlocs
Yang's avatar
Yang committed
        if fire.n_newpixels < 1000:
Yang's avatar
Yang committed
            uselocs = fire.newlocs_geo
        else:
            # we can do a random sample of 1000 new pixels (it's likely going to be a forest fire anyways)
            uselocs = random.sample(fire.newlocs_geo, 1000)

        vLCT = FireIO.get_LCT_CONUS(
Yang's avatar
Yang committed
            uselocs
        )  # call get_LCT to get all LCT for the fire pixels
        try:
            LCTmax = max(
            set(vLCT), key=vLCT.count)  # extract the LCT with most pixel counts
        except:
            print('No LCT data available, setting ftype to 0...')
            ftype = 0
            return ftype
Yang's avatar
Yang committed
        # get and record fm1000 value at ignition
Yang's avatar
Yang committed
        ignct = fire.ignlocsMP.centroid  # ignition centroid
        loc = (ignct.y, ignct.x)  # (lat,lon)
Yang's avatar
Yang committed
        t = date(*fire.t_st[:-1])
        try: stFM1000 = FireIO.get_FM1000(t, loc)
        except:
            #print('FM1000 data is unavailable at this time.')
            stFM1000 = 0
Yang's avatar
Yang committed

        # determine the fire type using the land cover type and stFM1000
        if LCTmax in [0, 11, 31]:  #'NoData', 'Water', 'Barren' -> 'Other'
Yang's avatar
Yang committed
            ftype = 0
Yang's avatar
Yang committed
        elif LCTmax in [23]:  # 'Urban' -> 'Urban'
Yang's avatar
Yang committed
            ftype = 1
Yang's avatar
Yang committed
        elif LCTmax in [82]:  # 'Agriculture' -> 'Agriculture'
Yang's avatar
Yang committed
            ftype = 6
Yang's avatar
Yang committed
        elif LCTmax in [42]:  # 'Forest' ->
            if stFM1000 > 12:  # 'Forest manage'
Yang's avatar
Yang committed
                ftype = 3
Yang's avatar
Yang committed
            else:  # 'Forest wild'
Yang's avatar
Yang committed
                ftype = 2
        elif LCTmax in [52, 71]:  # 'Shrub', 'Grassland' ->
Yang's avatar
Yang committed
            if stFM1000 > 12:  # 'Shrub manage'
Yang's avatar
Yang committed
                ftype = 5
Yang's avatar
Yang committed
            else:  # 'Shrub wild'
Yang's avatar
Yang committed
                ftype = 4
        else:
            print(f"Unknown land cover type {LCTmax}. Setting ftype to 0.")
            ftype = 0
Yang's avatar
Yang committed
    elif FTYP_opt == 2:  # global type classification
         # update or read LCTmax; calculated using all newlocs
        if fire.n_newpixels < 1000:
            uselocs = fire.newlocs_geo
        else:
            # we can do a random sample of 1000 new pixels (it's likely going to be a forest fire anyways)
            uselocs = random.sample(fire.newlocs_geo, 1000)
        
        vLCT = FireIO.get_LCT_Global(
            uselocs
        )  # call get_LCT to get all LCT for the fire pixels
        
        try:
            LCTmax = max(
            set(vLCT), key=vLCT.count)  # extract the LCT with most pixel counts
        except:
            print('No LCT data available, setting ftype to 0...')
            ftype = 0
            return ftype
        
        #print("LCTMAX:",LCTmax)
        if LCTmax in [0, 50, 60, 70, 80, 90, 100, 200]:
            ftype = 0
        # ^^^ current catch-all for 'Other'. 
        # See: https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_Landcover_100m_Proba-V-C3_Global
        
        elif LCTmax in [20]: # Shrub --> Savanna
            ftype = 4
        
        elif LCTmax in [40]: # Agriculture class
            ftype = 5
        
        else: # begin forested class
            lat_list = [xy[1] for xy in uselocs]
            lat_mean = abs(np.nanmean(lat_list))
            # Forest Classifications based on: https://ucmp.berkeley.edu/exhibits/biomes/forests.php
            if lat_mean < 23.5:
                ftype = 2 # tropical
            elif lat_mean < 50:
                ftype = 1 # temperate
            else:
                ftype = 3 # boreal
Yang's avatar
Yang committed
    return ftype

Yang's avatar
Yang committed
def set_ftypename(fire):
Yang's avatar
Yang committed
    """ return Fire type name
Yang's avatar
Yang committed

    Parameters
    ----------
    fire : fire object
        the fire associated with the CONNECTIVITY_FIRE_KM

    Returns
    -------
    ftname : str
        the fire type name of the given fire

Yang's avatar
Yang committed
    """
Yang's avatar
Yang committed
    from FireConsts import FTYP_opt

Yang's avatar
Yang committed
    if FTYP_opt == 0:  # use preset ftype for all fires
Yang's avatar
Yang committed
        from FireConsts import FTYP_preset
Yang's avatar
Yang committed
        ftname = FTYP_preset[0]
Yang's avatar
Yang committed
    elif FTYP_opt == 1:  # use CA type classifications (determined using LCTmax)
Yang's avatar
Yang committed
        from FireConsts import FTYP_CA
Yang's avatar
Yang committed
        ftname = FTYP_CA[fire.ftype]
    elif FTYP_opt == 2:  # global type classification
        from FireConsts import FTYP_Glb
Yang's avatar
Yang committed
        ftname = FTYP_Glb[fire.ftype]
    return ftname