Ejemplo n.º 1
0
def ConsDaysOverOrLower(Data,Dates,Value,Comparation='Over'):
    '''
    DESCRIPTION:
    
        This function calculates the number of consecutive days with 
        values over or lower a specific value and also gives the dates at
        the beginning and end of evey season.
    _______________________________________________________________________

    INPUT:
        + Data: Data that needs to be counted.
        + Dates: Dates of the data, can be in datetime or string vector.
                 if the Dates are in a string vector it has to be in
                 yyyy/mm/dd.
        + Value: Value to search days over or lower.
        + Comparation: String with the comparation that is going to be 
                       done.
                       
                       It can recognize the following strings:

                             String           |       Interpretation 
                       'Over', 'over' or '>'  |             >
                       'Lower', 'lower' or '<'|             <
                              '>='            |             >=
                              '<='            |             <=
    _______________________________________________________________________
    
    OUTPUT:

        The output is the dictionary results with the following keys:

        - TotalNumDays: Vector with total number of consecutive days 
                        above or below the value.
        - TotalPrecCount: Vector with the total of values during the
                          different number of days, works with
                          precipitation, averages needs to be 
                          determined manually.
        - TotalDateB: Starting dates of the different events.
        - MaxNumDays: Maximum number of consecutive days above 
                      or below the value.
        - MaxPrecCount_MaxDay: Maximum values in the maximum day.
        - MaxNumDays_MaxPrec: Maximum days in the maximum values.
        - DateMaxDays: Beginnig date of the maximum days count.
    '''
    # keys
    keys = ['TotalNumDays','TotalPrecCount','TotalDateB','MaxNumDays',\
        'MaxPrecCount','DateMaxDays','MaxPrecCount_MaxDay','MaxNumDays_MaxPrec']
    # Determine operation
    Comp = utl.Oper_Det(Comparation)
    # ----------------
    # Error managment
    # ----------------
    if Comp == -1:
        return -1
    # Dates Error managment
    if isinstance(Dates[0],str):
        DatesP = DUtil.Dates_str2datetime(Dates)
        if list(DatesP)[0] == -1:
            return -1
        elif isinstance(DatesP[0],datetime):
            Er = utl.ShowError('DaysOverOrLower','Hydro_Analysis','Dates are not in days')
            return Er
    else:
        DatesP = Dates
        if isinstance(DatesP[0],datetime):
            Er = utl.ShowError('DaysOverOrLower','Hydro_Analysis','Dates are not in days')
            return Er
    # --------------
    # Calculations
    # --------------
    results = dict()
    results['TotalNumDays'] = [] # List with all the days
    results['TotalPrecCount'] = [] # List for the total
    results['TotalDateB'] = [] # List of dates
    x = np.where(Comp(Data,Value))[0]
    if len(x) > 1:
        # Loop to calculate all the days
        DaysCount = 1 # Days counter
        PrecCount = Data[x[0]] # Value counter
        for i in range(1,len(x)):
            if x[i] == x[i-1]+1:
                DaysCount += 1
                PrecCount += Data[x[i]]
            else:
                results['TotalNumDays'].append(DaysCount)
                results['TotalPrecCount'].append(PrecCount)
                results['TotalDateB'].append(DatesP[x[i]-DaysCount])
                DaysCount = 0
                PrecCount = 0

            if i == len(x)-1:
                results['TotalNumDays'].append(DaysCount)
                results['TotalPrecCount'].append(PrecCount)
                results['TotalDateB'].append(DatesP[x[i]-DaysCount])
                DaysCount = 0
                PrecCount = 0

        results['TotalNumDays'] = np.array(results['TotalNumDays'])
        # Maximum number of days
        results['MaxNumDays'] = np.max(results['TotalNumDays'])
        x = np.where(results['TotalNumDays'] == results['MaxNumDays'])[0]

        results['TotalPrecCount'] = np.array(results['TotalPrecCount'])
        # Maximum value counter of number of days that was max
        results['MaxPrecCount_MaxDay'] = np.max(results['TotalPrecCount'][x])

        # Maximum value in those days
        results['MaxPrecCount'] = np.max(results['TotalPrecCount'])
        x = np.where(results['TotalPrecCount'] == results['MaxPrecCount'])[0]
        # Maximum number of days of the maximum value
        results['MaxNumDays_MaxPrec'] = np.max(results['TotalNumDays'][x])

        # Beginning date of the maximum 
        results['TotalDateB'] = np.array(results['TotalDateB'])
        xx = np.where(results['TotalNumDays'] == results['MaxNumDays'])[0]
        results['DateMaxDays'] = results['TotalDateB'][xx]
    else:
        for ikey,key in enumerate(keys):
            if ikey > 2:
                results[key] = 0
            else:
                results[key] = np.array([0])

    return results
