<commit_before>import numpy as np
import os



## original database and code provided by
## <NAME> - NOAA Storm Prediction Center (hail)
## <NAME> - NOAA Storm Prediction Center (supercell)



## Routines implemented in Python by <NAME> - CIMMS and <NAME> (OU SoM)
## <EMAIL>, <EMAIL>, <EMAIL>, <EMAIL>


def sars_supercell(database_fn, mlcape, mllcl, h5temp, lr, shr, srh, shr3k, shr9k, srh3):
    # SARS for Supercells
    database_fn = os.path.join( os.path.dirname( __file__ ), database_fn)

    supercell_database = np.loadtxt(database_fn, skiprows=1, dtype=str, comments="%%%%")

    # Set range citeria for matching soundings

    # MLCAPE ranges
    range_mlcape = 1300 # J/kg
    range_mlcape_t1 = mlcape * 0.25 # J/kg

    # MLLCL ranges
    range_mllcl = 50 # m
    range_mllcl_t1 = 200 # m

    # 0-6 km shear ranges (kts)
    range_shr = 14
    range_shr_t1 = 10

    # 0-1 km SRH Ranges (m2/s2)
    if np.abs(srh) < 50:
        range_srh = 100.
    else:
        range_srh = srh

    if np.abs(srh) < 100:
        range_srh_t1 = 50
    else:
        range_srh_t1 = np.abs(shr) * 0.30

    # 0-3 SRH tier 1 ranges (m2/s2)
    if np.abs(srh3) < 100:
        range_srh3_t1 = 50.
    else:
        range_srh3_t1 = np.abs(srh3) * 0.50

    # 500 mb temperature ranges
    range_temp = 7 # C
    range_temp_t1 = 5 # C

    # 700-500 mb lapse rate ranges (C/km)
    range_lr = 1.0
    range_lr_t1 = 0.8

    # 3 km and 9 km shear matching
    range_shr3k_t1 = 15
    range_shr9k_t1 = 25

    mat_category = np.asarray(supercell_database[:,1], dtype=float) # category of match (0=non, 1=weak, 2=sig)
    mat_mlcape = np.asarray(supercell_database[:,3], dtype=float)
    mat_mllcl = np.asarray(supercell_database[:,5], dtype=float)
    mat_shr = np.asarray(supercell_database[:,7], dtype=float) # 0-6 KM SHEAR
    mat_srh = np.asarray(supercell_database[:,6], dtype=float) # 0-1 KM SRH
    mat_srh3 = np.asarray(supercell_database[:,14], dtype=float) # 0-3 KM SRH
    mat_h5temp = np.asarray(supercell_database[:,9], dtype=float) # 500 MB TEMP C
    mat_lr75 = np.asarray(supercell_database[:,11], dtype=float) # 700-500 MB LAPSE RATE
    mat_shr3 = np.asarray(supercell_database[:,12], dtype=float) # 0-3 KM SHEAR
    mat_shr9 = np.asarray(supercell_database[:,13], dtype=float) # 0-9 KM SHEAR

    loose_match_idx = np.where((mlcape >= (mat_mlcape - range_mlcape)) & (mlcape <= (mat_mlcape + range_mlcape)) & \
                               (mllcl >= (mat_mllcl - range_mllcl)) & (mllcl <= (mat_mllcl + range_mllcl)) & \
                               (shr >= (mat_shr - range_shr)) & (shr <= (mat_shr + range_shr)) & \
                               (srh >= (mat_srh - range_srh)) & (srh <= (mat_srh + range_srh)) & \
                               (h5temp >= (mat_h5temp - range_temp)) & (h5temp <= (mat_h5temp + range_temp)) & \
                               (lr >= (mat_lr75 - range_lr)) & (lr <= (mat_lr75 + range_lr)))[0]
    loose_match_soundings = supercell_database[:,0][loose_match_idx]

    num_matches = len(np.where(mat_category[loose_match_idx] > 0)[0]) #number of weak and sig matches in the loose matches

    # Probability for tornado
    if len(loose_match_idx) > 0.:
        tor_prob = num_matches / float(len(loose_match_idx))
    else:
        tor_prob = 0.

    # Tier 1 matches (also known as the quality matches)
    quality_match_idx = np.where((mlcape >= (mat_mlcape - range_mlcape_t1)) & (mlcape <= (mat_mlcape + range_mlcape_t1)) & \
                               (mllcl >= (mat_mllcl - range_mllcl_t1)) & (mllcl <= (mat_mllcl + range_mllcl_t1)) & \
                               (shr >= (mat_shr - range_shr_t1)) & (shr <= (mat_shr + range_shr_t1)) & \
                               (srh >= (mat_srh - range_srh_t1)) & (srh <= (mat_srh + range_srh_t1)) & \
                               (h5temp >= (mat_h5temp - range_temp_t1)) & (h5temp <= (mat_h5temp + range_temp_t1)) & \
                               (lr >= (mat_lr75 - range_lr_t1)) & (lr <= (mat_lr75 + range_lr_t1)) & \
                               (shr3k >= (mat_shr3 - range_shr3k_t1)) & (shr3k <= (mat_shr3 + range_shr3k_t1)) & \
                               (shr9k >= (mat_shr9 - range_shr9k_t1)) & (shr9k <= (mat_shr9 + range_shr9k_t1)) & \
                               (srh3 >= (mat_srh3 - range_srh3_t1)) & (srh3 <= (mat_srh3 + range_srh3_t1)))[0]

    quality_match_soundings = supercell_database[:,0][quality_match_idx]
    quality_match_tortype = np.asarray(supercell_database[:,1][quality_match_idx], dtype='|S7')

    np.place(quality_match_tortype, quality_match_tortype=='2', 'SIGTOR')
    np.place(quality_match_tortype, quality_match_tortype=='1', 'WEAKTOR')
    np.place(quality_match_tortype, quality_match_tortype=='0', 'NONTOR')
    return quality_match_soundings, quality_match_tortype, len(loose_match_idx), num_matches, tor_prob





