예제 #1
0
def run_parallel_synthetics_mt3d(home, project_name, station_file, model_name,
                                 forceMT, mt, insar, rank, size):
    '''
    Use green functions and compute synthetics at stations for a single source
    and multiple stations. This code makes an external system call to syn.c first it
    will make the external call for the strike-slip component then a second externall
    call will be made for the dip-slip component. The unit amount of moment is 1e15
    which corresponds to Mw=3.9333...
    
    IN:
        source: 1-row numpy array containig informaiton aboutt he source, lat, lon, depth, etc...
        station_file: File name with the station coordinates
        green_path: Directopry where GFs are stored
        model_file: File containing the Earth velocity structure
        integrate: =0 if youw ant velocity waveforms, =1 if you want displacements
        static: =0 if computing full waveforms, =1 if computing only the static field
        subfault: String indicating the subfault being worked on
        coord_type: =0 if problem is in cartesian coordinates, =1 if problem is in lat/lon
        
    OUT:
        log: Sysytem standard output and standard error for log
    '''

    import os
    import subprocess
    from mudpy.forward import get_mu
    from numpy import array, genfromtxt, loadtxt, savetxt, log10
    from obspy import read
    from shlex import split
    from mudpy.green import src2sta, rt2ne, origin_time, okada_synthetics
    from glob import glob
    from mudpy.green import silentremove
    from os import remove

    #What parameters are we using?
    if rank == 0:
        out = '''Running all processes with:
        home = %s
        project_name = %s
        station_file = %s
        model_name = %s
        forceMT = %s
        mt = %s
        insar = %s
        ''' % (home, project_name, station_file, model_name, str(forceMT),
               str(mt), str(insar))
        print(out)

    #temporary outoput files to be merged later, these will hold every soruce this process runs
    tmp_Mxx = 'tmp_Mxx_process' + str(rank)
    tmp_Mxy = 'tmp_Mxy_process' + str(rank)
    tmp_Mxz = 'tmp_Mxz_process' + str(rank)
    tmp_Myy = 'tmp_Myy_process' + str(rank)
    tmp_Myz = 'tmp_Myz_process' + str(rank)
    tmp_Mzz = 'tmp_Mzz_process' + str(rank)

    #temproary throw away files that will contain only one source
    tmp_small_Mxx = 'tMxx_proc' + str(rank)
    tmp_small_Mxy = 'tMxy_proc' + str(rank)
    tmp_small_Mxz = 'tMxz_proc' + str(rank)
    tmp_small_Myy = 'tMyy_proc' + str(rank)
    tmp_small_Myz = 'tMyz_proc' + str(rank)
    tmp_small_Mzz = 'tMzz_proc' + str(rank)

    #Read your corresponding source file
    mpi_source = genfromtxt(home + project_name +
                            '/data/model_info/mpi_source.' + str(rank) +
                            '.fault')

    #Constant parameters
    tb = 50  #Number of samples before first arrival (should be 50, NEVER CHANGE, if you do then adjust in fk.pl)

    #Load structure
    model_file = home + project_name + '/structure/' + model_name
    structure = loadtxt(model_file, ndmin=2)

    #Where the data
    green_path = home + project_name + '/GFs/static/'

    #delete files from rpevious runs
    try:
        remove(green_path + tmp_Mxx)
    except:
        pass
    try:
        remove(green_path + tmp_Mxy)
    except:
        pass
    try:
        remove(green_path + tmp_Mxz)
    except:
        pass
    try:
        remove(green_path + tmp_Myy)
    except:
        pass
    try:
        remove(green_path + tmp_Myz)
    except:
        pass
    try:
        remove(green_path + tmp_Mzz)
    except:
        pass

    #Create output files
    f_Mxx = open(green_path + tmp_Mxx, 'a+')
    f_Mxy = open(green_path + tmp_Mxy, 'a+')
    f_Mxz = open(green_path + tmp_Mxz, 'a+')
    f_Myy = open(green_path + tmp_Myy, 'a+')
    f_Myz = open(green_path + tmp_Myz, 'a+')
    f_Mzz = open(green_path + tmp_Mzz, 'a+')

    #Make moment tensor components
    if forceMT == True:
        Mxx = mt[0]
        Mxy = mt[1]
        Mxz = mt[2]
        Myy = mt[3]
        Myz = mt[4]
        Mzz = mt[5]

    #Off we go now
    for ksource in range(len(mpi_source)):

        source = mpi_source[ksource, :]

        #Parse the soruce information
        num = str(int(source[0])).rjust(4, '0')
        xs = source[1]
        ys = source[2]
        zs = source[3]

        strdepth = '%.4f' % zs
        subfault = str(int(source[0])).rjust(4, '0')
        staname = genfromtxt(station_file, dtype="U", usecols=0)

        if staname.shape == ():  #Single staiton file
            staname = array([staname])

        #Compute distances and azimuths
        d, az, lon_sta, lat_sta = src2sta(station_file,
                                          source,
                                          output_coordinates=True)

        #Get moment corresponding to 1 meter of slip on subfault
        Mw = 5.0
        M0 = 10**(5.0 * 1.5 + 9.1) * 1e7  #to dyne-cm

        #Load LOS vector for projection
        los_path = home + project_name + '/data/statics/'

        #Move to output folder
        os.chdir(green_path)
        print('Processor ' + str(rank) + ' is working on subfault ' +
              str(int(source[0])) + ' and ' + str(len(d)) + ' stations ')

        #Go one station at a time for that subfault
        for k in range(len(d)):

            #Read los vector for this subfault
            if insar == True:
                los = genfromtxt(los_path + staname[k] + '.los')
                los = los[1:]

            # Load the GFs
            if insar == False:
                green_file = model_name + ".static." + strdepth + ".sub" + subfault + '.gps'  #Output dir
            else:
                green_file = model_name + ".static." + strdepth + ".sub" + subfault + '.insar'  #Output dir
            statics = loadtxt(green_file)  #Load GFs
            if len(statics) < 1:
                print('ERROR: Empty GF file')
                break

            #Print static GFs into a pipe and pass into synthetics command
            try:
                temp_pipe = statics[k, :]
            except:
                temp_pipe = statics
            inpipe = ''
            for j in range(len(temp_pipe)):
                inpipe = inpipe + ' %.6e' % temp_pipe[j]

            #Form command for external call (remember syn.c and mudpy coordiante systems are not the same)
            # order of elelments in syn.c is M0/Mxx/Mxy/Mxz/Myy/Myz/Mzz

            if forceMT == True:  #Only run one thing
                command_Mxx="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                    " -A"+str(az[k])+" -P"

                command_Mxx = split(command_Mxx)  #Lexical split

                #Make system calls, one for each MT component (rememebr to delete file when youa re done
                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Mxx,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Mxx, 'w'))
                p.communicate()
                p.wait()

                #Rotate radial/transverse to East/North, correct vertical and scale to m
                statics = loadtxt(tmp_small_Mxx)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Mxx.write(line)

            else:  #Stuff to dow he computing entire MT
                Mxx = 1
                Myy = 0
                Mzz = 0
                Mxy = 0
                Mxz = 0
                Myz = 0
                command_Mxx="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                        " -A"+str(az[k])+" -P"

                Mxx = 0
                Myy = 0
                Mzz = 0
                Mxy = 1
                Mxz = 0
                Myz = 0
                command_Mxy="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                        " -A"+str(az[k])+" -P"

                Mxx = 0
                Myy = 0
                Mzz = 0
                Mxy = 0
                Mxz = 1
                Myz = 0
                command_Mxz="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                        " -A"+str(az[k])+" -P"

                Mxx = 0
                Myy = 1
                Mzz = 0
                Mxy = 0
                Mxz = 0
                Myz = 0
                command_Myy="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                        " -A"+str(az[k])+" -P"

                Mxx = 0
                Myy = 0
                Mzz = 0
                Mxy = 0
                Mxz = 0
                Myz = 1
                command_Myz="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                        " -A"+str(az[k])+" -P"

                Mxx = 0
                Myy = 0
                Mzz = 1
                Mxy = 0
                Mxz = 0
                Myz = 0
                command_Mzz="syn -M"+str(M0)+"/"+str(Mxx)+"/"+str(Mxy)+"/"+str(Mxz)+"/"+str(Myy)+"/"+str(Myz)+"/"+str(Mzz)+\
                        " -A"+str(az[k])+" -P"

                command_Mxx = split(command_Mxx)  #Lexical split
                command_Mxy = split(command_Mxy)
                command_Mxz = split(command_Mxz)
                command_Myy = split(command_Myy)
                command_Myz = split(command_Myz)
                command_Mzz = split(command_Mzz)

                #Make system calls, one for each MT component (rememebr to delete file when youa re done
                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Mxx,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Mxx, 'w'))
                p.communicate()
                p.wait()

                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Mxy,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Mxy, 'w'))
                p.communicate()
                p.wait()

                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Mxz,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Mxz, 'w'))
                p.communicate()
                p.wait()

                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Myy,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Myy, 'w'))
                p.communicate()
                p.wait()

                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Myz,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Myz, 'w'))
                p.communicate()
                p.wait()

                ps = subprocess.Popen(
                    ['printf', inpipe], stdout=subprocess.PIPE
                )  #This is the statics pipe, pint stdout to syn's stdin
                p = subprocess.Popen(command_Mzz,
                                     stdin=ps.stdout,
                                     stdout=open(tmp_small_Mzz, 'w'))
                p.communicate()
                p.wait()

                #Rotate radial/transverse to East/North, correct vertical and scale to m
                statics = loadtxt(tmp_small_Mxx)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Mxx.write(line)

                statics = loadtxt(tmp_small_Mxy)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                n = ntemp[0]
                e = etemp[0]
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Mxy.write(line)

                statics = loadtxt(tmp_small_Mxz)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                n = ntemp[0]
                e = etemp[0]
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Mxz.write(line)

                statics = loadtxt(tmp_small_Myy)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                n = ntemp[0]
                e = etemp[0]
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Myy.write(line)

                statics = loadtxt(tmp_small_Myz)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                n = ntemp[0]
                e = etemp[0]
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Myz.write(line)

                statics = loadtxt(tmp_small_Mzz)
                u = statics[2] / 100
                r = statics[3] / 100
                t = statics[4] / 100
                ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                n = ntemp[0]
                e = etemp[0]
                #now project onto LOS if doing insar
                if insar == True:
                    los_mt = los.dot(array([ntemp[0], etemp[0], u]))
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, los_mt)
                else:
                    n = ntemp[0]
                    e = etemp[0]
                    line = '%s\t%s\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4e\t%.4e\t%.4e\n' % (
                        staname[k], str(subfault).rjust(5, '0'), lon_sta[k],
                        lat_sta[k], xs, ys, zs, n, e, u)
                #write to file
                f_Mzz.write(line)

    f_Mxx.close()
    f_Mxy.close()
    f_Mxz.close()
    f_Myy.close()
    f_Myz.close()
    f_Mzz.close()
