Example #1
0
def readgeonet(geonetfile):
    """
    Read strong motion data from a GeoNet data file
    @param geonetfile: Path to a valid GeoNet data file.
    @return: List of ObsPy Trace objects, containing accelerometer data in m/s.
    """
    f = open(geonetfile, 'rt')
    tracelist = []
    headerlist = []
    try:
        hdrlines = readheaderlines(f)
    except:
        pass
    while len(hdrlines[-1]):
        hdrdict = readheader(hdrlines)
        numlines = int(np.ceil(hdrdict['npts'] / 10.0))
        data = []
        for i in range(0, numlines):
            line = f.readline()
            parts = line.strip().split()
            mdata = [float(p) for p in parts]
            data = data + mdata
        data = np.array(data)
        header = hdrdict.copy()
        stats = Stats(hdrdict)
        trace = Trace(data, header=stats)
        #apply the calibration and convert from mm/s^2 to m/s^2
        trace.data = trace.data * trace.stats[
            'calib'] * 0.001  #convert to m/s^2
        tracelist.append(trace.copy())
        headerlist.append(header.copy())
        hdrlines = readheaderlines(f)

    f.close()
    return (tracelist, headerlist)
Example #2
0
def readgeonet(geonetfile):
    """
    Read strong motion data from a GeoNet data file
    @param geonetfile: Path to a valid GeoNet data file.
    @return: List of ObsPy Trace objects, containing accelerometer data in m/s.
    """
    f = open(geonetfile,'rt')
    tracelist = []
    headerlist = []
    try:
        hdrlines = readheaderlines(f)
    except:
        pass
    while len(hdrlines[-1]):
        hdrdict = readheader(hdrlines)
        numlines = int(np.ceil(hdrdict['npts']/10.0))
        data = []
        for i in range(0,numlines):
            line = f.readline()
            parts = line.strip().split()
            mdata = [float(p) for p in parts]
            data = data + mdata
        data = np.array(data)
        header = hdrdict.copy()
        stats = Stats(hdrdict)
        trace = Trace(data,header=stats)
        #apply the calibration and convert from mm/s^2 to m/s^2
        trace.data = trace.data * trace.stats['calib'] * 0.001 #convert to m/s^2
        tracelist.append(trace.copy())
        headerlist.append(header.copy())
        hdrlines = readheaderlines(f)

    f.close()
    return (tracelist,headerlist)
Example #3
0
def readiran(iranfile, doRotation=True):
    """
    Read strong motion data from a Iran data file
    @param iranfile: Path to a valid Iran data file.
    @keyword doRotation: Apply back-azimuth rotation of L & T channels to NS and EW.
    @return: List of ObsPy Trace objects, containing accelerometer data in m/s.
    """
    f = open(iranfile, 'rt')
    tracelist = []
    headerlist = []
    try:
        hdrlines = readheaderlines(f)
    except:
        pass
    while len(hdrlines[-1]):
        hdrdict = readheader(hdrlines)
        numlines = int(np.ceil(hdrdict['npts'] / 10.0))
        data = []
        for i in range(0, numlines):
            line = f.readline()
            parts = line.strip().split()
            mdata = [float(p) for p in parts]
            data = data + mdata
        data = np.array(data)
        header = hdrdict.copy()
        stats = Stats(hdrdict)
        trace = Trace(data, header=stats)
        #apply the calibration and convert from mm/s^2 to m/s^2
        trace.data = trace.data * trace.stats[
            'calib'] * 0.98  #convert to m/s^2 from g/10
        tracelist.append(trace.copy())
        headerlist.append(header.copy())
        endblock = f.readline()
        hdrlines = readheaderlines(f)

    f.close()

    #data from Iran may be rotated so that one channel is aligned in the direction between the earthquake
    #epicenter and the station.  We want to rotate the data back so that we have what are presumably the
    #original NS and EW channels.  We presume that the "L" channel will rotate back to become NS, and
    #"T" will become EW.
    #First, find the channel called L*
    if doRotation:
        channels = [h['channel'][0:1] for h in headerlist]
        lidx = channels.index('L')
        tidx = channels.index('T')
        ldata = tracelist[lidx].data
        tdata = tracelist[tidx].data
        backaz = headerlist[0]['rotation']['L']
        ndata, edata = rotate.rotate_RT_NE(ldata, tdata, backaz)
        tracelist[lidx].data = ndata.copy()
        tracelist[lidx].stats[
            'channel'] = 'H1'  #most probably NS, but we're being cautious
        tracelist[tidx].data = edata.copy()
        tracelist[tidx].stats[
            'channel'] = 'H2'  #most probably EW, but we're being cautious

    return (tracelist, headerlist)
