# Automatically generated by GPRPy import gprpy.gprpy as gp mygpr = gp.gprpyProfile() mygpr.importdata('G1.DT1') mygpr.setZeroTime(7.5) mygpr.truncateY(400) mygpr.dewow(99999999999999) mygpr.remMeanTrace(999999999999999) mygpr.agcGain(100) mygpr.setVelocity(0.11) mygpr.fkMigration() mygpr.topoCorrect('G1_Topo_3d.txt', delimiter='\t') #mygpr.save('G1.gpr') mygpr.printProfile('G1.pdf', color='bwr', contrast=3, yrng=[1200, 1225], xrng=[0, 202.2], asp=1, dpi=600) mygpr.exportVTK('G1', gpsinfo=mygpr.threeD, thickness=0, delimiter='\t', aspect=1, smooth=True, win_length=51, porder=3)
def __init__(self,master): self.window = master # Set up for high-resolution screens normscrwidt=1024 normscrhigt=768 scrwidt=master.winfo_screenwidth() scrhigt=master.winfo_screenheight() # These to use if operating system doesn't automatically adjust #self.widfac=scrwidt/normscrwidt #self.highfac=scrhigt/normscrhigt self.widfac=normscrwidt/normscrhigt self.highfac=1 fontfac=(normscrwidt/normscrhigt)/(scrwidt/scrhigt) master.title("GPRPy") # Variables specific to GUI self.balloon = Pmw.Balloon() self.picking = False self.delimiter = None self.grid = False # Initialize the gprpy proj = gp.gprpyProfile() # Show splash screen fig=Figure(figsize=(8*self.widfac,5*self.highfac)) a=fig.add_subplot(111) dir_path = os.path.dirname(os.path.realpath(__file__)) splash.showSplash(a,dir_path,self.widfac,self.highfac,fontfac) # Set font size for screen res mpl.rcParams.update({'font.size': mpl.rcParams['font.size']*self.widfac}) a.tick_params(direction='out',length=6*self.widfac,width=self.highfac) a.get_xaxis().set_visible(False) a.get_yaxis().set_visible(False) canvas = FigureCanvasTkAgg(fig, master=self.window) canvas.get_tk_widget().grid(row=2,column=0,columnspan=figcolsp,rowspan=figrowsp,sticky='nsew') canvas.draw() ## Visualization Buttons # Undo Button undoButton = tk.Button( text="undo", command=lambda : [self.resetYrng(proj), self.undo(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) undoButton.config(height = 1, width = 2*halfwid) undoButton.grid(row=0, column=0, sticky='nsew',rowspan=2) self.balloon.bind(undoButton, '"Undoes" the most recent processing step and\n' 'sets the data back to its previous state.\n' 'This also removes the most recent processing\n' 'step from the history. Does not revert\n' 'visualization settings such as "set x-range"\n' 'etc.') # Full view FullButton = tk.Button( text="full view", fg="black", command=lambda : [self.setFullView(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) FullButton.config(height = 1, width = 2*halfwid) FullButton.grid(row=0, column=1, sticky='nsew',rowspan=2) self.balloon.bind(FullButton,"Resets x- and y-axis limits to full data.") # Grid button GridButton = tk.Button( text="grid", fg="black", command=lambda : [self.toggleGrid(), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) GridButton.config(height = 1, width = 2*halfwid) GridButton.grid(row=0, column=2, sticky='nsew',rowspan=2) self.balloon.bind(GridButton,"Toggles grid on/off.") # X range XrngButton = tk.Button( text="set x-range", fg="black", command=lambda : [self.setXrng(), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) XrngButton.config(height = 1, width = 2*halfwid) XrngButton.grid(row=0, column=3, sticky='nsew',rowspan=2) self.balloon.bind(XrngButton,"Set the x-axis display limits.") # Y range YrngButton = tk.Button( text="set y-range", fg="black", command=lambda : [self.setYrng(), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) YrngButton.config(height = 1, width = 2*halfwid) YrngButton.grid(row=0, column=4, sticky='nsew',rowspan=2) self.balloon.bind(YrngButton,"Set the y-axis display limits.") # Aspect AspButton = tk.Button( text="aspect ratio", fg="black", command=lambda : [self.setAspect(), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) AspButton.config(height = 1, width = 2*halfwid) AspButton.grid(row=0, column=5, sticky='nsew',rowspan=2) self.balloon.bind(AspButton, "Set the aspect ratio between x- and y-axis.") # Contrast contrtext = tk.StringVar() contrtext.set("contrast") contrlabel = tk.Label(master, textvariable=contrtext,height = 1,width = 2*halfwid) contrlabel.grid(row=0, column=6, sticky='nsew') self.balloon.bind(contrlabel,"Set color saturation") self.contrast = tk.DoubleVar() contrbox = tk.Entry(master, textvariable=self.contrast, width=2*halfwid) contrbox.grid(row=1, column=6, sticky='nsew') #contr.set("1.0") self.contrast.set("1.0") # Mode switch for figure color self.color=tk.StringVar() self.color.set("gray") colswitch = tk.OptionMenu(master,self.color,"gray","bwr") colswitch.grid(row=0, column=7, sticky='nsew',rowspan=2) self.balloon.bind(colswitch, "Choose between gray-scale\n" "and red-white-blue (rwb)\n" "data representation.") # Refreshing plot plotButton = tk.Button( text="refresh plot", command=lambda : self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)) plotButton.config(height = 1, width = 2*halfwid) plotButton.grid(row=0, column=8, sticky='nsew',rowspan=2) self.balloon.bind(plotButton, "Refreshes the figure after changes\n" "in the visualization settings. Also\n" "removes any plotted hyperbolae.") ## Methods buttons # Load data LoadButton = tk.Button( text="import data", fg="black", command=lambda : [self.loadData(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) LoadButton.config(height = 1, width = 2*halfwid) LoadButton.grid(row=0, column=rightcol, sticky='nsew',columnspan=colsp,rowspan=2) self.balloon.bind(LoadButton,"Load .gpr, .DT1, or .DZT data.") # Adjust profile length; if trigger wheel is not good AdjProfileButton = tk.Button( text="adj profile", fg="black", command=lambda : [self.adjProfile(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) AdjProfileButton.config(height = 1, width = 2*halfwid) AdjProfileButton.grid(row=2, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(AdjProfileButton, "Adjust the profile length to \n" "known start and end positions\n" "and/or flip the profile horizontally\n" "(left to right)") # Set new zero time SetZeroTimeButton = tk.Button( text="set zero time", fg="black", command=lambda : [self.setZeroTime(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) SetZeroTimeButton.config(height = 1, width = 2*halfwid) SetZeroTimeButton.grid(row=3, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(SetZeroTimeButton, "Set the two-way travel time that \n" "that corresponds to the surface.") # TimeZero Adjust = align traces TrAlignButton = tk.Button( text="align traces", fg="black", command=lambda : [proj.alignTraces(), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) TrAlignButton.config(height = 1, width = 2*halfwid) TrAlignButton.grid(row=4, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(TrAlignButton, 'Automatically shifts each trace up or down\n' 'such that the maximum aplitudes of the individual\n' 'traces align. Can lead to problems when the maxima\n' 'are not in the air waves. If the results are bad,\n' 'use the "undo" button.') # truncate Y truncYButton = tk.Button( text="truncate Y", fg="black", command=lambda : [self.truncateY(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) truncYButton.config(height = 1, width = 2*halfwid) truncYButton.grid(row=5, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(truncYButton, "Remove data points at arrival times\n" "later than the chosen value. If velocity\n" "is given: remove data points at depths greater\n" "than the chosen value") # Dewow DewowButton = tk.Button( text="dewow", fg="black", command=lambda : [self.dewow(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) DewowButton.config(height = 1, width = 2*halfwid) DewowButton.grid(row=6, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(DewowButton, "Trace-wise low-cut filter. Removes\n" "from each trace a running mean of\n" "chosen window width.") # Rem mean trace remMeanTraceButton = tk.Button( text="rem mean tr", fg="black", command=lambda : [self.remMeanTrace(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) remMeanTraceButton.config(height = 1, width = 2*halfwid) remMeanTraceButton.grid(row=7, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(remMeanTraceButton, "Removes from each traces the average\n" "of its surrounding traces. This can be\n" "useful to remove air waves, or\n" "horizontal features.") # Smooth SmoothButton = tk.Button( text="smooth (temp)", fg="black", command=lambda : [self.smooth(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) SmoothButton.config(height = 1, width = 2*halfwid) SmoothButton.grid(row=8, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(SmoothButton, "Trace-wise high-cut filter. Replaces\n" "each sample within a trace by a\n" "running mean of chosen window width.") # profile Smoothing Button profSmButton = tk.Button( text="profile smoothing", fg="black", command=lambda : [self.profileSmooth(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) profSmButton.config(height = 1, width = 2*halfwid) profSmButton.grid(row=9, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(profSmButton, "First oversamples the profile (makes 'n' copies\n" "of each trace) and then replaces each trace by\n" "the mean of its neighboring 'm' traces." ) # Gain tpowButton = tk.Button( text="tpow", fg="black", command=lambda : [self.tpowGain(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) tpowButton.config(height=1, width=halfwid) tpowButton.grid(row=10, column=rightcol, sticky='nsew') self.balloon.bind(tpowButton, "t-power gain. Increases the power of the\n" "signal by a factor of (two-way travel time)^p,\n" "where the user provides p. This gain is often\n" "less aggressive than agc.") agcButton = tk.Button( text="agc",fg="black", command=lambda : [self.agcGain(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) agcButton.config(height=1, width=halfwid) agcButton.grid(row=10, column=rightcol+1, sticky='nsew') self.balloon.bind(agcButton, "Automatic gain controll. Normalizes the power\n" "of the signal per given sample window along\n" "each trace.") # show hyperbola hypButton = tk.Button( text="show hyperb", fg="black", command=lambda : [self.showHyp(proj,a), canvas.draw()]) hypButton.config(height = 1, width = 2*halfwid) hypButton.grid(row=11, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(hypButton, "Draws a hyperbola depending on profile position,\n" "two-way travel time, and estimated velocity. This\n" "can be used to find the subsurface velocity when\n" "a hyperbola is visible in the data.\n" "The plotted hyperbola will disappear when the image\n" "is refreshed.") # Set Velocity setVelButton = tk.Button( text="set velocity", fg="black", command=lambda : [self.setVelocity(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) setVelButton.config(height = 1, width = 2*halfwid) setVelButton.grid(row=12, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(setVelButton, "Set the known subsurface radar velocity. This will\n" "turn the y-axis from two-way travel time to depth.\n" "This step is necessary for topographic correction.") # Migration Button migButton = tk.Button( text="fk migration", fg="black", command=lambda : [self.fkMigration(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) migButton.config(height = 1, width = 2*halfwid) migButton.grid(row=13, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(migButton, "Stolt fk migration using a code originally written\n" "in Matlab for the CREWES software package.\n" "Translated into Python 2 by Nat Wilson.\n" "\n" "Not included in the public version because of License\n" "uncertainty. Contact [email protected]\n" "if you would like to use it.") # Topo Correct topoCorrectButton = tk.Button( text="topo correct", fg="black", command=lambda : [self.topoCorrect(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) topoCorrectButton.config(height = 1, width = 2*halfwid) topoCorrectButton.grid(row=14, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(topoCorrectButton, "Reads a comma- or tab-separated file containing\n" "either 3 columns (easting, northing, elevation)\n" "or two columns (profile position, elevation).\n" "All coordinates in meters.") # Cut cutButton = tk.Button( text="cut profile", fg="black", command=lambda : [self.cut(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) cutButton.config(height = 1, width = 2*halfwid) cutButton.grid(row=15, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(cutButton, "trims data to desired along-profile range.") startPickButton = tk.Button( text="start pick", fg="black", command=lambda : self.startPicking(proj,fig=fig,a=a,canvas=canvas)) startPickButton.config(height = 1, width = halfwid) startPickButton.grid(row=16, column=rightcol, sticky='nsew',columnspan=1) stopPickButton = tk.Button( text="stop pick", fg="black", command=lambda : [self.stopPicking(proj), self.plotProfileData(proj,fig=fig,a=a,canvas=canvas)]) stopPickButton.config(height = 1, width = halfwid) stopPickButton.grid(row=16, column=rightcol+1, sticky='nsew',columnspan=1) # Save data SaveButton = tk.Button( text="save data", fg="black", command=lambda : self.saveData(proj)) SaveButton.config(height = 1, width = 2*halfwid) SaveButton.grid(row=17, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(SaveButton, 'saves the processed data including its history in a\n' '.gpr file. The resulting file will contain absolute\n' 'path names of the used data and topography files.\n' 'Visualization settings such as "set x-range" or\n' '"contrast" will not be saved.') # Print Figure PrintButton = tk.Button( text="print figure", fg="black", command=lambda : self.printProfileFig(proj=proj,fig=fig)) PrintButton.config(height = 1, width = 2*halfwid) PrintButton.grid(row=18, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(PrintButton, "Saves the current visible figure in a pdf with \n" "chosen resolution. If there is a hyperbola on\n" "the current figure, then the hyperbola will also\n" "appear on the printed figure.") # Export to VTK VTKButton = tk.Button( text="export to VTK", fg="black", command = lambda : self.exportVTK(proj)) VTKButton.config(height = 1, width = 2*halfwid) VTKButton.grid(row=19, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(VTKButton, "Exports the processed figure to a\n" "VTK format, that can be read by\n" "Paraview or similar 3D programs") # Write script HistButton = tk.Button( text="write script", fg="black", command=lambda : self.writeHistory(proj)) HistButton.config(height = 1, width = 2*halfwid) HistButton.grid(row=20, column=rightcol, sticky='nsew',columnspan=colsp) self.balloon.bind(HistButton, 'Writes a python script to reproduce the \n' 'current status.\n' '\n' 'If the current data is from a .gpr file, \n' 'then the python script will contain all \n' 'steps going back to the raw data. \n' '\n' 'The script will not contain visualization \n' 'settings such as x-range settings, unless \n' 'the "print figure" command was used. ')
def showSplash(a,dir_path,widfac,highfac,fontfac): ''' Creates the splash screen shown when starting GPRPy GUI for common-offset profiles. ''' try: filename=os.path.join(dir_path,'exampledata','SnS','ComOffs','XLINE00.DT1') snakeGPR = gp.gprpyProfile(filename) maxpoint=100; x=snakeGPR.twtt[0:maxpoint] y=snakeGPR.data[0:maxpoint,10] except: rick = signal.ricker(150, 4.0) x = np.linspace(0,85,100) y = rick[50:150]*25000 # Snake body lw=7#5 a.plot(x,y,'k',linewidth=lw*widfac,solid_capstyle='round') # Snake head Path = mpath.Path xshift=0 headval=2500*widfac/highfac path_data = [ (Path.MOVETO, [xshift,headval]), (Path.CURVE3, [-20+xshift,0]), (Path.LINETO, [xshift,-headval]), (Path.CURVE3, [10+xshift,0]), (Path.LINETO, [xshift,headval]), (Path.CLOSEPOLY, [xshift,headval])] codes, verts = zip(*path_data) path = mpath.Path(verts, codes) patch = mpatches.PathPatch(path) patch.set_facecolor('black') a.add_patch(patch) # Eyes eye1 = mpatches.Ellipse([-2,1000], 3, 1000) eye2 = mpatches.Ellipse([-2,-1000], 3, 1000) eye1.set_facecolor('white') eye2.set_facecolor('white') a.add_patch(eye1) a.add_patch(eye2) # Tongue x, y = np.array([[-10, -13, -15], [0.0, 0.0, 600]]) line1 = mlines.Line2D(x, y, lw=2*widfac, color='black') x, y = np.array([[-10, -13, -15], [0.0, 0.0, -600]]) line2 = mlines.Line2D(x, y, lw=2*widfac, color='black') a.add_line(line1) a.add_line(line2) # Axis setup a.set_xlim([-25,90]) a.set_ylim([-28000,12000]) a.axis('off') # Text font = {'family': 'DejaVu Sans', 'color': 'black', 'weight': 'bold', 'style': 'italic', 'size': 60*fontfac #'size': 45.6 } # a.text(35,-10000,'GPRPy',fontdict=font) a.text(50,-10000,'GPRPy',fontdict=font) fontver = {'family': 'DejaVu Sans', 'color': 'black', 'style': 'italic', 'size': 13.5*fontfac #'size': 45.6 } a.text(50,-12000,'Version 1.0.9',fontdict=fontver) # add UA logo filename1=os.path.join(dir_path,'toolbox','splashdat', 'A_Square_Logo_4c.png') ua = im.imread(filename1) #yanchor = -24500 #yheight = 10000*0.9 yanchor = -24000 yheight = 10000*0.8 xanchor = -20 figsize = a.figure.get_size_inches() figratio = figsize[0]/figsize[1] ratio = a.get_data_ratio()*figratio xwidth = yheight/ratio a.imshow(ua, aspect='auto', extent=(xanchor, xanchor+xwidth, yanchor, yanchor+yheight), interpolation='spline36') # # add UA words # filename1=os.path.join(dir_path,'toolbox','splashdat', # 'UA-StackedNameplate.png') # ua = im.imread(filename1) # #yanchor = -24500 # #yheight = 10000*0.9 # yanchor = -24000 # yheight = 10000*0.4 # xanchor = -10 # figsize = a.figure.get_size_inches() # figratio = figsize[0]/figsize[1] # ratio = a.get_data_ratio()*figratio # xwidth = 5*yheight/ratio # a.imshow(ua, aspect='auto', extent=(xanchor, xanchor+xwidth, # yanchor, yanchor+yheight), # interpolation='spline36') # Add NSF logo filename2=os.path.join(dir_path,'toolbox','splashdat', 'NSF_4-Color_bitmap_Logo.png') nsf = im.imread(filename2) yanchor = -25000 yheight = 10000 xanchor = -5 figsize = a.figure.get_size_inches() figratio = figsize[0]/figsize[1] ratio = a.get_data_ratio()*figratio xwidth = yheight/ratio a.imshow(nsf, aspect='auto', extent=(xanchor, xanchor+xwidth, yanchor, yanchor+yheight), interpolation='spline36') font2 = {'family': 'DejaVu Sans', 'color': 'black', 'size': 13.5*fontfac} #'size': 10.26} a.text(-5,-27000,'EAR-1550732',fontdict=font2) # Add name/email font3 = {'family': 'DejaVu Sans', 'color': 'gray', 'size': 13.5*fontfac} #'size' : 10.26} a.text(70,-22000,'Alain Plattner',fontdict=font3) a.text(59,-24000,'*****@*****.**',fontdict=font3)
def makeDataCube(datalist, outname, nx=50, ny=50, nz=50, smooth=None, nprofile=None, ndepth=None, method='nearest', absvals=False): ''' Creates an interpolated data cube from a list of .gpr (GPRPy) preprocessed files. Allows for subsampling (to reduce computational cost) and for smoothing (to help interpretation) INPUT: datalist Python list containing the filenames (strings) for the preprocessed .gpr (GPRPy) data outname file name for the VTK file containing the resulting interpolated (and smoothed) data cube. Can be visualized using for example Paraview or MayaVi nx number of mesh points along x-axis [default: 50] ny number of mesh points along y-axis [default: 50] nz number of mesh points along z-axis [default: 50] smooth if smoothing is desired: Standard deviation for Gaussian kernel. Either as a single number for same smoothing in all directions, or as (smx,smy,smz) with smx smoothing in x-direction, smy smoothing in y-direction, and smz smoothing in z-direction [default: None] nprofile if subsampling is desired: Number of samples along the profile [default: None meaning do not subsample] ndepth if subsampling is desired: Number of samples along the two-way travel time [default: None meaning do not subsample] method method for interpolation: "nearest", "linear", or "cubic" I highly highly recommend "nearest" because the others are computationally much more costly [default: "nearest"] If "nearest" leads to too blocky results, use smoothing. absvals False or True: Use absolute values of the data? I recommend this when using smoothing as the positive and negative part of reflected waves will then be smoothed into one big positive reflector instead of cancelling out. [default: False] ''' # Read all profiles to find out total data size totlen = 0 totprof = 0 for i in range(0, len(datalist)): gpr = gp.gprpyProfile(datalist[i]) #gpr,nprofile,ndepth=reduceSampling(gpr,nprofile,ndepth) if gpr.data_pretopo is None: totlen = totlen + gpr.data.shape[0] * gpr.data.shape[1] totprof = totprof + gpr.data.shape[1] else: totlen = totlen + gpr.data_pretopo.shape[ 0] * gpr.data_pretopo.shape[1] totprof = totprof + gpr.data_pretopo.shape[1] # Allocate memory based on nprofile and ndepth. May be overallocating allpoints = np.zeros((totlen, 3)) alldata = np.zeros(totlen) datalength = np.zeros(len(datalist), dtype=int) topopoints = 2 * np.zeros((totprof, 3)) topolength = np.zeros(len(datalist), dtype=int) npoints = 0 # Read in all the data points and their topos print('Reading in profiles ...') for i in tqdm(range(0, len(datalist))): # These need to have a topo correction gpr = gp.gprpyProfile(datalist[i]) gpr, nprofile, ndepth = reduceSampling(gpr, nprofile, ndepth) if i == 0: currentmaxdepth = np.max(np.abs(gpr.depth)) depth = gpr.depth if gpr.data_pretopo is None: datalength[i] = gpr.data.shape[0] * gpr.data.shape[1] else: datalength[ i] = gpr.data_pretopo.shape[0] * gpr.data_pretopo.shape[1] x, y, z = tools.prepVTK(gpr.profilePos, gpr.threeD, smooth=False) topolength[i] = len(x) Z = np.reshape(z, (len(z), 1)) - np.reshape(gpr.depth, (1, len(gpr.depth))) if np.max(np.abs(gpr.depth)) < currentmaxdepth: depth = gpr.depth currentmaxdepth = np.max(np.abs(gpr.depth)) X = np.tile(x, Z.shape[1]) Y = np.tile(y, Z.shape[1]) indices = np.asarray( np.arange(np.sum(datalength[0:i]), np.sum(datalength[0:i + 1]))) topoindices = np.asarray( np.arange(np.sum(topolength[0:i]), np.sum(topolength[0:i + 1]))) allpoints[indices, :] = np.asarray( [X.flatten(), Y.flatten(), Z.flatten()]).transpose() topopoints[topoindices, :] = np.asarray([x, y, z]).squeeze().transpose() if gpr.data_pretopo is None: data = np.asarray(gpr.data.transpose()) #data = np.asarray(gpr.data) else: data = np.asarray(gpr.data_pretopo.transpose()) #data = np.asarray(gpr.data_pretopo) alldata[indices] = np.reshape(data, (data.shape[0] * data.shape[1])) # Remove overallocation allpoints = allpoints[0:np.sum(datalength), :] alldata = alldata[0:np.sum(datalength)] topopoints = topopoints[0:np.sum(topolength), :] # Interpolate xg = np.linspace(np.min(allpoints[:, 0]), np.max(allpoints[:, 0]), nx) yg = np.linspace(np.min(allpoints[:, 1]), np.max(allpoints[:, 1]), ny) dg = np.linspace(np.min(depth), np.max(depth), nz) [Xg, Yg] = np.meshgrid(xg, yg) topo = interp.griddata(topopoints[:, 0:2], topopoints[:, 2], np.asarray([Xg.flatten(), Yg.flatten()]).transpose(), method=method) topo = np.reshape(topo, Xg.shape) Zg = np.reshape(topo, (topo.shape[0], topo.shape[1], 1)) - np.reshape( dg, (1, 1, len(dg))) XXg = (Xg.reshape((Xg.shape[0], Xg.shape[1], 1))) * (np.ones( (1, 1, len(dg)))) YYg = (Yg.reshape((Yg.shape[0], Yg.shape[1], 1))) * (np.ones( (1, 1, len(dg)))) intpoints = np.asarray([XXg.flatten(), YYg.flatten(), Zg.flatten()]).transpose() print('Interpolating data') dataG = interp.griddata(allpoints, alldata, intpoints, method=method) DG = np.reshape(dataG, XXg.shape) if absvals: DG = np.abs(DG) # Smooth if smooth is not None: DG = gaussian_filter(DG, smooth) #gridToVTK(outname,XG,YG,ZG,cellData={'gpr data': DG}) gridToVTK(outname, XXg, YYg, Zg, pointData={'gpr data': DG})
def mergeProfiles(file1,file2,outfile,gapfill=0): ''' Merges two GPR profiles by placing the second one at the end of the first one. Make sure you preprocessed them in GPRPy and save them to have the correct starting and end times for the profile, or to both start at 0 to just append the second profile at the end of the first profile. INPUT: file1 File name (including path) of the first profile file2 File name (including path) of the second profile outfile File name (including path) for the merged file gapfill If there is a gap between the profiles, fill it with zeros (0) or NaN ('NaN')? [default: 0] ''' # Load the two profiles profile1 = gp.gprpyProfile(file1) profile2 = gp.gprpyProfile(file2) # make sure starting and end times are the same assert (profile1.twtt[0]==profile2.twtt[0] and profile1.twtt[-1]==profile2.twtt[-1]), "\n\nUse GPRPy to cut the profiles to the same two-way travel times\nCurrently: file 1 is %g ns to %g ns and file 2 is %g ns to %g ns \n" %(profile1.twtt[0],profile1.twtt[-1],profile2.twtt[0],profile2.twtt[-1]) # If they don't have the same number of samples, # then we need to interpolate the data to make them fit if len(profile1.twtt) > len(profile2.twtt): zfac = len(profile1.twtt)/len(profile2.twtt) profile2.data = zoom(profile2.data,[zfac,1]) elif len(profile1.twtt) < len(profile2.twtt): zfac = len(profile2.twtt)/len(profile1.twtt) profile1.data = zoom(profile1.data,[zfac,1]) profile1.twtt = profile2.twtt # If they don't have the same along-profile sampling, # need to interpolate the data such that it makes sense: if np.diff(profile1.profilePos)[3] < np.diff(profile2.profilePos)[3]: zfac = np.diff(profile2.profilePos)[3]/np.diff(profile1.profilePos)[3] profile2.data = zoom(profile2.data,[1,zfac]) profile2.profilePos=zoom(profile2.profilePos,zfac) elif np.diff(profile1.profilePos)[3] > np.diff(profile2.profilePos)[3]: zfac = np.diff(profile1.profilePos)[3]/np.diff(profile2.profilePos)[3] profile1.data = zoom(profile1.data,[1,zfac]) profile1.profilePos=zoom(profile1.profilePos,zfac) # Now concatenate the profile positions # In case someone didn't adjust their profile but just tries to merge them: if abs(profile2.profilePos[0]) < 1e-5: profile2.profilePos = profile2.profilePos + profile1.profilePos[-1]+np.diff(profile2.profilePos)[1] # Otherwise they probably know what they are doing # If there is a gap, create an array with zeros or NaNs dx=np.diff(profile2.profilePos)[0] if profile2.profilePos[0] - profile1.profilePos[-1] < dx: nfill = int(np.round((profile2.profilePos[0] - profile1.profilePos[-1])/dx)) posfill = np.arange(0,nfill)*dx + profile1.profilePos[-1] + dx datfill = np.empty(((profile2.data).shape[0],nfill)) if gapfill == 0: datfill.fill(0) else: datfill.fill(np.NaN) #datfill = np.zeros(((profile2.data).shape[0],nfill)) profile2.profilePos=np.append(posfill,profile2.profilePos) profile2.data = np.hstack((datfill,profile2.data)) # Append profile positions profile1.profilePos = np.append(profile1.profilePos,profile2.profilePos) # Now merge them into profile 1 profile1.data = np.asmatrix(np.hstack((profile1.data,profile2.data))) # Set history to shortest possible: profile1.history = ["mygpr = gp.gprpyProfile()", "mygpr.importdata('%s.gpr')" %(outfile)] profile1.info="Merged" # Save the result in a .gpr file profile1.save(outfile)