Esempio n. 1
0
 def test_align(self):
     """Check that alignment does as expected."""
     test_stream = Stream(read()[0])
     # Shift it
     length = 15
     st1 = test_stream.copy().trim(test_stream[0].stats.starttime + 3,
                                   test_stream[0].stats.starttime +
                                   3 + length)
     st2 = test_stream.trim(test_stream[0].stats.starttime,
                            test_stream[0].stats.starttime + length)
     aligned = subspace.align_design(design_set=[st1.copy(), st2.copy()],
                                     shift_len=5, reject=0.3,
                                     multiplex=False, plot=False)
     self.assertEqual(aligned[0][0].stats.starttime,
                      aligned[1][0].stats.starttime)
Esempio n. 2
0
def stack_party(party,
                sac_dir,
                method='linear',
                filt_params=None,
                align=True,
                shift_len=0.1,
                prepick=2.,
                postpick=5.,
                reject=0.7,
                normalize=False,
                plot=False,
                outdir=None):
    """
    Return a stream for the linear stack of the templates in a multiplet.

    The approach here is to first stack all of the detections in a family
    over the rejection ccc threshold and THEN stack the Family stacks into
    the final stack for the multiplet. This avoids attempting to correlate
    detections from different Families with each other, which is nonsensical.

    :param party: Party for the multiplet we're interested in
    :param sac_dir: Directory of SAC files made for Stefan
    :param method: Stacking method: 'linear' or 'PWS'
    :param filt_params: (optional) Dictionary of filter parameters to use
        before aligning waveforms. Keys must be 'highcut', 'lowcut',
        'filt_order', and 'samp_rate'
    :param align: Whether or not to align the waveforms
    :param shift_len: Allowed shift in aligning in seconds
    :param reject: Correlation coefficient cutoff in aligning
    :param normalize: Whether to normalize before stacking
    :param plot: Alignment plot flag
    :return:
    """

    sac_dirs = glob('{}/2*'.format(sac_dir))
    fam_stacks = {}
    for fam in party:
        fam_id = fam.template.event.resource_id
        print('For Family {}'.format(fam_id))
        eids = [str(ev.resource_id).split('/')[-1] for ev in fam.catalog]
        raws = []
        for s_dir in sac_dirs:
            if s_dir.split('/')[-1] in eids:
                raws.append(
                    read('{}/*'.format(s_dir)).merge(fill_value='interpolate'))
        # Stupid check for empty det directories. Not yet resolved
        lens = [len(raw) for raw in raws]
        if len(lens) == 0: continue
        if max(lens) == 0: continue
        print('Removing all traces without 3001 samples')
        for st in raws:
            for tr in st.copy():
                if len(tr.data) != 3001:
                    st.remove(tr)
        if filt_params:
            for raw in raws:
                shortproc(raw,
                          lowcut=filt_params['lowcut'],
                          highcut=filt_params['highcut'],
                          filt_order=filt_params['filt_order'],
                          samp_rate=filt_params['samp_rate'])
        print('Now trimming around pick times')
        z_streams = []
        for raw in raws:
            z_stream = Stream()
            for tr in raw.copy():
                if 'a' in tr.stats.sac:
                    strt = tr.stats.starttime
                    z_stream += tr.trim(
                        starttime=strt + tr.stats.sac['a'] - prepick,
                        endtime=strt + tr.stats.sac['a'] + postpick)
            if len(z_stream) > 0:
                z_streams.append(z_stream)
        # At the moment, the picks are based on P-arrival correlation already!
        if align:
            z_streams = align_design(z_streams,
                                     shift_len=shift_len,
                                     reject=reject,
                                     multiplex=False,
                                     no_missed=False,
                                     plot=plot)
        if method == 'linear':
            fam_stacks[fam_id] = linstack(z_streams, normalize=normalize)
        elif method == 'PWS':
            fam_stacks[fam_id] = PWS_stack(z_streams, normalize=normalize)
    if plot:
        # Plot up the stacks of the Families first
        for id, fam_stack in fam_stacks.items():
            fam_stack.plot(equal_scale=False)
    if outdir:
        if not os.path.isdir(outdir):
            os.mkdir(outdir)
        for id, fam_stack in fam_stacks.items():
            filename = '{}/Family_{}_stack.mseed'.format(
                outdir,
                str(id).split('/')[-1])
            fam_stack.write(filename, format='MSEED')
    return fam_stacks