Example #4
0
def readiran(iranfile,doRotation=True):
    """
    Read strong motion data from a Iran data file
    @param iranfile: Path to a valid Iran data file.
    @keyword doRotation: Apply back-azimuth rotation of L & T channels to NS and EW.
    @return: List of ObsPy Trace objects, containing accelerometer data in m/s.
    """
    f = open(iranfile,'rt')
    tracelist = []
    headerlist = []
    try:
        hdrlines = readheaderlines(f)
    except:
        pass
    while len(hdrlines[-1]):
        hdrdict = readheader(hdrlines)
        numlines = int(np.ceil(hdrdict['npts']/10.0))
        data = []
        for i in range(0,numlines):
            line = f.readline()
            parts = line.strip().split()
            mdata = [float(p) for p in parts]
            data = data + mdata
        data = np.array(data)
        header = hdrdict.copy()
        stats = Stats(hdrdict)
        trace = Trace(data,header=stats)
        #apply the calibration and convert from mm/s^2 to m/s^2
        trace.data = trace.data * trace.stats['calib'] * 0.98 #convert to m/s^2 from g/10
        tracelist.append(trace.copy())
        headerlist.append(header.copy())
        endblock = f.readline()
        hdrlines = readheaderlines(f)

    f.close()
    
    #data from Iran may be rotated so that one channel is aligned in the direction between the earthquake
    #epicenter and the station.  We want to rotate the data back so that we have what are presumably the 
    #original NS and EW channels.  We presume that the "L" channel will rotate back to become NS, and
    #"T" will become EW.
    #First, find the channel called L*
    if doRotation:
        channels = [h['channel'][0:1] for h in headerlist]
        lidx = channels.index('L')
        tidx = channels.index('T')
        ldata = tracelist[lidx].data
        tdata = tracelist[tidx].data
        backaz = headerlist[0]['rotation']['L']
        ndata,edata = rotate.rotate_RT_NE(ldata,tdata,backaz)
        tracelist[lidx].data = ndata.copy()
        tracelist[lidx].stats['channel'] = 'H1' #most probably NS, but we're being cautious
        tracelist[tidx].data = edata.copy()
        tracelist[tidx].stats['channel'] = 'H2' #most probably EW, but we're being cautious
    
    return (tracelist,headerlist)
Example #5
0
def getCatData(date, opt):

    """
    Download data from IRIS or Earthworm waveserver with padding and filter it. This is
    a specialized version getData() for catalog events, pulling a smaller amount of time
    around a known event.

    date: UTCDateTime of known catalog event
    opt: Options object describing station/run parameters
    
    Returns ObsPy stream objects, one for cutting and the other for triggering
    """    
    
    nets = opt.network.split(',')
    stas = opt.station.split(',')
    locs = opt.location.split(',')
    chas = opt.channel.split(',')
    
    if opt.server == "IRIS":
        client = Client("IRIS")
    else:
        client = EWClient(opt.server, opt.port)
        
    st = Stream()
    for n in range(len(stas)):
        try:
            stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                    date - opt.atrig, date + 3*opt.atrig)
            stmp = stmp.filter("bandpass", freqmin=opt.fmin, freqmax=opt.fmax,
                corners=2, zerophase=True)
            stmp = stmp.merge(method=1, fill_value='interpolate')
        except (obspy.fdsn.header.FDSNException):
            try: # try again
                stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                        date - opt.atrig, date + 3*opt.atrig)
                stmp = stmp.filter("bandpass", freqmin=opt.fmin, freqmax=opt.fmax,
                    corners=2, zerophase=True)
                stmp = stmp.merge(method=1, fill_value='interpolate')
            except (obspy.fdsn.header.FDSNException):
                print('No data found for {0}.{1}'.format(stas[n],nets[n]))
                trtmp = Trace()
                trtmp.stats.sampling_rate = opt.samprate
                trtmp.stats.station = stas[n]
                stmp = Stream().extend([trtmp.copy()])
        # Resample to ensure all traces are same length
        if stmp[0].stats.sampling_rate != opt.samprate:
            stmp = stmp.resample(opt.samprate)
        st.extend(stmp.copy()) 
    
    st = st.trim(starttime=date-opt.atrig, endtime=date+3*opt.atrig, pad=True,
        fill_value=0)
    stC = st.copy() 

    return st, stC
Example #6
0
def readgeonet(geonetfile):
    """
    Read strong motion data from a GeoNet data file
    @param geonetfile: Path to a valid GeoNet data file.
    @return: List of ObsPy Trace objects, containing accelerometer data in m/s.
    """
    #notes on implementation:
    # originally I had written code to read each line of data manually, just
    # as I was reading the header lines.  However, this became VERY slow for large
    # files.  I discovered that numpy's genfromtxt function was much faster.  However,
    # I could not get that function to work when I passed it a file object instead of a file name.
    # Consequently, the only way I could keep the genfromtxt() method and file pointer in sync was
    # to read and discard all of the lines of data that genfromtxt() parsed.  While annoying, the combination
    # of these two seems to still be at least an order of magnitude faster than manually reading the file.
    
    f = open(geonetfile,'rt')
    tracelist = []
    headerlist = []
    totlines = 0
    hdrlines = readheaderlines(f)
    while len(hdrlines[-1]):
        totlines += len(hdrlines)
        hdrdict = readheader(hdrlines)
        numlines = int(np.ceil(hdrdict['npts']/10.0))
        data = np.genfromtxt(geonetfile,skip_header=totlines,max_rows=numlines)
        totlines += numlines
        #now we need to set the file position to where we just ended
        for i in range(0,numlines):
            f.readline()
        data = data.flatten()
        header = hdrdict.copy()
        stats = Stats(hdrdict)
        trace = Trace(data,header=stats)
        #apply the calibration and convert from mm/s^2 to m/s^2
        trace.data = trace.data * trace.stats['calib'] * 0.001 #convert to m/s^2
        tracelist.append(trace.copy())
        headerlist.append(header.copy())
        hdrlines = readheaderlines(f)

    f.close()
    return (tracelist,headerlist)
