def seam_carving_row(arr, peaks): arrc = arr.copy() # minlist = np.argmin(arrc[:,0]) minlist = peaks for i in range(arr.shape[1] - 1): output = minimum_filter1d(arr[:, i].copy(), size=3, mode='reflect') arr[:, i + 1] = output + arr[:, i + 1] minindex_list = [] print(minlist) allpath = [] for min in minlist: minindex_list.append(min) result = None for i in range(0, arr.shape[1] - 1): min = minindex_list[-1] output = minimum_filter1d(arr[:, i + 1].copy(), size=3, mode='reflect') index = np.argwhere(arr[:, i + 1] == output[min]) index = np.squeeze(index, axis=1) for inner in index: if abs(inner - min) < 2: result = inner break minindex_list.append(result) path = minindex_list minindex_list = [] # pathcheck(path) allpath.append(path) return allpath
def test_multiple_modes_sequentially(): # Test that the filters with multiple mode cababilities for different # dimensions give the same result as applying the filters with # different modes sequentially arr = np.array([[1., 0., 0.], [1., 1., 0.], [0., 0., 0.]]) modes = ['reflect', 'wrap'] expected = sndi.gaussian_filter1d(arr, 1, axis=0, mode=modes[0]) expected = sndi.gaussian_filter1d(expected, 1, axis=1, mode=modes[1]) assert_equal(expected, sndi.gaussian_filter(arr, 1, mode=modes)) expected = sndi.uniform_filter1d(arr, 5, axis=0, mode=modes[0]) expected = sndi.uniform_filter1d(expected, 5, axis=1, mode=modes[1]) assert_equal(expected, sndi.uniform_filter(arr, 5, mode=modes)) expected = sndi.maximum_filter1d(arr, size=5, axis=0, mode=modes[0]) expected = sndi.maximum_filter1d(expected, size=5, axis=1, mode=modes[1]) assert_equal(expected, sndi.maximum_filter(arr, size=5, mode=modes)) expected = sndi.minimum_filter1d(arr, size=5, axis=0, mode=modes[0]) expected = sndi.minimum_filter1d(expected, size=5, axis=1, mode=modes[1]) assert_equal(expected, sndi.minimum_filter(arr, size=5, mode=modes))
def test_minmaximum_filter1d(): # Regression gh-3898 in_ = np.arange(10) out = sndi.minimum_filter1d(in_, 1) assert_equal(in_, out) out = sndi.maximum_filter1d(in_, 1) assert_equal(in_, out) # Test reflect out = sndi.minimum_filter1d(in_, 5, mode='reflect') assert_equal([0, 0, 0, 1, 2, 3, 4, 5, 6, 7], out) out = sndi.maximum_filter1d(in_, 5, mode='reflect') assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 9, 9], out) #Test constant out = sndi.minimum_filter1d(in_, 5, mode='constant', cval=-1) assert_equal([-1, -1, 0, 1, 2, 3, 4, 5, -1, -1], out) out = sndi.maximum_filter1d(in_, 5, mode='constant', cval=10) assert_equal([10, 10, 4, 5, 6, 7, 8, 9, 10, 10], out) # Test nearest out = sndi.minimum_filter1d(in_, 5, mode='nearest') assert_equal([0, 0, 0, 1, 2, 3, 4, 5, 6, 7], out) out = sndi.maximum_filter1d(in_, 5, mode='nearest') assert_equal([2, 3, 4, 5, 6, 7, 8, 9, 9, 9], out) # Test wrap out = sndi.minimum_filter1d(in_, 5, mode='wrap') assert_equal([0, 0, 0, 1, 2, 3, 4, 5, 0, 0], out) out = sndi.maximum_filter1d(in_, 5, mode='wrap') assert_equal([9, 9, 4, 5, 6, 7, 8, 9, 9, 9], out)
def move_nanmin_filter(arr, window, axis=-1): "Moving window minimium ignoring NaNs, implemented with a filter." global minimum_filter1d, convolve1d if minimum_filter1d is None: try: from scipy.ndimage import minimum_filter1d except ImportError: raise ValueError("'filter' method requires SciPy.") if convolve1d is None: try: from scipy.ndimage import convolve1d except ImportError: raise ValueError("'filter' method requires SciPy.") if axis == None: raise ValueError, "An `axis` value of None is not supported." if window < 1: raise ValueError, "`window` must be at least 1." if window > arr.shape[axis]: raise ValueError, "`window` is too long." arr = arr.astype(float) nrr = np.isnan(arr) arr[nrr] = np.inf x0 = (window - 1) // 2 minimum_filter1d(arr, window, axis=axis, mode='constant', cval=np.nan, origin=x0, output=arr) w = np.ones(window, dtype=int) nrr = nrr.astype(int) x0 = (1 - window) // 2 convolve1d(nrr, w, axis=axis, mode='constant', cval=0, origin=x0, output=nrr) arr[nrr == window] = np.nan return arr
def move_min_filter(arr, window, axis=-1): "Moving window minimium implemented with a filter." arr = np.array(arr, copy=False) global minimum_filter1d if minimum_filter1d is None: try: from scipy.ndimage import minimum_filter1d except ImportError: raise ValueError("'filter' method requires SciPy.") if axis == None: raise ValueError("An `axis` value of None is not supported.") if window < 1: raise ValueError("`window` must be at least 1.") if window > arr.shape[axis]: raise ValueError("`window` is too long.") y = arr.astype(float) x0 = (window - 1) // 2 minimum_filter1d(y, window, axis=axis, mode='constant', cval=np.nan, origin=x0, output=y) return y
def seam_carving(arr): for i in range(arr.shape[0] - 1): output = minimum_filter1d(arr[i].copy(), size=3, mode='reflect') arr[i + 1] = output + arr[i + 1] minindex_list = [] min = np.argmin(arr[-1]) minindex_list.append(min) checklist = [] result = None for i in reversed(range(1, arr.shape[0])): min = minindex_list[-1] output = minimum_filter1d(arr[i - 1].copy(), size=3, mode='reflect') # number=np.argmin([arr[i-1][min-1],arr[i-1][min],arr[i-1][min+1]]) index = np.argwhere(arr[i - 1] == output[min]) index = np.squeeze(index, axis=1) for inner in index: if abs(inner - min) < 2: result = inner break checklist.append(abs(inner - min)) checklist = [] minindex_list.append(result) path = list(reversed(minindex_list)) pathcheck(path) return list(reversed(minindex_list))
def plot_max_min(rewards, labels, sigma, save=False, filename=''): ''' Like plot_iterations, but plots max and min instead of stds ''' plt.figure(figsize=figure_size) ax = plt.gca() for i in range(len(rewards)): rewards[i] = rewards[i].squeeze() color = next(ax._get_lines.prop_cycler)['color'] rewards_mean = np.mean(rewards[i], axis=(0, 2)) rewards_mean = gaussian_filter(rewards_mean, sigma=sigma) rewards_min = np.min(rewards[i], axis=(0, 2)) rewards_min = minimum_filter1d(rewards_min, sigma) rewards_max = np.max(rewards[i], axis=(0, 2)) rewards_max = maximum_filter1d(rewards_max, sigma) plt.plot(rewards_mean, color=color, label=labels[i]) plt.fill_between(range(rewards_mean.size), rewards_min, rewards_max, alpha=0.3) # plt.plot(gaussian_filter(rewards_min, 100), color = color, linestyle = 'dashed') # plt.plot(gaussian_filter(rewards_max, 100), color = color, linestyle = 'dashed') plt.xlabel('Episodes') plt.ylabel('Rewards') plt.legend() if save: plt.savefig(filename) plt.show()
def smoothing(self, data, sigma): """ Smooth out 1D dataset with a gaussian kernel Parameters ---------- data: 2D array x-y coordinates to be smoothed sigma: float STD of the smoothing gaussian Returns ------- dnew: 2D array smoothed x-y coordinates """ x, y = data x = ndimage.minimum_filter1d(x, sigma) x = ndimage.maximum_filter1d(x, 4 * sigma) # filtered = ndimage.gaussian_filter1d(x, sigma, mode='reflect') #filtered[:2 * sigma] = x[:2 * sigma] #filtered[-2 * sigma:] = x[-2 * sigma:] dnew = x, y plot = False if plot: fig = plt.figure() ax = fig.add_subplot(111) # ax.plot(filtered, lw=0.5) #ax.plot(x, lw=0.5) # ax.set_xlim([900, 2500]) fig.savefig('smooting_debug.png', dpi=300) return dnew
def move_min_filter(arr, window, axis=-1): "Moving window minimium implemented with a filter." global minimum_filter1d if minimum_filter1d is None: try: from scipy.ndimage import minimum_filter1d except ImportError: raise ValueError("'filter' method requires SciPy.") if axis == None: raise ValueError, "An `axis` value of None is not supported." if window < 1: raise ValueError, "`window` must be at least 1." if window > arr.shape[axis]: raise ValueError, "`window` is too long." y = arr.astype(float) x0 = (window - 1) // 2 minimum_filter1d(y, window, axis=axis, mode='constant', cval=np.nan, origin=x0, output=y) return y
def move_nanmin_filter(arr, window, axis=-1): "Moving window minimium ignoring NaNs, implemented with a filter." global minimum_filter1d, convolve1d arr = np.array(arr, copy=False) if minimum_filter1d is None: try: from scipy.ndimage import minimum_filter1d except ImportError: raise ValueError("'filter' method requires SciPy.") if convolve1d is None: try: from scipy.ndimage import convolve1d except ImportError: raise ValueError("'filter' method requires SciPy.") if axis == None: raise ValueError("An `axis` value of None is not supported.") if window < 1: raise ValueError("`window` must be at least 1.") if window > arr.shape[axis]: raise ValueError("`window` is too long.") arr = arr.astype(float) nrr = np.isnan(arr) arr[nrr] = np.inf x0 = (window - 1) // 2 minimum_filter1d(arr, window, axis=axis, mode='constant', cval=np.nan, origin=x0, output=arr) w = np.ones(window, dtype=int) nrr = nrr.astype(int) x0 = (1 - window) // 2 convolve1d(nrr, w, axis=axis, mode='constant', cval=0, origin=x0, output=nrr) arr[nrr == window] = np.nan return arr
def local_extrema_2(arr, min_distance = 20): """Find all local maxima of the array, separated by at least min_distance.""" cval = 0 mode = 'constant' cval = arr.max()+1 max_points = arr == maximum_filter1d(arr, min_distance) min_points = arr == minimum_filter1d(arr, min_distance) return [arr[nonzero(min_points==True)[0]],nonzero(min_points==True)[0], arr[nonzero(max_points==True)[0]],nonzero(max_points==True)[0]]
def get_y_derivativemap(flat, flat_bpix, bg_std_norm, max_sep_order=150, pad=50, med_filter_size=(7, 7), flat_mask=None): """ flat flat_bpix : bpix'ed flat """ # 1d-derivatives along y-axis : 1st attempt # im_deriv = ni.gaussian_filter1d(flat, 1, order=1, axis=0) # 1d-derivatives along y-axis : 2nd attempt. Median filter first. flat_deriv_bpix = ni.gaussian_filter1d(flat_bpix, 1, order=1, axis=0) # We also make a median-filtered one. This one will be used to make masks. flat_medianed = ni.median_filter(flat, size=med_filter_size) flat_deriv = ni.gaussian_filter1d(flat_medianed, 1, order=1, axis=0) # min/max filter flat_max = ni.maximum_filter1d(flat_deriv, size=max_sep_order, axis=0) flat_min = ni.minimum_filter1d(flat_deriv, size=max_sep_order, axis=0) # mask for aperture boundray if pad is None: sl = slice() else: sl = slice(pad, -pad) flat_deriv_masked = np.zeros_like(flat_deriv) flat_deriv_masked[sl, sl] = flat_deriv[sl, sl] if flat_mask is not None: flat_deriv_pos_msk = (flat_deriv_masked > flat_max * 0.5) & flat_mask flat_deriv_neg_msk = (flat_deriv_masked < flat_min * 0.5) & flat_mask else: flat_deriv_pos_msk = (flat_deriv_masked > flat_max * 0.5) flat_deriv_neg_msk = (flat_deriv_masked < flat_min * 0.5) return dict( data=flat_deriv, #_bpix, pos_mask=flat_deriv_pos_msk, neg_mask=flat_deriv_neg_msk, )
def get_y_derivativemap(flat, flat_bpix, bg_std_norm, max_sep_order=150, pad=50, med_filter_size=(7, 7), flat_mask=None): """ flat flat_bpix : bpix'ed flat """ # 1d-derivatives along y-axis : 1st attempt # im_deriv = ni.gaussian_filter1d(flat, 1, order=1, axis=0) # 1d-derivatives along y-axis : 2nd attempt. Median filter first. flat_deriv_bpix = ni.gaussian_filter1d(flat_bpix, 1, order=1, axis=0) # We also make a median-filtered one. This one will be used to make masks. flat_medianed = ni.median_filter(flat, size=med_filter_size) flat_deriv = ni.gaussian_filter1d(flat_medianed, 1, order=1, axis=0) # min/max filter flat_max = ni.maximum_filter1d(flat_deriv, size=max_sep_order, axis=0) flat_min = ni.minimum_filter1d(flat_deriv, size=max_sep_order, axis=0) # mask for aperture boundray if pad is None: sl=slice() else: sl=slice(pad, -pad) flat_deriv_masked = np.zeros_like(flat_deriv) flat_deriv_masked[sl,sl] = flat_deriv[sl, sl] if flat_mask is not None: flat_deriv_pos_msk = (flat_deriv_masked > flat_max * 0.5) & flat_mask flat_deriv_neg_msk = (flat_deriv_masked < flat_min * 0.5) & flat_mask else: flat_deriv_pos_msk = (flat_deriv_masked > flat_max * 0.5) flat_deriv_neg_msk = (flat_deriv_masked < flat_min * 0.5) return dict(data=flat_deriv, #_bpix, pos_mask=flat_deriv_pos_msk, neg_mask=flat_deriv_neg_msk, )
def cumulative_minimum_energy_map(energyImage, seamDirection): if seamDirection == 'VERTICAL': cumulativeMinimumEnergyMap = np.copy(energyImage) elif seamDirection == 'HORIZONTAL': cumulativeMinimumEnergyMap = np.transpose(np.copy(energyImage)) energyImage = np.transpose(energyImage) m, n = cumulativeMinimumEnergyMap.shape for row in range(1, m): prev_row = cumulativeMinimumEnergyMap[row - 1] cumulativeMinimumEnergyMap[row] = energyImage[row] + minimum_filter1d( prev_row, 3) if seamDirection == 'HORIZONTAL': cumulativeMinimumEnergyMap = np.transpose(cumulativeMinimumEnergyMap) return cumulativeMinimumEnergyMap
def peak_corr(pulse, receiver, name): corr = np.correlate(receiver, pulse, mode='valid') corr_abs = np.abs(corr) corr_max = ndimage.maximum_filter1d(corr_abs, L // 8, mode='constant') corr_min = ndimage.minimum_filter1d(corr_abs, L // 8, mode='constant') indics_mask = (corr_abs == corr_max) & (corr_max - corr_min >= .3 * signal_power * L) indics = np.argwhere(indics_mask).flatten() plt.figure(figsize=(15, 5)) # plot received signal plt.subplot(121) plt.plot(receiver) plt.title(f'{name} pulse receiver') # plot absolute correlation plt.subplot(122) plt.plot(corr_abs) plt.title( f'absolute correlation of {name} pulse\nestimated delays: {indics}')
def greatest_amplitude(signals, size, threshold=0.005): """ Return 1D array with indices of the signal with the greatest amplitude. If signals.ndim == 1 or signals.shape[1] == 1 returns an array of boolean values which are True, if amplitude of signal is > threshold. Parameters ---------- signals : 2D array 2D array of a signal for which the amplitudes should be compared. If only one signal is given, the amplitude is compared to threshold. Otherwise, the amplitude is compared to the other amplitudes of the other signals. First dimension datapoints, second dimension different signals. size : int Size of the window the amplitudes should be calculated from and compared to each other. Needs to be >= 2. threshold : float Value, the amplitude of a signal is compared to, if only one signal is provided. Returns ------- 1D numpy.ndarray dtype=int or dtype=bool Index of where amplitude of first signal (first axis) is greater than the other signals or True where amplitude is greater than the threshold. """ if size <= 1: raise ValueError("Size should be at least 2, to calculate amplitudes " "within the signals!") amplitude = (maximum_filter1d(signals, size, axis=0) - minimum_filter1d(signals, size, axis=0)) if signals.ndim == 1 or signals.shape[1] == 1: greatest = amplitude > threshold greatest.shape = -1 else: greatest = np.argmax(amplitude, axis=1) return greatest
def temporal_minima(img=None, weight=1.): ''' Subtracts the minima calculated in time,for each pixel. Parameters ---------- imgs : array_like Series of images as a 3D numpy array, or a list or a set weight : scalar Fraction of minima to be subtracted from each pixel. Value of `weight` should be in the interval (0.0,1.0). ''' time_axis = 0 nb_imgs = img.shape[time_axis] if img.ndim < 3 or nb_imgs <= 1: raise ValueError( 'Need more than one image to apply temporal filtering.') window_size = img.shape[time_axis] img_out = img - weight * nd.minimum_filter1d( img, size=window_size, axis=time_axis) return img_out
def scan_blink_correction(image, axis=1): """ This filter can be used to filter out impulsive noise from a 2D array along a single axis. As filter we apply a sequence of two filters. First a min-filter and then a max-filter. This composite non-linear filter technique is also called opening filter. This filter will completely remove single-pixel (along given axis) brightness spikes from the image but will cause the image to be more "blocky"/less smooth. Of course you need to ensure that the image features of interest are larger than @param numpy.ndarray image: A 2D numpy array to be filtered (e.g. image data) @param int axis: The axis along which to apply the 1D filter @return numpy.ndarray: The filtered image. Same dimensions as input image """ if not isinstance(image, np.ndarray): logger.error('Image must be 2D numpy array.') return image if image.ndim != 2: logger.error('Image must be 2D numpy array.') return image if axis != 0 and axis != 1: logger.error('Optional axis parameter must be either 0 or 1.') return image # Calculate median value of the image. This value is used for padding image boundaries during # filtering. median = np.median(image) # Apply a minimum filter along the chosen axis. filt_img = minimum_filter1d(image, size=2, axis=axis, mode='constant', cval=median) # Apply a maximum filter along the chosen axis. Flip the previous filter result to avoid # translation of image features. filt_img = maximum_filter1d( np.flip(filt_img, axis), size=2, axis=axis, mode='constant', cval=median) # Flip back the image to obtain original orientation and return result. return np.flip(filt_img, axis)
def temporal_minima(img=None, weight=1.): ''' Subtracts the minima calculated in time,for each pixel. Parameters ---------- imgs : array_like Series of images as a 3D numpy array, or a list or a set weight : scalar Fraction of minima to be subtracted from each pixel. Value of `weight` should be in the interval (0.0,1.0). ''' time_axis = 0 nb_imgs = img.shape[time_axis] if img.ndim < 3 or nb_imgs <= 1: raise ValueError( 'Need more than one image to apply temporal filtering.') window_size = img.shape[time_axis] img_out = img - weight * nd.minimum_filter1d(img, size=window_size, axis=time_axis) return img_out
def id_slits(flat_data): # # Identifies slits and starboxes. # y_axis = flat_data.shape[0] # Squash the data to one dimension if flat_data.ndim == 2: slice = flat_data.mean(axis=1) else: slice = flat_data.copy() # We assume that the starboxes are at least 2.5x greater than # the mean of the array. star_threshold = slice.mean() * 2.5 slit_threshold = slice.mean() / 2.5 # Pixels with noise levels that greatly differ from the "model" noise # level (ie Poisson shot noise) are set to zero, as are pixels below # the slit threshold. This finds edges, even when two slits are close # together and the edge floor is above the slit threshold. original = slice.copy() for i in range(y_axis): start = i - 2 end = i + 3 if start < 0: start = 0 if end > y_axis: end = y_axis tmp = original[start:end].std() sigma = scipy.sqrt(original[i]) if tmp > 5 * sigma: slice[i] = 0. if slice[i] < slit_threshold: slice[i] = 0. # Narrow the slits by two pixels mask = ndimage.minimum_filter1d(slice, 5) mask[mask > 0] = 1 slice *= mask star = [] slit = [] start = 0 i = 0 while i < y_axis: # Check for a rising edge if slice[i] < slit_threshold: while i < y_axis and slice[i] < slit_threshold: i += 1 start = i # Checking for the falling edge of a slit while i < y_axis and slice[i] > slit_threshold: i += 1 end = i if start == end: i += 1 continue sigma = slice[start:end].std() if scipy.sqrt(slice[start:end].mean()) > sigma: sigma = scipy.sqrt(slice[start:end].mean()) while start > 0 and abs(original[start - 1] - original[start]) < sigma: start -= 1 while end < y_axis and abs(original[end] - original[end - 1]) < sigma: end += 1 slice[start:end] = original[start:end].copy() i = end if end - start < 6: continue if slice[start:end].mean() > star_threshold: limits = scipy.where(slice[start:end] > star_threshold) # end = start + limits[0][-1] - limits[0][0] + 1 start += limits[0][0] end = start + limits[0].size star.append([start, end]) elif end - start > 10: slit.append([start, end]) return slit, star slice = flat_data.copy() mask = ndimage.maximum_filter(slice, 5) std = scipy.sqrt(mask) diff = abs(slice - mask) mask = scipy.where(diff < std, slice, 0) mask = scipy.where(mask > slit_threshold, 1, 0) slit = [] star = [] start = 0 i = 0 while i < slice.size: # In a valley if mask[i] == 0: i += 1 continue # Not in a valley! start = i while i < slice.size and mask[i] != 0: i += 1 end = i if end - start < 6: continue if slice[start:end].mean() > star_threshold: limits = scipy.where(slice[start:end] > star_threshold) start += limits[0][0] end = start + limits[0].size star.append([start, end]) elif end - start > 10: slit.append([start, end]) return slit, star
def detect_dippers(mjd, mag, magerr, xpos, ypos, catflags, verbose=False, return_mjd=False, num_sequential=3): ''' a docstring ''' # moved into here for lack of better place group_observations = cython_function('dipper', 'group_observations') if len(mjd) == 0: if return_mjd: return -1., float('nan') else: return -1. mjd = np.array(mjd) order = np.argsort(mjd) # Convert everything to numpy arrays and sort them by MJD sort_mjd = mjd[order] sort_mag = np.array(mag)[order] sort_magerr = np.array(magerr)[order] sort_xpos = np.array(xpos)[order] sort_ypos = np.array(ypos)[order] sort_catflags = np.array(catflags)[order] # Mask out bad or repeated observations. pad_width = 20 x_border = 3072 y_border = 3080 mask = ( (np.abs(sort_mjd - np.roll(sort_mjd, 1)) > 1e-5) & (sort_xpos > pad_width) & (sort_xpos < x_border - pad_width) & (sort_ypos > pad_width) & (sort_ypos < y_border - pad_width) & (sort_catflags == 0) # In the oct19 data, some observations have a magerr of 0 and aren't flagged. # This causes a world of problems, so throw them out. & (sort_magerr > 0) # In the oct19 data, a lot of dippers are the result of bad columns... # Unfortunately, in this version of the ZTF data we don't know which amplifier # everything came from. To get a reasonably clean sample (with some unnecessary # attrition), we cut any observations that are in the "bad" x ranges. & ((sort_xpos < 24) | (sort_xpos > 31)) & ((sort_xpos < 95) | (sort_xpos > 106)) & ((sort_xpos < 328) | (sort_xpos > 333)) & ((sort_xpos < 1169) | (sort_xpos > 1177)) & ((sort_xpos < 1249) | (sort_xpos > 1257)) & ((sort_xpos < 1339) | (sort_xpos > 1349)) & ((sort_xpos < 2076) | (sort_xpos > 2100)) & ((sort_xpos < 2521) | (sort_xpos > 2537)) & ((sort_xpos < 2676) | (sort_xpos > 2682)) & ((sort_xpos < 2888) | (sort_xpos > 2895))) if np.sum(mask) < 10: # Require at least 10 observations to have reasonable statistics. if return_mjd: return -1., float('nan') else: return -1. mask_mjd = sort_mjd[mask] mask_mag = sort_mag[mask] mask_magerr = sort_magerr[mask] # Unused for now, so don't bother calculating them. # mask_xpos = sort_xpos[mask] # mask_ypos = sort_ypos[mask] # mask_catflags = sort_catflags[mask] use_mjd, use_mag, use_magerr = group_observations(mask_mjd, mask_mag, mask_magerr) # For well-measured observations, use the core standard deviation. For poorly # measured ones, use the measured standard deviation. The core standard deviation # should be very similar to the measured ones for stable light curves, so we # shouldn't be adding these in quadrature. Instead, we take whichever value is # larger. #core_std = np.std(use_mag) # NMAD core_std = 1.4826 * np.nanmedian(np.abs(use_mag - np.nanmedian(use_mag))) use_magerr[use_magerr < core_std] = core_std scores = (use_mag - np.median(use_mag)) / use_magerr # Get the minimum score for a run. filtered_scores = minimum_filter1d(scores, num_sequential, mode='constant') max_loc = np.argmax(filtered_scores) result = float(filtered_scores[max_loc]) max_mjd = use_mjd[max_loc] if verbose: print("Max mjd: ", max_mjd) if return_mjd: return result, max_mjd else: return result