def sars_hail(database_fn, mumr, mucape, h5_temp, lr, shr6, shr9, shr3, srh):
    '''
    The SARS Hail database was provided by <NAME> of the NOAA Storm
    Prediction Center in Norman, Oklahoma. This is a database of observed
    and model proximity analogue soundings to hail events.
    
    This function works by searching for matches to particular variables in 
    the database that have been attributed to hail events given a certain 
    range of uncertainty. The loose matches are used for statistics such as
    % significant hail matches, and are based on a looser criteria for
    matches. The analogues that get displayed are based on a tighter criteria
    for matches to insure that only quality matches are received. Ranges for
    loose and quality matches are semi-arbitrary, and were tuned by testing
    internally by SPC.
    
    The loose matches are based on the most unstable parcel mixing ratio (mumr),
    most unstable cape (mucape), 700-500mb labse rate (lr), 500mb temperature
    (h5_temp), 0-3km shear (shr3), 0-6km shear (shr6), and the 0-9km shear (shr9).
    
    The ranges for the loose matches are set as such:
        mumr: +/- 2.0 g/kg
        mucape: +/- 30% J/kg
        lr: +/- 2.0 C/km
        h5_temp: +/- 9.0 C/km
        shr6: +/- 12 m^2/s^2
        shr9: +/- 22 m^2/s^2
        shr3: +/- 10 m^2/s^2
    
    The quality matches use the fields described in the loose matches, plus the
    0-3km Storm Relative Helicity (srh). The bounds for the search for quality 
    matches is much more strict that the loose matches.
    
    The ranges for the quality matches are set as such:
        mumr: +/- 2.0 g/kg
        mucape < 500 J/kg: +/- 50% J/kg
        mucape < 2000 J/kg: +/- 25% J/kg
        mucape >= 2000 J/kg: +/- 20% J/kg
        lr: +/- 0.4 C/km
        h5_temp: +/- 1.5 C/km
        shr6: +/- 6 m^2/s^2
        shr9: +/- 15 m^2/s^2
        shr3: +/- 8 m^2/s^2
        srh < 50 m^2/s^2: +/- 25 m^2/s^2
        srh >= 50 m^2/s^2: +/- 50% m^2/s^2
    
    Parameters
    ----------
    mumr - most unstable parcel mixing ratio (g/kg)<commit_msg>Updated documentation for SARS Supercell database<commit_after>import numpy as np
import os



## original database and code provided by
## <NAME> - NOAA Storm Prediction Center (hail)
## <NAME> - NOAA Storm Prediction Center (supercell)



## Routines implemented in Python by <NAME> - CIMMS and <NAME> (OU SoM)
## <EMAIL>, <EMAIL>, <EMAIL>, <EMAIL>


def sars_supercell(database_fn, mlcape, mllcl, h5temp, lr, shr, srh, shr3k, shr9k, srh3):
    '''
    The SARS Supercell database was provided by <NAME> of the 
    NOAA Storm Prediction Center in Norman, Oklahoma. This is a database
    of observed and model proximity soundings to both tornadic and 
    nontornadic supercell thunderstorms.
    
    This function works by searching for matches to particular variables
    in the database that have been found to be useful in forecasting 
    supercell thunderstorms. It searches through the database to find 
    matches to a given sounding within a range of uncertainty that
    has been tested internally in SPC to provide the best analogues
    possible. There is a loose criteria that is used to get probabilities,
    and there is a tighter criteria for quality matches that are supposed to
    be similar to the given sounding.
    
    The loose matches are based on the mixed layer cape (mlcape), mixex layer
    lcl (mllcl), 0-1km shear (shr), 0-1km storm relative helicity (srh), 500mb
    temperature (h5temp), and the 700-500mb lapse rate (lr).
    
    The ranges for the loose matches are set as such:
        mlcape: +/- 1300 J/kg
        mllcl: +/- 50 m
        shr: +/- 14 kts
        srh < 50 m^2/s^2: +/- 100 m^2/s^2
        srh >= 50 m^2/s^2: +/- 100% m^2/s^2
        h5temp: +/- 7.0 C
        lr: +/-1.0 C/km
    
    The quality matches are based on the same variables as the loose matches,
    with the addition of the 0-3km shear (shr3k), 0-9km shear (shr9k), and the
    0-3km Storm Relative Helicity (srh3).
    
    The ranges for the quality matches are set as such:
        mlcape: +/- 25% J/kg
        mllcl: +/- 200 m
        shr: +/- 10 kts
        srh < 100 m^2/s^2: +/- 50 m^2/s^2
        srh >= 100 m^2/s^2: +/- 30% m^2/s^2
        srh3 < 100 m^2/s^2: +/- 50 m^2/s^2
        srh3 >= 100 m^2/s^2: +/- 50% m^s/s^2
        h5temp: +/- 5 C
        lr: +/- 0.8 C/km
        shr3k: +/- 15 kts
        shr9k: +/- 25 kts
        
    Parameters
    ----------
    database_fn - filename of the database
    mlcape - the mixed layer cape (J/kg)
    mllcl - the mixed layer LCL (m)
    h5temp - the 500mb temp (C)
    lr - the 700-500mb lapse rate (C/km)
    shr - the 0-1km shear (kts)
    srh - the 0-1km storm relative helicity (m^2/s^2)
    shr3k - the 0-3km shear (kts)
    shr9k - the 0-9km shear (kts)
    srh3 - the 0-3km storm relative helicity (m^2/s^2)
    
    Returns
    -------
    quality_match_soundings: The dates/locations of the quality matches
    quality_match_tortype: The type of quality match (SIGTOR/WEAKTOR/NONTOR)
    len(loose_match_idx):  The number of loose matches
    num_matches: The number of weak and sig matches in the loose matches
    tor_prob: SARS sig. tornado probability
    '''
    # SARS for Supercells
    database_fn = os.path.join( os.path.dirname( __file__ ), database_fn)

    supercell_database = np.loadtxt(database_fn, skiprows=1, dtype=str, comments="%%%%")

    # Set range citeria for matching soundings

    # MLCAPE ranges
    range_mlcape = 1300 # J/kg
    range_mlcape_t1 = mlcape * 0.25 # J/kg

    # MLLCL ranges
    range_mllcl = 50 # m
    range_mllcl_t1 = 200 # m

    # 0-6 km shear ranges (kts)
    range_shr = 14
    range_shr_t1 = 10

    # 0-1 km SRH Ranges (m2/s2)
    if np.abs(srh) < 50:
        range_srh = 100.
    else:
        range_srh = srh

    if np.abs(srh) < 100:
        range_srh_t1 = 50
    else:
        range_srh_t1 = np.abs(shr) * 0.30

    # 0-3 SRH tier 1 ranges (m2/s2)
    if np.abs(srh3) < 100:
        range_srh3_t1 = 50.
    else:
        range_srh3_t1 = np.abs(srh3) * 0.50

    # 500 mb temperature ranges
    range_temp = 7 # C
    range_temp_t1 = 5 # C

    # 700-500 mb lapse rate ranges (C/km)
    range_lr = 1.0
    range_lr_t1 = 0.8

    # 3 km and 9 km shear matching
    range_shr3k_t1 = 15
    range_shr9k_t1 = 25

    mat_category = np.asarray(supercell_database[:,1], dtype=float) # category of match (0=non, 1=weak, 2=sig)
    mat_mlcape = np.asarray(supercell_database[:,3], dtype=float)
    mat_mllcl = np.asarray(supercell_database[:,5], dtype=float)
    mat_shr = np.asarray(supercell_database[:,7], dtype=float) # 0-6 KM SHEAR
    mat_srh = np.asarray(supercell_database[:,6], dtype=float) # 0-1 KM SRH
    mat_srh3 = np.asarray(supercell_database[:,14], dtype=float) # 0-3 KM SRH
    mat_h5temp = np.asarray(supercell_database[:,9], dtype=float) # 500 MB TEMP C
    mat_lr75 = np.asarray(supercell_database[:,11], dtype=float) # 700-500 MB LAPSE RATE
    mat_shr3 = np.asarray(supercell_database[:,12], dtype=float) # 0-3 KM SHEAR
    mat_shr9 = np.asarray(supercell_database[:,13], dtype=float) # 0-9 KM SHEAR

    loose_match_idx = np.where((mlcape >= (mat_mlcape - range_mlcape)) & (mlcape <= (mat_mlcape + range_mlcape)) & \
                               (mllcl >= (mat_mllcl - range_mllcl)) & (mllcl <= (mat_mllcl + range_mllcl)) & \
                               (shr >= (mat_shr - range_shr)) & (shr <= (mat_shr + range_shr)) & \
                               (srh >= (mat_srh - range_srh)) & (srh <= (mat_srh + range_srh)) & \
                               (h5temp >= (mat_h5temp - range_temp)) & (h5temp <= (mat_h5temp + range_temp)) & \
                               (lr >= (mat_lr75 - range_lr)) & (lr <= (mat_lr75 + range_lr)))[0]
    loose_match_soundings = supercell_database[:,0][loose_match_idx]

    num_matches = len(np.where(mat_category[loose_match_idx] > 0)[0]) #number of weak and sig matches in the loose matches

    # Probability for tornado
    if len(loose_match_idx) > 0.:
        tor_prob = num_matches / float(len(loose_match_idx))
    else:
        tor_prob = 0.

    # Tier 1 matches (also known as the quality matches)
    quality_match_idx = np.where((mlcape >= (mat_mlcape - range_mlcape_t1)) & (mlcape <= (mat_mlcape + range_mlcape_t1)) & \
                               (mllcl >= (mat_mllcl - range_mllcl_t1)) & (mllcl <= (mat_mllcl + range_mllcl_t1)) & \
                               (shr >= (mat_shr - range_shr_t1)) & (shr <= (mat_shr + range_shr_t1)) & \
                               (srh >= (mat_srh - range_srh_t1)) & (srh <= (mat_srh + range_srh_t1)) & \
                               (h5temp >= (mat_h5temp - range_temp_t1)) & (h5temp <= (mat_h5temp + range_temp_t1)) & \
                               (lr >= (mat_lr75 - range_lr_t1)) & (lr <= (mat_lr75 + range_lr_t1)) & \
                               (shr3k >= (mat_shr3 - range_shr3k_t1)) & (shr3k <= (mat_shr3 + range_shr3k_t1)) & \
                               (shr9k >= (mat_shr9 - range_shr9k_t1)) & (shr9k <= (mat_shr9 + range_shr9k_t1)) & \
                               (srh3 >= (mat_srh3 - range_srh3_t1)) & (srh3 <= (mat_srh3 + range_srh3_t1)))[0]

    quality_match_soundings = supercell_database[:,0][quality_match_idx]
    quality_match_tortype = np.asarray(supercell_database[:,1][quality_match_idx], dtype='|S7')

    np.place(quality_match_tortype, quality_match_tortype=='2', 'SIGTOR')
    np.place(quality_match_tortype, quality_match_tortype=='1', 'WEAKTOR')
    np.place(quality_match_tortype, quality_match_tortype=='0', 'NONTOR')
    return quality_match_soundings, quality_match_tortype, len(loose_match_idx), num_matches, tor_prob





def sars_hail(database_fn, mumr, mucape, h5_temp, lr, shr6, shr9, shr3, srh):
    '''
    The SARS Hail database was provided by <NAME> of the NOAA Storm
    Prediction Center in Norman, Oklahoma. This is a database of observed
    and model proximity analogue soundings to hail events.
    
    This function works by searching for matches to particular variables in 
    the database that have been attributed to hail events given a certain 
    range of uncertainty. The loose matches are used for statistics such as
    % significant hail matches, and are based on a looser criteria for
    matches. The analogues that get displayed are based on a tighter criteria
    for matches to insure that only quality matches are received. Ranges for
    loose and quality matches are semi-arbitrary, and were tuned by testing
    internally by SPC.
    
    The loose matches are based on the most unstable parcel mixing ratio (mumr),
    most unstable cape (mucape), 700-500mb labse rate (lr), 500mb temperature
    (h5_temp), 0-3km shear (shr3), 0-6km shear (shr6), and the 0-9km shear (shr9).
    
    The ranges for the loose matches are set as such:
        mumr: +/- 2.0 g/kg
        mucape: +/- 30% J/kg
        lr: +/- 2.0 C/km
        h5_temp: +/- 9.0 C
        shr6: +/- 12 m^2/s^2
        shr9: +/- 22 m^2/s^2
        shr3: +/- 10 m^2/s^2
    
    The quality matches use the fields described in the loose matches, plus the
    0-3km Storm Relative Helicity (srh). The bounds for the search for quality 
    matches is much more strict that the loose matches.
    
    The ranges for the quality matches are set as such:
        mumr: +/- 2.0 g/kg
        mucape < 500 J/kg: +/- 50% J/kg
        mucape < 2000 J/kg: +/- 25% J/kg
        mucape >= 2000 J/kg: +/- 20% J/kg
        lr: +/- 0.4 C/km
        h5_temp: +/- 1.5 C/km
        shr6: +/- 6 m^2/s^2
        shr9: +/- 15 m^2/s^2
        shr3: +/- 8 m^2/s^2
        srh < 50 m^2/s^2: +/- 25 m^2/s^2
        srh >= 50 m^2/s^2: +/- 50% m^2/s^2
    
    Parameters
    ----------
    mumr - most unstable parcel mixing ratio (g/kg)
{'fraction_non_alphanumeric': 0.11730134932533733, 'fraction_numerical': 0.04419790104947526, 'mean_word_length': 2.3949511400651464, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4791488', 'n_tokens_mistral': 6584, 'n_tokens_neox': 5892, 'n_words': 1679}