예제 #1
0
def ReadBMKG(inp=None, phase=True, maglist=False, distkm=False):

    flag_ori = False
    flag_mag = False
    flag_pha = False
    flag_mlst = False

    bmkg_dic = {}

    # if distkm:
    sts_data = os.path.join(os.path.dirname(__file__), 'input',
                            'bmkg_station.dat')
    sts_dic = ReadStation(sts_data)

    i = 0
    ev = 0
    for file in inp:

        with open(file) as f:

            for l in f:

                i += 1

                if 'Origin:' in l and len(l.split()) < 4:
                    ev += 1
                    flag_ori = True
                    continue

                if 'Network magnitudes:' in l and len(l.split()) < 4:
                    flag_mag = True
                    continue

                if phase and 'Phase arrivals:' in l and len(l.split()) < 4:
                    sta = []
                    net = []
                    dis = []
                    azi = []
                    pha = []
                    dtm = []
                    res = []
                    wth = []
                    pha_dic = {}
                    flag_pha = True
                    continue

                if maglist and 'Station magnitudes:' in l and len(
                        l.split()) < 4:
                    sta = []
                    net = []
                    dis = []
                    azi = []
                    typ = []
                    val = []
                    res = []
                    amp = []
                    mag_dic = {}
                    flag_mlst = True
                    continue

                if flag_ori:

                    if flag_ori and not l.strip():
                        flag_ori = False
                        continue

                    if 'Date' in l:
                        tahun, bulan, tanggal = map(
                            int,
                            l.split()[1].split('-')[0:3])
                        continue

                    if 'Time' in l:
                        jam, menit = map(int, l.split()[1].split(':')[0:2])
                        detik = float(l.split()[1].split(':')[2])
                        sec = int(detik)
                        msec = round((detik - sec) * 1e6)

                        if '+/-' in l:
                            err_tim = float(l.split()[3])

                        try:
                            ot = dt(tahun, bulan, tanggal, jam, menit, sec,
                                    msec)
                        except ValueError:
                            print(
                                f'Error encountered on event {ev} data-line {i}\n'
                            )
                        continue

                    if 'Latitude' in l:
                        lintang = float(l.split()[1])
                        if '+/-' in l:
                            err_lat = float(l.split()[4])
                        continue

                    if 'Longitude' in l:
                        bujur = float(l.split()[1])
                        if '+/-' in l:
                            err_lon = float(l.split()[4])
                        continue

                    if 'Depth' in l:
                        depth = float(l.split()[1])
                        if '+/-' in l:
                            err_dep = l.split()[4]
                        else:
                            err_dep = '-0.0'
                        continue

                    if 'manual' in l:
                        mod = l.split()[1]
                    elif 'automatic' in l:
                        mod = l.split()[1]

                    if 'RMS' in l:
                        rms = float(l.split()[2])
                        continue

                    if 'gap' in l:
                        gap = int(l.split()[2])
                        continue

                if flag_mag:

                    if 'preferred' in l:
                        mag = float(l.split()[1])
                        mag_type = l.split()[0]
                        if '+/-' in l:
                            err_mag = l.split()[3]
                        else:
                            err_mag = '-0.0'

                        bmkg_dic[ot] = {
                            'lat': lintang,
                            'lon': bujur,
                            'dep': depth,
                            'mag': mag,
                            'typ': mag_type,
                            'gap': gap,
                            'rms': rms,
                            'mod': mod,
                            'err': {
                                'e_tim': err_tim,
                                'e_lat': err_lat,
                                'e_lon': err_lon,
                                'e_dep': err_dep,
                                'e_mag': err_mag
                            }
                        }

                        flag_mag = False
                        continue

                if flag_pha:

                    if flag_pha and not l.strip():
                        pha_dic[ot] = {
                            'arr': {
                                'sta': sta,
                                'net': net,
                                'dis': dis,
                                'azi': azi,
                                'pha': pha,
                                'del': dtm,
                                'res': res,
                                'wth': wth
                            }
                        }

                        bmkg_dic[ot].update(pha_dic[ot])

                        flag_pha = False
                        continue

                    if '##' not in l and isnumber(
                            l.split()[6]) and 'X' not in l.split()[7]:

                        if distkm:
                            dist, az1, az2 = dist_km(lintang, bujur,
                                                     l.split()[0], sts_dic)
                            if az2 is None:
                                print(
                                    f'Enter station coordinate on {sts_data} to calculate the distance\n'
                                )
                                continue
                        else:
                            dist = float(l.split()[2])

                        jam2, menit = map(int, l.split()[5].split(':')[0:2])
                        detik = float((l.split())[5].split(':')[2])
                        sec = int(detik)
                        msec = round((detik - sec) * 1e6)

                        try:
                            at = dt(tahun, bulan, tanggal, jam2, menit, sec,
                                    msec)
                            if jam2 < jam:
                                at = at + td(days=1)
                            deltatime = float(
                                '%.2f' % (at.timestamp() - ot.timestamp()))
                        except ValueError:
                            print(
                                f'Error encountered on event {ev} data-line {i}\n'
                            )

                        sta.append(l.split()[0])
                        net.append(l.split()[1])
                        dis.append(dist)
                        azi.append(int(l.split()[3]))
                        pha.append(l.split()[4])
                        dtm.append(deltatime)
                        res.append(float(l.split()[6]))
                        wth.append(l.split()[8])

                if flag_mlst:

                    if flag_mlst and not l.strip():
                        mag_dic[ot] = {
                            'mls': {
                                'sta': sta,
                                'net': net,
                                'dis': dis,
                                'azi': azi,
                                'typ': typ,
                                'val': val,
                                'res': res,
                                'amp': amp
                            }
                        }

                        bmkg_dic[ot].update(mag_dic[ot])

                        flag_mlst = False
                        continue

                    if isnumber(l.split()[2]) and isnumber(l.split()[3]) and isnumber(l.split()[5]) and \
                            isnumber(l.split()[6]) and isnumber(l.split()[7]):

                        if distkm:
                            dist, az1, az2 = dist_km(lintang, bujur,
                                                     l.split()[0], sts_dic)
                            if az2 is None:
                                print(
                                    f'Enter station coordinate on {sts_data} to calculate the distance\n'
                                )
                                continue
                        else:
                            dist = float(l.split()[2])

                        sta.append(l.split()[0])
                        net.append(l.split()[1])
                        dis.append(dist)
                        azi.append(int(l.split()[3]))
                        typ.append(l.split()[4])
                        val.append(float(l.split()[5]))
                        res.append(float(l.split()[6]))
                        amp.append(l.split()[7])

    return bmkg_dic
