Beispiel #1
0
def tr2sitechan(tr):
    """Provide a sac header dictionary, get a filled sitechan table instance."""

    #1) from obspy header
    sitechandict = _map_header({'station': 'sta', 'channel': 'chan'}, tr.stats, 
                                OBSPYDEFAULT)

    #2) from sac header
    try:
        sac2sitechan = {'cmpaz': 'hang', 'cmpinc': 'vang', 'stdp': 'edepth'}
        sitechandict.update(_map_header(sac2sitechan, tr.stats.sac, SACDEFAULT))
        try:           
            sitechandict['edepth'] /= 1000.
        except (TypeError, KeyError):
            #edepth is None or missing
            pass
    except (AttributeError, KeyError):
        # no tr.stats.sac
        pass

    if sitechandict:
        sitechan = Sitechan(**sitechandict)
    else:
        sitechan = None

    return sitechan
Beispiel #2
0
def tr2site(tr):
    """
    Provide an ObsPy Trace, get a filled site table instance, using available
    header.
    """
    sitedict = {}

    #1) from obspy header first
    if tr.stats.station:
        sitedict['sta'] = tr.stats.station

    #2) get from sac header
    try:
        sac2site = {'stla': 'lat', 'stlo': 'lon', 'stel': 'elev'}
        sitedict.update(_map_header(sac2site, tr.stats.sac, SACDEFAULT))
        try:            
            sitedict['elev'] /= 1000
        except KeyError:
            #no 'elev' 
            pass
    except (AttributeError, KeyError):
        # tr.stats has no "sac" attribute
        pass

    if sitedict:
        site = Site(**sitedict)
    else:
        site = None

    return site
Beispiel #3
0
def tr2affiliation(tr):
    #1) from obspy header
    affildict = _map_header({'network': 'net', 'station': 'sta'}, tr.stats,
                             OBSPYDEFAULT)

    #2) from sac header
    try:
        sac2affiliation = {'knetwk': 'net', 'kstnm': 'sta'}
        affildict.update(_map_header(sac2affiliation, tr.stats.sac, SACDEFAULT))
    except (AttributeError, KeyError):
        # no tr.stats.sac or 'knetwk', etc.
        pass

    if affildict:
        affil = Affiliation(**affildict)
    else:
        affil = None

    return affil
Beispiel #4
0
def tr2event(tr):
    eventdict = {}
    try:
        eventdict.update(_map_header({'nevid': 'evid', 'kevnm': 'evname'},
                                tr.stats.sac, SACDEFAULT))
    except AttributeError:
        #no tr.stats.sac
        pass

    if eventdict:
        event = Event(**eventdict)
    else:
        event = None

    return event
Beispiel #5
0
def tr2instrument(tr):
    #TODO: investigate hdr['resp0-9'] values
    #1) from sac header
    instrdict = {'samprate': int(tr.stats.sampling_rate)}
    try:
        instrdict = _map_header({'kinst': 'ins', 'iinst': 'instype'}, 
                                tr.stats.sac, SACDEFAULT)
    except AttributeError:
        #no tr.stats.sac
        pass

    if instrdict:
        instr = Instrument(**instrdict)
    else:
        instr = None

    return instr
Beispiel #6
0
def sachdr2reftime(hdr):
    """Get SAC reference UTCDateTime from header dictionary.
    """
    # reftime = nzyear + nzjday + nzhour + nzminute + nzsecond + nzmsec*1000
    tdict = {'year': 1970, 'month': 1, 'day': 1, 'minute': 0, 'microsecond': 0}
    # for non-default values in hdr, return desired values, mapped to new keys
    mapdict = _map_header({'nzyear': 'year', 'nzjday':'julday', 'nzhour':'hour', 
                           'nzmin':'minute', 'nzsec':'second', 
                           'nzmsec':'microsecond'}, hdr, SACDEFAULT)
    tdict.update(mapdict)
    if tdict['microsecond']:
        tdict['microsecond'] *= 1000.
    
    #tdict = {}
    #tdict.update((key, val) for key, val in tmpdict.iteritems() \
    #        if val is not None)

    t0 = UTCDateTime(**tdict)