Example #7
0
def getData(tstart, tend, opt):

    """
    Download data from files in a folder, from IRIS, or a Earthworm waveserver
    
    A note on SAC/miniSEED files: as this makes no assumptions about the naming scheme of
    your data files, please ensure that your headers contain the correct SCNL information!

    tstart: UTCDateTime of beginning of period of interest
    tend: UTCDateTime of end of period of interest
    opt: Options object describing station/run parameters
    
    Returns ObsPy stream objects, one for cutting and the other for triggering
    """    
    
    nets = opt.network.split(',')
    stas = opt.station.split(',')
    locs = opt.location.split(',')
    chas = opt.channel.split(',')
    
    st = Stream()
    
    if opt.server == 'file':
    
        # Generate list of files
        if opt.server == 'file':
            flist = list(itertools.chain.from_iterable(glob.iglob(os.path.join(
                root,opt.filepattern)) for root, dirs, files in os.walk(opt.searchdir)))
                
        # Determine which subset of files to load based on start and end times and
        # station name; we'll fully deal with stations below
        flist_sub = []
        for f in flist:
            # Load header only
            stmp = obspy.read(f, headonly=True)
            # Check if station is contained in the stas list
            if stmp[0].stats.station in stas:
                # Check if contains either start or end time
                ststart = stmp[0].stats.starttime
                stend = stmp[-1].stats.endtime
                if (ststart<=tstart and tstart<=stend) or (ststart<=tend and
                    tend<=stend) or (tstart<=stend and ststart<=tend):
                    flist_sub.append(f)
        
        # Fully load data from file
        stmp = Stream()
        for f in flist_sub:
            tmp = obspy.read(f, starttime=tstart, endtime=tend+opt.maxdt)
            if len(tmp) > 0:
                stmp = stmp.extend(tmp)
    
        # Filter and merge
        stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax, corners=2,
            zerophase=True)
        stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
        for m in range(len(stmp)):
            if stmp[m].stats.sampling_rate != opt.samprate:
                stmp[m] = stmp[m].resample(opt.samprate)
        stmp = stmp.merge(method=1, fill_value=0)
        
        # Only grab stations/channels that we want and in order
        netlist = []
        stalist = []
        chalist = []
        loclist = []
        for s in stmp:
            stalist.append(s.stats.station)
            chalist.append(s.stats.channel)
            netlist.append(s.stats.network)
            loclist.append(s.stats.location)
            
        # Find match of SCNL in header or fill empty
        for n in range(len(stas)):
            for m in range(len(stalist)):
                if (stas[n] in stalist[m] and chas[n] in chalist[m] and nets[n] in
                    netlist[m] and locs[n] in loclist[m]):
                    st = st.append(stmp[m])
            if len(st) == n:
                print("Couldn't find "+stas[n]+'.'+chas[n]+'.'+nets[n]+'.'+locs[n])
                trtmp = Trace()
                trtmp.stats.sampling_rate = opt.samprate
                trtmp.stats.station = stas[n]
                st = st.append(trtmp.copy())
    
    else:   
     
        if '.' not in opt.server:
            client = Client(opt.server)
        else:
            client = EWClient(opt.server, opt.port)
        
        for n in range(len(stas)):
            try:
                stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                        tstart, tend+opt.maxdt)
                for m in range(len(stmp)):
                    stmp[m].data = np.where(stmp[m].data == -2**31, 0, stmp[m].data) # replace -2**31 (Winston NaN token) w 0
                stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax,
                    corners=2, zerophase=True)
                stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
                for m in range(len(stmp)):
                    if stmp[m].stats.sampling_rate != opt.samprate:
                        stmp[m] = stmp[m].resample(opt.samprate)
                stmp = stmp.merge(method=1, fill_value=0)
            except (obspy.clients.fdsn.header.FDSNException):
                try: # try again
                    stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                            tstart, tend+opt.maxdt)
                    for m in range(len(stmp)):
                        stmp[m].data = np.where(stmp[m].data == -2**31, 0, stmp[m].data) # replace -2**31 (Winston NaN token) w 0
                    stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax,
                        corners=2, zerophase=True)
                    stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
                    for m in range(len(stmp)):
                        if stmp[m].stats.sampling_rate != opt.samprate:
                            stmp[m] = stmp[m].resample(opt.samprate)
                    stmp = stmp.merge(method=1, fill_value=0)
                except (obspy.clients.fdsn.header.FDSNException):
                    print('No data found for {0}.{1}'.format(stas[n],nets[n]))
                    trtmp = Trace()
                    trtmp.stats.sampling_rate = opt.samprate
                    trtmp.stats.station = stas[n]
                    stmp = Stream().extend([trtmp.copy()])
                                            
            # Last check for length; catches problem with empty waveserver
            if len(stmp) != 1:
                print('No data found for {0}.{1}'.format(stas[n],nets[n]))
                trtmp = Trace()
                trtmp.stats.sampling_rate = opt.samprate
                trtmp.stats.station = stas[n]
                stmp = Stream().extend([trtmp.copy()])
                
            st.extend(stmp.copy()) 
    
    # Edit 'start' time if using offset option
    if opt.maxdt:
        dts = np.fromstring(opt.offset, sep=',')
        for n, tr in enumerate(st):
            tr.stats.starttime = tr.stats.starttime-dts[n]
    
    st = st.trim(starttime=tstart, endtime=tend, pad=True, fill_value=0)
    stC = st.copy()
    
    return st, stC
