Esempio n. 1
0
# 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)
Esempio n. 2
0
    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. ')
Esempio n. 3
0
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)
Esempio n. 4
0
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})
Esempio n. 5
0
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)