Example #1
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from pylot.core.io.phases import writephases
from pylot.core.util.version import get_git_version as _getVersionString

__version__ = _getVersionString()


def export(picks, fnout, eventinfo, parameter=None):
    '''
    Take <picks> dictionary and exports picking data to a VELEST-cnv
    <phasefile> without creating an ObsPy event object.

    :param picks: picking data dictionary
    :type picks: dict

    :param fnout: complete path to the exporting obs file
    :type fnout: str
    
    :param: eventinfo, source time needed for VELEST-cnv format
    :type:  list object

    :param: parameter, all input information
    :type:  object
    '''
    # write phases to VELEST-phase file
    writephases(picks, 'VELEST', fnout, parameter, eventinfo)
Example #2
0
def autoPyLoT(input_dict=None,
              parameter=None,
              inputfile=None,
              fnames=None,
              eventid=None,
              savepath=None,
              savexml=True,
              station='all',
              iplot=0,
              ncores=0):
    """
    Determine phase onsets automatically utilizing the automatic picking
    algorithms by Kueperkoch et al. 2010/2012.

    :param inputfile: path to the input file containing all parameter
    information for automatic picking (for formatting details, see.
    `~pylot.core.io.inputs.PylotParameter`
    :type inputfile: str
    :return:

    .. rubric:: Example

    """

    if ncores == 1:
        sp_info = 'autoPyLoT is running serial on 1 cores.'
    else:
        if ncores == 0:
            ncores_readable = 'all available'
        else:
            ncores_readable = ncores
        sp_info = 'autoPyLoT is running in parallel on {} cores.'.format(
            ncores_readable)

    splash = '''************************************\n
                *********autoPyLoT starting*********\n
                The Python picking and Location Tool\n
                Version {version} 2017\n
                \n
                Authors:\n
                L. Kueperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n
                M. Paffrath (Ruhr-Universitaet Bochum)\n
                S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
                
                {sp}
                ***********************************'''.format(
        version=_getVersionString(), sp=sp_info)
    print(splash)

    parameter = real_None(parameter)
    inputfile = real_None(inputfile)
    eventid = real_None(eventid)

    fig_dict = None
    fig_dict_wadatijack = None

    locflag = 1
    if input_dict and isinstance(input_dict, dict):
        if 'parameter' in input_dict:
            parameter = input_dict['parameter']
        if 'fig_dict' in input_dict:
            fig_dict = input_dict['fig_dict']
        if 'fig_dict_wadatijack' in input_dict:
            fig_dict_wadatijack = input_dict['fig_dict_wadatijack']
        if 'station' in input_dict:
            station = input_dict['station']
        if 'fnames' in input_dict:
            fnames = input_dict['fnames']
        if 'eventid' in input_dict:
            eventid = input_dict['eventid']
        if 'iplot' in input_dict:
            iplot = input_dict['iplot']
        if 'locflag' in input_dict:
            locflag = input_dict['locflag']
        if 'savexml' in input_dict:
            savexml = input_dict['savexml']

    if not parameter:
        if inputfile:
            parameter = PylotParameter(inputfile)
            #iplot = parameter['iplot']
        else:
            infile = os.path.join(os.path.expanduser('~'), '.pylot',
                                  'pylot.in')
            print('Using default input file {}'.format(infile))
            parameter = PylotParameter(infile)
    else:
        if not type(parameter) == PylotParameter:
            print('Wrong input type for parameter: {}'.format(type(parameter)))
            return
        if inputfile:
            print(
                'Parameters set and input file given. Choose either of both.')
            return

    evt = None

    # reading parameter file
    if parameter.hasParam('datastructure'):
        # getting information on data structure
        datastructure = DATASTRUCTURE[parameter.get('datastructure')]()
        dsfields = {
            'root': parameter.get('rootpath'),
            'dpath': parameter.get('datapath'),
            'dbase': parameter.get('database')
        }

        exf = ['root', 'dpath', 'dbase']

        if parameter['eventID'] is not '*' and fnames == 'None':
            dsfields['eventID'] = parameter['eventID']
            exf.append('eventID')

        datastructure.modifyFields(**dsfields)
        datastructure.setExpandFields(exf)

        # check if default location routine NLLoc is available
        if real_None(parameter['nllocbin']) and locflag:
            # get NLLoc-root path
            nllocroot = parameter.get('nllocroot')
            # get path to NLLoc executable
            nllocbin = parameter.get('nllocbin')
            nlloccall = '%s/NLLoc' % nllocbin
            # get name of phase file
            phasef = parameter.get('phasefile')
            phasefile = '%s/obs/%s' % (nllocroot, phasef)
            # get name of NLLoc-control file
            ctrf = parameter.get('ctrfile')
            ctrfile = '%s/run/%s' % (nllocroot, ctrf)
            # pattern of NLLoc ttimes from location grid
            ttpat = parameter.get('ttpatter')
            # pattern of NLLoc-output file
            nllocoutpatter = parameter.get('outpatter')
            maxnumit = 3  # maximum number of iterations for re-picking
        else:
            locflag = 0
            print("                 !!!              ")
            print(
                "!!No location routine available, autoPyLoT is running in non-location mode!!"
            )
            print("!!No source parameter estimation possible!!")
            print("                 !!!              ")

        if not input_dict:
            # started in production mode
            datapath = datastructure.expandDataPath()
            if fnames == 'None' and parameter['eventID'] is '*':
                # multiple event processing
                # read each event in database
                events = [
                    events for events in glob.glob(os.path.join(datapath, '*'))
                    if os.path.isdir(events)
                ]
            elif fnames == 'None' and parameter[
                    'eventID'] is not '*' and not type(
                        parameter['eventID']) == list:
                # single event processing
                events = glob.glob(os.path.join(datapath,
                                                parameter['eventID']))
            elif fnames == 'None' and type(parameter['eventID']) == list:
                # multiple event processing
                events = []
                for eventID in parameter['eventID']:
                    events.append(os.path.join(datapath, eventID))
            else:
                # autoPyLoT was initialized from GUI
                events = []
                events.append(eventid)
                evID = os.path.split(eventid)[-1]
                locflag = 2
        else:
            # started in tune or interactive mode
            datapath = os.path.join(parameter['rootpath'],
                                    parameter['datapath'])
            events = []
            for eventID in eventid:
                events.append(
                    os.path.join(datapath, parameter['database'], eventID))

        if not events:
            print('autoPyLoT: No events given. Return!')
            return

        # transform system path separator to '/'
        for index, eventpath in enumerate(events):
            eventpath = eventpath.replace(SEPARATOR, '/')
            events[index] = eventpath

        allpicks = {}
        glocflag = locflag
        for eventpath in events:
            evID = os.path.split(eventpath)[-1]
            fext = '.xml'
            filename = os.path.join(eventpath, 'PyLoT_' + evID + fext)
            try:
                data = Data(evtdata=filename)
                data.get_evt_data().path = eventpath
                print(
                    'Reading event data from filename {}...'.format(filename))
            except Exception as e:
                print('Could not read event from file {}: {}'.format(
                    filename, e))
                data = Data()
                pylot_event = Event(
                    eventpath)  # event should be path to event directory
                data.setEvtData(pylot_event)
            if fnames == 'None':
                data.setWFData(
                    glob.glob(os.path.join(datapath, eventpath, '*')))
                # the following is necessary because within
                # multiple event processing no event ID is provided
                # in autopylot.in
                try:
                    parameter.get('eventID')
                except:
                    now = datetime.datetime.now()
                    eventID = '%d%02d%02d%02d%02d' % (
                        now.year, now.month, now.day, now.hour, now.minute)
                    parameter.setParam(eventID=eventID)
            else:
                data.setWFData(fnames)

                eventpath = events[0]
                # now = datetime.datetime.now()
                # evID = '%d%02d%02d%02d%02d' % (now.year,
                #                               now.month,
                #                               now.day,
                #                               now.hour,
                #                               now.minute)
                parameter.setParam(eventID=eventid)
            wfdat = data.getWFData()  # all available streams
            if not station == 'all':
                wfdat = wfdat.select(station=station)
                if not wfdat:
                    print('Could not find station {}. STOP!'.format(station))
                    return
            wfdat = remove_underscores(wfdat)
            # trim components for each station to avoid problems with different trace starttimes for one station
            wfdat = check4gaps(wfdat)
            wfdat = check4doubled(wfdat)
            wfdat = trim_station_components(wfdat,
                                            trim_start=True,
                                            trim_end=False)
            metadata = read_metadata(parameter.get('invdir'))
            # rotate stations to ZNE
            wfdat = check4rotated(wfdat, metadata)
            corr_dat = None
            if locflag:
                print("Restitute data ...")
                corr_dat = restitute_data(wfdat.copy(),
                                          *metadata,
                                          ncores=ncores)
            if not corr_dat and locflag:
                locflag = 2
            print('Working on event %s. Stations: %s' % (eventpath, station))
            print(wfdat)
            ##########################################################
            # !automated picking starts here!
            fdwj = None
            if fig_dict_wadatijack:
                fdwj = fig_dict_wadatijack[evID]
            picks = autopickevent(wfdat,
                                  parameter,
                                  iplot=iplot,
                                  fig_dict=fig_dict,
                                  fig_dict_wadatijack=fdwj,
                                  ncores=ncores,
                                  metadata=metadata,
                                  origin=data.get_evt_data().origins)
            ##########################################################
            # locating
            if locflag > 0:
                # write phases to NLLoc-phase file
                nll.export(picks, phasefile, parameter)

                # For locating the event the NLLoc-control file has to be modified!
                nllocout = '%s_%s' % (evID, nllocoutpatter)
                # create comment line for NLLoc-control file
                nll.modify_inputs(ctrf, nllocroot, nllocout, phasef, ttpat)

                # locate the event
                nll.locate(ctrfile, inputfile)

                # !iterative picking if traces remained unpicked or occupied with bad picks!
                # get theoretical onset times for picks with weights >= 4
                # in order to reprocess them using smaller time windows around theoretical onset
                # get stations with bad onsets
                badpicks = []
                for key in picks:
                    if picks[key]['P']['weight'] >= 4 or picks[key]['S'][
                            'weight'] >= 4:
                        badpicks.append([key, picks[key]['P']['mpp']])

                # TODO keep code DRY (Don't Repeat Yourself) the following part is written twice
                # suggestion: delete block and modify the later similar block to work properly

                if len(badpicks) == 0:
                    print(
                        "autoPyLoT: No bad onsets found, thus no iterative picking necessary!"
                    )
                    # get NLLoc-location file
                    locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (
                        nllocroot, nllocout)
                    if len(glob.glob(locsearch)) > 0:
                        # get latest NLLoc-location file if several are available
                        nllocfile = max(glob.glob(locsearch),
                                        key=os.path.getctime)
                        evt = read_events(nllocfile)[0]
                        # calculate seismic moment Mo and moment magnitude Mw
                        moment_mag = MomentMagnitude(corr_dat, evt,
                                                     parameter.get('vp'),
                                                     parameter.get('Qp'),
                                                     parameter.get('rho'),
                                                     True, iplot)
                        # update pick with moment property values (w0, fc, Mo)
                        for stats, props in moment_mag.moment_props.items():
                            picks[stats]['P'].update(props)
                        evt = moment_mag.updated_event()
                        net_mw = moment_mag.net_magnitude()
                        print("Network moment magnitude: %4.1f" % net_mw.mag)
                        # calculate local (Richter) magntiude
                        WAscaling = parameter.get('WAscaling')
                        magscaling = parameter.get('magscaling')
                        local_mag = LocalMagnitude(corr_dat, evt,
                                                   parameter.get('sstop'),
                                                   WAscaling, True, iplot)
                        for stats, amplitude in local_mag.amplitudes.items():
                            picks[stats]['S'][
                                'Ao'] = amplitude.generic_amplitude
                        print("Local station magnitudes scaled with:")
                        print("log(Ao) + %f * log(r) + %f * r + %f" %
                              (WAscaling[0], WAscaling[1], WAscaling[2]))
                        evt = local_mag.updated_event(magscaling)
                        net_ml = local_mag.net_magnitude(magscaling)
                        print("Network local magnitude: %4.1f" % net_ml.mag)
                        print("Network local magnitude scaled with:")
                        print("%f * Ml + %f" % (magscaling[0], magscaling[1]))
                    else:
                        print("autoPyLoT: No NLLoc-location file available!")
                        print("No source parameter estimation possible!")
                        locflag = 9
                else:
                    # get theoretical P-onset times from NLLoc-location file
                    locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (
                        nllocroot, nllocout)
                    if len(glob.glob(locsearch)) > 0:
                        # get latest file if several are available
                        nllocfile = max(glob.glob(locsearch),
                                        key=os.path.getctime)
                        nlloccounter = 0
                        while len(badpicks) > 0 and nlloccounter <= maxnumit:
                            nlloccounter += 1
                            if nlloccounter > maxnumit:
                                print(
                                    "autoPyLoT: Number of maximum iterations reached, stop iterative picking!"
                                )
                                break
                            print(
                                "autoPyLoT: Starting with iteration No. %d ..."
                                % nlloccounter)
                            if input_dict:
                                if 'fig_dict' in input_dict:
                                    fig_dict = input_dict['fig_dict']
                                    picks = iteratepicker(wfdat,
                                                          nllocfile,
                                                          picks,
                                                          badpicks,
                                                          parameter,
                                                          fig_dict=fig_dict)
                            else:
                                picks = iteratepicker(wfdat, nllocfile, picks,
                                                      badpicks, parameter)
                            # write phases to NLLoc-phase file
                            nll.export(picks, phasefile, parameter)
                            # remove actual NLLoc-location file to keep only the last
                            os.remove(nllocfile)
                            # locate the event
                            nll.locate(ctrfile, inputfile)
                            print("autoPyLoT: Iteration No. %d finished." %
                                  nlloccounter)
                            # get updated NLLoc-location file
                            nllocfile = max(glob.glob(locsearch),
                                            key=os.path.getctime)
                            # check for bad picks
                            badpicks = []
                            for key in picks:
                                if picks[key]['P']['weight'] >= 4 or picks[
                                        key]['S']['weight'] >= 4:
                                    badpicks.append(
                                        [key, picks[key]['P']['mpp']])
                            print(
                                "autoPyLoT: After iteration No. %d: %d bad onsets found ..."
                                % (nlloccounter, len(badpicks)))
                            if len(badpicks) == 0:
                                print(
                                    "autoPyLoT: No more bad onsets found, stop iterative picking!"
                                )
                                nlloccounter = maxnumit
                        evt = read_events(nllocfile)[0]
                        if locflag < 2:
                            # calculate seismic moment Mo and moment magnitude Mw
                            moment_mag = MomentMagnitude(
                                corr_dat, evt, parameter.get('vp'),
                                parameter.get('Qp'), parameter.get('rho'),
                                True, iplot)
                            # update pick with moment property values (w0, fc, Mo)
                            for stats, props in moment_mag.moment_props.items(
                            ):
                                if picks.has_key(stats):
                                    picks[stats]['P'].update(props)
                            evt = moment_mag.updated_event()
                            net_mw = moment_mag.net_magnitude()
                            print("Network moment magnitude: %4.1f" %
                                  net_mw.mag)
                            # calculate local (Richter) magntiude
                            WAscaling = parameter.get('WAscaling')
                            magscaling = parameter.get('magscaling')
                            local_mag = LocalMagnitude(corr_dat, evt,
                                                       parameter.get('sstop'),
                                                       WAscaling, True, iplot)
                            for stats, amplitude in local_mag.amplitudes.items(
                            ):
                                if picks.has_key(stats):
                                    picks[stats]['S'][
                                        'Ao'] = amplitude.generic_amplitude
                            print("Local station magnitudes scaled with:")
                            print("log(Ao) + %f * log(r) + %f * r + %f" %
                                  (WAscaling[0], WAscaling[1], WAscaling[2]))
                            evt = local_mag.updated_event(magscaling)
                            net_ml = local_mag.net_magnitude(magscaling)
                            print("Network local magnitude: %4.1f" %
                                  net_ml.mag)
                            print("Network local magnitude scaled with:")
                            print("%f * Ml + %f" %
                                  (magscaling[0], magscaling[1]))
                    else:
                        print(
                            "autoPyLoT: No NLLoc-location file available! Stop iteration!"
                        )
                        locflag = 9
            ##########################################################
            # write phase files for various location
            # and fault mechanism calculation routines
            # ObsPy event object
            if evt is not None:
                event_id = eventpath.split('/')[-1]
                evt.resource_id = ResourceIdentifier('smi:local/' + event_id)
                data.applyEVTData(evt, 'event')
            data.applyEVTData(picks)
            if savexml:
                if savepath == 'None' or savepath == None:
                    saveEvtPath = eventpath
                else:
                    saveEvtPath = savepath
                fnqml = '%s/PyLoT_%s' % (saveEvtPath, evID)
                data.exportEvent(fnqml,
                                 fnext='.xml',
                                 fcheck=['auto', 'magnitude', 'origin'])
            if locflag == 1:
                # HYPO71
                hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (eventpath, evID)
                hypo71.export(picks, hypo71file, parameter)
                # HYPOSAT
                hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (eventpath, evID)
                hyposat.export(picks, hyposatfile, parameter)
                # VELEST
                velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (eventpath,
                                                                evID)
                velest.export(picks, velestfile, evt, parameter)
                # hypoDD
                hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (eventpath,
                                                                evID)
                hypodd.export(picks, hypoddfile, parameter, evt)
                # FOCMEC
                focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (eventpath, evID)
                focmec.export(picks, focmecfile, parameter, evt)
                # HASH
                hashfile = '%s/PyLoT_%s_HASH' % (eventpath, evID)
                hash.export(picks, hashfile, parameter, evt)

            endsplash = '''------------------------------------------\n'
                           -----Finished event %s!-----\n'
                           ------------------------------------------'''.format \
                            (version=_getVersionString()) % evID
            print(endsplash)
            locflag = glocflag
            if locflag == 0:
                print("autoPyLoT was running in non-location mode!")

            # save picks for current event ID to dictionary with ALL picks
            allpicks[evID] = picks

    endsp = '''####################################\n
               ************************************\n
               *********autoPyLoT terminates*******\n
               The Python picking and Location Tool\n
               ************************************'''.format(
        version=_getVersionString())
    print(endsp)
    return allpicks