Example #8
0
def grab_file_data(filepath, scnl, tstart, tend, fill_value=0):
    import obspy
    from obspy import Stream, Trace
    import glob, os, itertools

    stas = []
    chas = []
    nets = []
    locs = []
    for sta in scnl:
        stas.append(sta.split('.')[0])
        chas.append(sta.split('.')[1])
        nets.append(sta.split('.')[2])
        if len(sta) == 4:
            locs.append(sta.split('.')[3])
        else:
            locs.append('')

    st = Stream()

    #if opt.server == 'file':
    if True:

        # Generate list of files
        #if opt.server == 'file':
        flist = list(
            itertools.chain.from_iterable(
                glob.iglob(os.path.join(root, "*"))
                for root, dirs, files in os.walk(filepath)))
        # "*" takes the place of wildcard lists, see REDPy documentation

        # Determine which subset of files to load based on start and end times and
        # station name; we'll fully deal with stations below
        flist_sub = []
        for f in flist:
            # Load header only
            stmp = obspy.read(f, headonly=True)
            # Check if station is contained in the stas list
            if stmp[0].stats.station in stas:
                # Check if contains either start or end time
                ststart = stmp[0].stats.starttime
                stend = stmp[0].stats.endtime
                if (ststart <= tstart and tstart <= stend) or (
                        ststart <= tend
                        and tend <= stend) or (tstart <= stend
                                               and ststart <= tend):
                    flist_sub.append(f)

        # Fully load data from file
        stmp = Stream()
        for f in flist_sub:
            tmp = obspy.read(f, starttime=tstart, endtime=tend)
            if len(tmp) > 0:
                stmp = stmp.extend(tmp)

        # Filter and merge
        #stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax, corners=2,
        #    zerophase=True)
        #stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
        #for m in range(len(stmp)):
        #    if stmp[m].stats.sampling_rate != opt.samprate:
        #        stmp[m] = stmp[m].resample(opt.samprate)
        stmp = stmp.merge(method=1, fill_value=fill_value)

        # Only grab stations/channels that we want and in order
        netlist = []
        stalist = []
        chalist = []
        loclist = []
        for s in stmp:
            stalist.append(s.stats.station)
            chalist.append(s.stats.channel)
            netlist.append(s.stats.network)
            loclist.append(s.stats.location)

        # Find match of SCNL in header or fill empty
        for n in range(len(stas)):
            for m in range(len(stalist)):
                if (stas[n] in stalist[m] and chas[n] in chalist[m]
                        and nets[n] in netlist[m] and locs[n] in loclist[m]):
                    st = st.append(stmp[m])
            if len(st) == n:
                print("Couldn't find " + stas[n] + '.' + chas[n] + '.' +
                      nets[n] + '.' + locs[n])
                trtmp = Trace()
                trtmp.stats.station = stas[n]
                st = st.append(trtmp.copy())

        if len(st) > 1:
            if fill_value == 0 or fill_value == None:
                st.detrend('demean')
                st.taper(max_percentage=0.01)
            st.merge(fill_value=fill_value)
        st.trim(tstart, tend, pad=0)
        st.detrend('demean')

    print(st)
    return st