Beispiel #7
0
def tr2wfdisc(tr):
    """Produce wfdisc kbcore table instance from sac header dictionary.
    Clearly this will be a skeleton instance, as the all-important 'dir' and 
    'dfile' must be filled in later.

    Note: if you read a little-endian SAC file onto a big-endian machine, it
    seems that obspy.sac.sacio.SacIO.swap_byte_order has trouble.

    """
    # from obspy header
    wfdict = {}
    wfdict['nsamp'] = tr.stats.npts
    wfdict['time'] = tr.stats.starttime.timestamp
    wfdict['endtime'] = tr.stats.endtime.timestamp
    wfdict['jdate'] = int(tr.stats.starttime.strftime('%Y%j'))
    wfdict['samprate'] = int(tr.stats.sampling_rate)
    if tr.stats.station:
        wfdict['sta'] = tr.stats.station
    if tr.stats.channel: 
        wfdict['chan'] = tr.stats.channel
    if tr.stats.calib:
        wfdict['calib'] = tr.stats.calib

    #from sac header
    try:
        wfdict.update(_map_header({'nwfid': 'wfid'}, tr.stats.sac, SACDEFAULT))
        wfdict['foff'] = 634
        if sys.byteorder == 'little':
            wfdict['datatype'] = 'f4'
        else:
            wfdict['datatype'] = 't4'
    except AttributeError:
        #no tr.stats.sac
        pass

    return Wfdisc(**wfdict)
Beispiel #8
0
def tr2assoc(tr, pickmap=None):
    """
    Takes a sac header dictionary, and produces a list of up to 10 
    Assoc instances. Header->phase mappings follow SAC2000, i.e.:

    * t0: P
    * t1: Pn
    * t2: Pg
    * t3: S
    * t4: Sn
    * t5: Sg
    * t6: Lg
    * t7: LR
    * t8: Rg
    * t9: pP

    An alternate mapping for some or all picks can be supplied, however, 
    as a dictionary of strings in the above form.  
    
    Note: arid values will not be filled in, so do:
    >>> for assoc in kbio.tables['assoc']:
            assoc.arid = lastarid+1
            lastarid += 1

    """
    pick2phase = {'t0': 'P', 't1': 'Pn', 't2': 'Pg', 't3': 'S',
    't4': 'Sn', 't5': 'Sg', 't6': 'Lg', 't7': 'LR', 't8': 'Rg',
    't9': 'pP'} 

    #overwrite defaults with supplied map
    if pickmap:
        pick2phase.update(pickmap)

    #geographic relations
    # obspy.read tries to calculate these values if lcalca is True and needed
    #header info is there, so we only need to try to if lcalca is False.
    #XXX: I just calculate it if no values are currently filled in.
    assocdict = {}
    try:
        assocdict.update(_map_header({'az': 'esaz', 'baz': 'seaz', 
                                      'gcarc': 'delta'}, tr.stats.sac, 
                                      SACDEFAULT))
    except AttributeError:
        # no tr.stats.sac
        pass

    #overwrite if any are None
    if not assocdict:
        try:
            delta = geod.locations2degrees(tr.stats.sac.stla, tr.stats.sac.stlo, 
                                           tr.stats.sac.evla, tr.stats.sac.evlo)
            m, seaz, esaz = geod.gps2DistAzimuth(tr.stats.sac.stla, 
                tr.stats.sac.stlo, tr.stats.sac.evla, tr.stats.sac.evlo)
            assocdict['esaz'] = esaz
            assocdict['seaz'] = seaz
            assocdict['delta'] = delta
        except (AttributeError, TypeError):
            #some sac header values are None
            pass

    if tr.stats.station:
        assocdict['sta'] = tr.stats.station

    assocdict.update(_map_header({'norid': 'orid'}, tr.stats.sac, SACDEFAULT))

    #now, do the phase arrival mappings
    #for each pick in hdr, make a separate dictionary containing assocdict plus
    #the new phase info.
    assocs = []
    for key in pick2phase:
        kkey = 'k' + key
        #if there's a value in t[0-9]
        if tr.stats.sac[key] != SACDEFAULT[key]:
            #if the phase name kt[0-9] is null
            if tr.stats.sac[kkey] == SACDEFAULT[kkey]:
                #take it from the map
                iassoc = {'phase': pick2phase[key]}
            else:
                #take it directly
                iassoc = {'phase': tr.stats.sac[kkey]}

            iassoc.update(assocdict)
            assocs.append(iassoc)

    return [Assoc(**assoc) for assoc in assocs]