예제 #2
0
def run_parallel_green(home, project_name, station_file, model_name, dt, NFFT,
                       static, dk, pmin, pmax, kmax, tsunami, insar, rank,
                       size):
    '''
    Compute GFs using Zhu & Rivera code for a given velocity model, source depth
    and station file. This function will make an external system call to fk.pl
    
    IN:
        source: 1-row numpy array containig informaiton aboutt he source, lat, lon, depth, etc...
        station_file: File name with the station coordinates
        dt: Desired sampling interval for waveforms
        NFFT: No. of samples requested in waveform (must be power of 2)
        static: =0 if computing full waveforms, =1 if computing only the static field
        coord_type: =0 if problem is in cartesian coordinates, =1 if problem is in lat/lon
    OUT:
        log: Sysytem standard output and standard error for log
    '''
    import subprocess
    from os import chdir
    from shutil import copy, rmtree
    from numpy import genfromtxt
    from shlex import split
    from shutil import copy
    from glob import glob
    from mudpy.green import src2sta
    import os

    #What parameters are we using?
    if rank == 0:
        out = '''Running all processes with:
        home = %s
        project_name = %s
        station_file = %s
        model_name = %s
        static = %s
        tsunami = %s
        dt = %.3f
        NFFT = %d
        dk = %.3f
        pmin = %.3f
        pmax = %.3f
        kmax = %.3f
        insar = %s
        ''' % (home, project_name, station_file, model_name, str(static),
               str(tsunami), dt, NFFT, dk, pmin, pmax, kmax, str(insar))
        print(out)
    #read your corresponding source file
    source = genfromtxt(home + project_name + '/data/model_info/mpi_source.' +
                        str(rank) + '.fault')
    for ksource in range(len(source)):
        #Where should I be working boss?
        depth = '%.4f' % source[ksource, 3]
        subfault = str(int(source[ksource, 0])).rjust(4, '0')
        if tsunami == False and static == 0:
            subfault_folder = home + project_name + '/GFs/dynamic/' + model_name + '_' + depth + '.sub' + subfault
        elif tsunami == True and static == 1:
            subfault_folder = home + project_name + '/GFs/tsunami/' + model_name + '_' + depth + '.sub' + subfault
        elif static == 1:
            subfault_folder = home + project_name + '/GFs/static/' + model_name + '_' + depth + '.sub' + subfault

        #Check if subfault folder exists, if not create it
        if os.path.exists(subfault_folder + '/') == False:
            os.makedirs(subfault_folder + '/')

        #Copy velocity model file
        copy(home + project_name + '/structure/' + model_name,
             subfault_folder + '/' + model_name)
        #Move to work folder
        chdir(subfault_folder)
        #Get station distances to source
        d, az = src2sta(station_file, source[ksource, :])
        #Make distance string for system call
        diststr = ''
        for k in range(len(d)):
            diststr = diststr + ' %.6f' % d[
                k]  #Truncate distance to 6 decimal palces (meters)
        # Keep the user informed, lest he get nervous
        print('MPI: processor #', rank, 'is now working on subfault',
              int(source[ksource, 0]), '(', ksource + 1, '/', len(source), ')')
        #Make the calculation
        if static == 0:  #Compute full waveform
            command = split("fk.pl -M" + model_name + "/" + depth + "/f -N" +
                            str(NFFT) + "/" + str(dt) + '/1/' + repr(dk) +
                            ' -P' + repr(pmin) + '/' + repr(pmax) + '/' +
                            repr(kmax) + diststr)
            p = subprocess.Popen(command,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            p.communicate()
            # Move files up one level and delete folder created by fk
            files_list = glob(subfault_folder + '/' + model_name + '_' +
                              depth + '/*.grn*')
            for f in files_list:
                newf = subfault_folder + '/' + f.split('/')[-1]
                copy(f, newf)
            rmtree(subfault_folder + '/' + model_name + '_' + depth)
        else:  #Compute only statics
            if insar == True:
                suffix = 'insar'
            else:
                suffix = 'gps'
            write_file = subfault_folder + '/' + model_name + '.static.' + depth + '.sub' + subfault + '.' + suffix
            command = split("fk.pl -M" + model_name + "/" + depth + "/f -N1 " +
                            diststr)
            file_is_empty = True
            while file_is_empty:
                p = subprocess.Popen(command,
                                     stdout=open(write_file, 'w'),
                                     stderr=subprocess.PIPE)
                p.communicate()
                if os.stat(write_file).st_size != 0:  #File is NOT empty
                    file_is_empty = False
                else:
                    print(
                        'Warning: I just had a mini-seizure and made an empty GF file on first try, re-running'
                    )
예제 #3
0
def run_parallel_synthetics(home,
                            project_name,
                            station_file,
                            model_name,
                            integrate,
                            static,
                            tsunami,
                            time_epi,
                            beta,
                            custom_stf,
                            impulse,
                            rank,
                            size,
                            insar=False,
                            okada=False,
                            mu_okada=45e9):
    '''
    Use green functions and compute synthetics at stations for a single source
    and multiple stations. This code makes an external system call to syn.c first it
    will make the external call for the strike-slip component then a second externall
    call will be made for the dip-slip component. The unit amount of moment is 1e15
    which corresponds to Mw=3.9333...
    
    IN:
        source: 1-row numpy array containig informaiton aboutt he source, lat, lon, depth, etc...
        station_file: File name with the station coordinates
        green_path: Directopry where GFs are stored
        model_file: File containing the Earth velocity structure
        integrate: =0 if youw ant velocity waveforms, =1 if you want displacements
        static: =0 if computing full waveforms, =1 if computing only the static field
        subfault: String indicating the subfault being worked on
        coord_type: =0 if problem is in cartesian coordinates, =1 if problem is in lat/lon
        
    OUT:
        log: Sysytem standard output and standard error for log
    '''

    import os
    import subprocess
    from mudpy.forward import get_mu
    from numpy import array, genfromtxt, loadtxt, savetxt, log10
    from obspy import read
    from shlex import split
    from mudpy.green import src2sta, rt2ne, origin_time, okada_synthetics
    from glob import glob
    from mudpy.green import silentremove
    from os import remove

    #What parameters are we using?
    if rank == 0:
        out = '''Running all processes with:
        home = %s
        project_name = %s
        station_file = %s
        model_name = %s
        integrate = %s
        static = %s
        tsunami = %s
        time_epi = %s
        beta = %d
        custom_stf = %s
        impulse = %s
        insar = %s
        okada = %s
        mu = %.2e
        ''' % (home, project_name, station_file, model_name, str(integrate),
               str(static), str(tsunami), str(time_epi), beta, custom_stf,
               impulse, insar, okada, mu_okada)
        print(out)

    #Read your corresponding source file
    mpi_source = genfromtxt(home + project_name +
                            '/data/model_info/mpi_source.' + str(rank) +
                            '.fault')

    #Constant parameters
    rakeDS = 90 + beta  #90 is thrust, -90 is normal
    rakeSS = 0 + beta  #0 is left lateral, 180 is right lateral
    tb = 50  #Number of samples before first arrival (should be 50, NEVER CHANGE, if you do then adjust in fk.pl)

    #Figure out custom STF
    if custom_stf.lower() != 'none':
        custom_stf = home + project_name + '/GFs/STFs/' + custom_stf
    else:
        custom_stf = None

    #Load structure
    model_file = home + project_name + '/structure/' + model_name
    structure = loadtxt(model_file, ndmin=2)

    for ksource in range(len(mpi_source)):

        source = mpi_source[ksource, :]

        #Parse the soruce information
        num = str(int(source[0])).rjust(4, '0')
        xs = source[1]
        ys = source[2]
        zs = source[3]
        strike = source[4]
        dip = source[5]
        rise = source[6]
        if impulse == True:
            duration = 0
        else:
            duration = source[7]
        ss_length = source[8]
        ds_length = source[9]
        ss_length_in_km = ss_length / 1000.
        ds_length_in_km = ds_length / 1000.
        strdepth = '%.4f' % zs
        subfault = str(int(source[0])).rjust(4, '0')
        if static == 0 and tsunami == 0:  #Where to save dynamic waveforms
            green_path = home + project_name + '/GFs/dynamic/' + model_name + "_" + strdepth + ".sub" + subfault + "/"
        if static == 1 and tsunami == 1:  #Where to save dynamic waveforms
            green_path = home + project_name + '/GFs/tsunami/' + model_name + "_" + strdepth + ".sub" + subfault + "/"
        if static == 1 and tsunami == 0:  #Where to save statics
            green_path = home + project_name + '/GFs/static/' + model_name + "_" + strdepth + ".sub" + subfault + "/"
        staname = genfromtxt(station_file, dtype="U", usecols=0)
        if staname.shape == ():  #Single staiton file
            staname = array([staname])
        #Compute distances and azimuths
        d, az, lon_sta, lat_sta = src2sta(station_file,
                                          source,
                                          output_coordinates=True)

        #Get moment corresponding to 1 meter of slip on subfault
        mu = get_mu(structure, zs)
        Mo = mu * ss_length * ds_length * 1.0
        Mw = (2. / 3) * (log10(Mo) - 9.1)

        #Move to output folder
        os.chdir(green_path)
        print('Processor ' + str(rank) + ' is working on subfault ' +
              str(int(source[0])) + ' and ' + str(len(d)) + ' stations ')
        for k in range(len(d)):
            if static == 0:  #Compute full waveforms
                diststr = '%.6f' % d[
                    k]  #Need current distance in string form for external call
                #Form the strings to be used for the system calls according to user desired options
                if integrate == 1:  #Make displ.
                    #First Stike-Slip GFs
                    if custom_stf == None:
                        commandSS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.disp.x -G"+green_path+diststr+".grn.0"
                        commandSS = split(
                            commandSS
                        )  #Split string into lexical components for system call
                        #Now dip slip
                        commandDS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.disp.x -G"+green_path+diststr+".grn.0"
                        commandDS = split(commandDS)
                    else:
                        commandSS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.disp.x -G"+green_path+diststr+".grn.0"
                        commandSS = split(
                            commandSS
                        )  #Split string into lexical components for system call
                        #Now dip slip
                        commandDS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.disp.x -G"+green_path+diststr+".grn.0"
                        commandDS = split(commandDS)
                else:  #Make vel.
                    #First Stike-Slip GFs
                    if custom_stf == None:
                        commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.vel.x -G"+green_path+diststr+".grn.0"
                        commandSS = split(commandSS)
                        #Now dip slip
                        commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.vel.x -G"+green_path+diststr+".grn.0"
                        commandDS = split(commandDS)
                    else:
                        commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.vel.x -G"+green_path+diststr+".grn.0"
                        commandSS = split(commandSS)
                        #Now dip slip
                        commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.vel.x -G"+green_path+diststr+".grn.0"
                        commandDS = split(commandDS)
                #Run the strike- and dip-slip commands (make system calls)
                p = subprocess.Popen(commandSS)
                p.communicate()
                p = subprocess.Popen(commandDS)
                p.communicate()
                #Result is in RTZ system (+Z is down) rotate to NEZ with +Z up and scale to m or m/s
                if integrate == 1:  #'tis displacememnt
                    #Strike slip
                    if duration > 0:  #Is there a source time fucntion? Yes!
                        r = read(staname[k] + ".subfault" + num + '.SS.disp.r')
                        t = read(staname[k] + ".subfault" + num + '.SS.disp.t')
                        z = read(staname[k] + ".subfault" + num + '.SS.disp.z')
                    else:  #No! This is the impulse response!
                        r = read(staname[k] + ".subfault" + num +
                                 '.SS.disp.ri')
                        t = read(staname[k] + ".subfault" + num +
                                 '.SS.disp.ti')
                        z = read(staname[k] + ".subfault" + num +
                                 '.SS.disp.zi')
                    ntemp, etemp = rt2ne(r[0].data, t[0].data, az[k])
                    #Scale to m and overwrite with rotated waveforms
                    n = r.copy()
                    n[0].data = ntemp / 100
                    e = t.copy()
                    e[0].data = etemp / 100
                    z[0].data = z[0].data / 100
                    n = origin_time(n, time_epi, tb)
                    e = origin_time(e, time_epi, tb)
                    z = origin_time(z, time_epi, tb)
                    n.write(staname[k] + ".subfault" + num + '.SS.disp.n',
                            format='SAC')
                    e.write(staname[k] + ".subfault" + num + '.SS.disp.e',
                            format='SAC')
                    z.write(staname[k] + ".subfault" + num + '.SS.disp.z',
                            format='SAC')
                    silentremove(staname[k] + ".subfault" + num + '.SS.disp.r')
                    silentremove(staname[k] + ".subfault" + num + '.SS.disp.t')
                    if impulse == True:
                        silentremove(staname[k] + ".subfault" + num +
                                     '.SS.disp.ri')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.SS.disp.ti')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.SS.disp.zi')
                    #Dip Slip
                    if duration > 0:  #Is there a source time fucntion? Yes!
                        r = read(staname[k] + ".subfault" + num + '.DS.disp.r')
                        t = read(staname[k] + ".subfault" + num + '.DS.disp.t')
                        z = read(staname[k] + ".subfault" + num + '.DS.disp.z')
                    else:  #No! This is the impulse response!
                        r = read(staname[k] + ".subfault" + num +
                                 '.DS.disp.ri')
                        t = read(staname[k] + ".subfault" + num +
                                 '.DS.disp.ti')
                        z = read(staname[k] + ".subfault" + num +
                                 '.DS.disp.zi')
                    ntemp, etemp = rt2ne(r[0].data, t[0].data, az[k])
                    n = r.copy()
                    n[0].data = ntemp / 100
                    e = t.copy()
                    e[0].data = etemp / 100
                    z[0].data = z[0].data / 100
                    n = origin_time(n, time_epi, tb)
                    e = origin_time(e, time_epi, tb)
                    z = origin_time(z, time_epi, tb)
                    n.write(staname[k] + ".subfault" + num + '.DS.disp.n',
                            format='SAC')
                    e.write(staname[k] + ".subfault" + num + '.DS.disp.e',
                            format='SAC')
                    z.write(staname[k] + ".subfault" + num + '.DS.disp.z',
                            format='SAC')
                    silentremove(staname[k] + ".subfault" + num + '.DS.disp.r')
                    silentremove(staname[k] + ".subfault" + num + '.DS.disp.t')
                    if impulse == True:
                        silentremove(staname[k] + ".subfault" + num +
                                     '.DS.disp.ri')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.DS.disp.ti')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.DS.disp.zi')
                else:  #Waveforms are velocity, as before, rotate from RT-Z to NE+Z and scale to m/s
                    #Strike slip
                    if duration > 0:  #Is there a source time fucntion? Yes!
                        r = read(staname[k] + ".subfault" + num + '.SS.vel.r')
                        t = read(staname[k] + ".subfault" + num + '.SS.vel.t')
                        z = read(staname[k] + ".subfault" + num + '.SS.vel.z')
                    else:  #No! This is the impulse response!
                        r = read(staname[k] + ".subfault" + num + '.SS.vel.ri')
                        t = read(staname[k] + ".subfault" + num + '.SS.vel.ti')
                        z = read(staname[k] + ".subfault" + num + '.SS.vel.zi')
                    ntemp, etemp = rt2ne(r[0].data, t[0].data, az[k])
                    n = r.copy()
                    n[0].data = ntemp / 100
                    e = t.copy()
                    e[0].data = etemp / 100
                    z[0].data = z[0].data / 100
                    n = origin_time(n, time_epi, tb)
                    e = origin_time(e, time_epi, tb)
                    z = origin_time(z, time_epi, tb)
                    n.write(staname[k] + ".subfault" + num + '.SS.vel.n',
                            format='SAC')
                    e.write(staname[k] + ".subfault" + num + '.SS.vel.e',
                            format='SAC')
                    z.write(staname[k] + ".subfault" + num + '.SS.vel.z',
                            format='SAC')
                    silentremove(staname[k] + ".subfault" + num + '.SS.vel.r')
                    silentremove(staname[k] + ".subfault" + num + '.SS.vel.t')
                    if impulse == True:
                        silentremove(staname[k] + ".subfault" + num +
                                     '.SS.vel.ri')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.SS.vel.ti')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.SS.vel.zi')
                    #Dip Slip
                    if duration > 0:  #Is there a source time fucntion? Yes!
                        r = read(staname[k] + ".subfault" + num + '.DS.vel.r')
                        t = read(staname[k] + ".subfault" + num + '.DS.vel.t')
                        z = read(staname[k] + ".subfault" + num + '.DS.vel.z')
                    else:  #No! This is the impulse response!
                        r = read(staname[k] + ".subfault" + num + '.DS.vel.ri')
                        t = read(staname[k] + ".subfault" + num + '.DS.vel.ti')
                        z = read(staname[k] + ".subfault" + num + '.DS.vel.zi')
                    ntemp, etemp = rt2ne(r[0].data, t[0].data, az[k])
                    n = r.copy()
                    n[0].data = ntemp / 100
                    e = t.copy()
                    e[0].data = etemp / 100
                    z[0].data = z[0].data / 100
                    n = origin_time(n, time_epi, tb)
                    e = origin_time(e, time_epi, tb)
                    z = origin_time(z, time_epi, tb)
                    n.write(staname[k] + ".subfault" + num + '.DS.vel.n',
                            format='SAC')
                    e.write(staname[k] + ".subfault" + num + '.DS.vel.e',
                            format='SAC')
                    z.write(staname[k] + ".subfault" + num + '.DS.vel.z',
                            format='SAC')
                    silentremove(staname[k] + ".subfault" + num + '.DS.vel.r')
                    silentremove(staname[k] + ".subfault" + num + '.DS.vel.t')
                    if impulse == True:
                        silentremove(staname[k] + ".subfault" + num +
                                     '.DS.vel.ri')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.DS.vel.ti')
                        silentremove(staname[k] + ".subfault" + num +
                                     '.DS.vel.zi')
            else:  #Compute static synthetics
                if okada == False:  #Layered earth model
                    temp_pipe = []
                    diststr = '%.1f' % d[
                        k]  #Need current distance in string form for external call
                    if insar == True:
                        green_file = green_path + model_name + ".static." + strdepth + ".sub" + subfault + '.insar'  #Output dir
                    else:  #GPS
                        green_file = green_path + model_name + ".static." + strdepth + ".sub" + subfault + '.gps'  #Output dir
                    statics = loadtxt(green_file)  #Load GFs
                    if len(statics) < 1:
                        print('ERROR: Empty GF file')
                        break
                    #Print static GFs into a pipe and pass into synthetics command
                    try:
                        temp_pipe = statics[k, :]
                    except:
                        temp_pipe = statics
                    inpipe = ''
                    for j in range(len(temp_pipe)):
                        inpipe = inpipe + ' %.6e' % temp_pipe[j]
                    #Form command for external call
                    commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+\
                            " -A"+str(az[k])+" -P"
                    commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+\
                            " -A"+str(az[k])+" -P"
                    commandSS = split(commandSS)  #Lexical split
                    commandDS = split(commandDS)
                    #Make system calls, one for DS, one for SS
                    ps = subprocess.Popen(
                        ['printf', inpipe], stdout=subprocess.PIPE
                    )  #This is the statics pipe, pint stdout to syn's stdin
                    p = subprocess.Popen(
                        commandSS,
                        stdin=ps.stdout,
                        stdout=open(
                            green_path + staname[k] + '.subfault' + num +
                            '.SS.static.rtz', 'w'))
                    p.communicate()
                    ps = subprocess.Popen(
                        ['printf', inpipe], stdout=subprocess.PIPE
                    )  #This is the statics pipe, pint stdout to syn's stdin
                    p = subprocess.Popen(
                        commandDS,
                        stdin=ps.stdout,
                        stdout=open(
                            green_path + staname[k] + '.subfault' + num +
                            '.DS.static.rtz', 'w'))
                    p.communicate()
                    #Rotate radial/transverse to East/North, correct vertical and scale to m
                    statics = loadtxt(green_path + staname[k] + '.subfault' +
                                      num + '.SS.static.rtz')
                    u = statics[2] / 100
                    r = statics[3] / 100
                    t = statics[4] / 100
                    ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                    n = ntemp[0]
                    e = etemp[0]
                    savetxt(
                        green_path + staname[k] + '.subfault' + num +
                        '.SS.static.neu', (n, e, u, beta))
                    statics = loadtxt(green_path + staname[k] + '.subfault' +
                                      num + '.DS.static.rtz')
                    u = statics[2] / 100
                    r = statics[3] / 100
                    t = statics[4] / 100
                    ntemp, etemp = rt2ne(array([r, r]), array([t, t]), az[k])
                    n = ntemp[0]
                    e = etemp[0]
                    savetxt(green_path + staname[k] + '.subfault' + num +
                            '.DS.static.neu', (n, e, u, beta),
                            header='north(m),east(m),up(m),beta(degs)')
                else:  #Okada half space solutions
                    #SS
                    n, e, u = okada_synthetics(strike, dip, rakeSS,
                                               ss_length_in_km,
                                               ds_length_in_km, xs, ys, zs,
                                               lon_sta[k], lat_sta[k],
                                               mu_okada)
                    savetxt(staname[k] + '.subfault' + num + '.SS.static.neu',
                            (n, e, u, beta),
                            header='north(m),east(m),up(m),beta(degs)')
                    #DS
                    n, e, u = okada_synthetics(strike, dip, rakeDS,
                                               ss_length_in_km,
                                               ds_length_in_km, xs, ys, zs,
                                               lon_sta[k], lat_sta[k],
                                               mu_okada)
                    savetxt(staname[k] + '.subfault' + num + '.DS.static.neu',
                            (n, e, u, beta),
                            header='north(m),east(m),up(m),beta(degs)')