Example #9
0
def get_stream(datasource,
               scnl,
               tstart,
               tend,
               fill_value=0,
               filepattern='*',
               filter=None,
               samprate=100,
               verbose=False):
    """
    Generalized (and more robust) way to retrieve waveform data through ObsPy
    Download data from files in a folder, from IRIS, or a Earthworm waveserver
    
    A note on SAC/miniSEED files: as this makes no assumptions about the naming scheme of
    your data files, please ensure that your headers contain the correct SCNL information!
    tstart: UTCDateTime of beginning of period of interest
    tend: UTCDateTime of end of period of interest
    
    filepattern='*'
     You can specify a pattern for your files to reduce the files within the directory
     searched. For example, filepattern=2019.06.*.mseed if your files are miniSEED files
     named by date and you only want those from June 2019. Simple wildcarding is supported
     (i.e., * and ?, [] for ranges of values or lists) but not full regular expressions.
     
    samprate=100
     Resamples all waveforms to the same sample rate.
    
    Returns ObsPy stream objects
    
    Based on code by Alicia Hotovec-Ellis and Aaron Wech.
    
    Example:
    >>> get_stream(['vdap.org', 16024], ['HSR.EHZ.CC.--'], '2004-09-28T00:00:00', '2004-09-28T01:00:00')
    >>> get_stream(['file', '/Users/vdapseismo/data/'], ['HSR.EHZ.CC.--'], '2004-09-28T00:00:00', '2004-09-28T01:00:00')
    >>> get_stream(['IRIS'], ['HSR.EHZ.CC.--'], '2004-09-28T00:00:00', '2004-09-28T01:00:00')
    """

    from obspy import UTCDateTime
    import obspy
    from obspy.clients.fdsn import Client
    from obspy.clients.earthworm import Client as EWClient
    from obspy.core.trace import Trace
    from obspy.core.stream import Stream
    from obspy.signal.trigger import coincidence_trigger
    import numpy as np
    from scipy import stats
    from scipy.fftpack import fft
    import glob, os, itertools

    #print(datasource)
    #print(scnl)
    #print(tstart)
    #print(tend)

    tstart = UTCDateTime(tstart)
    tend = UTCDateTime(tend)

    nets = []
    stas = []
    locs = []
    chas = []
    for s in scnl:
        #print(s)
        nets.append(s.split('.')[2])
        stas.append(s.split('.')[0])
        locs.append(s.split('.')[3])
        chas.append(s.split('.')[1])

    st = Stream()

    if '/' in datasource:
        # Retrieve data from file structure

        flist = list(
            itertools.chain.from_iterable(
                glob.iglob(os.path.join(root, filepattern))
                for root, dirs, files in os.walk(datasource)))

        # Determine which subset of files to load based on start and end times and
        # station name; we'll fully deal with stations below
        flist_sub = []
        for f in flist:
            # Load header only
            stmp = obspy.read(f, headonly=True)
            # Check if station is contained in the stas list
            if stmp[0].stats.station in stas:
                # Check if contains either start or end time
                ststart = stmp[0].stats.starttime
                stend = stmp[0].stats.endtime
                if (ststart <= tstart and tstart <= stend) or (
                        ststart <= tend
                        and tend <= stend) or (tstart <= stend
                                               and ststart <= tend):
                    flist_sub.append(f)

        # Fully load data from file
        stmp = Stream()
        for f in flist_sub:
            tmp = obspy.read(f, starttime=tstart, endtime=tend)
            if len(tmp) > 0:
                stmp = stmp.extend(tmp)

        # merge
        stmp = stmp.taper(max_percentage=0.01)
        for m in range(len(stmp)):
            if stmp[m].stats.sampling_rate != samprate:
                stmp[m] = stmp[m].resample(samprate)
        stmp = stmp.merge(method=1, fill_value=fill_value)

        # Only grab stations/channels that we want and in order
        netlist = []
        stalist = []
        chalist = []
        loclist = []
        for s in stmp:
            stalist.append(s.stats.station)
            chalist.append(s.stats.channel)
            netlist.append(s.stats.network)
            loclist.append(s.stats.location)

        # Find match of SCNL in header or fill empty
        for n in range(len(stas)):
            for m in range(len(stalist)):
                if (stas[n] in stalist[m] and chas[n] in chalist[m]
                        and nets[n] in netlist[m] and locs[n] in loclist[m]):
                    st = st.append(stmp[m])
            if len(st) == n:
                print('No data found for {}.{}.{}.{}'.format(
                    stas[n], chas[n], nets[n], locs[n]))
                trtmp = Trace()
                trtmp.stats.sampling_rate = samprate
                trtmp.stats.station = stas[n]
                st = st.append(trtmp.copy())

    else:
        # retrieve data from server

        if '.' not in datasource:
            client = Client(datasource)
        else:
            datasource = datasource.split(':')
            client = EWClient(datasource[0], int(datasource[1]))

        for n in range(len(stas)):
            try:
                stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                                            tstart, tend)
                for m in range(len(stmp)):
                    #stmp[m].data = np.ma.masked_where(stmp[m].data == -2**31, stmp[m].data) # masks out all values of -2**31 (Winston NaN Token)
                    #stmp[m] = stmp[m].split().merge(method=0, fill_value='interpolate')[0] # splits trace at masked values; then re-merges using linear interpolation
                    stmp[m].data = np.where(stmp[m].data == -2**31, 0,
                                            stmp[m].data)
                    if stmp[m].stats.sampling_rate != samprate:
                        stmp[m] = stmp[m].resample(samprate)
                stmp = stmp.taper(max_percentage=0.01)
                stmp = stmp.merge(method=1, fill_value=fill_value)
            except (obspy.clients.fdsn.header.FDSNException):
                try:  # try again
                    stmp = client.get_waveforms(nets[n], stas[n], locs[n],
                                                chas[n], tstart, tend)
                    for m in range(len(stmp)):
                        #stmp[m].data = np.ma.masked_where(stmp[m].data == -2**31, stmp[m].data) # masks out all values of -2**31 (Winston NaN Token)
                        #stmp[m] = stmp[m].split().merge(method=0, fill_value='interpolate')[0] # splits trace at masked values; then re-merges using linear interpolation
                        stmp[m].data = np.where(stmp[m].data == -2**31, 0,
                                                stmp[m].data)
                        if stmp[m].stats.sampling_rate != samprate:
                            stmp[m] = stmp[m].resample(samprate)
                    stmp = stmp.taper(max_percentage=0.01)
                    stmp = stmp.merge(method=1, fill_value=fill_value)
                except (obspy.clients.fdsn.header.FDSNException):
                    print('No data found for {0}.{1}'.format(stas[n], nets[n]))
                    trtmp = Trace()
                    trtmp.stats.sampling_rate = samprate
                    trtmp.stats.station = stas[n]
                    stmp = Stream().extend([trtmp.copy()])

            # Last check for length; catches problem with empty waveserver
            if len(stmp) != 1:
                print('No data found for {}.{}.{}.{}'.format(
                    stas[n], chas[n], nets[n], locs[n]))
                trtmp = Trace()
                trtmp.stats.sampling_rate = samprate
                trtmp.stats.station = stas[n]
                stmp = Stream().extend([trtmp.copy()])

            st.extend(stmp.copy())

    st = st.trim(starttime=tstart,
                 endtime=tend,
                 pad=True,
                 fill_value=fill_value)

    return st