Esempio n. 3
0
def temp_det_dict_shifts(cat,
                         temp_cat,
                         det_dir,
                         ccs_thresh,
                         shift_len,
                         plot=False):
    """
    Function to create a dictionary of {temp_id: {...relevant info...}}
    including shift information
    :param cat: catalog of detections
    :param temp_cat: catalog of templates
    :param det_dir: directory of detection waveforms
    :param ccs_thresh: cc threshold for alignment
    :param shift_len: allowed shift for alignment (sec)
    :param plot: plot bool
    :return: template dictionary
    """
    # Make convenience dict of {temp_id: index} for use in creating template_dict
    ind_dict = {}
    for i, ev in enumerate(cat):
        ind_dict[ev.resource_id] = i
    temp_files = glob(det_dir)
    template_dict = {}
    for filename in temp_files:
        temp_rid = ResourceIdentifier('smi:org.gfz-potsdam.de/geofon/' +
                                      filename.split('/')[-1].split('_')[0])
        det_rid = ResourceIdentifier('smi:local/' +
                                     filename.split('/')[-1].rstrip('.mseed'))
        if det_rid in ind_dict:
            if temp_rid not in template_dict and str(det_rid).split(
                    '/')[-1].split('_')[-1] == 'self':
                template_dict[temp_rid] = {
                    det_rid: {
                        'stream': read(filename),
                        'shifts': {},
                        'ind': ind_dict[det_rid],
                        'align_stream': read(filename)
                    },
                    'temp_mag': [
                        ev.preferred_magnitude().mag for ev in temp_cat
                        if ev.resource_id == temp_rid
                    ][0],
                    'temp_ind':
                    ind_dict[det_rid]
                }
            elif temp_rid not in template_dict:
                template_dict[temp_rid] = {
                    det_rid: {
                        'stream': read(filename),
                        'shifts': {},
                        'ind': ind_dict[det_rid],
                        'align_stream': read(filename)
                    },
                    'temp_mag': None
                }
            elif str(det_rid).split('/')[-1].split('_')[-1] == 'self':
                template_dict[temp_rid][det_rid] = {
                    'stream': read(filename),
                    'shifts': {},
                    'ind': ind_dict[det_rid],
                    'align_stream': read(filename)
                }
                template_dict[temp_rid]['temp_mag'] = [
                    ev.preferred_magnitude().mag for ev in temp_cat
                    if ev.resource_id == temp_rid
                ][0]
                template_dict[temp_rid]['temp_ind'] = ind_dict[det_rid]
            else:
                template_dict[temp_rid][det_rid] = {
                    'stream': read(filename),
                    'shifts': {},
                    'ind': ind_dict[det_rid],
                    'align_stream': read(filename)
                }
    # Trim the waveforms to shorter lengths
    # Templates from /2015_det2cats/* are 3 sec pre-pick and 7 sec post-pick
    for tid, det_dict in template_dict.iteritems():
        for evid, ev_dict in det_dict.iteritems():
            if evid != 'temp_mag' and evid != 'temp_ind':
                for tr in ev_dict['stream']:
                    tr.trim(starttime=tr.stats.starttime + 2.7,
                            endtime=tr.stats.endtime - 5)
                for tr in ev_dict['align_stream']:
                    tr.trim(starttime=tr.stats.starttime + 2.9,
                            endtime=tr.stats.endtime - 6)
    # Variable of random keys for plotting
    samp_ids = [
        id for i, id in enumerate(template_dict.keys())
        if i in np.random.choice(
            range(len(template_dict)), len(template_dict) // 20, replace=False)
    ]
    # Now shift and save shift value
    for tid, det_dict in template_dict.iteritems():
        design_set = []
        design_inds = []
        print('Shifting waveforms for template %s' % str(tid))
        if plot:
            if tid in samp_ids: plotvar = True
            else: plotvar = False
        else: plotvar = False
        for eid, ev_dict in det_dict.iteritems():
            if eid != 'temp_mag' and eid != 'temp_ind':
                design_set.append(ev_dict['align_stream'])
                design_inds.append(ev_dict['ind'])
        aligned_streams = subspace.align_design(design_set,
                                                reject=ccs_thresh,
                                                multiplex=False,
                                                shift_len=shift_len,
                                                plot=plotvar)
        det_dict['aligned'] = aligned_streams
        det_dict['aligned_inds'] = design_inds
    return template_dict