예제 #4
0
def run_parallel_synthetics(home,project_name,station_file,model_name,integrate,static,tsunami,time_epi,
                beta,custom_stf,impulse,rank,size,insar=False,okada=False,mu_okada=45e9):
    '''
    Use green functions and compute synthetics at stations for a single source
    and multiple stations. This code makes an external system call to syn.c first it
    will make the external call for the strike-slip component then a second externall
    call will be made for the dip-slip component. The unit amount of moment is 1e15
    which corresponds to Mw=3.9333...
    
    IN:
        source: 1-row numpy array containig informaiton aboutt he source, lat, lon, depth, etc...
        station_file: File name with the station coordinates
        green_path: Directopry where GFs are stored
        model_file: File containing the Earth velocity structure
        integrate: =0 if youw ant velocity waveforms, =1 if you want displacements
        static: =0 if computing full waveforms, =1 if computing only the static field
        subfault: String indicating the subfault being worked on
        coord_type: =0 if problem is in cartesian coordinates, =1 if problem is in lat/lon
        
    OUT:
        log: Sysytem standard output and standard error for log
    '''

    import os
    import subprocess
    from pandas import DataFrame as df
    from mudpy.forward import get_mu
    from numpy import array,genfromtxt,loadtxt,savetxt,log10,zeros,sin,cos,ones,deg2rad
    from obspy import read
    from shlex import split
    from mudpy.green import src2sta,rt2ne,origin_time,okada_synthetics
    from glob import glob
    from mudpy.green import silentremove
    from os import remove
    
    #What parameters are we using?
    if rank==0:
        out='''Running all processes with:
        home = %s
        project_name = %s
        station_file = %s
        model_name = %s
        integrate = %s
        static = %s
        tsunami = %s
        time_epi = %s
        beta = %d
        custom_stf = %s
        impulse = %s
        insar = %s
        okada = %s
        mu = %.2e
        ''' %(home,project_name,station_file,model_name,str(integrate),str(static),str(tsunami),str(time_epi),beta,custom_stf,impulse,insar,okada,mu_okada)
        print(out)
        
    #Read your corresponding source file
    mpi_source=genfromtxt(home+project_name+'/data/model_info/mpi_source.'+str(rank)+'.fault')
    
    #Constant parameters
    rakeDS=90+beta #90 is thrust, -90 is normal
    rakeSS=0+beta #0 is left lateral, 180 is right lateral
    tb=50 #Number of samples before first arrival (should be 50, NEVER CHANGE, if you do then adjust in fk.pl)
    
    #Figure out custom STF
    if custom_stf.lower()!='none':
        custom_stf=home+project_name+'/GFs/STFs/'+custom_stf
    else:
        custom_stf=None
    
    #Load structure
    model_file=home+project_name+'/structure/'+model_name
    structure=loadtxt(model_file,ndmin=2)
    
    #this keeps track of statics dataframe
    write_df=False
    
    for ksource in range(len(mpi_source)):
        
        source=mpi_source[ksource,:]
        
        #Parse the soruce information
        num=str(int(source[0])).rjust(4,'0')
        xs=source[1]
        ys=source[2]
        zs=source[3]
        strike=source[4]
        dip=source[5]
        rise=source[6]
        if impulse==True:
            duration=0
        else:
            duration=source[7]
        ss_length=source[8]
        ds_length=source[9]
        ss_length_in_km=ss_length/1000.
        ds_length_in_km=ds_length/1000.
        strdepth='%.4f' % zs
        subfault=str(int(source[0])).rjust(4,'0')
        if static==0 and tsunami==0:  #Where to save dynamic waveforms
            green_path=home+project_name+'/GFs/dynamic/'+model_name+"_"+strdepth+".sub"+subfault+"/"
        if static==1 and tsunami==1:  #Where to save dynamic waveforms
            green_path=home+project_name+'/GFs/tsunami/'+model_name+"_"+strdepth+".sub"+subfault+"/"
        if static==1 and tsunami==0:  #Where to save statics
            green_path=home+project_name+'/GFs/static/'+model_name+"_"+strdepth+".sub"+subfault+"/"
        staname=genfromtxt(station_file,dtype="U",usecols=0)
        if staname.shape==(): #Single staiton file
            staname=array([staname])
        #Compute distances and azimuths
        d,az,lon_sta,lat_sta=src2sta(station_file,source,output_coordinates=True)
        
        #Get moment corresponding to 1 meter of slip on subfault
        mu=get_mu(structure,zs)
        Mo=mu*ss_length*ds_length*1.0
        Mw=(2./3)*(log10(Mo)-9.1)
        
        #Move to output folder
        os.chdir(green_path)
        print('Processor '+str(rank)+' is working on subfault '+str(int(source[0]))+' and '+str(len(d))+' stations ')
        
        #This is looping over "sites"
        for k in range(len(d)):
            
            if static==0: #Compute full waveforms
                diststr='%.6f' % d[k] #Need current distance in string form for external call
                #Form the strings to be used for the system calls according to user desired options
                if integrate==1: #Make displ.
                    #First Stike-Slip GFs
                    if custom_stf==None:
                        commandSS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.disp.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS) #Split string into lexical components for system call
                        #Now dip slip
                        commandDS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.disp.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                    else:
                        commandSS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.disp.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS) #Split string into lexical components for system call
                        #Now dip slip
                        commandDS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.disp.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                else: #Make vel.
                    #First Stike-Slip GFs
                    if custom_stf==None:
                        commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.vel.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS)
                        #Now dip slip
                        commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.vel.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                    else:
                        commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.vel.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS)
                        #Now dip slip
                        commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.vel.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                #Run the strike- and dip-slip commands (make system calls)
                p=subprocess.Popen(commandSS)
                p.communicate() 
                p=subprocess.Popen(commandDS)
                p.communicate()
                #Result is in RTZ system (+Z is down) rotate to NEZ with +Z up and scale to m or m/s
                if integrate==1: #'tis displacememnt
                    #Strike slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.SS.disp.r')
                        t=read(staname[k]+".subfault"+num+'.SS.disp.t')
                        z=read(staname[k]+".subfault"+num+'.SS.disp.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.SS.disp.ri')
                        t=read(staname[k]+".subfault"+num+'.SS.disp.ti')
                        z=read(staname[k]+".subfault"+num+'.SS.disp.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    #Scale to m and overwrite with rotated waveforms
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    # get rid of numerical "noise" in the first tb samples
                    n[0].data[0:tb]=0
                    e[0].data[0:tb]=0
                    z[0].data[0:tb]=0
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.SS.disp.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.SS.disp.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.SS.disp.z',format='SAC')
                    silentremove(staname[k]+".subfault"+num+'.SS.disp.r')
                    silentremove(staname[k]+".subfault"+num+'.SS.disp.t')
                    if impulse==True:
                        silentremove(staname[k]+".subfault"+num+'.SS.disp.ri')
                        silentremove(staname[k]+".subfault"+num+'.SS.disp.ti')
                        silentremove(staname[k]+".subfault"+num+'.SS.disp.zi')
                    #Dip Slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.DS.disp.r')
                        t=read(staname[k]+".subfault"+num+'.DS.disp.t')
                        z=read(staname[k]+".subfault"+num+'.DS.disp.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.DS.disp.ri')
                        t=read(staname[k]+".subfault"+num+'.DS.disp.ti')
                        z=read(staname[k]+".subfault"+num+'.DS.disp.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.DS.disp.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.DS.disp.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.DS.disp.z',format='SAC')
                    silentremove(staname[k]+".subfault"+num+'.DS.disp.r')
                    silentremove(staname[k]+".subfault"+num+'.DS.disp.t')
                    if impulse==True:
                        silentremove(staname[k]+".subfault"+num+'.DS.disp.ri')
                        silentremove(staname[k]+".subfault"+num+'.DS.disp.ti')
                        silentremove(staname[k]+".subfault"+num+'.DS.disp.zi')
                else: #Waveforms are velocity, as before, rotate from RT-Z to NE+Z and scale to m/s
                    #Strike slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.SS.vel.r')
                        t=read(staname[k]+".subfault"+num+'.SS.vel.t')
                        z=read(staname[k]+".subfault"+num+'.SS.vel.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.SS.vel.ri')
                        t=read(staname[k]+".subfault"+num+'.SS.vel.ti')
                        z=read(staname[k]+".subfault"+num+'.SS.vel.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.SS.vel.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.SS.vel.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.SS.vel.z',format='SAC')
                    silentremove(staname[k]+".subfault"+num+'.SS.vel.r')
                    silentremove(staname[k]+".subfault"+num+'.SS.vel.t')
                    if impulse==True:
                        silentremove(staname[k]+".subfault"+num+'.SS.vel.ri')
                        silentremove(staname[k]+".subfault"+num+'.SS.vel.ti')
                        silentremove(staname[k]+".subfault"+num+'.SS.vel.zi')
                    #Dip Slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.DS.vel.r')
                        t=read(staname[k]+".subfault"+num+'.DS.vel.t')
                        z=read(staname[k]+".subfault"+num+'.DS.vel.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.DS.vel.ri')
                        t=read(staname[k]+".subfault"+num+'.DS.vel.ti')
                        z=read(staname[k]+".subfault"+num+'.DS.vel.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.DS.vel.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.DS.vel.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.DS.vel.z',format='SAC')
                    silentremove(staname[k]+".subfault"+num+'.DS.vel.r')
                    silentremove(staname[k]+".subfault"+num+'.DS.vel.t')
                    if impulse==True:
                        silentremove(staname[k]+".subfault"+num+'.DS.vel.ri')
                        silentremove(staname[k]+".subfault"+num+'.DS.vel.ti')
                        silentremove(staname[k]+".subfault"+num+'.DS.vel.zi')
            else: #Compute static synthetics
                if okada==False:  #Layered earth model
                    
                    #this is because when I first wrote this code it processed each
                    #source/station pair independently but now that it's vectorized
                    #it's does ALL stations in one fell swoop, given the logic it's 
                    #easier to just keep this inside the for loop and use the if to
                    #run it jsut the first time for all sites
                    if k==0:   
                        
                        #initalize output variables
                        staticsSS = zeros((len(d),4))
                        staticsDS = zeros((len(d),4))
                        write_df=True
                        
                        #read GFs file
                        if insar==True:
                            green_file=green_path+model_name+".static."+strdepth+".sub"+subfault+'.insar' #Output dir
                        else: #GPS
                            green_file=green_path+model_name+".static."+strdepth+".sub"+subfault+'.gps' #Output 

                        statics=loadtxt(green_file) #Load GFs
                        Nsites=len(statics) 
                        
                        if len(statics)<1:
                            print('ERROR: Empty GF file')
                            break
                        
                        #Now get radiation pattern terms, there will be 3 terms
                        #for each direction so 9 terms total. THis comes from funtion
                        #dc_radiat() in radiats.c from fk
                        radiation_pattern_ss = zeros((Nsites,9))
                        radiation_pattern_ds = zeros((Nsites,9))
                        
                        rakeSSrad = deg2rad(rakeSS)
                        rakeDSrad = deg2rad(rakeDS)
                        dip_rad = deg2rad(dip)
                        pseudo_strike = deg2rad(az-strike)
                        
                        #Let's do SS first
                        r = rakeSSrad
                        
                        #trigonometric terms following nomenclature used in radiats.c
                        sstk=sin(pseudo_strike) ; cstk=cos(pseudo_strike)
                        sdip=sin(dip_rad) ; cdip=cos(dip_rad)
                        srak=sin(r) ; crak=cos(r)
                        sstk2=2*sstk*cstk ; cstk2=cstk*cstk-sstk*sstk
                        sdip2=2*sdip*cdip ; cdip2=cdip*cdip-sdip*sdip
                        
                        # terms for up component
                        u_dd = 0.5*srak*sdip2*ones(Nsites)
                        u_ds = -sstk*srak*cdip2+cstk*crak*cdip
                        u_ss = -sstk2*crak*sdip-0.5*cstk2*srak*sdip2
                        
                        #terms for r component
                        r_dd = u_dd.copy()
                        r_ds = u_ds.copy()
                        r_ss = u_ss.copy()
                        
                        #terms for t component
                        t_dd = zeros(Nsites)
                        t_ds = cstk*srak*cdip2+sstk*crak*cdip
                        t_ss = cstk2*crak*sdip-0.5*sstk2*srak*sdip2

                        #assemble in one variable
                        radiation_pattern_ss[:,0] = u_dd
                        radiation_pattern_ss[:,1] = u_ds
                        radiation_pattern_ss[:,2] = u_ss
                        
                        radiation_pattern_ss[:,3] = r_dd
                        radiation_pattern_ss[:,4] = r_ds
                        radiation_pattern_ss[:,5] = r_ss
                        
                        radiation_pattern_ss[:,6] = t_dd
                        radiation_pattern_ss[:,7] = t_ds
                        radiation_pattern_ss[:,8] = t_ss
                        
                        
                        #Now radiation pattern for DS
                        r = rakeDSrad
                        
                        #trigonometric terms following nomenclature used in radiats.c
                        sstk=sin(pseudo_strike) ; cstk=cos(pseudo_strike)
                        sdip=sin(dip_rad) ; cdip=cos(dip_rad)
                        srak=sin(r) ; crak=cos(r)
                        sstk2=2*sstk*cstk ; cstk2=cstk*cstk-sstk*sstk
                        sdip2=2*sdip*cdip ; cdip2=cdip*cdip-sdip*sdip
                        
                        # terms for up component
                        u_dd = 0.5*srak*sdip2*ones(Nsites)
                        u_ds = -sstk*srak*cdip2+cstk*crak*cdip
                        u_ss = -sstk2*crak*sdip-0.5*cstk2*srak*sdip2
                        
                        #terms for r component
                        r_dd = u_dd.copy()
                        r_ds = u_ds.copy()
                        r_ss = u_ss.copy()
                        
                        #terms for t component
                        t_dd = zeros(Nsites)
                        t_ds = cstk*srak*cdip2+sstk*crak*cdip
                        t_ss = cstk2*crak*sdip-0.5*sstk2*srak*sdip2
                        
                        #assemble in one variable
                        radiation_pattern_ds[:,0] = u_dd
                        radiation_pattern_ds[:,1] = u_ds
                        radiation_pattern_ds[:,2] = u_ss
                        
                        radiation_pattern_ds[:,3] = r_dd
                        radiation_pattern_ds[:,4] = r_ds
                        radiation_pattern_ds[:,5] = r_ss
                        
                        radiation_pattern_ds[:,6] = t_dd
                        radiation_pattern_ds[:,7] = t_ds
                        radiation_pattern_ds[:,8] = t_ss
                        
                        
                        #Now define the scalng based on magnitude this is variable
                        #"coef" in the syn.c original source code
                        scale = 10**(1.5*Mw+16.1-20) #definition used in syn.c
                        
                        #Scale radiation patterns accordingly
                        radiation_pattern_ss *= scale
                        radiation_pattern_ds *= scale
                        
                        #Now multiply each GF component by the appropriate SCALED
                        #radiation pattern term and add em up to get the displacements
                        # also /100 to convert  to meters
                        up_ss = radiation_pattern_ss[:,0:3]*statics[:,[1,4,7]] 
                        up_ss = up_ss.sum(axis=1) / 100
                        up_ds = radiation_pattern_ds[:,0:3]*statics[:,[1,4,7]] 
                        up_ds = up_ds.sum(axis=1)    / 100                     

                        radial_ss = radiation_pattern_ss[:,3:6]*statics[:,[2,5,8]] 
                        radial_ss = radial_ss.sum(axis=1) / 100
                        radial_ds = radiation_pattern_ds[:,3:6]*statics[:,[2,5,8]] 
                        radial_ds = radial_ds.sum(axis=1) / 100 
                        
                        tangential_ss = radiation_pattern_ss[:,6:9]*statics[:,[3,6,9]] 
                        tangential_ss = tangential_ss.sum(axis=1) / 100
                        tangential_ds = radiation_pattern_ds[:,6:9]*statics[:,[3,6,9]] 
                        tangential_ds = tangential_ds.sum(axis=1) / 100
                        
                        #rotate to neu
                        n_ss,e_ss=rt2ne(radial_ss,tangential_ss,az)
                        n_ds,e_ds=rt2ne(radial_ds,tangential_ds,az)

                        #put in output variables
                        staticsSS[:,0]=n_ss
                        staticsSS[:,1]=e_ss
                        staticsSS[:,2]=up_ss
                        staticsSS[:,3]=beta*ones(Nsites)
                        
                        staticsDS[:,0]=n_ds
                        staticsDS[:,1]=e_ds
                        staticsDS[:,2]=up_ds
                        staticsDS[:,3]=beta*ones(Nsites)
                        
                    else:
                        pass
            

                else: #Okada half space solutions
                #SS
                    n,e,u=okada_synthetics(strike,dip,rakeSS,ss_length_in_km,ds_length_in_km,xs,ys,
                        zs,lon_sta[k],lat_sta[k],mu_okada)
                    savetxt(staname[k]+'.subfault'+num+'.SS.static.neu',(n,e,u,beta),header='north(m),east(m),up(m),beta(degs)')
                    #DS
                    n,e,u=okada_synthetics(strike,dip,rakeDS,ss_length_in_km,ds_length_in_km,xs,ys,
                        zs,lon_sta[k],lat_sta[k],mu_okada)
                    savetxt(staname[k]+'.subfault'+num+'.DS.static.neu',(n,e,u,beta),header='north(m),east(m),up(m),beta(degs)')

        
        if write_df==True and static ==1: #Note to self: stop using 0,1 and swithc to True/False
            
            #Strike slip
            SSdf = df(data=None, index=None, columns=['staname','n','e','u','beta'])
            SSdf.staname=staname
            SSdf.n=staticsSS[:,0]
            SSdf.e=staticsSS[:,1]
            SSdf.u=staticsSS[:,2]
            SSdf.beta=staticsSS[:,3]
            SSdf.to_csv(green_path+'subfault'+num+'.SS.static.neu',sep='\t',index=False,header=False)
            
            DSdf = df(data=None, index=None, columns=['staname','n','e','u','beta'])     
            DSdf.staname=staname
            DSdf.n=staticsDS[:,0]
            DSdf.e=staticsDS[:,1]
            DSdf.u=staticsDS[:,2]
            DSdf.beta=staticsDS[:,3]
            DSdf.to_csv(green_path+'subfault'+num+'.DS.static.neu',sep='\t',index=False,header=False)
예제 #5
0
def run_parallel_synthetics(home,project_name,station_file,model_name,integrate,static,tsunami,time_epi,
                beta,custom_stf,rank,size):
    '''
    Use green functions and compute synthetics at stations for a single source
    and multiple stations. This code makes an external system call to syn.c first it
    will make the external call for the strike-slip component then a second externall
    call will be made for the dip-slip component. The unit amount of moment is 1e15
    which corresponds to Mw=3.9333...
    
    IN:
        source: 1-row numpy array containig informaiton aboutt he source, lat, lon, depth, etc...
        station_file: File name with the station coordinates
        green_path: Directopry where GFs are stored
        model_file: File containing the Earth velocity structure
        integrate: =0 if youw ant velocity waveforms, =1 if you want displacements
        static: =0 if computing full waveforms, =1 if computing only the static field
        subfault: String indicating the subfault being worked on
        coord_type: =0 if problem is in cartesian coordinates, =1 if problem is in lat/lon
        
    OUT:
        log: Sysytem standard output and standard error for log
    '''

    import os
    import subprocess
    from mudpy.forward import get_mu
    from string import rjust
    from numpy import array,genfromtxt,loadtxt,savetxt,log10
    from obspy import read
    from shlex import split
    from mudpy.green import src2sta,rt2ne,origin_time
    from glob import glob
    from os import remove
        #What parameters are we using?
    if rank==0:
        out='''Running all processes with:
        home = %s
        project_name = %s
        station_file = %s
        model_name = %s
        integrate = %s
        static = %s
        tsunami = %s
        time_epi = %s
        beta = %d
        custom_stf = %s
        ''' %(home,project_name,station_file,model_name,str(integrate),str(static),str(tsunami),str(time_epi),beta,custom_stf)
        print out
    #Read your corresponding source file
    mpi_source=genfromtxt(home+project_name+'/data/model_info/mpi_source.'+str(rank)+'.fault')
    #Constant parameters
    rakeDS=90+beta #90 is thrust, -90 is normal
    rakeSS=0+beta #0 is left lateral, 180 is right lateral
    tb=50 #Number of samples before first arrival
    #Figure out custom STF
    if custom_stf.lower()!='none':
        custom_stf=home+project_name+'/GFs/STFs/'+custom_stf
    else:
        custom_stf=None
    #Load structure
    model_file=home+project_name+'/structure/'+model_name
    structure=loadtxt(model_file,ndmin=2)
    for ksource in range(len(mpi_source)):
        source=mpi_source[ksource,:]
        #Parse the soruce information
        num=rjust(str(int(source[0])),4,'0')
        zs=source[3]
        strike=source[4]
        dip=source[5]
        rise=source[6]
        duration=source[7]
        ss_length=source[8]
        ds_length=source[9]
        strdepth='%.4f' % zs
        subfault=rjust(str(int(source[0])),4,'0')
        if static==0 and tsunami==0:  #Where to save dynamic waveforms
            green_path=home+project_name+'/GFs/dynamic/'+model_name+"_"+strdepth+".sub"+subfault+"/"
        if static==0 and tsunami==1:  #Where to save dynamic waveforms
            green_path=home+project_name+'/GFs/tsunami/'+model_name+"_"+strdepth+".sub"+subfault+"/"
        if static==1:  #Where to save dynamic waveforms
            green_path=home+project_name+'/GFs/static/'
        staname=genfromtxt(station_file,dtype="S6",usecols=0)
        if staname.shape==(): #Single staiton file
            staname=array([staname])
        #Compute distances and azmuths
        d,az=src2sta(station_file,source)
        #Get moment corresponding to 1 meter of slip on subfault
        mu=get_mu(structure,zs)
        Mo=mu*ss_length*ds_length*1
        Mw=(2./3)*(log10(Mo)-9.1)
        #Move to output folder
        os.chdir(green_path)
        print 'Processor '+str(rank)+' is working on subfault '+str(int(source[0]))+' and '+str(len(d))+' stations '
        for k in range(len(d)):
            if static==0: #Compute full waveforms
                diststr='%.3f' % d[k] #Need current distance in string form for external call
                #Form the strings to be used for the system calls according to suer desired options
                if integrate==1: #Make displ.
                    #First Stike-Slip GFs
                    if custom_stf==None:
                        commandSS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.disp.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS) #Split string into lexical components for system call
                        #Now dip slip
                        commandDS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.disp.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                    else:
                        #print "Using custom STF "+custom_stf
                        commandSS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.disp.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS) #Split string into lexical components for system call
                        #Now dip slip
                        commandDS="syn -I -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.disp.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                else: #Make vel.
                    #First Stike-Slip GFs
                    if custom_stf==None:
                        commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.vel.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS)
                        #Now dip slip
                        commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -D"+str(duration)+ \
                            "/"+str(rise)+" -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.vel.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                    else:
                        #print "Using custom STF "+custom_stf
                        commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".SS.vel.x -G"+green_path+diststr+".grn.0"
                        commandSS=split(commandSS)
                        #Now dip slip
                        commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+" -S"+custom_stf+ \
                            " -A"+str(az[k])+" -O"+staname[k]+".subfault"+num+".DS.vel.x -G"+green_path+diststr+".grn.0"
                        commandDS=split(commandDS)
                #Run the strike- and dip-slip commands (make system calls)
                p=subprocess.Popen(commandSS)
                p.communicate() 
                p=subprocess.Popen(commandDS)
                p.communicate()
                #Result is in RTZ system (+Z is down) rotate to NEZ with +Z up and scale to m or m/s
                if integrate==1: #'tis displacememnt
                    #Strike slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.SS.disp.r')
                        t=read(staname[k]+".subfault"+num+'.SS.disp.t')
                        z=read(staname[k]+".subfault"+num+'.SS.disp.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.SS.disp.ri')
                        t=read(staname[k]+".subfault"+num+'.SS.disp.ti')
                        z=read(staname[k]+".subfault"+num+'.SS.disp.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    #Scale to m and overwrite with rotated waveforms
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.SS.disp.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.SS.disp.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.SS.disp.z',format='SAC')
                    #Dip Slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.DS.disp.r')
                        t=read(staname[k]+".subfault"+num+'.DS.disp.t')
                        z=read(staname[k]+".subfault"+num+'.DS.disp.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.DS.disp.ri')
                        t=read(staname[k]+".subfault"+num+'.DS.disp.ti')
                        z=read(staname[k]+".subfault"+num+'.DS.disp.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.DS.disp.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.DS.disp.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.DS.disp.z',format='SAC')
                else: #Waveforms are velocity, as before, rotate from RT-Z to NE+Z and scale to m/s
                    #Strike slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.SS.vel.r')
                        t=read(staname[k]+".subfault"+num+'.SS.vel.t')
                        z=read(staname[k]+".subfault"+num+'.SS.vel.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.SS.vel.ri')
                        t=read(staname[k]+".subfault"+num+'.SS.vel.ti')
                        z=read(staname[k]+".subfault"+num+'.SS.vel.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.SS.vel.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.SS.vel.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.SS.vel.z',format='SAC')
                    #Dip Slip
                    if duration>0: #Is there a source time fucntion? Yes!
                        r=read(staname[k]+".subfault"+num+'.DS.vel.r')
                        t=read(staname[k]+".subfault"+num+'.DS.vel.t')
                        z=read(staname[k]+".subfault"+num+'.DS.vel.z')
                    else: #No! This is the impulse response!
                        r=read(staname[k]+".subfault"+num+'.DS.vel.ri')
                        t=read(staname[k]+".subfault"+num+'.DS.vel.ti')
                        z=read(staname[k]+".subfault"+num+'.DS.vel.zi')
                    ntemp,etemp=rt2ne(r[0].data,t[0].data,az[k])
                    n=r.copy()
                    n[0].data=ntemp/100
                    e=t.copy()
                    e[0].data=etemp/100
                    z[0].data=z[0].data/100
                    n=origin_time(n,time_epi,tb)
                    e=origin_time(e,time_epi,tb)
                    z=origin_time(z,time_epi,tb)
                    n.write(staname[k]+".subfault"+num+'.DS.vel.n',format='SAC')
                    e.write(staname[k]+".subfault"+num+'.DS.vel.e',format='SAC')
                    z.write(staname[k]+".subfault"+num+'.DS.vel.z',format='SAC')
            else: #Compute static synthetics
                temp_pipe=[]
                diststr='%.1f' % d[k] #Need current distance in string form for external call
                green_file=model_name+".static."+strdepth+".sub"+subfault #Output dir
                statics=loadtxt(green_file) #Load GFs
                if len(statics)<1:
                    print 'ERROR: Empty GF file'
                    break
                #Print static GFs into a pipe and pass into synthetics command
                try:
                    temp_pipe=statics[k,:]
                except:
                    temp_pipe=statics
                inpipe=''
                for j in range(len(temp_pipe)):
                    inpipe=inpipe+' %.6e' % temp_pipe[j]
                #Form command for external call
                commandDS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeDS)+\
                        " -A"+str(az[k])+" -P"
                commandSS="syn -M"+str(Mw)+"/"+str(strike)+"/"+str(dip)+"/"+str(rakeSS)+\
                        " -A"+str(az[k])+" -P"
                commandSS=split(commandSS) #Lexical split
                commandDS=split(commandDS)
                #Make system calls, one for DS, one for SS
                ps=subprocess.Popen(['printf',inpipe],stdout=subprocess.PIPE)  #This is the statics pipe, pint stdout to syn's stdin
                p=subprocess.Popen(commandSS,stdin=ps.stdout,stdout=open(staname[k]+'.subfault'+num+'.SS.static.rtz','w'))     
                p.communicate()  
                ps=subprocess.Popen(['printf',inpipe],stdout=subprocess.PIPE)  #This is the statics pipe, pint stdout to syn's stdin
                p=subprocess.Popen(commandDS,stdin=ps.stdout,stdout=open(staname[k]+'.subfault'+num+'.DS.static.rtz','w'))     
                p.communicate()       
                #Rotate radial/transverse to East/North, correct vertical and scale to m
                statics=loadtxt(staname[k]+'.subfault'+num+'.SS.static.rtz')
                u=statics[2]/100
                r=statics[3]/100
                t=statics[4]/100
                ntemp,etemp=rt2ne(array([r,r]),array([t,t]),az[k])
                n=ntemp[0]
                e=etemp[0]
                savetxt(staname[k]+'.subfault'+num+'.SS.static.neu',(n,e,u,beta))
                statics=loadtxt(staname[k]+'.subfault'+num+'.DS.static.rtz')
                u=statics[2]/100
                r=statics[3]/100
                t=statics[4]/100
                ntemp,etemp=rt2ne(array([r,r]),array([t,t]),az[k])
                n=ntemp[0]
                e=etemp[0]
                savetxt(staname[k]+'.subfault'+num+'.DS.static.neu',(n,e,u,beta),header='north(m),east(m),up(m),beta(degs)')     