Example #10
0
def getData(tstart, tend, opt):
    """
    Download data from files in a folder, from IRIS, or a Earthworm waveserver
    
    A note on SAC/miniSEED files: as this makes no assumptions about the naming scheme of
    your data files, please ensure that your headers contain the correct SCNL information!

    tstart: UTCDateTime of beginning of period of interest
    tend: UTCDateTime of end of period of interest
    opt: Options object describing station/run parameters
    
    Returns ObsPy stream objects, one for cutting and the other for triggering
    """

    nets = opt.network.split(',')
    stas = opt.station.split(',')
    locs = opt.location.split(',')
    chas = opt.channel.split(',')

    st = Stream()

    if opt.server == 'SAC' or opt.server == 'miniSEED':

        # Generate list of files
        if opt.server == 'SAC':
            flist = glob.glob(opt.sacdir + '*.sac') + glob.glob(opt.sacdir +
                                                                '*.SAC')
        elif opt.server == 'miniSEED':
            flist = glob.glob(opt.mseeddir +
                              '*.mseed') + glob.glob(opt.mseeddir + '*.MSEED')

        # Load data from file
        stmp = Stream()
        for f in flist:
            tmp = obspy.read(f, starttime=tstart, endtime=tend)
            if len(tmp) > 0:
                stmp = stmp.extend(tmp)

        # Filter and merge
        stmp = stmp.filter('bandpass',
                           freqmin=opt.fmin,
                           freqmax=opt.fmax,
                           corners=2,
                           zerophase=True)
        stmp = stmp.taper(0.05, type='hann', max_length=opt.mintrig)
        for m in range(len(stmp)):
            if stmp[m].stats.sampling_rate != opt.samprate:
                stmp[m] = stmp[m].resample(opt.samprate)
        stmp = stmp.merge(method=1, fill_value=0)

        # Only grab stations/channels that we want and in order
        netlist = []
        stalist = []
        chalist = []
        loclist = []
        for s in stmp:
            stalist.append(s.stats.station)
            chalist.append(s.stats.channel)
            netlist.append(s.stats.network)
            loclist.append(s.stats.location)

        # Find match of SCNL in header or fill empty
        for n in range(len(stas)):
            for m in range(len(stalist)):
                if (stas[n] in stalist[m] and chas[n] in chalist[m]
                        and nets[n] in netlist[m] and locs[n] in loclist[m]):
                    st = st.append(stmp[m])
            if len(st) == n:
                print("Couldn't find " + stas[n] + '.' + chas[n] + '.' +
                      nets[n] + '.' + locs[n])
                trtmp = Trace()
                trtmp.stats.sampling_rate = opt.samprate
                trtmp.stats.station = stas[n]
                st = st.append(trtmp.copy())

    else:

        if '.' not in opt.server:
            client = Client(opt.server)
        else:
            client = EWClient(opt.server, opt.port)

        for n in range(len(stas)):
            try:
                stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                                            tstart, tend)
                stmp = stmp.filter('bandpass',
                                   freqmin=opt.fmin,
                                   freqmax=opt.fmax,
                                   corners=2,
                                   zerophase=True)
                stmp = stmp.taper(0.05, type='hann', max_length=opt.mintrig)
                for m in range(len(stmp)):
                    if stmp[m].stats.sampling_rate != opt.samprate:
                        stmp[m] = stmp[m].resample(opt.samprate)
                stmp = stmp.merge(method=1, fill_value=0)
            except (obspy.fdsn.header.FDSNException):
                try:  # try again
                    stmp = client.get_waveforms(nets[n], stas[n], locs[n],
                                                chas[n], tstart, tend)
                    stmp = stmp.filter('bandpass',
                                       freqmin=opt.fmin,
                                       freqmax=opt.fmax,
                                       corners=2,
                                       zerophase=True)
                    stmp = stmp.taper(0.05,
                                      type='hann',
                                      max_length=opt.mintrig)
                    for m in range(len(stmp)):
                        if stmp[m].stats.sampling_rate != opt.samprate:
                            stmp[m] = stmp[m].resample(opt.samprate)
                    stmp = stmp.merge(method=1, fill_value=0)
                except (obspy.fdsn.header.FDSNException):
                    print('No data found for {0}.{1}'.format(stas[n], nets[n]))
                    trtmp = Trace()
                    trtmp.stats.sampling_rate = opt.samprate
                    trtmp.stats.station = stas[n]
                    stmp = Stream().extend([trtmp.copy()])
            st.extend(stmp.copy())

    st = st.trim(starttime=tstart, endtime=tend, pad=True, fill_value=0)
    stC = st.copy()

    return st, stC
