def get_idx_from_plot_pick(deskew_row,plot_pick,flip=False,dist_e=None): data_file_path = os.path.join(deskew_row["data_dir"],deskew_row["comp_name"]) data_df = utl.open_mag_file(data_file_path) if flip: projected_distances = utl.calc_projected_distance(deskew_row['inter_lon'],deskew_row['inter_lat'],data_df['lon'].tolist(),data_df['lat'].tolist(),(180+deskew_row['strike'])%360) else: projected_distances = utl.calc_projected_distance(deskew_row['inter_lon'],deskew_row['inter_lat'],data_df['lon'].tolist(),data_df['lat'].tolist(),deskew_row['strike']) min_idx = (projected_distances["dist"]-plot_pick).abs().idxmin() return min_idx,projected_distances["dist"][min_idx]
def on_sub_btn(self, event): if self.parent.user_warning( "WARNING: This is a non-reversable function please be sure this is what you want to do. Also if you are not looking at the 0 phase profile this may have unexpected results, please view the 0 phase profile before hitting OK." ): try: self.deg = int(self.deg_box.GetValue()) except (ValueError, TypeError) as e: self.parent.user_warning( "Degree of polynomial must be a natural number") try: mag_path = os.path.join(self.parent.dsk_row["data_dir"], self.parent.dsk_row["comp_name"]) mag_df = utl.open_mag_file(mag_path) self.projected_distances = utl.calc_projected_distance( self.parent.dsk_row["inter_lon"], self.parent.dsk_row["inter_lat"], mag_df["lon"], mag_df["lat"], self.parent.dsk_row["strike"])["dist"] shifted_mag = mag_df['mag'].tolist() self.pols = np.polyfit(self.projected_distances, shifted_mag, self.deg) self.poly = np.polyval(self.pols, self.projected_distances) mag_df["mag"] = mag_df["mag"] - self.poly utl.write_mag_file_df(mag_df, mag_path) except AttributeError: return self.on_plot_btn(event)
def plot_tracer_on_self_and_parent(self, dsk_row, lonlat): proj_locs = utl.calc_projected_distance(dsk_row['inter_lon'], dsk_row['inter_lat'], [lonlat[0]], [lonlat[1]], dsk_row['strike']) self.plot_tracer_point(dsk_row, proj_locs.iloc[0]["dist"], color="red", marker="o", s=10) self.parent.plot_tracer_point(proj_locs.iloc[0]["dist"], linestyle='--', color='red', alpha=.5)
def on_select_dleft_click(self, event): try: dsk_row = self.parent.dsk_row except AttributeError: event.Skip() return pos = event.GetPosition() width, height = self.canvas.get_width_height() pos = [pos[0], height - pos[1]] pos = self.ax.transData.inverted().transform(pos) lonlat = ccrs.PlateCarree().transform_point(*pos, self.proj) proj_locs = utl.calc_projected_distance(dsk_row['inter_lon'], dsk_row['inter_lat'], [lonlat[0]], [lonlat[1]], dsk_row['strike']) self.parent.set_new_intercept(proj_locs.iloc[0]["dist"]) self.parent.update(event) self.update()
def fit_poly(self): try: self.deg = int(self.deg_box.GetValue()) except (ValueError, TypeError) as e: self.parent.user_warning( "Degree of polynomial must be a natural number") try: mag_path = os.path.join(self.parent.dsk_row["data_dir"], self.parent.dsk_row["comp_name"]) mag_df = utl.open_mag_file(mag_path) self.projected_distances = utl.calc_projected_distance( self.parent.dsk_row["inter_lon"], self.parent.dsk_row["inter_lat"], mag_df["lon"], mag_df["lat"], (180 + self.parent.dsk_row["strike"]) % 360)["dist"] shifted_mag = sk.phase_shift_data( mag_df['mag'].tolist(), self.parent.dsk_row["phase_shift"]) self.pols = np.polyfit(self.projected_distances, shifted_mag, self.deg) self.poly = np.polyval(self.pols, self.projected_distances) except AttributeError: return
def old_get_idx_from_plot_pick(deskew_row,plot_pick,dist_e=.01): drow,correction=deskew_row,plot_pick data_file_path = os.path.join(drow["data_dir"],drow["comp_name"]) data_df = pd.read_csv(data_file_path,names=["dist","idk","mag","lat","lon"],delim_whitespace=True) projected_distances = utl.calc_projected_distance(drow['inter_lon'],drow['inter_lat'],data_df['lon'].tolist(),data_df['lat'].tolist(),drow['strike']) found_dist=False for j,row in projected_distances.iterrows(): if row['dist']>=correction-dist_e and row['dist']<=correction+dist_e: picked_idx = j picked_distance = row['dist'] found_dist=True break if found_dist: print("found lat lon of %s at a distance %.3f"%(drow["comp_name"],picked_distance)) else: print("couldn't find picked distance in datafile to calculate lat and lon for %s"%drow["comp_name"]); return (drow['inter_lon'],drow['inter_lat'],0) return picked_idx,picked_distance
def draw_figures(self): ####################################################Get Values dsk_row = self.parent.dsk_row track = self.parent.track ddis = float(self.parent.samp_dis_box.GetValue()) if ddis==0: self.parent.user_warning("Synthetic is required for comparision of phase, start by initalilzing a synthetic"); return synth_dis = self.parent.dis_synth synth_mag = self.parent.synth filter_type = self.filter_type_box.GetValue() lowcut = float(self.lowcut_box.GetValue()) highcut = float(self.highcut_box.GetValue()) order = int(self.order_box.GetValue()) left_bound = float(self.low_bound_box.GetValue()) right_bound = float(self.high_bound_box.GetValue()) aero_diff = float(self.aero_diff_box.GetValue()) left_idx = np.argmin(np.abs(synth_dis-left_bound)) right_idx = np.argmin(np.abs(synth_dis-right_bound)) left_idx,right_idx = min([left_idx,right_idx]),max([left_idx,right_idx]) bin_range,bin_num = (-180,180),120 ###################################################Filter Data data_path = os.path.join(dsk_row["data_dir"],dsk_row["comp_name"]) data_df = utl.open_mag_file(data_path) projected_distances = utl.calc_projected_distance(dsk_row['inter_lon'],dsk_row['inter_lat'],data_df['lon'].tolist(),data_df['lat'].tolist(),(180+dsk_row['strike'])%360) shifted_mag = sk.phase_shift_data(data_df["mag"],dsk_row["phase_shift"]) if np.any(np.diff(projected_distances["dist"])<0): itshifted_mag = np.interp(-synth_dis,-projected_distances["dist"],shifted_mag) else: itshifted_mag = np.interp(synth_dis,projected_distances["dist"],shifted_mag) fitshifted_mag = self.filters[filter_type](itshifted_mag,lowcut,highcut,fs=1/ddis,order=order) ###################################################Actual Plotting outer = gridspec.GridSpec(4, 1) ###################################################Axis 0: Magnetic profiles self.ax0 = self.fig.add_subplot(outer[0]) if self.parent.show_other_comp: #Handle Other Aeromag Component if dsk_row["track_type"]=="aero": if "Ed.lp" in track: other_track = track.replace("Ed.lp","Vd.lp") total_track = track.replace("Ed.lp","Td.lp") other_phase = dsk_row["phase_shift"]-90 elif "Hd.lp" in track: other_track = track.replace("Hd.lp","Vd.lp") total_track = track.replace("Hd.lp","Td.lp") other_phase = dsk_row["phase_shift"]-90 elif "Vd.lp" in track: other_track = track.replace("Vd.lp","Ed.lp") total_track = track.replace("Vd.lp","Td.lp") if other_track not in self.parent.deskew_df["comp_name"].tolist(): other_track = track.replace("Vd.lp","Hd.lp") other_phase = dsk_row["phase_shift"]+90 else: self.parent.user_warning("Improperly named component files should have either Ed.lp, Hd.lp, or Vd.lp got: %s"%track); return oth_row = self.parent.deskew_df[self.parent.deskew_df["comp_name"]==other_track].iloc[0] oth_data_path = os.path.join(oth_row["data_dir"],oth_row["comp_name"]) tot_data_path = os.path.join(oth_row["data_dir"],total_track) #Should be in same place oth_data_df = utl.open_mag_file(oth_data_path) oth_shifted_mag = sk.phase_shift_data(oth_data_df["mag"],other_phase) if np.any(np.diff(projected_distances["dist"])<0): oth_itshifted_mag = np.interp(-synth_dis,-projected_distances["dist"],oth_shifted_mag) else: oth_itshifted_mag = np.interp(synth_dis,projected_distances["dist"],oth_data_df) oth_fitshifted_mag = self.filters[filter_type](oth_itshifted_mag,lowcut,highcut,fs=1/ddis,order=order) if filter_type=="None": psk.plot_skewness_data(oth_row,other_phase,self.ax0,xlims=[None,None],color='darkgreen',zorder=2,picker=True,alpha=.7,return_objects=True,flip=True) else: self.ax0.plot(synth_dis,oth_fitshifted_mag,color="#299C29",zorder=3,alpha=.6) tot_data_df = utl.open_mag_file(tot_data_path) if np.any(np.diff(projected_distances["dist"])<0): tot_imag = np.interp(-synth_dis,-projected_distances["dist"],tot_data_df["mag"]) else: tot_imag = np.interp(synth_dis,projected_distances["dist"],tot_data_df["mag"]) tot_fimag = self.filters[filter_type](tot_imag,lowcut,highcut,fs=1/ddis,order=order) if filter_type=="None": psk.plot_skewness_data(dsk_row,dsk_row["phase_shift"],self.ax0,xlims=[None,None],zorder=3,picker=True,return_objects=True,flip=True) else: self.ax0.plot(synth_dis,fitshifted_mag,color="#7F7D7D",zorder=3,alpha=.6) self.ax0.plot(self.parent.dis_synth,self.parent.synth,'r-',alpha=.4,zorder=1) self.ax0.set_ylabel("Magnetic Profiles") # self.ax0.get_xaxis().set_ticklabels([]) ###################################################Axis 1/2: Phase Angles and Differences self.ax1 = self.fig.add_subplot(outer[1], sharex=self.ax0) self.ax2 = self.fig.add_subplot(outer[2], sharex=self.ax0) ###################################################Calculate: Phase Differences trimmed_dis = synth_dis[left_idx:right_idx] trimmed_synth = synth_mag[left_idx:right_idx] trimmed_fitshifted_mag = fitshifted_mag[left_idx:right_idx] al_data = np.angle(hilbert(fitshifted_mag),deg=False)[left_idx:right_idx] al_synth = np.angle(hilbert(np.real(synth_mag)),deg=False)[left_idx:right_idx] data_synth_diff = phase_diff_func(al_synth,al_data) if self.parent.show_other_comp and dsk_row["track_type"]=="aero": trimmed_oth_fitshifted_mag = oth_fitshifted_mag[left_idx:right_idx] al_oth = np.angle(hilbert(oth_fitshifted_mag),deg=False)[left_idx:right_idx] oth_synth_diff = phase_diff_func(al_synth,al_oth) oth_data_diff = phase_diff_func(al_oth,al_data) if abs(aero_diff) > 0: idx = ma.array(np.abs(oth_data_diff)<aero_diff) self.ax1.plot((trimmed_dis[~idx]),(np.rad2deg(al_oth[~idx])),color="darkgreen",linestyle=":") self.ax2.plot((trimmed_dis[~idx]),(oth_synth_diff[~idx]),color="tab:pink",alpha=.8,linestyle=":") self.ax2.plot((trimmed_dis[~idx]),(oth_data_diff[~idx]),color="tab:grey",alpha=.8,linestyle=":") self.ax1.plot((trimmed_dis[~idx]),(np.rad2deg(al_data[~idx])),color="k",linestyle=":") self.ax1.plot((trimmed_dis[~idx]),(np.rad2deg(al_synth[~idx])),color="r",linestyle=":") self.ax2.plot((trimmed_dis[~idx]),(data_synth_diff[~idx]),color="tab:red",alpha=.8,linestyle=":") # import pdb; pdb.set_trace() # not_trimmed_dis = (trimmed_dis[~idx]) # not_trimmed_dis[np.diff(~idx,prepend=[0])] = ma.masked # not_al_data = (al_data[~idx]) # not_al_data[np.diff(~idx)] = ma.masked # not_al_synth = (al_synth[~idx]) # not_al_synth[np.diff(~idx)] = ma.masked # not_al_oth = (al_oth[~idx]) # not_al_oth[np.diff(~idx)] = ma.masked # not_data_synth_diff = (data_synth_diff[~idx]) # not_data_synth_diff[np.diff(~idx)] = ma.masked # not_oth_synth_diff = (oth_synth_diff[~idx]) # not_oth_synth_diff[np.diff(~idx)] = ma.masked # not_oth_data_diff = (oth_data_diff[~idx]) # not_oth_data_diff[np.diff(~idx)] = ma.masked trimmed_dis = (trimmed_dis[idx]) al_data = (al_data[idx]) al_synth = (al_synth[idx]) al_oth = (al_oth[idx]) data_synth_diff = (data_synth_diff[idx]) oth_synth_diff = (oth_synth_diff[idx]) oth_data_diff = (oth_data_diff[idx]) self.ax1.plot(trimmed_dis,np.rad2deg(al_oth),color="darkgreen") self.ax2.plot(trimmed_dis,oth_synth_diff,color="tab:pink",alpha=.8) self.ax2.plot(trimmed_dis,oth_data_diff,color="tab:grey",alpha=.8) self.ax1.plot(trimmed_dis,np.rad2deg(al_data),color="k") self.ax1.plot(trimmed_dis,np.rad2deg(al_synth),color="r") self.ax2.plot(trimmed_dis,data_synth_diff,color="tab:red",alpha=.8) # self.ax2.get_xaxis.set_ticklabels self.ax0.set_xlim(*self.parent.ax.get_xlim()) self.ax0.set_ylim(*self.parent.ax.get_ylim()) self.ax1.set_ylabel("Phase Angles") self.ax2.set_ylabel("Phase Differences") ###################################################Axis 2.1: Power Spectrum # inner = gridspec.GridSpecFromSubplotSpec(1, 2, subplot_spec=outer[2])#, hspace=0.) # self.ax2 = self.fig.add_subplot(inner[0]) ###################################################Axis 2.2: Phase Statistics self.ax3 = self.fig.add_subplot(outer[3]) if self.parent.show_other_comp and dsk_row["track_type"]=="aero": self.ax3.hist(oth_synth_diff,range=bin_range,bins=bin_num,color="tab:pink",alpha=.5,zorder=2) self.ax3.hist(oth_data_diff,range=bin_range,bins=bin_num,color="tab:grey",alpha=.5,zorder=1) self.ax3.hist(data_synth_diff,range=bin_range,bins=bin_num,color="tab:red",alpha=.5,zorder=3) self.ax3.axvline(np.median(data_synth_diff),color="k",alpha=.5,zorder=5,linestyle=":") self.ax3.axvline(np.mean(data_synth_diff),color="k",alpha=.5,zorder=5) self.ax3.axvspan(np.mean(data_synth_diff)-np.std(data_synth_diff),np.mean(data_synth_diff)+np.std(data_synth_diff),color="tab:grey",alpha=.3,zorder=0) self.ax3.annotate(r"$\theta_{mean}$ = $%.1f^\circ \pm %.1f^\circ$"%(np.mean(data_synth_diff),np.std(data_synth_diff)) + "\n" + r"$\theta_{median}$ = %.1f$^\circ$"%np.median(data_synth_diff),xy=(0.02,1-0.02),xycoords="axes fraction",bbox=dict(boxstyle="round", fc="w",alpha=.5),fontsize=self.fontsize,va='top',ha='left') self.ax3.set_ylabel(r"$\Delta \theta$ Count") self.fig.suptitle("%s\n%s\n"%(dsk_row["sz_name"],track)) ###################################################Power Figure N = (right_idx-left_idx) #Length of signal in distance domain NW = 3 #following Parker and O'brien '97 and HJ-Gordon '03 we use a time-bandwith product of 6 (Nw is half) Ns = 5 #Number of points to use in running average smoothing #Handle Distance Domain # import pdb; pdb.set_trace() Sk_complex, weights, eigenvalues=pmtm(itshifted_mag[left_idx:right_idx], NW=NW, NFFT=N, show=False) Sk = np.abs(Sk_complex)**2 smoothed_tshifted_freq = (np.mean(Sk * np.transpose(weights), axis=0) * ddis)[N//2:][::-1] # smoothed_tshifted_freq = np.convolve(smoothed_tshifted_freq, np.ones((Ns,))/Ns, mode='same') #10 point running average smoothing tdata_freqs = np.linspace(0.0, 1.0/(2.0*ddis), N-N//2) #0 to Nyquest self.power_ax = self.power_fig.add_subplot(111) if self.parent.show_other_comp and dsk_row["track_type"]=="aero": Sk_complex, weights, eigenvalues=pmtm(oth_itshifted_mag[left_idx:right_idx], NW=NW, NFFT=N, show=False) Sk = np.abs(Sk_complex)**2 oth_smoothed_tshifted_freq = (np.mean(Sk * np.transpose(weights), axis=0) * ddis)[N//2:][::-1] # oth_smoothed_tshifted_freq = np.convolve(oth_smoothed_tshifted_freq, np.ones((Ns,))/Ns, mode='same') #10 point running average smoothing self.power_ax.semilogy(tdata_freqs, oth_smoothed_tshifted_freq, color="darkgreen") # self.power_ax.semilogy(tdata_freqs, oth_smoothed_tshifted_freq+smoothed_tshifted_freq, color="grey") Sk_complex, weights, eigenvalues=pmtm(tot_imag[left_idx:right_idx], NW=NW, NFFT=N, show=False) Sk = np.abs(Sk_complex)**2 tot_smoothed_tshifted_freq = (np.mean(Sk * np.transpose(weights), axis=0) * ddis)[N//2:][::-1] # tot_smoothed_tshifted_freq = np.convolve(tot_smoothed_tshifted_freq, np.ones((Ns,))/Ns, mode='same') #10 point running average smoothing self.power_ax.semilogy(tdata_freqs, tot_smoothed_tshifted_freq, color="tab:orange") #Old Numpy Method # synth_freqs = np.fft.fftfreq(len(synth_dis[left_idx:right_idx]),ddis) # tdata_freqs = np.fft.fftfreq(len(shifted_mag[left_idx:right_idx]),ddis) # tshifted_freq = np.fft.fft(shifted_mag[left_idx:right_idx]) # fitshifted_freq = np.fft.fft(fitshifted_mag[left_idx:right_idx]) # tsynth_freq = np.fft.fft(synth_mag[left_idx:right_idx]) self.power_ax.semilogy(tdata_freqs, smoothed_tshifted_freq, color="k",zorder=100) # self.power_ax.semilogy(tdata_freqs, np.abs(tshifted_freq), color="k") # self.power_ax.plot(synth_freqs, np.abs(fitshifted_freq), color="#7F7D7D") # self.power_ax.plot(synth_freqs, np.abs(tsynth_freq), color="r") self.power_ax.set_xlim(0.0,0.4) self.power_ax.set_ylim(1e-1,1e6)
def auto_dsk(dsk_row,synth,bounds,conv_limit=0,conv_bounds=[None,None],phase_args=(0.,360.,1.),highcut=0.,order=3): """ Returns the maximum likelihood phase shift to deskew the data to match a provided synthetic given a bounds on a window to match. Parameters ---------- dsk_row : Pandas.Series Single row of a deskew file with valid path to data file synth : list This should be the output of the make synthetic function it needs to contain three elements 0) an array of the synthetic magnetic anomalies 1) an array of the distance coordinates of the points in 0, should be of equal length to 0, MUST be in the same coordinate system as the profile provided in dsk_row!!! Which it may not by default. 2) the distance resolution of the synthetic in 0 and 1 bounds : list of floats Has two elements which corespond to the left and right bounds of the window conv_limit : float, optional Weather or not to realign the anomaly each phase shift using a time lagged convolution method which increases runtime significantly but can also increase accuracy. This argument should be a positve float which corresponds to the amount of +- shift the anomaly is allowed to move used otherwise it should be 0 to not use the shift method (Default: 0, which implies not to use method). conv_bounds : list of 2 floats, optional The left and right boundary in the distance domain to use to time lag convolve the synthetic and the filtered data signal. Thus 300 km of signal can be convolved but only the 10 km of motion allowed to pin down the crossing location. (Default: [None,None], which implies conv_bounds=bounds) phase_args : tuple or other unpackable sequence, optional Arguments to np.arange which define the phases searched in the minimization. (Default: (0.,360.,1.) which implies a search of the entire parameter space of phases at 1 degree resolution) highcut : float, optional The upper cutoff frequency to filter the data by in order to remove any topographic anomalies in the data. This value should be between 0 and Nyquest of the synthetic which MUST be regularly sampled like those returned by make_synthetic. The data is up or down sampled to the synthetic before filtering. (Default: 0 which implies not to filter the data) order : int, optional The order of the lowpass butterworth filter to apply to the data. Returns ---------- best_phase : float The maximum liklehood phase shift to match the data to the synthetic best_shift : float the maximum likelihood shift for the best_phase which aligned the two anomalies phase_func : Numpy.NdArray The summed phase asynchrony between the data and the synthetic as a function of phase shift (best_phase is the global minimum of this function) best_shifts : Numpy.NdArray the maximum likelihood shift as a function of the phase shift """ #Unpack Arguments dage = dsk_row["age_max"]-dsk_row["age_min"] phases = np.arange(*phase_args) left_bound,right_bound = bounds synth_mag = np.array(synth[0]) synth_dis = np.array(synth[1]) ddis = synth[2] data_path = os.path.join(dsk_row["data_dir"],dsk_row["comp_name"]) data_df = utl.open_mag_file(data_path) projected_distances = utl.calc_projected_distance(dsk_row['inter_lon'],dsk_row['inter_lat'],data_df['lon'].tolist(),data_df['lat'].tolist(),(180+dsk_row['strike'])%360) if conv_limit: #create the fully interpolated profile for convolution #create the shortened synthetic for the time lagged convolution if isinstance(conv_bounds[0],type(None)): conv_bounds[0] = bounds[0] if isinstance(conv_bounds[1],type(None)): conv_bounds[1] = bounds[1] left_idx = np.argmin(np.abs(synth_dis - conv_bounds[0])) right_idx = np.argmin(np.abs(synth_dis - conv_bounds[1])) right_idx,left_idx = max([right_idx,left_idx]),min([right_idx,left_idx]) conv_synth,conv_synth_dis = synth_mag[left_idx:right_idx],synth_dis[left_idx:right_idx] if np.any(np.diff(projected_distances["dist"])<0): #redefine to the right because interp dumbs mag = data_df["mag"].to_numpy()[::-1] mag_dis = projected_distances["dist"].to_numpy()[::-1] full_imag = np.interp(conv_synth_dis,mag_dis,mag) if highcut: full_fimag = butter_lowpass_filter(full_imag,highcut=highcut,fs=1/ddis,order=order) else: full_fimag = full_imag #trim to only window of relivence left_idx = np.argmin(np.abs(synth_dis - left_bound)) right_idx = np.argmin(np.abs(synth_dis - right_bound)) right_idx,left_idx = max([right_idx,left_idx]),min([right_idx,left_idx]) tsynth_mag = synth_mag[left_idx:right_idx] tsynth_dis = synth_dis[left_idx:right_idx] N = len(tsynth_mag) #because this is easier and regularly sampled plus the user can set it simply al2 = np.angle(hilbert(np.real(tsynth_mag),N),deg=False) best_shifts = [] #record best shifts as function of phase shift phase_async_func = [] #record summed phase asynchrony as a function of phase shift for i,phase in enumerate(phases): shifted_mag = phase_shift_data(data_df["mag"],phase) if conv_limit: #DON'T YOU KNOW WE'RE GONNAAAA DOOOOOOO THE COOONVOLUTIOOOON!!! shifted_full_fimag = phase_shift_data(full_fimag,phase) correlation_func = np.abs(np.convolve(shifted_full_fimag,conv_synth,"full")) correlation_func = correlation_func[int(len(conv_synth)-conv_limit/ddis+.5):int(len(conv_synth)+conv_limit/ddis+.5)] best_shift = ddis*(len(correlation_func)/2-np.argmax(correlation_func))/2 else: best_shift = 0. #trim the data to the right segments left_idx = np.argmin(np.abs(projected_distances["dist"] - left_bound + best_shift)) right_idx = np.argmin(np.abs(projected_distances["dist"]- right_bound + best_shift)) right_idx,left_idx = max([right_idx,left_idx]),min([right_idx,left_idx]) tproj_dist = projected_distances["dist"][left_idx:right_idx] + best_shift tshifted_mag = shifted_mag[left_idx:right_idx] #numpy.interp only works for monotonic increasing independent variable data if np.any(np.diff(tproj_dist)<0): itshifted_mag = np.interp(-tsynth_dis,-tproj_dist,tshifted_mag) else: itshifted_mag = np.interp(tsynth_dis,tproj_dist,tshifted_mag) if highcut: fitshifted_mag = butter_lowpass_filter(itshifted_mag,highcut=highcut,fs=1/ddis,order=order) else: fitshifted_mag = itshifted_mag al1 = np.angle(hilbert(fitshifted_mag,N),deg=False) phase_asynchrony = np.sin((al1-al2)/2) #shouldn't go negative but...just in case best_shifts.append(best_shift) phase_async_func.append(phase_asynchrony.sum()) best_idx = np.argmin(phase_async_func) return phases[best_idx],best_shifts[best_idx],phase_async_func,best_shifts