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
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