Example #11
0
    def detect_stalta(self):

        STA_len = self.params["STA_len"]
        LTA_len = self.params["LTA_len"]
        STALTA_thresh = self.params["STALTA_thresh"]
        det_off_win = self.params["no_det_win"]

        try:
            devices = self.traces.data["device_id"].unique()
        except Exception as exception:
            logging.error(exception)
            devices = []

        for device in devices:

            for channel in ["x", "y", "z"]:

                trace = self.traces.data[self.traces.data["device_id"] ==
                                         device][channel].to_numpy()
                time = self.traces.data[self.traces.data["device_id"] ==
                                        device]["cloud_t"]
                sr = self.traces.data[self.traces.data["device_id"] ==
                                      device]["sr"].iloc[0]

                if len(trace) > int(np.ceil(sr * (STA_len + LTA_len))):

                    # set new trace
                    tr = Trace()
                    tr.data = trace
                    tr.stats.delta = 1 / sr
                    tr.stats.channel = channel
                    tr.stats.station = device

                    # tr.filter("highpass", freq=0.2)
                    tr.detrend(type="constant")

                    tr_orig = tr.copy()
                    std = np.std(tr_orig.data[:int(STA_len * sr)])

                    tr.trigger(
                        "recstalta",
                        sta=self.params["STA_len"],
                        lta=self.params["LTA_len"],
                    )

                    (ind, ) = np.where(tr.data > STALTA_thresh)

                    if len(ind) > 0:

                        det_time = time.iloc[ind[0]]

                        past_detections = self.detections.data[
                            (self.detections.data["device_id"] == device)
                            & (self.detections.data["cloud_t"] - det_time +
                               det_off_win) > 0]

                        if (past_detections.shape[0]
                                == 0) & (std <= self.params["max_std"]):

                            # Get event ID
                            # timestamp
                            timestamp = datetime.utcfromtimestamp(det_time)
                            year = str(timestamp.year - 2000).zfill(2)
                            month = str(timestamp.month).zfill(2)
                            day = str(timestamp.day).zfill(2)
                            hour = str(timestamp.hour).zfill(2)
                            minute = str(timestamp.minute).zfill(2)
                            detection_id = "D_" + year + month + day + hour + minute

                            new_detection = pd.DataFrame(
                                {
                                    "detection_id": detection_id,
                                    "device_id": device,
                                    "cloud_t": det_time,
                                    "mag1": None,
                                    "mag2": None,
                                    "mag3": None,
                                    "mag4": None,
                                    "mag5": None,
                                    "mag6": None,
                                    "mag7": None,
                                    "mag8": None,
                                    "mag9": None,
                                    "event_id": None,
                                },
                                index=[0],
                            )

                            # plot all detections and save in obj/detections folder
                            if self.params["plot_detection"]:
                                self.plot_detection(tr_orig, tr, device,
                                                    detection_id, std)

                            self.detections.update(new_detection)