예제 #2
0
def ReadNLLoc(fileinput='data.hyp', mag_cat='nlloc_mag.dat'):
    """
    :param fileinput: nlloc locsum.hyp file
    :param mag_cat: catalog magnitudo from bmkg2nlloc output (take magnitudo value from bmkg catalog
    if not calculate magnitudo directly on nlloc
    """

    dsec = 40
    nloc_event = 0

    # Crosscheck nlloc event and bmkg magnitudo catalog to detect eliminated event
    file = open(fileinput, 'r')
    baris = file.readlines()
    file.close()
    for i in range(len(baris)):
        baris[i] = baris[i].split()
        if len(baris[i]) > 0 and baris[i][0] == 'GEOGRAPHIC':
            nloc_event += 1
    cat = open(mag_cat, 'r')
    event = cat.readlines()
    for i in range(len(event)):
        event[i] = event[i].split()
    cat.close()
    n_elim_cat = len(event) - nloc_event

    flag_evt = False
    flag_pha = False
    flag_wrt = False

    nlloc_dic = {}
    i = 0
    ev = 0
    elim_cat = 0
    elim_event = []

    with open(fileinput, "r", -1) as f:

        for l in f:

            i += 1

            if 'Location completed.' in l:
                ev += 1
                flag_evt = True
                flag_wrt = False
                continue

            if flag_evt:

                if 'SEARCH' in l:
                    mod = l.split()[1]
                    continue

                if 'GEOGRAPHIC' in l:
                    tahun, bulan, tanggal, jam, menit = map(
                        int,
                        l.split()[2:7])
                    detik = float(l.split()[7])
                    sec = int(detik)
                    msec = round((detik - sec) * 1e6)

                    try:
                        ot = dt(tahun, bulan, tanggal, jam, menit, sec, msec)
                    except ValueError:
                        print(
                            f'Error encountered on event {ev} data-line {i}\n')

                    lintang, bujur, depth = map(float, l.split()[9:14:2])

                    mag = 'NaN'
                    mag_type = 'Unk'
                    err_mag = 'NaN'
                    for j in range(n_elim_cat - elim_cat + 1):
                        if ev + j + elim_cat == int(event[ev - 1 + j + elim_cat][0]) and \
                                round(ot.timestamp()) in range(round(float(event[ev - 1 + j + elim_cat][1])) - dsec,
                                                               round(float(event[ev - 1 + j + elim_cat][1])) + dsec):
                            mag = float('%.2f' %
                                        float(event[ev - 1 + j + elim_cat][2]))
                            mag_type = event[ev - 1 + j + elim_cat][3]
                            err_mag = event[ev - 1 + j + elim_cat][4]
                            elim_cat += j
                            break
                        else:
                            elim_event.append(ev + j + elim_cat)
                            print(
                                f'Eliminated, event no. {ev + j + elim_cat} on BMKG catalog'
                            )
                    if mag == 'NaN':
                        print(
                            f'Event {ev} magnitude not found on catalog. '
                            f'Check OT time deviation or number of eliminated catalog!'
                        )

                if 'QUALITY' in l:
                    rms = float(l.split()[8])
                    gap = float(l.split()[12])
                    continue

                if 'STATISTICS' in l:
                    err_lon = mt.sqrt(float(l.split()[8]))
                    err_lat = mt.sqrt(float(l.split()[14]))
                    err_v = mt.sqrt(float(l.split()[18]))
                    continue

                if 'STAT_GEOG' in l:
                    lat_gau, lon_gau, dep_gau = map(float, l.split()[2:7:2])
                    continue

                if 'QML_OriginQuality' in l:
                    # pha_count = int(l.split()[4])
                    err_time = float(l.split()[12])
                    continue

                if 'PHASE ID' in l:  # unused phased included
                    arr_sta = []
                    arr_pha = []
                    arr_dis = []
                    arr_azi = []
                    arr_del = []
                    arr_res = []
                    arr_wth = []
                    flag_pha = True
                    continue
                if flag_pha and 'END_PHASE' in l:
                    flag_pha = False
                    flag_evt = False
                    flag_wrt = True
                    continue
                if flag_pha and 'PHASE' not in l:
                    try:
                        jam_arr = int(l.split()[7][0:2])
                        menit_arr = int(l.split()[7][2:4])
                        detik_arr = float(l.split()[8])
                        sec = int(detik_arr)
                        msec = round((detik_arr - sec) * 1e6)
                        try:
                            at = dt(tahun, bulan, tanggal, jam_arr, menit_arr,
                                    sec, msec)
                            if at < ot:
                                at = at + td(days=1)
                            deltatime = float(
                                '%.4f' % (at.timestamp() - ot.timestamp()))
                        except ValueError:
                            print(
                                f'Error encountered on event {ev} data-line {i}\n'
                            )

                        res = l.split()[17]
                        dis = l.split()[22]
                        azi = l.split()[23]
                        if not isnumber(dis) or not isnumber(
                                azi) or not isnumber(res):
                            print(f'Potential data error line {i}')

                        arr_sta.append(l.split()[0])
                        arr_pha.append(l.split()[4])
                        arr_dis.append(float(dis))
                        arr_azi.append(int(float(azi)))
                        arr_del.append(deltatime)
                        arr_res.append(float(res))
                        arr_wth.append(l.split()[18])
                    except:
                        print(f'Potential data error line {i}')

            if flag_wrt:
                nlloc_dic[ot] = {
                    'lat': lintang,
                    'lon': bujur,
                    'dep': depth,
                    'lat_gau': lat_gau,
                    'lon_gau': lon_gau,
                    'dep_gau': dep_gau,
                    'mag': mag,
                    'typ': mag_type,
                    'gap': gap,
                    'rms': rms,
                    'mod': mod,
                    'err': {
                        'e_tim': err_time,
                        'e_lat': err_lat,
                        'e_lon': err_lon,
                        'e_dep': err_v,
                        'e_mag': err_mag
                    },
                    'arr': {
                        'sta': arr_sta,
                        # 'net': [],
                        'dis': arr_dis,
                        'azi': arr_azi,
                        'pha': arr_pha,
                        'del': arr_del,
                        'res': arr_res,
                        'wth': arr_wth
                    }
                }
                flag_wrt = False

    print(f'Eliminated events on BMKG catalog {elim_event}')
    return nlloc_dic, ids, elim_event
