def get_optimum_time_range(input_data, new_time_range): """ This grabs a few more (or a few less, if enough not available) points so that the FFT is more efficient. For FFTW, it is more efficient to zero pad to a nice number above even if it is a long way away. This is always true for Fourier filtering, in which case you never see the zeros. For general applications, the zeros might be confusing if you forget they have been put there. """ from pyfusion.utils.primefactors import fft_time_estimate nt_args = searchsorted(input_data.timebase, new_time_range) # try for 20 more points extension = ((new_time_range[1]-new_time_range[0]) *float(20)/(nt_args[1]-nt_args[0])) (dum,trial_upper) = searchsorted(input_data.timebase, [new_time_range[0], new_time_range[1]+extension]) # if not consider using less than the original request trial_lower = trial_upper - 20 times = [] for num in range(trial_lower, trial_upper): times.append(fft_time_estimate(num - nt_args[0])) newupper = trial_lower+np.argmin(times) if newupper != nt_args[1]: pyfusion.utils.warn('Interval fft optimized from {old} to {n} points' .format(n=newupper-nt_args[0], old=nt_args[1]-nt_args[0])) best_upper_time = input_data.timebase[newupper] new_time_range[1] = (best_upper_time - 0.5*np.average(np.diff(input_data.timebase))) if pyfusion.VERBOSE>0: print('returning new time range={n}'.format(n=new_time_range)) return(new_time_range)
def get_optimum_time_range(input_data, new_time_range): """ This grabs a few more (or a few less, if enough not available) points so that the FFT is more efficient. For FFTW, it is more efficient to zero pad to a nice number above even if it is a long way away. This is always true for Fourier filtering, in which case you never see the zeros. For general applications, the zeros might be confusing if you forget they have been put there. """ from pyfusion.utils.primefactors import fft_time_estimate nt_args = searchsorted(input_data.timebase, new_time_range) # try for 20 more points extension = ((new_time_range[1] - new_time_range[0]) * float(20) / (nt_args[1] - nt_args[0])) (dum, trial_upper) = searchsorted( input_data.timebase, [new_time_range[0], new_time_range[1] + extension]) # if not consider using less than the original request trial_lower = trial_upper - 20 times = [] for num in range(trial_lower, trial_upper): times.append(fft_time_estimate(num - nt_args[0])) newupper = trial_lower + np.argmin(times) if newupper != nt_args[1]: pyfusion.utils.warn( 'Interval fft optimized from {old} to {n} points'.format( n=newupper - nt_args[0], old=nt_args[1] - nt_args[0])) best_upper_time = input_data.timebase[newupper] new_time_range[1] = (best_upper_time - 0.5 * np.average(np.diff(input_data.timebase))) if pyfusion.VERBOSE > 0: print('returning new time range={n}'.format(n=new_time_range)) return (new_time_range)
def get_optimum_time_range(input_data, new_time_range, try_more=0.0002): """This grabs a few more (or a few less, if enough not available in input_data) points than requested so that the FFT is more efficient. try_more is the number of samples to increase/decrease as a fraction of the input data. Note: For FFTW, it is more efficient to zero pad to a nice number above, even if it is a long way away. This is always true for Fourier filtering, in which case you never see the zeros. For general applications, the zeros might be confusing if you forget they have been put there. """ from pyfusion.utils.primefactors import fft_time_estimate # obtain indices of the beginning and end times - not sure of precision effects. nt_args = searchsorted(input_data.timebase, new_time_range) if nt_args[0] == nt_args[1]: raise LookupError( 'No samples in {dr} in the requested new time range {tr}'.format( tr=str(new_time_range), dr=str([input_data.timebase.min(), input_data.timebase.max()]))) # try for try_more more points (as a fraction of the timebase) # extension is in seconds if abs(try_more) == 1: try_more = 0.0002 * try_more # avoid error on small samples try_more = max(10, int(len(input_data.timebase) * try_more)) extension = ((new_time_range[1] - new_time_range[0]) * float(try_more) / (nt_args[1] - nt_args[0])) if pyfusion.VERBOSE > 0: print('try_more = {tm}, nt_args = {nt}, extension = {ex}'.format( tm=try_more, ex=extension, nt=nt_args)) (dum, trial_upper) = searchsorted( input_data.timebase, [new_time_range[0], new_time_range[1] + extension]) # if not consider using less than the original request trial_lower = trial_upper - try_more times = [] if pyfusion.VERBOSE > 0: print('get_optimum_time_range {l} to {u}'.format(l=trial_lower, u=trial_upper)) for num in range(trial_lower, trial_upper, np.sign(try_more)): times.append(fft_time_estimate(num - nt_args[0])) newupper = trial_lower + np.argmin(times) if newupper != nt_args[1]: pyfusion.utils.warn( 'Interval fft optimized from {old} to {n} points'.format( n=newupper - nt_args[0], old=nt_args[1] - nt_args[0])) best_upper_time = input_data.timebase[newupper] new_time_range[1] = (best_upper_time - 0.5 * np.nanmean(np.diff(input_data.timebase))) debug_(pyfusion.DEBUG, 5, key='reduce_time') if pyfusion.VERBOSE > 0: print('returning new time range={n}'.format(n=new_time_range)) return (new_time_range)