Example #12
0
def getData(tstart, tend, opt):

    """
    Download data from files in a folder, from IRIS, or a Earthworm waveserver
    
    A note on SAC/miniSEED files: as this makes no assumptions about the naming scheme of
    your data files, please ensure that your headers contain the correct SCNL information!

    tstart: UTCDateTime of beginning of period of interest
    tend: UTCDateTime of end of period of interest
    opt: Options object describing station/run parameters
    
    Returns ObsPy stream objects, one for cutting and the other for triggering
    """    
    
    nets = opt.network.split(',')
    stas = opt.station.split(',')
    locs = opt.location.split(',')
    chas = opt.channel.split(',')
    
    st = Stream()
    
    if opt.server == 'SAC' or opt.server == 'miniSEED':
    
        # Generate list of files
        if opt.server == 'SAC':
            flist = list(itertools.chain.from_iterable(glob.iglob(os.path.join(
                root,'*.sac')) for root, dirs, files in os.walk(opt.sacdir)))+list(
                itertools.chain.from_iterable(glob.iglob(os.path.join(
                root,'*.SAC')) for root, dirs, files in os.walk(opt.sacdir)))
        elif opt.server == 'miniSEED':
            flist = list(itertools.chain.from_iterable(glob.iglob(os.path.join(
                root,'*.mseed')) for root, dirs, files in os.walk(opt.mseeddir)))+list(
                itertools.chain.from_iterable(glob.iglob(os.path.join(
                root,'*.MSEED')) for root, dirs, files in os.walk(opt.mseeddir)))
                
        # Determine which subset of files to load based on start and end times and
        # station name; we'll fully deal with stations below
        flist_sub = []
        for f in flist:
            # Load header only
            stmp = obspy.read(f, headonly=True)
            # Check if station is contained in the stas list
            if stmp[0].stats.station in stas:
                # Check if contains either start or end time
                ststart = stmp[0].stats.starttime
                stend = stmp[0].stats.endtime
                if (ststart<=tstart and tstart<=stend) or (ststart<=tend and
                    tend<=stend) or (tstart<=stend and ststart<=tend):
                    flist_sub.append(f)
        
        # Fully load data from file
        stmp = Stream()
        for f in flist_sub:
            tmp = obspy.read(f, starttime=tstart, endtime=tend+opt.maxdt)
            if len(tmp) > 0:
                stmp = stmp.extend(tmp)
    
        # Filter and merge
        stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax, corners=2,
            zerophase=True)
        stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
        for m in range(len(stmp)):
            if stmp[m].stats.sampling_rate != opt.samprate:
                stmp[m] = stmp[m].resample(opt.samprate)
        stmp = stmp.merge(method=1, fill_value=0)
        
        # Only grab stations/channels that we want and in order
        netlist = []
        stalist = []
        chalist = []
        loclist = []
        for s in stmp:
            stalist.append(s.stats.station)
            chalist.append(s.stats.channel)
            netlist.append(s.stats.network)
            loclist.append(s.stats.location)
            
        # Find match of SCNL in header or fill empty
        for n in range(len(stas)):
            for m in range(len(stalist)):
                if (stas[n] in stalist[m] and chas[n] in chalist[m] and nets[n] in
                    netlist[m] and locs[n] in loclist[m]):
                    st = st.append(stmp[m])
            if len(st) == n:
                print("Couldn't find "+stas[n]+'.'+chas[n]+'.'+nets[n]+'.'+locs[n])
                trtmp = Trace()
                trtmp.stats.sampling_rate = opt.samprate
                trtmp.stats.station = stas[n]
                st = st.append(trtmp.copy())
    
    else:   
     
        if '.' not in opt.server:
            client = Client(opt.server)
        else:
            client = EWClient(opt.server, opt.port)
        
        for n in range(len(stas)):
            try:
                stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                        tstart, tend+opt.maxdt)
                stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax,
                    corners=2, zerophase=True)
                stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
                for m in range(len(stmp)):
                    if stmp[m].stats.sampling_rate != opt.samprate:
                        stmp[m] = stmp[m].resample(opt.samprate)
                stmp = stmp.merge(method=1, fill_value=0)
            except (obspy.clients.fdsn.header.FDSNException):
                try: # try again
                    stmp = client.get_waveforms(nets[n], stas[n], locs[n], chas[n],
                            tstart, tend+opt.maxdt)
                    stmp = stmp.filter('bandpass', freqmin=opt.fmin, freqmax=opt.fmax,
                        corners=2, zerophase=True)
                    stmp = stmp.taper(0.05,type='hann',max_length=opt.mintrig)
                    for m in range(len(stmp)):
                        if stmp[m].stats.sampling_rate != opt.samprate:
                            stmp[m] = stmp[m].resample(opt.samprate)
                    stmp = stmp.merge(method=1, fill_value=0)
                except (obspy.clients.fdsn.header.FDSNException):
                    print('No data found for {0}.{1}'.format(stas[n],nets[n]))
                    trtmp = Trace()
                    trtmp.stats.sampling_rate = opt.samprate
                    trtmp.stats.station = stas[n]
                    stmp = Stream().extend([trtmp.copy()])
                                            
            # Last check for length; catches problem with empty waveserver
            if len(stmp) != 1:
                print('No data found for {0}.{1}'.format(stas[n],nets[n]))
                trtmp = Trace()
                trtmp.stats.sampling_rate = opt.samprate
                trtmp.stats.station = stas[n]
                stmp = Stream().extend([trtmp.copy()])
                
            st.extend(stmp.copy()) 
    
    # Edit 'start' time if using offset option
    if opt.maxdt:
        dts = np.fromstring(opt.offset, sep=',')
        for n, tr in enumerate(st):
            tr.stats.starttime = tr.stats.starttime-dts[n]
    
    st = st.trim(starttime=tstart, endtime=tend, pad=True, fill_value=0)
    stC = st.copy()
    
    return st, stC