Ejemplo n.º 2
0
def DaysOverOrLower(Data,Dates,Value,flagMonths=False,Comparation='Over'):
    '''
    DESCRIPTION:

        This function calculates the days over or lower one specific value
        in every year or month and year of the series.
    _______________________________________________________________________

    INPUT:
        + Data: Data that needs to be counted.
        + Dates: Dates of the data, can be in datetime or string vector.
                 if the Dates are in a string vector it has to be in
                 yyyy/mm/dd.
        + Value: Value to search days over or lower.
        + flagMonths: flag to know if the count would be monthly.
                      True: to make the count monthly.
                      False: to make the count annualy.
        + Comparation: String with the comparation that is going to be 
                       done.
                       
                       It can recognize the following strings:

                             String           |       Interpretation 
                       'Over', 'over' or '>'  |             >
                       'Lower', 'lower' or '<'|             <
                              '>='            |             >=
                              '<='            |             <=

    _______________________________________________________________________
    
    OUTPUT:
    
        - results: number of days over or lower a value for every year or
                   month.
        - An: Dates where the operation was made.
    '''
    # Determine operation
    Comp = utl.Oper_Det(Comparation)
    # ----------------
    # Error managment
    # ----------------
    if Comp == -1:
        return -1, -1
    # Dates Error managment
    if isinstance(Dates[0],str):
        DatesP = DUtil.Dates_str2datetime(Dates)
        if list(DatesP)[0] == -1:
            return -1, -1
        elif isinstance(DatesP[0],datetime):
            Er = utl.ShowError('DaysOverOrLower','Hydro_Analysis','Dates are not in days')
            return Er, Er
    else:
        DatesP = Dates
        if isinstance(DatesP[0],datetime):
            Er = utl.ShowError('DaysOverOrLower','Hydro_Analysis','Dates are not in days')
            return Er, Er
    # ----------------
    # Dates managment
    # ----------------
    if flagMonths:
        An = DUtil.Dates_datetime2str(DatesP,Date_Format='%Y/%m')
        if list(An)[0] == -1:
            return -1,-1
    else:
        An = DUtil.Dates_datetime2str(DatesP,Date_Format='%Y')
        if list(An)[0] == -1:
            return -1,-1
    # ----------------
    # Calculations
    # ----------------
    results = []
    if flagMonths:      
        for i in range(DatesP[0].year,DatesP[-1].year+1):
            for j in range(1,13):
                if j < 10:
                    m = '%s/0%s' %(i,j)
                else:
                    m = '%s/%s' %(i,j)
                x = np.where(An == m)[0]
                P = Data[x]
                xx = np.where(Comp(P,Value))[0]
                if sum(~np.isnan(P)) >= 0.70*len(P):
                    results.append(len(xx))
                else:
                    results.append(np.nan)
    else:
        for i in range(DatesP[0].year,DatesP[-1].year+1):
            x = np.where(An == str(i))[0]

            P = Data[x]
            xx = np.where(Comp(P,Value))[0]
            if sum(~np.isnan(P)) >= 0.70*len(P):
                results.append(len(xx))
            else:
                results.append(np.nan)

    return results,An