diff --git a/function/utils.py b/function/utils.py index 2aee6d5..c844689 100644 --- a/function/utils.py +++ b/function/utils.py @@ -210,12 +210,14 @@ def near_value( list_ , value ): def find_peak_low_high( list_ , value ): """ - Return index of start and end of the biggest peak in a list + Return index of start and end of rise and descent of peaks crossing + a given value in a list """ indexes = near_value( list_, value, ) + old_list_ = list_ list_ = np.gradient( list_ ) if list_[ indexes[0] ] < 0: indexes.insert( 0 , 0 ) @@ -236,35 +238,123 @@ def find_peak_low_high( list_ , value ): descents = [ indexes[ i ] for i in range( 1 , len( indexes ) , 2 ) ] - np.where( list_[ : rises[0] ] < 0 )[-1] - np.where( list_[ descents[ i - 1 ] : rises[ i ] ] < 0 )[-1] - np.where( list_[ rises[ i - 1 ] : descents[ i ] ] < 0 )[-1] - first_rise , last_rise = indexes[0] , indexes[0] - first_descent , last_descent = indexes[1] , indexes[1] - min_diff = ( max( list_ ) - min( list_ ) ) * 0.001 - max_high_value = max( list_ ) - min_high_value = min( list_ ) - max_low_value = max( list_ ) - min_low_value = min( list_ ) - while ( - max_high_value - min_high_value > min_diff or - max_low_value - min_low_value > min_diff - ): - current_high = min_high_value + ( - max_high_value - min_high_value - ) / 2 - current_low = min_low_value + ( - max_low_value - min_low_value - ) / 2 - indexes_high = near_value( list_ , current_high ) - indexes_low = near_value( list_ , current_low ) - if len( indexes_low ) != 2: - min_low_value = current_low - else: - max_low_value = current_low - if len( indexes_high ) != 2: - max_high_value = current_high - else: - min_high_value = current_high - return indexes_low, indexes_high + i = 0 + start_rise = np.where( list_[ : rises[i] ] < 0 ) + end_rise = rises[i] + np.where( + list_[ rises[i] : descents[i] ] < 0 + ) + start_descent = rises[i] + np.where( + list_[ rises[i] : descents[i] ] > 0 + ) + if len( rises ) == 1: + end_descent = descents[i] + np.where( + list_[ descents[i] : ] > 0 + ) + else: + end_descent = descents[i] + np.where( + list_[ descents[i] : rises[i + 1] ] > 0 + ) + + if len( start_rise[0] ) == 0: + rise_starts = [ 0 ] + else: + rise_starts = [ start_rise[0][-1] ] + if len( end_rise[0] ) == 0: + rise_ends = [ rise_starts[0] ] # if first is a descent + else: + rise_ends = [ end_rise[0][0] ] + if len( start_descent[0] ) == 0: + descent_starts = [ rise_ends[0] ] # same + else: + descent_starts = [ start_descent[0][-1] ] + if len( end_descent[0] ) == 0: # edge case: + descent_ends = [ descent_starts[0] ] # one pixel decrease + else: + descent_ends = [ end_descent[0][0] ] + + while i < len( rises ) - 2: # last is i == len( rises ) - 2, works + # if len( rises ) = 1 or 2 + i += 1 + start_rise = descents[i - 1 ] + np.where( + list_[ descents[i - 1] : rises[i] ] < 0 + ) + end_rise = rises[i] + np.where( + list_[ rises[i] : descents[i] ] < 0 + ) + start_descent = rises[i] + np.where( + list_[ rises[i] : descents[i] ] > 0 + ) + end_descent = descents[i] + np.where( + list_[ descents[i] : rises[i + 1] ] > 0 + ) + + if len( start_rise[0] ) == 0: + rise_starts.append( descent_ends[-1] ) + else: + rise_starts.append( + start_rise[0][-1] # last pixel that decrease + ) + if len( end_rise[0] ) == 0: + rise_ends.append( rise_starts[-1] ) + else: + rise_ends.append( + end_rise[0][0] # first pixel that decrease + ) + if len( start_descent[0] ) == 0: + descent_starts.append( rises_ends[-1] ) + else: + descent_starts.append( + start_descent[0][-1] # last pixel that increase + ) + if len( end_descent[0] ) == 0: + descent_ends.append( descent_starts[-1] ) + else: + descent_ends.append( + end_descent[0][0] # first pixel that increase + ) + if i != 0 or len( rises ) != 1: + i += 1 + start_rise = descents[i - 1] + np.where( + list_[ descents[i - 1] : rises[i] ] < 0 + ) + end_rise = rises[i] + np.where( + list_[ rises[i] : descents[i] ] < 0 + ) + start_descent = rises[i] + np.where( + list_[ rises[i] : descents[i] ] > 0 + ) + end_descent = descents[i] + np.where( + list_[ descents[i] : ] > 0 + ) + + if len( start_rise[0] ) == 0: + rise_starts.append( descent_ends[-1] ) + else: + rise_starts.append( + start_rise[0][-1] # last pixel that decrease + ) + if len( end_rise[0] ) == 0: + rise_ends.append( rise_starts[-1] ) + else: + rise_ends.append( + end_rise[0][0] # first pixel that decrease + ) + if len( start_descent[0] ) == 0: + descent_starts.append( rises_ends[-1] ) + else: + descent_starts.append( + start_descent[0][-1] # last pixel that increase + ) + if len( end_descent[0] ) == 0: + descent_ends.append( descent_starts[-1] ) + else: + descent_ends.append( + end_descent[0][0] # first pixel that increase + ) + return [ + rise_starts , + rise_ends , + descent_starts, + descent_ends , + ]