Beispiel #9
0
def tr2origin(tr):
    """
    Provide a sac header dictionary, get a filled origin table instance.
    A few things:
    1) If sac reference time isn't event-based, origin time is unknown
    2) magnitude is taken first from hdr['mag'], hdr['imagtyp'] if defined,
       then replaced by hdr['user0'],hdr['kuser0']
    3) sac moment, duration, and user-defined magnitude headers aren't
       put into the origin table
    4) origin.auth is taken first from hdr['imagsrc'], then replaced by
       hdr['kuser1'] if defined.  the imagsrc->auth translations are:

     * INEIC -> ISC:NEIC
     * IPDE -> PDE
     * IISC -> ISC
     * IBRK -> ISC:BERK
     * IUSGS, ICALTECH, ILLNL, IEVLOC, IJSOP, IUSER, IUNKNOWN -> unchanged 
    
    """
    # simple SAC translations
    sac2origin = {'evla': 'lat', 'evlo': 'lon', 'norid': 'orid', 
                  'nevid': 'evid', 'ievreg': 'grn', 'evdp': 'depth'}
    try:
        origindict = _map_header(sac2origin, tr.stats.sac, SACDEFAULT)
    except AttributeError:
        #no tr.stats.sac
        pass

    #depth
    try:
        origindict['depth'] = tr.stats.sac['evdp']/1000.
    except (TypeError, AttributeError):
        #evdp is None, or no tr.stats.sac
        pass

    #etype translations
    edict = {37: 'en', 38: 'ex', 39: 'ex', 40: 'qt', 41: 'qt', 42: 'qt', 
            43: 'ec', 72: 'me', 73: 'me', 74: 'me', 75: 'me', 76: 'mb',
            77: 'qt', 78: 'qt', 79: 'qt', 80: 'ex', 81: 'ex', 82: 'en',
            83: 'mc'}
    try:
        origindict['etype'] = edict[tr.stats.sac['ievtype']]
    except (AttributeError, KeyError):
        #ievtyp is None, or not a key in edict (e.g. sac default value)
        pass

    #1: 
    try:
        t = get_sac_reftime(tr)
        if tr.stats.sac['iztype'] == 11:
            #reference time is an origin time
            if tr.stats.sac.o is SACDEFAULT['o']:
                o = 0.0
            else:
                o = tr.stats.sac.o
            origindict['time'] = t.timestamp - o
            origindict['jdate'] = int((t-o).strftime('%Y%j'))
    except (AttributeError, KeyError):
        # no trace.stats.sac, no iztype
        pass

    #2: magnitude
    magdict = {52: 'mb', 53: 'ms', 54: 'ml'}
    try:
        origindict[magdict[tr.stats.sac['imagtyp']]] = tr.stats.sac['mag']
    except KeyError:
        #imagtyp is None or not a key in magdict
        pass

    # is kuser0 is a recognized magnitude type, overwrite mag
    #XXX: this is a LANL wfdisc2sac thing
    try:
        magtype = tr.stats.sac['kuser0'].strip()
        if magtype in magdict.values():
            origindict[magtype] = tr.stats.sac['user0']
    except AttributeError:
        #kuser0 is None
        pass

    #3: origin author
    authdict = {58: 'ISC:NEIC', 61: 'PDE', 62: 'ISC', 63: 'REB-ICD', 
            64: 'IUSGS', 65: 'ISC:BERK', 66: 'ICALTECH', 67: 'ILLNL',
            68: 'IEVLOC', 69: 'IJSOP', 70: 'IUSER', 71: 'IUNKNOWN'}
    try:
        origindict['auth'] = authdict[tr.stats.sac['imagsrc']]
    except KeyError:
        # imagsrc not in authdict (i.e. sac default value)
        pass

    #XXX: this is LANL wfdisc2sac thing.  maybe turn it off?
    if tr.stats.sac['kuser1']:
        origindict['auth'] = tr.stats.sac['kuser1']

    if origindict:
        origin = Origin(**origindict)
    else:
        origin = None

    return origin