예제 #6
0
def run_parallel_green(home,project_name,station_file,model_name,dt,NFFT,static,dk,pmin,pmax,kmax,tsunami,rank,size):
    '''
    Compute GFs using Zhu & Rivera code for a given velocity model, source depth
    and station file. This function will make an external system call to fk.pl
    
    IN:
        source: 1-row numpy array containig informaiton aboutt he source, lat, lon, depth, etc...
        station_file: File name with the station coordinates
        dt: Desired sampling interval for waveforms
        NFFT: No. of samples requested in waveform (must be power of 2)
        static: =0 if computing full waveforms, =1 if computing only the static field
        coord_type: =0 if problem is in cartesian coordinates, =1 if problem is in lat/lon

    OUT:
        log: Sysytem standard output and standard error for log
    '''
    import subprocess
    from os import chdir
    from shutil import copy,rmtree
    from numpy import genfromtxt
    from string import rjust
    from shlex import split
    from shutil import copy
    from glob import glob
    from mudpy.green import src2sta
    import os

    #What parameters are we using?
    if rank==0:
        out='''Running all processes with:
        home = %s
        project_name = %s
        station_file = %s
        model_name = %s
        static = %s
        tsunami = %s
        dt = %.3f
        NFFT = %d
        dk = %.3f
        pmin = %.3f
        pmax = %.3f
        kmax = %.3f
        ''' %(home,project_name,station_file,model_name,str(static),str(tsunami),dt,NFFT,dk,pmin,pmax,kmax)
        print out
    #read your corresponding source file
    source=genfromtxt(home+project_name+'/data/model_info/mpi_source.'+str(rank)+'.fault')
    for ksource in range(len(source)):
        #Where should I be working boss?
        depth='%.4f' % source[ksource,3]
        subfault=rjust(str(int(source[ksource,0])),4,'0')
        if tsunami==False and static==0:
            subfault_folder=home+project_name+'/GFs/dynamic/'+model_name+'_'+depth+'.sub'+subfault
        elif tsunami==True and static==0:
            subfault_folder=home+project_name+'/GFs/tsunami/'+model_name+'_'+depth+'.sub'+subfault
        elif static==1:
            subfault_folder=home+project_name+'/GFs/static/'
        #Copy velocity model file
        copy(home+project_name+'/structure/'+model_name,subfault_folder+'/'+model_name)
        #Move to work folder
        chdir(subfault_folder)
        #Get station distances to source
        d,az=src2sta(station_file,source[ksource,:])
        #Make distance string for system call
        diststr=''
        for k in range(len(d)):
            diststr=diststr+' %.3f' % d[k] #Truncate distance to 3 decimal palces (meters)
        # Keep the user informed, lest he get nervous
        print 'MPI: processor #',rank,'is now working on subfault',int(source[ksource,0]),'(',ksource+1,'/',len(source),')'
        #Make the calculation
        if static==0: #Compute full waveform
            command=split("fk.pl -M"+model_name+"/"+depth+"/f -N"+str(NFFT)+"/"+str(dt)+'/1/'+repr(dk)+' -P'+repr(pmin)+'/'+repr(pmax)+'/'+repr(kmax)+diststr)
            p=subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
            p.communicate() 
            # Move files up one level and delete folder created by fk
            files_list=glob(subfault_folder+'/'+model_name+'_'+depth+'/*.grn*')
            for f in files_list:
                newf=subfault_folder+'/'+f.split('/')[-1]
                copy(f,newf)
            rmtree(subfault_folder+'/'+model_name+'_'+depth)
        else: #Compute only statics
            write_file=subfault_folder+model_name+'.static.'+depth+'.sub'+subfault
            command=split("fk.pl -M"+model_name+"/"+depth+"/f -N1 "+diststr)
            file_is_empty=True
            while file_is_empty:
                p=subprocess.Popen(command,stdout=open(write_file,'w'),stderr=subprocess.PIPE)
                p.communicate()
                if os.stat(write_file).st_size!=0: #File is NOT empty
                    file_is_empty=False
                else:
                    print 'Warning: I just had a mini-seizure and made an empty GF file on first try, re-running'