def R99p_calculation(arr, percentile_arr, fill_val=None, out_unit="days"): """ Calculate the R99p indice: number of extremely wet days (i.e. days with daily precipitation amount > 99th percentile of daily amount in the base period). :param arr: daily precipitation flux (liquid form) (e.g. "pr") in mm/day :type arr: numpy.ndarray (3D) or numpy.ma.MaskedArray (3D) :param dt_arr: corresponding time steps vector :type dt_arr: numpy.ndarray (1D) of datetime objects :param percentile_dict: 99th percentile of daily precipitation amount at wet days in mm/day :type percentile_dict: dict :param fill_val: fill value :type fill_val: float :rtype: numpy.ndarray (2D) (if "arr" is numpy.ndarray) or numpy.ma.MaskedArray (2D) (if "arr" is numpy.ma.MaskedArray) .. warning:: If "arr" is a masked array, the parameter "fill_val" is ignored, because it has no sense in this case. """ wet_arr = calc.get_wet_days(arr=arr, fill_val=fill_val) # masked array R99p = calc.get_nb_events( wet_arr, logical_operation="gt", thresh=percentile_arr, fill_val=fill_val, out_unit=out_unit ) return R99p
def get_percentile_arr(arr, percentile, callback=None, callback_percentage_start_value=0, callback_percentage_total=100, chunk_counter=1, precipitation=True, fill_val=None, interpolation="hyndman_fan"): ''' Returns an 2D array with computed percentile values. :param arr: array of values (in case of precipitation, units must be `mm/day`) :type arr: numpy.ndarray (3D) or numpy.ma.MaskedArray (3D) of float :param dt_arr: corresponding time steps vector (base period: usually 1961-1990) :type dt_arr: numpy.ndarray (1D) of datetime objects :param percentile: percentile to compute which must be between 0 and 100 inclusive :type percentile: int :param callback: progress bar, if ``None`` progress bar will not be printed :type callback: :func:`callback.defaultCallback2` :param callback_percentage_start_value: init value for percentage of progress bar (default: 0) :type callback_percentage_start_value: int :param callback_percentage_total: final value for percentage of progress bar (default: 100) :type callback_percentage_total: int :param chunk_counter: chunk counter in case of chunking :type chunk_counter: int :param precipitation: if True, only values >=1.0 mm will be processed (i.e. wet days) :type precipitation: bool :param fill_val: fill value of ``arr`` :type fill_val: float :rtype: numpy.ndarray (2D) .. warning:: If "arr" is a masked array, the parameter "fill_val" is ignored, because it has no sense in this case. ''' assert (arr.ndim == 3) # we mask our array in case it has fill_values arr_masked = get_masked_arr(arr, fill_val) fill_val = arr_masked.fill_value ### not precipitation if precipitation == False: arr_filled = arr_masked.filled(fill_val) ### precipitation else: # we process only wet days (daily precip. amount >= 1.0 mm) wet_arr = calc.get_wet_days(arr=arr_masked) # we fill all masked values with fill_val to pass the filled array to the C function arr_filled = wet_arr.filled(fill_val) del arr_masked ############################## prepare calling C function # data type should be 'float32' to pass it to C function if arr_filled.dtype != 'float32': arr_filled = numpy.array(arr_filled, dtype='float32') C_percentile = libraryC.percentile_3d C_percentile.restype = None C_percentile.argtypes = [ ndpointer(ctypes.c_float), ctypes.c_int, ctypes.c_int, ctypes.c_int, ndpointer(ctypes.c_double), ctypes.c_int, ctypes.c_float, ctypes.c_char_p ] ## we check the fill_value (we need it to be the maximum value in the array) if fill_val == arr_filled.max(): pass else: fill_val_new = 1e+20 arr_filled[arr_filled == fill_val] = fill_val_new fill_val = fill_val_new ############################# arr_percentille = numpy.zeros([arr.shape[1], arr.shape[2]]) # we reserve memory # we compute the percentiles C_percentile(arr_filled, arr_filled.shape[0], arr_filled.shape[1], arr_filled.shape[2], arr_percentille, percentile, fill_val, interpolation) arr_percentille = arr_percentille.reshape(arr.shape[1], arr.shape[2]) return arr_percentille
def get_percentile_arr(arr, percentile, callback=None, callback_percentage_start_value=0, callback_percentage_total=100, chunk_counter=1, precipitation=True, fill_val=None, interpolation="hyndman_fan"): ''' Returns an 2D array with computed percentile values. :param arr: array of values (in case of precipitation, units must be `mm/day`) :type arr: numpy.ndarray (3D) or numpy.ma.MaskedArray (3D) of float :param dt_arr: corresponding time steps vector (base period: usually 1961-1990) :type dt_arr: numpy.ndarray (1D) of datetime objects :param percentile: percentile to compute which must be between 0 and 100 inclusive :type percentile: int :param callback: progress bar, if ``None`` progress bar will not be printed :type callback: :func:`callback.defaultCallback2` :param callback_percentage_start_value: init value for percentage of progress bar (default: 0) :type callback_percentage_start_value: int :param callback_percentage_total: final value for percentage of progress bar (default: 100) :type callback_percentage_total: int :param chunk_counter: chunk counter in case of chunking :type chunk_counter: int :param precipitation: if True, only values >=1.0 mm will be processed (i.e. wet days) :type precipitation: bool :param fill_val: fill value of ``arr`` :type fill_val: float :rtype: numpy.ndarray (2D) .. warning:: If "arr" is a masked array, the parameter "fill_val" is ignored, because it has no sense in this case. ''' assert(arr.ndim == 3) # we mask our array in case it has fill_values arr_masked = get_masked_arr(arr, fill_val) fill_val = arr_masked.fill_value ### not precipitation if precipitation == False: arr_filled = arr_masked.filled(fill_val) ### precipitation else: # we process only wet days (daily precip. amount >= 1.0 mm) wet_arr = calc.get_wet_days(arr=arr_masked) # we fill all masked values with fill_val to pass the filled array to the C function arr_filled = wet_arr.filled(fill_val) del arr_masked ############################## prepare calling C function # data type should be 'float32' to pass it to C function if arr_filled.dtype != 'float32': arr_filled = numpy.array(arr_filled, dtype='float32') C_percentile = libraryC.percentile_3d C_percentile.restype = None C_percentile.argtypes = [ndpointer(ctypes.c_float), ctypes.c_int, ctypes.c_int, ctypes.c_int, ndpointer(ctypes.c_double), ctypes.c_int, ctypes.c_float, ctypes.c_char_p] ## we check the fill_value (we need it to be the maximum value in the array) if fill_val == arr_filled.max(): pass else: fill_val_new = 1e+20 arr_filled[arr_filled==fill_val] = fill_val_new fill_val = fill_val_new ############################# arr_percentille = numpy.zeros([arr.shape[1], arr.shape[2]]) # we reserve memory # we compute the percentiles C_percentile(arr_filled, arr_filled.shape[0], arr_filled.shape[1], arr_filled.shape[2], arr_percentille, percentile, fill_val, interpolation) arr_percentille = arr_percentille.reshape(arr.shape[1], arr.shape[2]) return arr_percentille