예제 #3
0
def WriteNLLoc(inp,
               area,
               out_nlloc='phase.obs',
               out_mag='nlloc_mag.dat',
               out_arr='arrival.dat',
               out_cat='catalog.dat',
               out_geom='sts_geometry.dat',
               out_log='log.txt',
               elim_event=None):

    sts_data = os.path.join(os.path.dirname(__file__), 'input',
                            'bmkg_station.dat')
    sts_dic = ReadStation(sts_data)

    nlloc = open(out_nlloc, 'w')
    nll_mag = open(out_mag, 'w')

    cat = open(out_cat, 'w')
    cat.write(
        'ev_num  Y   M  D    h:m:s       lon       lat     dep  mag    time_val           " time_str "        '
        '+/-   ot   lon   lat   dep   mag  mtype   rms   gap  nearsta mode   phnum\n'
    )

    arr = open(out_arr, 'w')
    arr.write(
        'ev_num pha      tp       ts      ts-p  res_p res_s  depth  mag    dis\n'
    )

    sts_gmtry = open(out_geom, 'w')
    sts_gmtry.write('ev_num sts    dist    azi1    azi2\n')

    # List var
    _err_pha = ''
    res_P: float = 0
    res_S: float = 0
    tS: float = 0
    tP: float = 0
    bobot = '0'
    maxdep = 0
    maxgap = 0
    maxrms = 0
    minpha = 100
    maxpha = 0
    minS = 100
    maxS = 0

    event = 0
    err_num = 0

    for evt in sorted(inp):
        d = inp[evt]
        lat = d['lat']
        lon = d['lon']
        depth = d['dep']

        event += 1
        time_sec = evt.timestamp()
        nll_mag.write(
            f"{event:<6} {time_sec} {d['mag']:4.2f} {d['typ']:6} {float(d['err']['e_mag']):5.2f} {evt}\n"
        )
        mag = d['mag']
        rms = d['rms']
        gap = d['gap']

        _catalog = cat_format(d, evt, sts_data, sts_dic)

        num_p = 0
        num_s = 0
        sta_P = 'P'
        sta_S = 'S'
        _arr = ''
        _NLLocPha = ''

        p = inp[evt]['arr']
        for i in range(len(p['sta'])):
            # if len(p['sta'][i]) > 4:
            #     idSta = p['sta'][i][:4]
            # else:
            idSta = p['sta'][i]

            if idSta == 'BANI':
                idSta = 'BNDI'

            phase = p['pha'][i]
            deltatime = p['del'][i]
            if deltatime < 0 or deltatime > 200:
                _err_pha += f' phase {phase} stasiun {idSta} event no. {event}\n'
                err_num += 1
            if deltatime > 1000:
                print(f'\nThere is ilogical phase on event {event}')
            res = p['res'][i]
            phase = phase[:1]

            dis, az1, az2 = dist_km(lat, lon, p['sta'][i], sts_dic)
            if az2 is None:
                print(
                    f'Enter station coordinate on {sts_data} to calculate the distance\n'
                )
                continue

            if phase == 'P':

                # Write geometry data to files (filter sts)
                if isnumber(az1):
                    sts_gmtry.write(
                        f'{event:<6} {idSta:4} {dis:8.3f} {az1:7.3f} {az2:7.3f}\n'
                    )

                sta_P = idSta
                res_P = res
                tP = deltatime
                num_p += 1

                arr_p = evt + td(seconds=tP)
                if num_p == 1:
                    _NLLocPha += f"{idSta.ljust(4)} {phase} {bobot} {str(arr_p.year)[2:]}{arr_p.month:02d}" \
                                 f"{arr_p.day:02d}{arr_p.hour:02d}{arr_p.minute:02d}" \
                                 f"{arr_p.second + np.round(arr_p.microsecond / 1e6, decimals=2):05.2f}"
                else:
                    _NLLocPha += f"\n{idSta.ljust(4)} {phase} {bobot} {str(arr_p.year)[2:]}{arr_p.month:02d}" \
                                 f"{arr_p.day:02d}{arr_p.hour:02d}{arr_p.minute:02d}" \
                                 f"{arr_p.second + np.round(arr_p.microsecond / 1e6, decimals=2):05.2f}"

            if phase == 'S':
                sta_S = idSta
                res_S = res
                tS = deltatime
                num_s = num_s + 1

            if sta_S == sta_P:
                arr_s = evt + td(seconds=tS)
                tSP = arr_s.timestamp() - arr_p.timestamp()
                _NLLocPha += f"       {np.round(arr_p.second + arr_p.microsecond / 1e6 + tSP, decimals=2):05.2f} " \
                             f"{phase} 1"

                _arr += (
                    f'{event:<6} {idSta:4} {tP:8.3f} {tS:8.3f} {tSP:8.3f} {float(res_P):5.2f} '
                    f'{float(res_S):5.2f} {depth:6.2f} {mag:.2f} {dis:8.3f}\n')

        _NLLocPha += '\n\n'
        P_pha = num_p
        S_pha = num_s
        cat.write(f"{event:<6} {_catalog} {len(p['sta']):3}\n")
        nlloc.write(_NLLocPha)

        if P_pha == 1:
            print(event)
        if P_pha < minpha:
            minpha = P_pha
        if P_pha > maxpha:
            maxpha = P_pha
        if S_pha < minS:
            minS = S_pha
        if S_pha > maxS:
            maxS = S_pha
        if S_pha > 0:
            arr.write(_arr)
        if depth > maxdep:
            maxdep = depth
        if rms > maxrms:
            maxrms = rms
        if gap > maxgap:
            maxgap = gap

    nlloc.close()
    nll_mag.close()
    cat.close()
    arr.close()
    sts_gmtry.close()

    par_dic = {
        'ev_num': event,
        'area': area,
        'max_dep': maxdep,
        'max_rms': maxrms,
        'max_gap': maxgap,
        'min_p': minpha,
        'max_p': maxpha,
        'min_s': minS,
        'max_s': maxS,
        'phase': {
            'err_num': err_num,
            'err_pha': _err_pha,
        },
        'err_sta': [],
        'elim_ev': elim_event
    }

    Log(inp=par_dic, out=out_nlloc, log=out_log)
예제 #4
0
def WriteHypoDD(inp,
                area,
                out='phase.dat',
                out_arr='arrival.dat',
                out_cat='catalog.dat',
                out_geom='sts_geometry.dat',
                out_log='log.txt',
                elim_event=None):
    """
    :param inp: dictionary data (q_format)
    :param area: dictionary area parameter from filter dictionary
    :param out: output hypodd phase file
    :param out_arr: output file for arrival data (q_format) input for q_plot
    :param out_cat: output file for extended catalog data (q_format) input for q_plot
    :param out_geom: output file for geometry station (distance & azimuth) (q_format) input for q_plot
    :param out_log: output log file
    :param elim_event: list of eliminated event (check with catalog BMKG output bmkg2nlloc)
    """

    sts_data = os.path.join(os.path.dirname(__file__), 'input',
                            'bmkg_station.dat')
    sts_dic = ReadStation(sts_data)

    pha = open(out, 'w')

    cat = open(out_cat, 'w')
    cat.write(
        'ev_num  Y   M  D    h:m:s       lon       lat     dep  mag    time_val           " time_str "        '
        '+/-   ot   lon   lat   dep   mag  mtype   rms   gap  nearsta mode   phnum\n'
    )

    arr = open(out_arr, 'w')
    arr.write(
        'ev_num pha      tp       ts      ts-p  res_p res_s  depth  mag    dis\n'
    )

    sts_gmtry = open(out_geom, 'w')
    sts_gmtry.write('ev_num sts    dist    azi1    azi2\n')

    # List var
    _err_pha = ''
    res_P: float = 0
    res_S: float = 0
    tS: float = 0
    tP: float = 0
    bobot = '0'
    maxdep = 0
    maxgap = 0
    maxrms = 0
    minpha = 100
    maxpha = 0
    minS = 100
    maxS = 0

    event = 0
    err_num = 0

    for evt in sorted(inp):
        d = inp[evt]
        lat = d['lat']
        lon = d['lon']
        depth = d['dep']
        mag = d['mag']
        rms = d['rms']
        gap = d['gap']

        event += 1

        err_tim, err_lon, err_lat, err_dep, err_mag = error_dic(d)

        err_hz = mt.sqrt(err_lat**2 + err_lon**2)

        _parameters = (
            f"# {str(evt.year):4} {int(evt.month):2} {int(evt.day):2} "
            f"{int(evt.hour):2} {int(evt.minute):2} {(evt.second + evt.microsecond * 1e-6):5.2f} "
            f"{lat:6.2f}   {lon:7.2f}   {depth:6.1f} {mag:4.1f} "
            f"{float(err_hz):5.2f} {float(err_dep):5.2f} {rms:7.3f}")

        _catalog = cat_format(d, evt, sts_data, sts_dic)

        num_p = 0
        num_s = 0
        sta_P = 'P'
        sta_S = 'S'
        _arr = ''
        _pha = ''

        p = inp[evt]['arr']
        for i in range(len(p['sta'])):

            idSta = p['sta'][i]

            if idSta == 'BANI':
                idSta = 'BNDI'

            phase = p['pha'][i]
            deltatime = p['del'][i]
            if deltatime < 0 or deltatime > 200:
                _err_pha += f' phase {phase} stasiun {idSta} event no. {event}\n'
                err_num += 1
            if deltatime > 1000:
                print(f'\nThere is ilogical phase on event {event}')
            res = p['res'][i]
            phase = phase[:1]

            dis, az1, az2 = dist_km(lat, lon, p['sta'][i], sts_dic)
            if az2 is None:
                print(
                    f'Enter station coordinate on {sts_data} to calculate the distance\n'
                )
                continue

            if phase == 'P':

                # Write geometry data to files (filter sts)
                if isnumber(az1):
                    sts_gmtry.write(
                        f'{event:<6} {idSta:4} {dis:8.3f} {az1:7.3f} {az2:7.3f}\n'
                    )

                sta_P = idSta
                res_P = res
                tP = deltatime
                num_p += 1

                arr_p = evt + td(seconds=tP)
                _pha += f"{idSta.rjust(5)}    {deltatime:8.2f}   {float(bobot):5.3f}   {phase}\n"

            if phase == 'S':
                sta_S = idSta
                res_S = res
                tS = deltatime
                num_s = num_s + 1
                _pha += f"{idSta.rjust(5)}    {deltatime:8.2f}   {float(bobot):5.3f}   {phase}\n"

            if sta_S == sta_P:
                arr_s = evt + td(seconds=tS)
                tSP = arr_s.timestamp() - arr_p.timestamp()
                _arr += (
                    f'{event:<6} {idSta:4} {tP:8.3f} {tS:8.3f} {tSP:8.3f} {float(res_P):5.2f} '
                    f'{float(res_S):5.2f} {depth:6.2f} {mag:.2f} {dis:8.3f}\n')

        P_pha = num_p
        S_pha = num_s
        pha.write(f"{_parameters}    {event:6}\n{_pha}")
        cat.write(f"{event:<6} {_catalog} {len(p['sta']):3}\n")

        if P_pha == 1:
            print(event)
        if P_pha < minpha:
            minpha = P_pha
        if P_pha > maxpha:
            maxpha = P_pha
        if S_pha < minS:
            minS = S_pha
        if S_pha > maxS:
            maxS = S_pha
        if S_pha > 0:
            arr.write(_arr)
        if depth > maxdep:
            maxdep = depth
        if rms > maxrms:
            maxrms = rms
        if gap > maxgap:
            maxgap = gap

    pha.close()
    cat.close()
    arr.close()
    sts_gmtry.close()

    par_dic = {
        'ev_num': event,
        'area': area,
        'max_dep': maxdep,
        'max_rms': maxrms,
        'max_gap': maxgap,
        'min_p': minpha,
        'max_p': maxpha,
        'min_s': minS,
        'max_s': maxS,
        'phase': {
            'err_num': err_num,
            'err_pha': _err_pha,
        },
        'err_sta': [],
        'elim_ev': elim_event
    }

    Log(inp=par_dic, out=out, log=out_log)